|
|
@@ -0,0 +1,629 @@
|
|
|
+<template>
|
|
|
+ <div class="container">
|
|
|
+ <!-- 标题区域 -->
|
|
|
+ <div class="title">
|
|
|
+ <div class="title_text">考勤管理</div>
|
|
|
+ <div class="title_sub">Attendance Management</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 内容区域 -->
|
|
|
+ <div class="content">
|
|
|
+ <!-- 切换考勤区域 -->
|
|
|
+ <div class="btns">
|
|
|
+ <div
|
|
|
+ class="button"
|
|
|
+ :class="currentIndex === 0 ? 'active' : ''"
|
|
|
+ @click="handleChange(0)"
|
|
|
+ >
|
|
|
+ 学生考勤
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="button"
|
|
|
+ :class="currentIndex === 1 ? 'active' : ''"
|
|
|
+ @click="handleChange(1)"
|
|
|
+ >
|
|
|
+ 教师考勤
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 考勤统计区域 -->
|
|
|
+ <div class="sub_title">考勤统计</div>
|
|
|
+ <div class="stat_msg">
|
|
|
+ <div class="msg_change">
|
|
|
+ <div
|
|
|
+ class="change_box"
|
|
|
+ :class="currentTimeRang === 0 ? 'active' : ''"
|
|
|
+ @click="changeTimeRang(0)"
|
|
|
+ >
|
|
|
+ 本学期
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="change_box"
|
|
|
+ :class="currentTimeRang === 1 ? 'active' : ''"
|
|
|
+ @click="changeTimeRang(1)"
|
|
|
+ >
|
|
|
+ 本周
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class="change_box"
|
|
|
+ :class="currentTimeRang === 2 ? 'active' : ''"
|
|
|
+ @click="changeTimeRang(2)"
|
|
|
+ >
|
|
|
+ 本月
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="msg_detail">
|
|
|
+ <div class="detail_box">
|
|
|
+ <div class="box_num" ref="statDom">{{ statValue }}</div>
|
|
|
+ <div class="box_type">正常</div>
|
|
|
+ </div>
|
|
|
+ <div class="detail_box">
|
|
|
+ <div class="box_num" ref="statDom2">{{ statValue2 }}</div>
|
|
|
+ <div class="box_type">请假</div>
|
|
|
+ </div>
|
|
|
+ <div class="detail_box">
|
|
|
+ <div class="box_num" ref="statDom3">{{ statValue3 }}</div>
|
|
|
+ <div class="box_type">迟到</div>
|
|
|
+ </div>
|
|
|
+ <div class="detail_box">
|
|
|
+ <div class="box_num" ref="statDom4">{{ statValue4 }}</div>
|
|
|
+ <div class="box_type">超时打卡</div>
|
|
|
+ </div>
|
|
|
+ <div class="detail_box">
|
|
|
+ <div class="box_num" ref="statDom5">{{ statValue5 }}</div>
|
|
|
+ <div class="box_type">未打卡</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 考勤记录区域 -->
|
|
|
+ <div class="sub_title">考勤记录</div>
|
|
|
+ <div class="record_msg">
|
|
|
+ <!-- 搜索框区域 -->
|
|
|
+ <div class="record_search">
|
|
|
+ <div class="search_input">
|
|
|
+ <input type="text" placeholder="请输入部门查询" />
|
|
|
+ </div>
|
|
|
+ <div class="search_btn">查询</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 筛选框区域 -->
|
|
|
+ <div class="record_select">
|
|
|
+ 时间
|
|
|
+ <el-select
|
|
|
+ v-model="valueTime"
|
|
|
+ placeholder="请选择时间"
|
|
|
+ style="width: 150px"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in optionsTime"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ 类别
|
|
|
+ <el-select
|
|
|
+ v-model="valueType"
|
|
|
+ placeholder="请选择类别"
|
|
|
+ style="width: 150px"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in optionsType"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 表格区域 -->
|
|
|
+ <div class="record_form form">
|
|
|
+ <el-table :data="tableData">
|
|
|
+ <el-table-column
|
|
|
+ prop="class"
|
|
|
+ label="部门"
|
|
|
+ align="center"
|
|
|
+ width="60"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="type"
|
|
|
+ label="考勤类别"
|
|
|
+ align="center"
|
|
|
+ width="60"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="leave"
|
|
|
+ label="请假"
|
|
|
+ align="center"
|
|
|
+ width="50"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="timeout"
|
|
|
+ label="超时打卡"
|
|
|
+ align="center"
|
|
|
+ width="60"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="late"
|
|
|
+ label="迟到"
|
|
|
+ align="center"
|
|
|
+ width="50"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="not"
|
|
|
+ label="未打卡"
|
|
|
+ align="center"
|
|
|
+ width="60"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ prop="normal"
|
|
|
+ label="正常"
|
|
|
+ align="center"
|
|
|
+ width="62"
|
|
|
+ />
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 分页器区域 -->
|
|
|
+ <div class="pagination">
|
|
|
+ <el-pagination
|
|
|
+ v-model:current-page="currentPage"
|
|
|
+ v-model:page-size="pageSize"
|
|
|
+ layout="prev, pager, next, jumper"
|
|
|
+ :total="1000"
|
|
|
+ :pager-count="5"
|
|
|
+ small
|
|
|
+ background
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, onMounted } from "vue";
|
|
|
+import { countUpNum } from "@/utils/countUpNum";
|
|
|
+
|
|
|
+const statValue = ref(50);
|
|
|
+const statValue2 = ref(50);
|
|
|
+const statValue3 = ref(50);
|
|
|
+const statValue4 = ref(50);
|
|
|
+const statValue5 = ref(50);
|
|
|
+
|
|
|
+const statDom = ref();
|
|
|
+const statDom2 = ref();
|
|
|
+const statDom3 = ref();
|
|
|
+const statDom4 = ref();
|
|
|
+const statDom5 = ref();
|
|
|
+
|
|
|
+// 切换学生教师考勤 0学生 1教师
|
|
|
+const currentIndex = ref(0);
|
|
|
+// 切换考勤统计时间 0本学期 1本周 2本月
|
|
|
+const currentTimeRang = ref(0);
|
|
|
+// 分页器当前页
|
|
|
+const currentPage = ref(1);
|
|
|
+// 每页多少条
|
|
|
+const pageSize = ref(8);
|
|
|
+// 时间筛选框绑定数据
|
|
|
+const valueTime = ref("");
|
|
|
+// 类别筛选框绑定数据
|
|
|
+const valueType = ref("");
|
|
|
+// 类别筛选框绑定数组
|
|
|
+const optionsType = [
|
|
|
+ {
|
|
|
+ value: "0",
|
|
|
+ label: "全部",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "1",
|
|
|
+ label: "请假",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "2",
|
|
|
+ label: "迟到",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "3",
|
|
|
+ label: "超时打卡",
|
|
|
+ },
|
|
|
+];
|
|
|
+// 时间筛选框绑定数组
|
|
|
+const optionsTime = [
|
|
|
+ {
|
|
|
+ value: "0",
|
|
|
+ label: "今日",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "1",
|
|
|
+ label: "本周",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: "2",
|
|
|
+ label: "本月",
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+// 考勤记录表格数据
|
|
|
+const tableData = [
|
|
|
+ {
|
|
|
+ class: "七(15)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: "七(5)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: "七(5)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: "七(5)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: "七(5)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: "七(5)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: "七(5)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ class: "七(5)班",
|
|
|
+ type: "123",
|
|
|
+ leave: "13",
|
|
|
+ timeout: "45",
|
|
|
+ late: "123",
|
|
|
+ not: "41",
|
|
|
+ normal: "246",
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getCountUpNum();
|
|
|
+});
|
|
|
+
|
|
|
+// 学生教师考勤切换按钮回调
|
|
|
+const handleChange = (value: number) => {
|
|
|
+ if (currentIndex.value !== value) {
|
|
|
+ if (value === 0) {
|
|
|
+ currentIndex.value = 0;
|
|
|
+ } else if (value === 1) {
|
|
|
+ currentIndex.value = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 考勤统计切换时间范围按钮回调
|
|
|
+const changeTimeRang = (value: number) => {
|
|
|
+ if (currentTimeRang.value !== value) {
|
|
|
+ if (value === 0) {
|
|
|
+ currentTimeRang.value = 0;
|
|
|
+ } else if (value === 1) {
|
|
|
+ currentTimeRang.value = 1;
|
|
|
+ } else if (value === 2) {
|
|
|
+ currentTimeRang.value = 2;
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 改变分页器当前页时的回调
|
|
|
+const handleCurrentChange = (value: number) => {
|
|
|
+ console.log(value);
|
|
|
+};
|
|
|
+
|
|
|
+const getCountUpNum = () => {
|
|
|
+ countUpNum(statDom.value, statValue.value);
|
|
|
+ countUpNum(statDom2.value, statValue2.value);
|
|
|
+ countUpNum(statDom3.value, statValue3.value);
|
|
|
+ countUpNum(statDom4.value, statValue4.value);
|
|
|
+ countUpNum(statDom5.value, statValue5.value);
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.container {
|
|
|
+ width: 435px;
|
|
|
+ height: 951px;
|
|
|
+ color: #fff;
|
|
|
+ background-image: url(@/assets/images/box-bg.png);
|
|
|
+
|
|
|
+ .title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ width: 430px;
|
|
|
+ height: 47px;
|
|
|
+ font-family: "庞门正道标题体";
|
|
|
+ background-image: url(@/assets/images/title-bg.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+
|
|
|
+ .title_text {
|
|
|
+ margin-left: 38px;
|
|
|
+ font-size: 20px;
|
|
|
+ text-shadow: 0px 0px 9px #158eff;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title_sub {
|
|
|
+ margin-left: 19px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #215a8e;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .content {
|
|
|
+ padding: 20px 19px 0 14px;
|
|
|
+ height: 904px;
|
|
|
+
|
|
|
+ .btns {
|
|
|
+ display: flex;
|
|
|
+ margin-top: 4px;
|
|
|
+ height: 58px;
|
|
|
+
|
|
|
+ .button {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ margin-right: 18px;
|
|
|
+ width: 88px;
|
|
|
+ height: 32px;
|
|
|
+ font-size: 14px;
|
|
|
+ border-radius: 4px;
|
|
|
+ border: 1px solid #bef4f7;
|
|
|
+ background-image: linear-gradient(
|
|
|
+ rgba(156, 255, 248, 0.4),
|
|
|
+ rgba(152, 217, 237, 0.15),
|
|
|
+ rgba(188, 216, 247, 0.4)
|
|
|
+ );
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .active {
|
|
|
+ background-image: linear-gradient(
|
|
|
+ rgba(29, 242, 228, 0.8),
|
|
|
+ rgba(61, 198, 239, 0.4),
|
|
|
+ rgba(26, 94, 232, 0.8)
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .sub_title {
|
|
|
+ padding-left: 28px;
|
|
|
+ height: 35px;
|
|
|
+ line-height: 18px;
|
|
|
+ color: #abd6ff;
|
|
|
+ font-weight: bold;
|
|
|
+ background-image: url(@/assets/images/title-bg2.png);
|
|
|
+ background-size: 100% 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .stat_msg {
|
|
|
+ height: 150px;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .msg_change {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin: 22px 0 22px 195px;
|
|
|
+ padding: 2px;
|
|
|
+ width: 200px;
|
|
|
+ height: 32px;
|
|
|
+ font-size: 14px;
|
|
|
+ border-radius: 2px;
|
|
|
+ border: 1px solid #9c9c9c;
|
|
|
+
|
|
|
+ .change_box {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 61px;
|
|
|
+ border-radius: 2px;
|
|
|
+ background-color: rgba(114, 151, 179, 0.3);
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+
|
|
|
+ .active {
|
|
|
+ border: 1px solid #70b7fa;
|
|
|
+ background-color: rgba(114, 151, 179, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .msg_detail {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-evenly;
|
|
|
+ height: 74px;
|
|
|
+
|
|
|
+ .detail_box {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .box_num {
|
|
|
+ font-size: 20px;
|
|
|
+ font-family: "庞门正道标题体";
|
|
|
+ }
|
|
|
+
|
|
|
+ .box_type {
|
|
|
+ margin-top: 10px;
|
|
|
+ font-size: 12px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .record_msg {
|
|
|
+ height: 600px;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ .record_search {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin-top: 20px;
|
|
|
+ height: 32px;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ .search_input {
|
|
|
+ padding: 0 12px;
|
|
|
+ width: 330px;
|
|
|
+ height: 32px;
|
|
|
+ border-radius: 2px;
|
|
|
+ border: 1px solid #9c9c9c;
|
|
|
+ background-color: rgba(48, 75, 95, 0.5);
|
|
|
+
|
|
|
+ input {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ color: #fff;
|
|
|
+ border: none;
|
|
|
+ outline: none;
|
|
|
+ background-color: transparent;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .search_btn {
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ width: 58px;
|
|
|
+ height: 32px;
|
|
|
+ background-image: linear-gradient(
|
|
|
+ rgba(29, 242, 228, 0.8),
|
|
|
+ rgba(61, 198, 239, 0.4),
|
|
|
+ rgba(26, 94, 232, 0.8)
|
|
|
+ );
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .record_select {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-top: 20px;
|
|
|
+ height: 32px;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .record_form {
|
|
|
+ margin-top: 22px;
|
|
|
+ height: 370px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .pagination {
|
|
|
+ display: flex;
|
|
|
+ justify-content: flex-end;
|
|
|
+ margin-top: 25px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 修改select背景颜色
|
|
|
+::v-deep(.el-input__wrapper) {
|
|
|
+ background: transparent;
|
|
|
+ background-color: rgba(48, 75, 95, 0.5);
|
|
|
+}
|
|
|
+
|
|
|
+// 修改select筛选框文字颜色
|
|
|
+::v-deep(.el-input__inner) {
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+/*最外层透明*/
|
|
|
+.form ::v-deep(.el-table),
|
|
|
+.form ::v-deep(.el-table__expanded-cell) {
|
|
|
+ background-color: transparent;
|
|
|
+ color: white;
|
|
|
+ border: none;
|
|
|
+}
|
|
|
+/* 表格内背景颜色 */
|
|
|
+.form ::v-deep(.el-table th),
|
|
|
+.form ::v-deep(.el-table tr),
|
|
|
+.form ::v-deep(.el-table td),
|
|
|
+::v-deep(.el-table th.el-table__cell.is-leaf) {
|
|
|
+ background-color: transparent !important;
|
|
|
+ color: white;
|
|
|
+ font-size: 12px;
|
|
|
+ border-color: rgba(255, 255, 255, 0.1);
|
|
|
+ height: 40px;
|
|
|
+}
|
|
|
+
|
|
|
+// 表格底部白线清除
|
|
|
+::v-deep(.el-table__inner-wrapper::before) {
|
|
|
+ height: 0;
|
|
|
+}
|
|
|
+
|
|
|
+// 修改表头背景颜色
|
|
|
+::v-deep(.el-table__header) {
|
|
|
+ background-color: rgba(58, 126, 199, 0.5);
|
|
|
+}
|
|
|
+// 清除表格默认padding
|
|
|
+::v-deep(.el-table .cell) {
|
|
|
+ padding: 0;
|
|
|
+}
|
|
|
+
|
|
|
+// 修改分页器未选中时的样式
|
|
|
+::v-deep(.el-pagination.is-background .btn-next),
|
|
|
+::v-deep(.el-pagination.is-background .btn-prev),
|
|
|
+::v-deep(.el-pagination.is-background .el-pager li:not(.disabled)) {
|
|
|
+ margin: 0 1px;
|
|
|
+ background-color: transparent;
|
|
|
+ border: 1px solid #707070;
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+
|
|
|
+// 修改分页器选中时的样式
|
|
|
+::v-deep(
|
|
|
+ .el-pagination.is-background .el-pager li:not(.is-disabled).is-active
|
|
|
+ ) {
|
|
|
+ color: #70b7fa;
|
|
|
+ border: 1px solid #70b7fa;
|
|
|
+}
|
|
|
+
|
|
|
+::v-deep(.el-pagination__goto),
|
|
|
+::v-deep(.el-pagination__classifier) {
|
|
|
+ color: #fff;
|
|
|
+}
|
|
|
+</style>
|