From a4d0446d7c1c1e56641fd4e887ad4d0ecd0534ca Mon Sep 17 00:00:00 2001
From: zhangwencui <1064582902@qq.com>
Date: 星期四, 05 三月 2026 17:43:55 +0800
Subject: [PATCH] 排班管理页面完成70%
---
src/api/personnelManagement/attendanceRules.js | 10
src/api/personnelManagement/class.js | 108 ++
src/views/personnelManagement/classsSheduling/index.vue | 2209 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue | 14
src/views/personnelManagement/attendanceCheckin/index.vue | 20
src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue | 6
6 files changed, 2,351 insertions(+), 16 deletions(-)
diff --git a/src/api/personnelManagement/attendanceRules.js b/src/api/personnelManagement/attendanceRules.js
index 021442e..5b07b8b 100644
--- a/src/api/personnelManagement/attendanceRules.js
+++ b/src/api/personnelManagement/attendanceRules.js
@@ -1,6 +1,6 @@
import request from "@/utils/request";
-// 鑾峰彇鎵撳崱瑙勫垯鍒楄〃
+// 鑾峰彇鐝鍒楄〃
export function getAttendanceRules(query) {
return request({
url: "/personalAttendanceLocationConfig/listPage",
@@ -9,7 +9,7 @@
});
}
-// 鏂板鎵撳崱瑙勫垯
+// 鏂板鐝
export function addAttendanceRule(data) {
return request({
url: "/personalAttendanceLocationConfig/add",
@@ -18,7 +18,7 @@
});
}
-// 鏇存柊鎵撳崱瑙勫垯
+// 鏇存柊鐝
export function updateAttendanceRule(data) {
return request({
url: "/attendanceRules/update",
@@ -27,7 +27,7 @@
});
}
-// 鍒犻櫎鎵撳崱瑙勫垯
+// 鍒犻櫎鐝
export function deleteAttendanceRule(ids) {
return request({
url: `/personalAttendanceLocationConfig/del`,
@@ -36,7 +36,7 @@
});
}
-// 鑾峰彇鍗曚釜鎵撳崱瑙勫垯璇︽儏
+// 鑾峰彇鍗曚釜鐝璇︽儏
export function getAttendanceRuleDetail(id) {
return request({
url: `/attendanceRules/detail/${id}`,
diff --git a/src/api/personnelManagement/class.js b/src/api/personnelManagement/class.js
new file mode 100644
index 0000000..cdba456
--- /dev/null
+++ b/src/api/personnelManagement/class.js
@@ -0,0 +1,108 @@
+// 鐝鐩稿叧鎺ュ彛
+
+import request from "@/utils/request";
+
+// 缁╂晥绠$悊-鐝-鍒嗛〉鏌ヨ
+export function page(query) {
+ return request({
+ url: "/performanceShift/page",
+ method: "get",
+ params: query,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-骞翠唤鍒嗛〉鏌ヨ
+export function pageYear(query) {
+ return request({
+ url: "/performanceShift/pageYear",
+ method: "get",
+ params: query,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-鎺掔彮
+export function add(data) {
+ return request({
+ url: "/performanceShift/add",
+ method: "post",
+ data: data,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-鏃堕棿閰嶇疆-鏌ヨ鏃堕棿閰嶇疆淇℃伅
+export function list(query) {
+ return request({
+ url: "/shiftTime/list",
+ method: "get",
+ params: query,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-鏃堕棿閰嶇疆-鏂板
+export function shiftAdd(data) {
+ return request({
+ url: "/shiftTime/add",
+ method: "post",
+ data: data,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-鏃堕棿閰嶇疆-淇敼
+export function shiftUpdate(data) {
+ return request({
+ url: "/shiftTime/update",
+ method: "post",
+ data: data,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-鏃堕棿閰嶇疆-鍒犻櫎
+export function shiftRemove(query) {
+ return request({
+ url: "/shiftTime/remove",
+ method: "delete",
+ params: query,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-瀵煎嚭
+export function exportFile(query) {
+ return request({
+ url: "/performanceShift/export",
+ method: "get",
+ params: query,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-瀵煎嚭
+export function obtainItemParameterList(query) {
+ return request({
+ url: "/laboratoryScope/obtainItemParameterList",
+ method: "get",
+ params: query,
+ });
+}
+
+// 缁╂晥绠$悊-鐝-鐝鐘舵�佷慨鏀�
+export function update(data) {
+ return request({
+ url: "/performanceShift/update",
+ method: "post",
+ data: data,
+ });
+}
+
+// 鑾峰彇鐢ㄦ埛鍒楄〃
+// export function selectUserCondition(query) {
+// return request({
+// url: "/system/newUser/selectUserCondition",
+// method: "get",
+// params: query,
+// });
+// }
+export function selectUserCondition() {
+ return request({
+ url: '/system/user/userListNoPage',
+ method: 'get'
+ })
+}
\ No newline at end of file
diff --git a/src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue b/src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue
index 11e21bc..49eafa9 100644
--- a/src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue
+++ b/src/views/personnelManagement/attendanceCheckin/checkinRules/components/form.vue
@@ -140,9 +140,9 @@
});
const dialogTitle = computed(() => {
- if (props.operationType === "add") return "鏂板鎵撳崱瑙勫垯";
- if (props.operationType === "edit") return "缂栬緫鎵撳崱瑙勫垯";
- return "鏌ョ湅鎵撳崱瑙勫垯";
+ if (props.operationType === "add") return "鏂板鐝";
+ if (props.operationType === "edit") return "缂栬緫鐝";
+ return "鏌ョ湅鐝";
});
// 琛ㄥ崟鏁版嵁
diff --git a/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue b/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue
index 1fd19f3..9064274 100644
--- a/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue
+++ b/src/views/personnelManagement/attendanceCheckin/checkinRules/index.vue
@@ -2,14 +2,14 @@
<div class="app-container">
<!-- 椤甸潰鏍囬鍜屾搷浣滄寜閽� -->
<div class="page-header">
- <div class="title">鎵撳崱瑙勫垯閰嶇疆</div>
+ <div class="title">鐝閰嶇疆</div>
<div class="actions">
<el-button type="primary"
@click="openForm('add')">
<el-icon>
<Plus />
</el-icon>
- 鏂板瑙勫垯
+ 鏂板鐝
</el-button>
</div>
</div>
@@ -50,7 +50,7 @@
</el-button>
</el-form-item>
</el-form> -->
- <!-- 瑙勫垯鍒楄〃 -->
+ <!-- 鐝鍒楄〃 -->
<el-card shadow="never"
class="mb16">
<el-table :data="tableData"
@@ -110,7 +110,7 @@
@pagination="paginationChange"
class="mt10" />
</el-card>
- <!-- 鏂板/缂栬緫瑙勫垯寮圭獥 -->
+ <!-- 鏂板/缂栬緫鐝寮圭獥 -->
<rule-form ref="ruleFormRef"
v-model="dialogVisible"
:operation-type="operationType"
@@ -206,7 +206,7 @@
return "";
};
- // 鏌ヨ瑙勫垯鍒楄〃
+ // 鏌ヨ鐝鍒楄〃
const fetchData = () => {
tableLoading.value = true;
getAttendanceRules({ ...page, ...searchForm })
@@ -240,9 +240,9 @@
dialogVisible.value = true;
};
- // 鍒犻櫎瑙勫垯
+ // 鍒犻櫎鐝
const handleDelete = id => {
- ElMessageBox.confirm("纭畾瑕佸垹闄よ繖鏉¤鍒欏悧锛�", "鍒犻櫎纭", {
+ ElMessageBox.confirm("纭畾瑕佸垹闄よ繖鏉$彮娆″悧锛�", "鍒犻櫎纭", {
confirmButtonText: "纭畾",
cancelButtonText: "鍙栨秷",
type: "warning",
diff --git a/src/views/personnelManagement/attendanceCheckin/index.vue b/src/views/personnelManagement/attendanceCheckin/index.vue
index f2d8776..9a3acfa 100644
--- a/src/views/personnelManagement/attendanceCheckin/index.vue
+++ b/src/views/personnelManagement/attendanceCheckin/index.vue
@@ -60,6 +60,15 @@
</el-descriptions>
</el-card> -->
<div class="attendance-operation">
+ <el-button @click="handleBack"
+ type="default"
+ size="small"
+ style="margin-right: 16px">
+ <el-icon>
+ <ArrowLeft />
+ </el-icon>
+ 杩斿洖鎺掔彮绠$悊
+ </el-button>
<!-- 鏌ヨ鏉′欢锛堢鐞嗗憳鑰冨嫟鏃ユ姤锛� -->
<el-form :model="searchForm"
:inline="true"
@@ -170,6 +179,7 @@
<script setup>
import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue";
+ import { useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import {
createPersonalAttendanceRecord,
@@ -178,9 +188,10 @@
} from "@/api/personnelManagement/personalAttendanceRecords.js";
import Pagination from "@/components/Pagination/index.vue";
import { deptTreeSelect } from "@/api/system/user.js";
- import { Refresh, Search } from "@element-plus/icons-vue";
+ import { Refresh, Search, ArrowLeft } from "@element-plus/icons-vue";
const { proxy } = getCurrentInstance();
+ const router = useRouter();
const tableLoading = ref(false);
// 鍒嗛〉鍙傛暟
const page = reactive({
@@ -445,6 +456,13 @@
fetchDeptOptions();
});
+ // 杩斿洖鎺掔彮绠$悊椤甸潰
+ const handleBack = () => {
+ router.push({
+ path: "/personnelManagement/classsSheduling/index",
+ });
+ };
+
onBeforeUnmount(() => {
if (timer) {
clearInterval(timer);
diff --git a/src/views/personnelManagement/classsSheduling/index.vue b/src/views/personnelManagement/classsSheduling/index.vue
new file mode 100644
index 0000000..bc5ed7f
--- /dev/null
+++ b/src/views/personnelManagement/classsSheduling/index.vue
@@ -0,0 +1,2209 @@
+<template>
+ <div class="class-page">
+ <div class="search-container">
+ <div class="search-form">
+ <div class="search-row">
+ <div class="search-item">
+ <label class="search-label">閫夋嫨鏃堕棿锛�</label>
+ <div class="search-input-group">
+ <el-date-picker v-model="query.year"
+ type="year"
+ size="small"
+ format="YYYY"
+ placeholder="閫夋嫨骞�"
+ @change="refreshTable()"
+ style="width: 90px"
+ :clearable="false" />
+ <el-select v-model="query.month"
+ clearable
+ placeholder="閫夋嫨鏈�"
+ style="width: 70px; margin-left: 8px"
+ size="small"
+ @change="refreshTable()">
+ <el-option v-for="item in monthOptions"
+ :key="item.value"
+ :label="item.label"
+ :value="item.value" />
+ </el-select>
+ </div>
+ </div>
+ <div class="search-item">
+ <el-input v-model="query.userName"
+ placeholder="璇疯緭鍏ヤ汉鍛樺悕绉�"
+ size="small"
+ style="width: 120px"
+ clearable
+ @keyup.enter="refreshTable()" />
+ </div>
+ <div class="search-item">
+ <el-tree-select v-model="query.deptId"
+ :data="deptOptions"
+ :props="{ value: 'id', label: 'label', children: 'children' }"
+ value-key="id"
+ placeholder="璇烽�夋嫨閮ㄩ棬"
+ size="small"
+ clearable
+ @change="refreshTable()"
+ style="width: 140px" />
+ </div>
+ <div class="search-actions">
+ <el-button size="small"
+ type="primary"
+ @click="refreshTable()"
+ :icon="Search">
+ 鏌ヨ
+ </el-button>
+ <el-button size="small"
+ @click="refresh()"
+ :icon="Refresh"
+ style="margin-left: 8px">
+ 閲嶇疆
+ </el-button>
+ </div>
+ <div class="search-buttons">
+ <el-button size="small"
+ type="primary"
+ @click="configTime"
+ :icon="Setting">
+ 鐝閰嶇疆
+ </el-button>
+ <el-button size="small"
+ type="success"
+ @click="handleDown"
+ :loading="downLoading"
+ :icon="Download"
+ style="margin-left: 8px">
+ 瀵煎嚭
+ </el-button>
+ <el-button size="small"
+ type="warning"
+ @click="schedulingVisible = true"
+ :icon="Calendar"
+ style="margin-left: 8px">
+ 鎺掔彮
+ </el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="scheduling-container"
+ v-loading="pageLoading">
+ <!-- 鏈堝害鎺掔彮 -->
+ <div class="scheduling-table"
+ v-show="query.month">
+ <div class="scheduling-left">
+ <div class="scheduling-header">
+ 浜哄憳鍚嶇О
+ </div>
+ <div class="scheduling-user"
+ :class="{ 'scheduling-user-hover': currentUserIndex == index }"
+ v-for="(item, index) in listForm"
+ :key="'e' + index"
+ @mouseenter="onMouseEnter(index)"
+ @mouseleave="currentUserIndex = null">
+ <div class="user-avatar">
+ {{ item.name ? item.name.charAt(0) : "" }}
+ </div>
+ <div class="user-details">
+ <h4 class="user-name">{{ item.name }}</h4>
+ <!-- <div class="user-stats">
+ <span class="stat-item">鏃�:{{ item.day0 }}</span>
+ <span class="stat-item">涓�:{{ item.day1 }}</span>
+ <span class="stat-item">澶�:{{ item.day2 }}</span>
+ <span class="stat-item">浼�:{{ item.day3 }}</span>
+ <span class="stat-item">鍋�:{{ item.day4 }}</span>
+ <span class="stat-item">宸�:{{ item.day6 }}</span>
+ </div> -->
+ <div class="user-total">
+ <span class="total-label">鍚堣鍑哄嫟:</span>
+ <span class="total-value">{{ item.monthlyAttendance.totalAttendance }}澶�</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="scheduling-right">
+ <div class="scheduling-calendar">
+ <div class="calendar-header">
+ <div class="calendar-header-item"
+ v-for="(item, index) in weeks"
+ :key="'b' + index">
+ <span class="week-number"
+ v-if="item.week == '鍛ㄦ棩'">{{ item.weekNum }}鍛�</span>
+ <div class="day-info">
+ <span class="day-number">{{ item.day }}</span>
+ <span class="day-week">{{ item.week.charAt(1) }}</span>
+ </div>
+ </div>
+ </div>
+ <div class="calendar-body">
+ <div class="calendar-row"
+ v-for="(item, index) in listForm"
+ :key="'c' + index"
+ :class="{ 'calendar-row-hover': currentUserIndex == index }"
+ @mouseenter="onMouseEnter(index)"
+ @mouseleave="currentUserIndex = null">
+ <div class="calendar-cell"
+ v-for="(m, i) in item.list"
+ :key="'d' + i">
+ <el-dropdown trigger="click"
+ placement="bottom"
+ @command="(e) => handleCommand(e, m)"
+ class="shift-dropdown">
+ <div class="shift-box"
+ :class="{
+ 'shift-box-early': m.shift === '0',
+ 'shift-box-mid': m.shift === '1',
+ 'shift-box-night': m.shift === '2',
+ 'shift-box-rest': m.shift === '3',
+ 'shift-box-leave': m.shift === '4',
+ 'shift-box-other': m.shift === '5',
+ 'shift-box-business': m.shift === '6',
+ }">
+ <span class="shift-text">{{ getShiftByDic(m.shift) || '鈥�' }}</span>
+ </div>
+ <template #dropdown>
+ <el-dropdown-menu>
+ <el-dropdown-item v-for="(n, j) in classType"
+ :key="'h' + j"
+ :command="n.id">{{ n.locationName
+ }}</el-dropdown-item>
+ </el-dropdown-menu>
+ </template>
+ </el-dropdown>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <!-- 骞村害鎺掔彮 -->
+ <div class="yearly-table"
+ v-show="!query.month">
+ <div class="scheduling-left">
+ <div class="scheduling-header">
+ 浜哄憳鍚嶇О
+ </div>
+ <div class="scheduling-user"
+ :class="{ 'scheduling-user-hover': currentUserIndex == index }"
+ v-for="(item, index) in yearList"
+ :key="'e' + index"
+ @mouseenter="onMouseEnter(index)"
+ @mouseleave="currentUserIndex = null">
+ <div class="user-avatar">
+ {{ item.name ? item.name.charAt(0) : "" }}
+ </div>
+ <div class="user-details">
+ <h4 class="user-name">{{ item.name }}</h4>
+ <!-- <div class="user-stats">
+ <span class="stat-item">鏃�:{{ item.day0 }}</span>
+ <span class="stat-item">涓�:{{ item.day1 }}</span>
+ <span class="stat-item">澶�:{{ item.day2 }}</span>
+ <span class="stat-item">浼�:{{ item.day3 }}</span>
+ <span class="stat-item">鍋�:{{ item.day4 }}</span>
+ <span class="stat-item">宸�:{{ item.day6 }}</span>
+ </div> -->
+ <div class="user-total">
+ <span class="total-label">鍚堣鍑哄嫟:</span>
+ <span class="total-value">{{ item.work_time }}澶�</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="scheduling-right">
+ <div class="yearly-calendar">
+ <div class="yearly-header">
+ <div class="yearly-header-item"
+ v-for="(item, index) in monthList"
+ :key="'b' + index">
+ <span class="month-name">{{ item }}鏈�</span>
+ </div>
+ </div>
+ <div class="yearly-body">
+ <div class="yearly-row"
+ v-for="(item, index) in yearList"
+ :key="'c' + index"
+ :class="{ 'calendar-row-hover': currentUserIndex == index }"
+ @mouseenter="onMouseEnter(index)"
+ @mouseleave="currentUserIndex = null">
+ <div class="yearly-cell"
+ v-for="(m, i) in item.monthList"
+ :key="'d' + i">
+ <div class="monthly-attendance">
+ <span class="attendance-label">鍚堣鍑哄嫟锛�</span>
+ <span class="attendance-value">{{ m.totalMonthAttendance }}</span>
+ </div>
+ <!-- <div class="monthly-stats">
+ <span class="stat-item">鏃�:{{ m.day0 }}</span>
+ <span class="stat-item">涓�:{{ m.day1 }}</span>
+ <span class="stat-item">澶�:{{ m.day2 }}</span>
+ <span class="stat-item">浼�:{{ m.day3 }}</span>
+ <span class="stat-item">鍋�:{{ m.day4 }}</span>
+ <span class="stat-item">宸�:{{ m.day6 }}</span>
+ </div> -->
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div style="display: flex; justify-content: flex-end; margin-top: 10px; margin-right: 30px">
+ <el-pagination background
+ @current-change="currentChange"
+ :page-size="pageSize"
+ :current-page="currentPage"
+ layout="total, prev, pager, next, jumper"
+ :total="total">
+ </el-pagination>
+ </div>
+ <el-dialog title="鎺掔彮"
+ v-model="schedulingVisible"
+ width="400px">
+ <div class="search_thing">
+ <div class="search_label"
+ style="width: 90px">
+ <span style="color: red; margin-right: 4px">*</span>鍛ㄦ锛�
+ </div>
+ <div class="search_input">
+ <el-date-picker v-model="schedulingQuery.week"
+ type="week"
+ format="YYYY 绗� ww 鍛�"
+ placeholder="閫夋嫨鍛ㄦ"
+ style="width: 100%">
+ </el-date-picker>
+ </div>
+ </div>
+ <div class="search_thing">
+ <div class="search_label"
+ style="width: 90px">
+ <span style="color: red; margin-right: 4px">*</span>浜哄憳鍚嶇О锛�
+ </div>
+ <div class="search_input">
+ <el-select v-model="schedulingQuery.userId"
+ placeholder="璇烽�夋嫨"
+ style="width: 100%"
+ multiple
+ clearable
+ collapse-tags>
+ <el-option v-for="item in personList"
+ :key="item.userId"
+ :label="item.nickName"
+ :value="item.userId">
+ </el-option>
+ </el-select>
+ </div>
+ </div>
+ <div class="search_thing">
+ <div class="search_label"
+ style="width: 90px">
+ <span style="color: red; margin-right: 4px">*</span>鐝锛�
+ </div>
+ <div class="search_input">
+ <el-select v-model="schedulingQuery.shift"
+ placeholder="璇烽�夋嫨"
+ style="width: 100%">
+ <el-option v-for="item in classType"
+ :key="item.id"
+ :label="item.locationName"
+ :value="item.id">
+ </el-option>
+ </el-select>
+ </div>
+ </div>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button @click="schedulingVisible = false">鍙� 娑�</el-button>
+ <el-button type="primary"
+ @click="confirmScheduling"
+ :loading="loading">纭� 瀹�</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ </div>
+</template>
+
+<script setup>
+ import { ref, reactive, onMounted, getCurrentInstance } from "vue";
+ import { useRouter } from "vue-router";
+ import {
+ page,
+ pageYear,
+ add,
+ exportFile,
+ update,
+ selectUserCondition,
+ } from "@/api/personnelManagement/class";
+ import { deptTreeSelect } from "@/api/system/user.js";
+ import { getAttendanceRules } from "@/api/personnelManagement/attendanceRules.js";
+ const { proxy } = getCurrentInstance();
+ const router = useRouter();
+
+ // 鏌ヨ鏉′欢
+ const query = reactive({
+ userName: "",
+ deptId: "",
+ year: new Date(),
+ month: new Date().getMonth() + 1,
+ });
+
+ // 鏈堜唤閫夐」
+ const monthOptions = [
+ { value: 1, label: "1鏈�" },
+ { value: 2, label: "2鏈�" },
+ { value: 3, label: "3鏈�" },
+ { value: 4, label: "4鏈�" },
+ { value: 5, label: "5鏈�" },
+ { value: 6, label: "6鏈�" },
+ { value: 7, label: "7鏈�" },
+ { value: 8, label: "8鏈�" },
+ { value: 9, label: "9鏈�" },
+ { value: 10, label: "10鏈�" },
+ { value: 11, label: "11鏈�" },
+ { value: 12, label: "12鏈�" },
+ ];
+
+ // 閮ㄩ棬鍒楄〃
+ const deptOptions = ref([]);
+
+ // 鍛ㄥ垪琛�
+ const weeks = ref([
+ { weekNum: 1, week: "鍛ㄤ竴", day: "01" },
+ { weekNum: 1, week: "鍛ㄤ簩", day: "02" },
+ { weekNum: 1, week: "鍛ㄤ笁", day: "03" },
+ { weekNum: 1, week: "鍛ㄥ洓", day: "04" },
+ { weekNum: 1, week: "鍛ㄤ簲", day: "05" },
+ { weekNum: 1, week: "鍛ㄥ叚", day: "06" },
+ { weekNum: 2, week: "鍛ㄦ棩", day: "07" },
+ { weekNum: 2, week: "鍛ㄤ竴", day: "08" },
+ { weekNum: 2, week: "鍛ㄤ簩", day: "09" },
+ { weekNum: 2, week: "鍛ㄤ笁", day: "10" },
+ { weekNum: 2, week: "鍛ㄥ洓", day: "11" },
+ { weekNum: 2, week: "鍛ㄤ簲", day: "12" },
+ { weekNum: 2, week: "鍛ㄥ叚", day: "13" },
+ { weekNum: 3, week: "鍛ㄦ棩", day: "14" },
+ { weekNum: 3, week: "鍛ㄤ竴", day: "15" },
+ { weekNum: 3, week: "鍛ㄤ簩", day: "16" },
+ { weekNum: 3, week: "鍛ㄤ笁", day: "17" },
+ { weekNum: 3, week: "鍛ㄥ洓", day: "18" },
+ { weekNum: 3, week: "鍛ㄤ簲", day: "19" },
+ { weekNum: 3, week: "鍛ㄥ叚", day: "20" },
+ { weekNum: 4, week: "鍛ㄦ棩", day: "21" },
+ { weekNum: 4, week: "鍛ㄤ竴", day: "22" },
+ { weekNum: 4, week: "鍛ㄤ簩", day: "23" },
+ { weekNum: 4, week: "鍛ㄤ笁", day: "24" },
+ { weekNum: 4, week: "鍛ㄥ洓", day: "25" },
+ { weekNum: 4, week: "鍛ㄤ簲", day: "26" },
+ { weekNum: 4, week: "鍛ㄥ叚", day: "27" },
+ { weekNum: 5, week: "鍛ㄦ棩", day: "28" },
+ { weekNum: 5, week: "鍛ㄤ竴", day: "29" },
+ { weekNum: 5, week: "鍛ㄤ簩", day: "30" },
+ ]);
+
+ // 鐝绫诲瀷
+ const classType = ref([]);
+
+ // 褰撳墠鐢ㄦ埛绱㈠紩
+ const currentUserIndex = ref(null);
+
+ // 鎺掔彮寮圭獥鏄剧ず鐘舵��
+ const schedulingVisible = ref(false);
+
+ // 浜哄憳鍒楄〃
+ const personList = ref([]);
+
+ // 鍔犺浇鐘舵��
+ const loading = ref(false);
+
+ // 鎺掔彮鏌ヨ鏉′欢
+ const schedulingQuery = reactive({
+ week: "",
+ userId: null,
+ shift: "",
+ });
+
+ // 鍒楄〃鏁版嵁
+ const listForm = ref([
+ {
+ id: 1,
+ name: "寮犱笁",
+ monthlyAttendance: {
+ totalAttendance: 22,
+ 鏃╃彮: 10,
+ 涓彮: 8,
+ 澶滅彮: 4,
+ 浼戞伅: 6,
+ 璇峰亣: 0,
+ 鍑哄樊: 0,
+ },
+ day0: 10,
+ day1: 8,
+ day2: 4,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ list: [
+ { id: 1, shift: "0" },
+ { id: 2, shift: "0" },
+ { id: 3, shift: "1" },
+ { id: 4, shift: "1" },
+ { id: 5, shift: "2" },
+ { id: 6, shift: "2" },
+ { id: 7, shift: "3" },
+ { id: 8, shift: "0" },
+ { id: 9, shift: "0" },
+ { id: 10, shift: "1" },
+ { id: 11, shift: "1" },
+ { id: 12, shift: "2" },
+ { id: 13, shift: "2" },
+ { id: 14, shift: "3" },
+ { id: 15, shift: "0" },
+ { id: 16, shift: "0" },
+ { id: 17, shift: "1" },
+ { id: 18, shift: "1" },
+ { id: 19, shift: "2" },
+ { id: 20, shift: "2" },
+ { id: 21, shift: "3" },
+ { id: 22, shift: "0" },
+ { id: 23, shift: "0" },
+ { id: 24, shift: "1" },
+ { id: 25, shift: "1" },
+ { id: 26, shift: "2" },
+ { id: 27, shift: "2" },
+ { id: 28, shift: "3" },
+ { id: 29, shift: "0" },
+ { id: 30, shift: "0" },
+ ],
+ },
+ {
+ id: 2,
+ name: "鏉庡洓",
+ monthlyAttendance: {
+ totalAttendance: 20,
+ 鏃╃彮: 8,
+ 涓彮: 6,
+ 澶滅彮: 6,
+ 浼戞伅: 8,
+ 璇峰亣: 2,
+ 鍑哄樊: 0,
+ },
+ day0: 8,
+ day1: 6,
+ day2: 6,
+ day3: 8,
+ day4: 2,
+ day6: 0,
+ list: [
+ { id: 31, shift: "1" },
+ { id: 32, shift: "1" },
+ { id: 33, shift: "2" },
+ { id: 34, shift: "2" },
+ { id: 35, shift: "3" },
+ { id: 36, shift: "0" },
+ { id: 37, shift: "0" },
+ { id: 38, shift: "1" },
+ { id: 39, shift: "1" },
+ { id: 40, shift: "2" },
+ { id: 41, shift: "2" },
+ { id: 42, shift: "3" },
+ { id: 43, shift: "0" },
+ { id: 44, shift: "0" },
+ { id: 45, shift: "1" },
+ { id: 46, shift: "1" },
+ { id: 47, shift: "2" },
+ { id: 48, shift: "2" },
+ { id: 49, shift: "3" },
+ { id: 50, shift: "0" },
+ { id: 51, shift: "0" },
+ { id: 52, shift: "4" },
+ { id: 53, shift: "4" },
+ { id: 54, shift: "1" },
+ { id: 55, shift: "1" },
+ { id: 56, shift: "2" },
+ { id: 57, shift: "2" },
+ { id: 58, shift: "3" },
+ { id: 59, shift: "0" },
+ { id: 60, shift: "0" },
+ ],
+ },
+ {
+ id: 3,
+ name: "鐜嬩簲",
+ monthlyAttendance: {
+ totalAttendance: 23,
+ 鏃╃彮: 9,
+ 涓彮: 9,
+ 澶滅彮: 5,
+ 浼戞伅: 5,
+ 璇峰亣: 0,
+ 鍑哄樊: 2,
+ },
+ day0: 9,
+ day1: 9,
+ day2: 5,
+ day3: 5,
+ day4: 0,
+ day6: 2,
+ list: [
+ { id: 61, shift: "2" },
+ { id: 62, shift: "2" },
+ { id: 63, shift: "3" },
+ { id: 64, shift: "0" },
+ { id: 65, shift: "0" },
+ { id: 66, shift: "1" },
+ { id: 67, shift: "1" },
+ { id: 68, shift: "2" },
+ { id: 69, shift: "2" },
+ { id: 70, shift: "3" },
+ { id: 71, shift: "0" },
+ { id: 72, shift: "0" },
+ { id: 73, shift: "1" },
+ { id: 74, shift: "1" },
+ { id: 75, shift: "2" },
+ { id: 76, shift: "2" },
+ { id: 77, shift: "3" },
+ { id: 78, shift: "0" },
+ { id: 79, shift: "0" },
+ { id: 80, shift: "1" },
+ { id: 81, shift: "1" },
+ { id: 82, shift: "6" },
+ { id: 83, shift: "6" },
+ { id: 84, shift: "2" },
+ { id: 85, shift: "2" },
+ { id: 86, shift: "3" },
+ { id: 87, shift: "0" },
+ { id: 88, shift: "0" },
+ { id: 89, shift: "1" },
+ { id: 90, shift: "1" },
+ ],
+ },
+ {
+ id: 4,
+ name: "寮犱笁",
+ monthlyAttendance: {
+ totalAttendance: 22,
+ 鏃╃彮: 10,
+ 涓彮: 8,
+ 澶滅彮: 4,
+ 浼戞伅: 6,
+ 璇峰亣: 0,
+ 鍑哄樊: 0,
+ },
+ day0: 10,
+ day1: 8,
+ day2: 4,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ list: [
+ { id: 1, shift: "0" },
+ { id: 2, shift: "0" },
+ { id: 3, shift: "1" },
+ { id: 4, shift: "1" },
+ { id: 5, shift: "2" },
+ { id: 6, shift: "2" },
+ { id: 7, shift: "3" },
+ { id: 8, shift: "0" },
+ { id: 9, shift: "0" },
+ { id: 10, shift: "1" },
+ { id: 11, shift: "1" },
+ { id: 12, shift: "2" },
+ { id: 13, shift: "2" },
+ { id: 14, shift: "3" },
+ { id: 15, shift: "0" },
+ { id: 16, shift: "0" },
+ { id: 17, shift: "1" },
+ { id: 18, shift: "1" },
+ { id: 19, shift: "2" },
+ { id: 20, shift: "2" },
+ { id: 21, shift: "3" },
+ { id: 22, shift: "0" },
+ { id: 23, shift: "0" },
+ { id: 24, shift: "1" },
+ { id: 25, shift: "1" },
+ { id: 26, shift: "2" },
+ { id: 27, shift: "2" },
+ { id: 28, shift: "3" },
+ { id: 29, shift: "0" },
+ { id: 30, shift: "0" },
+ ],
+ },
+ {
+ id: 5,
+ name: "寮犱笁",
+ monthlyAttendance: {
+ totalAttendance: 22,
+ 鏃╃彮: 10,
+ 涓彮: 8,
+ 澶滅彮: 4,
+ 浼戞伅: 6,
+ 璇峰亣: 0,
+ 鍑哄樊: 0,
+ },
+ day0: 10,
+ day1: 8,
+ day2: 4,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ list: [
+ { id: 1, shift: "0" },
+ { id: 2, shift: "0" },
+ { id: 3, shift: "1" },
+ { id: 4, shift: "1" },
+ { id: 5, shift: "2" },
+ { id: 6, shift: "2" },
+ { id: 7, shift: "3" },
+ { id: 8, shift: "0" },
+ { id: 9, shift: "0" },
+ { id: 10, shift: "1" },
+ { id: 11, shift: "1" },
+ { id: 12, shift: "2" },
+ { id: 13, shift: "2" },
+ { id: 14, shift: "3" },
+ { id: 15, shift: "0" },
+ { id: 16, shift: "0" },
+ { id: 17, shift: "1" },
+ { id: 18, shift: "1" },
+ { id: 19, shift: "2" },
+ { id: 20, shift: "2" },
+ { id: 21, shift: "3" },
+ { id: 22, shift: "0" },
+ { id: 23, shift: "0" },
+ { id: 24, shift: "1" },
+ { id: 25, shift: "1" },
+ { id: 26, shift: "2" },
+ { id: 27, shift: "2" },
+ { id: 28, shift: "3" },
+ { id: 29, shift: "0" },
+ { id: 30, shift: "0" },
+ ],
+ },
+ {
+ id: 6,
+ name: "寮犱笁",
+ monthlyAttendance: {
+ totalAttendance: 22,
+ 鏃╃彮: 10,
+ 涓彮: 8,
+ 澶滅彮: 4,
+ 浼戞伅: 6,
+ 璇峰亣: 0,
+ 鍑哄樊: 0,
+ },
+ day0: 10,
+ day1: 8,
+ day2: 4,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ list: [
+ { id: 1, shift: "0" },
+ { id: 2, shift: "0" },
+ { id: 3, shift: "1" },
+ { id: 4, shift: "1" },
+ { id: 5, shift: "2" },
+ { id: 6, shift: "2" },
+ { id: 7, shift: "3" },
+ { id: 8, shift: "0" },
+ { id: 9, shift: "0" },
+ { id: 10, shift: "1" },
+ { id: 11, shift: "1" },
+ { id: 12, shift: "2" },
+ { id: 13, shift: "2" },
+ { id: 14, shift: "3" },
+ { id: 15, shift: "0" },
+ { id: 16, shift: "0" },
+ { id: 17, shift: "1" },
+ { id: 18, shift: "1" },
+ { id: 19, shift: "2" },
+ { id: 20, shift: "2" },
+ { id: 21, shift: "3" },
+ { id: 22, shift: "0" },
+ { id: 23, shift: "0" },
+ { id: 24, shift: "1" },
+ { id: 25, shift: "1" },
+ { id: 26, shift: "2" },
+ { id: 27, shift: "2" },
+ { id: 28, shift: "3" },
+ { id: 29, shift: "0" },
+ { id: 30, shift: "0" },
+ ],
+ },
+ ]);
+
+ // 褰撳墠椤�
+ const currentPage = ref(1);
+
+ // 姣忛〉鏉℃暟
+ const pageSize = ref(6);
+
+ // 鎬绘潯鏁�
+ const total = ref(3);
+
+ // 椤甸潰鍔犺浇鐘舵��
+ const pageLoading = ref(false);
+
+ // 鏈堜唤鍒楄〃
+ const monthList = ref([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
+
+ // 骞村害鍒楄〃
+ const yearList = ref([
+ {
+ id: 1,
+ name: "寮犱笁",
+ work_time: 260,
+ day0: 98,
+ day1: 78,
+ day2: 46,
+ day3: 74,
+ day4: 14,
+ day6: 10,
+ monthList: [
+ {
+ totalMonthAttendance: 22,
+ day0: 10,
+ day1: 8,
+ day2: 4,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 19,
+ day0: 7,
+ day1: 6,
+ day2: 6,
+ day3: 9,
+ day4: 3,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 9,
+ day1: 9,
+ day2: 5,
+ day3: 5,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 0,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 18,
+ day0: 6,
+ day1: 6,
+ day2: 6,
+ day3: 8,
+ day4: 4,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 0,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 19,
+ day0: 7,
+ day1: 7,
+ day2: 5,
+ day3: 8,
+ day4: 2,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 0,
+ },
+ ],
+ },
+ {
+ id: 2,
+ name: "鏉庡洓",
+ work_time: 252,
+ day0: 90,
+ day1: 72,
+ day2: 50,
+ day3: 76,
+ day4: 18,
+ day6: 8,
+ monthList: [
+ {
+ totalMonthAttendance: 21,
+ day0: 9,
+ day1: 7,
+ day2: 5,
+ day3: 7,
+ day4: 2,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 18,
+ day0: 6,
+ day1: 6,
+ day2: 6,
+ day3: 10,
+ day4: 4,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 8,
+ day1: 8,
+ day2: 6,
+ day3: 6,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 20,
+ day0: 7,
+ day1: 6,
+ day2: 7,
+ day3: 8,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 17,
+ day0: 5,
+ day1: 5,
+ day2: 7,
+ day3: 9,
+ day4: 5,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 1,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 20,
+ day0: 7,
+ day1: 6,
+ day2: 7,
+ day3: 8,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 18,
+ day0: 6,
+ day1: 6,
+ day2: 6,
+ day3: 9,
+ day4: 3,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ },
+ ],
+ },
+ {
+ id: 3,
+ name: "鐜嬩簲",
+ work_time: 268,
+ day0: 102,
+ day1: 82,
+ day2: 48,
+ day3: 70,
+ day4: 10,
+ day6: 14,
+ monthList: [
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 24,
+ day0: 10,
+ day1: 9,
+ day2: 5,
+ day3: 4,
+ day4: 0,
+ day6: 3,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 8,
+ day2: 5,
+ day3: 5,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 24,
+ day0: 10,
+ day1: 9,
+ day2: 5,
+ day3: 4,
+ day4: 0,
+ day6: 3,
+ },
+ ],
+ },
+ {
+ id: 4,
+ name: "璧靛叚",
+ work_time: 248,
+ day0: 88,
+ day1: 70,
+ day2: 50,
+ day3: 78,
+ day4: 20,
+ day6: 6,
+ monthList: [
+ {
+ totalMonthAttendance: 20,
+ day0: 8,
+ day1: 6,
+ day2: 6,
+ day3: 8,
+ day4: 3,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 17,
+ day0: 5,
+ day1: 5,
+ day2: 7,
+ day3: 10,
+ day4: 5,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 7,
+ day1: 7,
+ day2: 7,
+ day3: 7,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 19,
+ day0: 6,
+ day1: 6,
+ day2: 7,
+ day3: 9,
+ day4: 2,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 20,
+ day0: 7,
+ day1: 7,
+ day2: 6,
+ day3: 8,
+ day4: 2,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 16,
+ day0: 4,
+ day1: 4,
+ day2: 8,
+ day3: 10,
+ day4: 6,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 20,
+ day0: 7,
+ day1: 7,
+ day2: 6,
+ day3: 8,
+ day4: 2,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 19,
+ day0: 6,
+ day1: 6,
+ day2: 7,
+ day3: 9,
+ day4: 2,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 20,
+ day0: 7,
+ day1: 7,
+ day2: 6,
+ day3: 8,
+ day4: 2,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 18,
+ day0: 6,
+ day1: 6,
+ day2: 6,
+ day3: 9,
+ day4: 4,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 7,
+ day2: 6,
+ day3: 7,
+ day4: 1,
+ day6: 1,
+ },
+ ],
+ },
+ {
+ id: 5,
+ name: "閽变竷",
+ work_time: 266,
+ day0: 100,
+ day1: 84,
+ day2: 46,
+ day3: 72,
+ day4: 12,
+ day6: 12,
+ monthList: [
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 21,
+ day0: 8,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 9,
+ day1: 9,
+ day2: 5,
+ day3: 5,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 20,
+ day0: 7,
+ day1: 7,
+ day2: 6,
+ day3: 8,
+ day4: 2,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 0,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 9,
+ day1: 9,
+ day2: 5,
+ day3: 5,
+ day4: 0,
+ day6: 2,
+ },
+ {
+ totalMonthAttendance: 22,
+ day0: 9,
+ day1: 8,
+ day2: 5,
+ day3: 6,
+ day4: 1,
+ day6: 1,
+ },
+ {
+ totalMonthAttendance: 20,
+ day0: 7,
+ day1: 7,
+ day2: 6,
+ day3: 8,
+ day4: 2,
+ day6: 0,
+ },
+ {
+ totalMonthAttendance: 23,
+ day0: 10,
+ day1: 9,
+ day2: 4,
+ day3: 5,
+ day4: 0,
+ day6: 0,
+ },
+ ],
+ },
+ ]);
+
+ // 瀵煎嚭鍔犺浇鐘舵��
+ const downLoading = ref(false);
+
+ // 鑾峰彇閮ㄩ棬鍒楄〃
+ const fetchDeptOptions = () => {
+ deptTreeSelect().then(response => {
+ deptOptions.value = filterDisabledDept(
+ JSON.parse(JSON.stringify(response.data))
+ );
+ });
+ };
+
+ // 杩囨护绂佺敤鐨勯儴闂�
+ const filterDisabledDept = deptList => {
+ return deptList.filter(dept => {
+ if (dept.disabled) {
+ return false;
+ }
+ if (dept.children && dept.children.length) {
+ dept.children = filterDisabledDept(dept.children);
+ }
+ return true;
+ });
+ };
+
+ // 鍒锋柊
+ const refresh = () => {
+ listForm.value = [];
+ yearList.value = [];
+ currentPage.value = 1;
+ query.userName = "";
+ query.deptId = "";
+ query.year = new Date();
+ query.month = new Date().getMonth() + 1;
+ if (query.month) {
+ init();
+ } else {
+ initYear();
+ }
+ };
+
+ // 鍒锋柊琛ㄦ牸
+ const refreshTable = () => {
+ currentPage.value = 1;
+ if (query.month) {
+ listForm.value = [];
+ init();
+ } else {
+ yearList.value = [];
+ initYear();
+ }
+ };
+
+ // 椤电爜鏀瑰彉
+ const currentChange = num => {
+ currentPage.value = num;
+ if (query.month) {
+ init();
+ } else {
+ initYear();
+ }
+ };
+
+ // 鏁板瓧杞腑鏂�
+ const transFromNumber = num => {
+ let changeNum = ["闆�", "涓�", "浜�", "涓�", "鍥�", "浜�", "鍏�", "涓�", "鍏�", "涔�"];
+ let unit = ["", "鍗�", "鐧�", "鍗�", "涓�"];
+ num = parseInt(num);
+ let getWan = temp => {
+ let strArr = temp.toString().split("").reverse();
+ let newNum = "";
+ for (var i = 0; i < strArr.length; i++) {
+ newNum =
+ (i == 0 && strArr[i] == 0
+ ? ""
+ : i > 0 && strArr[i] == 0 && strArr[i - 1] == 0
+ ? ""
+ : changeNum[strArr[i]] + (strArr[i] == 0 ? unit[0] : unit[i])) +
+ newNum;
+ }
+ return newNum;
+ };
+ let overWan = Math.floor(num / 10000);
+ let noWan = num % 10000;
+ if (noWan.toString().length < 4) noWan = "0" + noWan;
+ return overWan ? getWan(overWan) + "涓�" + getWan(noWan) : getWan(num);
+ };
+
+ // 鍒濆鍖栨湀搴︽暟鎹�
+ const init = () => {
+ pageLoading.value = true;
+ console.log(query.year, "query.year");
+ let year = query.year.getFullYear();
+ let month0 = query.month ? query.month : new Date().getMonth() + 1;
+ let month = month0 > 9 ? month0 : "0" + month0;
+ page({
+ size: pageSize.value,
+ current: currentPage.value,
+ time: year + "-" + month + "-01 00:00:00",
+ userName: query.userName,
+ deptId: query.deptId,
+ })
+ .then(res => {
+ pageLoading.value = false;
+ total.value = res.data.page.total;
+ listForm.value = res.data.page.records.map(item => {
+ for (let key in item.monthlyAttendance) {
+ let type = getDayByDic(key);
+ if (type != undefined || type != null) {
+ item[`day${type}`] = item.monthlyAttendance[key];
+ }
+ }
+ return item;
+ });
+ let headerList = res.data.headerList;
+ weeks.value = [];
+ headerList.forEach(item => {
+ let obj = {
+ weekNum: item.weekly,
+ week: item.headerTime.split(" ")[1],
+ day: item.headerTime.split(" ")[0],
+ };
+ weeks.value.push(obj);
+ });
+ })
+ .catch(() => {
+ pageLoading.value = false;
+ });
+ };
+
+ // 鍒濆鍖栧勾搴︽暟鎹�
+ const initYear = () => {
+ pageLoading.value = true;
+ let year = query.year.getFullYear();
+ pageYear({
+ size: pageSize.value,
+ current: currentPage.value,
+ time: year + "-01-01 00:00:00",
+ userName: query.userName,
+ deptId: query.deptId,
+ }).then(res => {
+ pageLoading.value = false;
+ total.value = res.data.total;
+ yearList.value = res.data.records.map(item => {
+ for (let key in item.year) {
+ let type = getDayByDic(key);
+ if (type != undefined || type != null) {
+ item[`day${type}`] = item.year[key];
+ }
+ }
+ item.monthList = [];
+ for (let m in item.month) {
+ let obj = {};
+ for (let key in item.month[m]) {
+ let type = getDayByDic(key);
+ if (type != undefined || type != null) {
+ obj[`day${type}`] = item.month[m][key];
+ }
+ }
+ obj.totalMonthAttendance = item.month[m].totalMonthAttendance;
+ item.monthList.push(obj);
+ }
+ return item;
+ });
+ });
+ };
+
+ // 榧犳爣杩涘叆
+ const onMouseEnter = index => {
+ currentUserIndex.value = index;
+ };
+
+ // 纭鎺掔彮
+ const confirmScheduling = () => {
+ if (!schedulingQuery.week) {
+ proxy.$modal.msgError("璇烽�夋嫨鍛ㄦ");
+ return;
+ }
+ let time = schedulingQuery.week.getTime();
+
+ // 鏍煎紡鍖栨棩鏈熶负 YYYY-MM-DD 鏍煎紡
+ const formatDate = date => {
+ const year = date.getFullYear();
+ const month = String(date.getMonth() + 1).padStart(2, "0");
+ const day = String(date.getDate()).padStart(2, "0");
+ return `${year}-${month}-${day}`;
+ };
+
+ let startWeek =
+ formatDate(new Date(time - 24 * 60 * 60 * 1000)) + " 00:00:00";
+ let endWeek =
+ formatDate(new Date(time + 24 * 60 * 60 * 1000 * 5)) + " 00:00:00";
+
+ if (!schedulingQuery.userId || schedulingQuery.userId.length == 0) {
+ proxy.$modal.msgError("璇烽�夋嫨浜哄憳");
+ return;
+ }
+ if (!schedulingQuery.shift) {
+ proxy.$modal.msgError("璇烽�夋嫨鐝");
+ return;
+ }
+ loading.value = true;
+ add({
+ startWeek,
+ endWeek,
+ userId: schedulingQuery.userId.join(","),
+ shift: schedulingQuery.shift,
+ })
+ .then(res => {
+ loading.value = false;
+ proxy.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+ schedulingVisible.value = false;
+ schedulingQuery.week = "";
+ schedulingQuery.userId = null;
+ schedulingQuery.shift = "";
+ refresh();
+ })
+ .catch(err => {
+ loading.value = false;
+ });
+ };
+
+ // 鏃堕棿閰嶇疆
+ const configTime = () => {
+ // 璺宠浆鍒拌�冨嫟鎵撳崱椤甸潰
+ router.push({
+ path: "/personnelManagement/checkinRules",
+ });
+ };
+
+ // 鍒ゆ柇鏄惁涓虹┖瀵硅薄
+ const isObjectEmpty = obj => {
+ return Object.keys(obj).some(key => !obj[key]);
+ };
+
+ // 瀵煎嚭
+ const handleDown = () => {
+ let year = query.year.getFullYear();
+ let time = "";
+ if (query.month) {
+ let month = query.month > 9 ? query.month : "0" + query.month;
+ time = year + "-" + month + "-01 00:00:00";
+ } else {
+ time = year + "-01-01 00:00:00";
+ }
+ downLoading.value = true;
+ exportFile({
+ time,
+ userName: query.userName,
+ deptId: query.deptId,
+ isMonth: query.month ? true : false,
+ })
+ .then(res => {
+ proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
+ downLoading.value = false;
+ const blob = new Blob([res], {
+ type: "application/force-download",
+ });
+ let fileName = "";
+ if (query.month) {
+ fileName = year + "-" + query.month + " 鐝淇℃伅";
+ } else {
+ fileName = year + " 鐝姹囨��";
+ }
+ proxy.$download.saveAs(blob, fileName + ".xlsx");
+ })
+ .catch(err => {
+ downLoading.value = false;
+ });
+ };
+ // 澶勭悊鍛戒护
+ const handleCommand = (e, m) => {
+ if (e != m.shift) {
+ update({
+ id: m.id,
+ shift: e,
+ }).then(res => {
+ proxy.$modal.msgSuccess("鎿嶄綔鎴愬姛");
+ m.shift = e;
+ });
+ }
+ };
+ // 鏌ヨ瑙勫垯鍒楄〃
+ const fetchData = () => {
+ getAttendanceRules({ current: -1, size: -1 }).then(res => {
+ classType.value = res.data.records;
+ });
+ };
+ // 鑾峰彇鐢ㄦ埛
+ const getUsers = () => {
+ // selectUserCondition({ type: 1 }).then(res => {
+ // let arr = res.data;
+ // personList.value = arr;
+ // });
+ selectUserCondition().then(res => {
+ let arr = res.data;
+ personList.value = arr;
+ });
+ };
+
+ // 鏍规嵁瀛楀吀鑾峰彇鏃ユ湡
+ const getDayByDic = e => {
+ let obj = classType.value.find(m => m.locationName == e);
+ if (obj) {
+ return obj.id;
+ }
+ };
+
+ // 鏍规嵁瀛楀吀鑾峰彇鐝
+ const getShiftByDic = e => {
+ let obj = classType.value.find(m => m.id == e);
+ if (obj) {
+ return obj.locationName;
+ }
+ return "鏃�";
+ };
+
+ // 鍒濆鍖�
+ onMounted(() => {
+ fetchData();
+ getUsers();
+ fetchDeptOptions();
+ if (query.month) {
+ init();
+ } else {
+ initYear();
+ }
+ monthList.value = [];
+ for (let i = 12; i > 0; i--) {
+ monthList.value.push(i);
+ }
+ monthList.value.reverse();
+ });
+</script>
+
+<style scoped>
+ .class-page {
+ padding: 16px;
+ }
+
+ .form_title {
+ height: 36px;
+ display: flex;
+ flex-direction: row;
+ justify-content: space-between;
+ font-weight: 800;
+ }
+
+ /* 鎼滅储鍖哄煙鏍峰紡 */
+ .search-container {
+ background: #f9fafb;
+ border-radius: 8px;
+ padding: 20px;
+ margin-bottom: 20px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ }
+
+ .search-form {
+ display: flex;
+ flex-direction: column;
+ gap: 16px;
+ }
+
+ .search-row {
+ display: flex;
+ align-items: center;
+ gap: 16px;
+ flex-wrap: nowrap;
+ overflow-x: auto;
+ }
+
+ .search-item {
+ display: flex;
+ align-items: center;
+ gap: 6px;
+ }
+
+ .search-label {
+ font-size: 14px;
+ font-weight: 500;
+ color: #333;
+ min-width: 65px;
+ text-align: right;
+ }
+
+ .search-input-group {
+ display: flex;
+ align-items: center;
+ }
+
+ .search-actions {
+ display: flex;
+ align-items: center;
+ margin-left: 8px;
+ }
+
+ .search-buttons {
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ flex: 1;
+ }
+
+ /* 鍝嶅簲寮忚皟鏁� */
+ @media (max-width: 1200px) {
+ .search-row {
+ gap: 12px;
+ }
+
+ .search-item {
+ gap: 4px;
+ }
+
+ .search-label {
+ min-width: 60px;
+ font-size: 13px;
+ }
+
+ .search-actions {
+ margin-left: 4px;
+ }
+
+ .search-buttons {
+ margin-left: 12px;
+ }
+ }
+
+ @media (max-width: 992px) {
+ .search-row {
+ flex-wrap: wrap;
+ justify-content: flex-start;
+ }
+
+ .search-buttons {
+ margin-left: 0;
+ margin-top: 12px;
+ width: 100%;
+ justify-content: flex-start;
+ }
+ }
+
+ /* 鎺掔彮瀹瑰櫒 */
+ .scheduling-container {
+ width: 100%;
+ min-height: calc(100vh - 280px);
+ background-color: #fff;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ overflow: hidden;
+ margin-bottom: 20px;
+ }
+
+ /* 鎺掔彮琛ㄦ牸 */
+ .scheduling-table {
+ display: flex;
+ width: 100%;
+ height: calc(100vh - 280px);
+ }
+
+ /* 宸︿晶浜哄憳淇℃伅 */
+ .scheduling-left {
+ width: 240px;
+ min-width: 240px;
+ background-color: #f9fafb;
+ border-right: 1px solid #e5e7eb;
+ }
+
+ /* 鍙充晶鎺掔彮鍐呭 */
+ .scheduling-right {
+ flex: 1;
+ overflow-x: auto;
+ }
+
+ /* 琛ㄥご */
+ .scheduling-header {
+ height: 48px;
+ line-height: 48px;
+ padding: 0 20px;
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+ background-color: #f3f4f6;
+ border-bottom: 1px solid #e5e7eb;
+ }
+
+ /* 浜哄憳淇℃伅琛� */
+ .scheduling-user {
+ display: flex;
+ align-items: center;
+ padding: 10px 10px;
+ border-bottom: 1px solid #e5e7eb;
+ transition: all 0.3s ease;
+ height: 65px;
+ box-sizing: border-box;
+ }
+
+ .scheduling-user:hover,
+ .scheduling-user-hover {
+ background-color: rgba(59, 130, 246, 0.05);
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
+ }
+
+ /* 鐢ㄦ埛澶村儚 */
+ .user-avatar {
+ width: 42px;
+ height: 42px;
+ border-radius: 50%;
+ background: linear-gradient(135deg, #3b82f6, #60a5fa);
+ color: #fff;
+ font-size: 18px;
+ font-weight: 600;
+ text-align: center;
+ line-height: 42px;
+ margin-right: 16px;
+ box-shadow: 0 2px 4px rgba(59, 130, 246, 0.2);
+ transition: all 0.3s ease;
+ }
+
+ .scheduling-user:hover .user-avatar {
+ transform: scale(1.05);
+ box-shadow: 0 4px 8px rgba(59, 130, 246, 0.3);
+ }
+
+ /* 鐢ㄦ埛璇︽儏 */
+ .user-details {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ height: 100%;
+ }
+
+ /* 鐢ㄦ埛鍚� */
+ .user-name {
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+ margin: 0 0 6px 0;
+ line-height: 1.2;
+ }
+
+ /* 鐢ㄦ埛缁熻 */
+ .user-stats {
+ /* display: flex; */
+ /* flex-wrap: wrap;
+ gap: 10px; */
+ margin-bottom: 4px;
+ }
+
+ .stat-item {
+ font-size: 12px;
+ color: #666;
+ /* background-color: #f9fafb; */
+ /* padding: 2px 8px; */
+ padding-right: 4px;
+ /* border-radius: 10px; */
+ /* border: 1px solid #e5e7eb; */
+ /* transition: all 0.3s ease; */
+ }
+
+ .scheduling-user:hover .stat-item {
+ background-color: rgba(59, 130, 246, 0.1);
+ border-color: rgba(59, 130, 246, 0.3);
+ }
+
+ /* 鍚堣鍑哄嫟 */
+ .user-total {
+ display: flex;
+ align-items: center;
+ }
+
+ .total-label {
+ font-size: 12px;
+ color: #666;
+ margin-right: 6px;
+ font-weight: 500;
+ }
+
+ .total-value {
+ font-size: 14px;
+ font-weight: 600;
+ color: #3b82f6;
+ background-color: rgba(59, 130, 246, 0.1);
+ padding: 2px 10px;
+ border-radius: 10px;
+ border: 1px solid rgba(59, 130, 246, 0.2);
+ }
+
+ /* 鏃ュ巻澶撮儴 */
+ .calendar-header {
+ display: flex;
+
+ border-bottom: 1px solid #e5e7eb;
+ }
+
+ .calendar-header-item {
+ width: 50px;
+ min-width: 50px;
+ height: 48px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ border-right: 1px solid #e5e7eb;
+ background-color: #f3f4f6;
+ position: relative;
+ }
+
+ .week-number {
+ position: absolute;
+ top: 6px;
+ font-size: 10px;
+ font-weight: 600;
+ color: #3b82f6;
+ background-color: #dbeafe;
+ padding: 3px 6px;
+ border-radius: 12px;
+ box-shadow: 0 1px 3px rgba(59, 130, 246, 0.2);
+ transition: all 0.3s ease;
+ }
+
+ .week-number:hover {
+ background-color: #3b82f6;
+ color: #fff;
+ transform: translateY(-1px);
+ }
+
+ .day-info {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ .day-number {
+ font-size: 14px;
+ font-weight: 500;
+ color: #333;
+ }
+
+ .day-week {
+ font-size: 12px;
+ color: #666;
+ }
+
+ /* 鏃ュ巻涓讳綋 */
+ .calendar-body {
+ display: flex;
+ flex-direction: column;
+ }
+
+ /* 鏃ュ巻琛� */
+ .calendar-row {
+ display: flex;
+ border-bottom: 1px solid #e5e7eb;
+ transition: all 0.3s ease;
+ }
+
+ .calendar-row:hover,
+ .calendar-row-hover {
+ background-color: rgba(59, 130, 246, 0.03);
+ }
+
+ /* 鏃ュ巻鍗曞厓鏍� */
+ .calendar-cell {
+ width: 50px;
+ min-width: 50px;
+ height: 65px;
+ border-right: 1px solid #e5e7eb;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ /* 鐝涓嬫媺妗� */
+ .shift-dropdown {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ }
+
+ /* 鐝妗� */
+ .shift-box {
+ width: 90%;
+ height: 80%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 6px;
+ font-size: 12px;
+ font-weight: 500;
+ transition: all 0.3s ease;
+ }
+
+ .shift-box:hover {
+ transform: scale(1.05);
+ }
+
+ /* 鐝绫诲瀷鏍峰紡 */
+ .shift-box-early {
+ background: rgba(59, 130, 246, 0.15);
+ color: #3b82f6;
+ }
+
+ .shift-box-mid {
+ background: rgba(139, 92, 246, 0.15);
+ color: #8b5cf6;
+ }
+
+ .shift-box-night {
+ background: rgba(245, 158, 11, 0.15);
+ color: #f59e0b;
+ }
+
+ .shift-box-rest {
+ background: rgba(16, 185, 129, 0.15);
+ color: #10b981;
+ }
+
+ .shift-box-leave {
+ background: rgba(239, 68, 68, 0.15);
+ color: #ef4444;
+ }
+
+ .shift-box-other {
+ background: rgba(236, 72, 153, 0.15);
+ color: #ec4899;
+ }
+
+ .shift-box-business {
+ background: rgba(17, 24, 39, 0.15);
+ color: #111827;
+ }
+
+ /* 鐝鏂囨湰 */
+ .shift-text {
+ text-align: center;
+ }
+
+ /* 骞村害琛ㄦ牸 */
+ .yearly-table {
+ display: flex;
+ width: 100%;
+ height: calc(100vh - 280px);
+ }
+
+ /* 骞村害鏃ュ巻 */
+ .yearly-calendar {
+ width: 100%;
+ }
+
+ /* 骞村害琛ㄥご */
+ .yearly-header {
+ display: grid;
+ grid-template-columns: repeat(12, 1fr);
+ background-color: #f3f4f6;
+ border-bottom: 1px solid #e5e7eb;
+ }
+
+ .yearly-header-item {
+ height: 48px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-right: 1px solid #e5e7eb;
+ }
+
+ .month-name {
+ font-size: 14px;
+ font-weight: 500;
+ color: #333;
+ }
+
+ /* 骞村害涓讳綋 */
+ .yearly-body {
+ display: flex;
+ flex-direction: column;
+ }
+
+ /* 骞村害琛� */
+ .yearly-row {
+ display: grid;
+ grid-template-columns: repeat(12, 1fr);
+ border-bottom: 1px solid #e5e7eb;
+ transition: all 0.3s ease;
+ }
+
+ /* 骞村害鍗曞厓鏍� */
+ .yearly-cell {
+ padding: 12px;
+ border-right: 1px solid #e5e7eb;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ }
+
+ /* 鏈堝害鍑哄嫟 */
+ .monthly-attendance {
+ margin-bottom: 8px;
+ }
+
+ .attendance-label {
+ font-size: 12px;
+ color: #666;
+ margin-right: 4px;
+ }
+
+ .attendance-value {
+ font-size: 14px;
+ font-weight: 600;
+ color: #333;
+ }
+
+ /* 鏈堝害缁熻 */
+ .monthly-stats {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 4px;
+ justify-content: center;
+ }
+
+ .monthly-stats .stat-item {
+ font-size: 11px;
+ }
+
+ /* 婊氬姩鏉℃牱寮� */
+ .scheduling-right::-webkit-scrollbar {
+ height: 8px;
+ }
+
+ .scheduling-right::-webkit-scrollbar-track {
+ background: #f1f1f1;
+ }
+
+ .scheduling-right::-webkit-scrollbar-thumb {
+ background: #c1c1c1;
+ border-radius: 4px;
+ }
+
+ .scheduling-right::-webkit-scrollbar-thumb:hover {
+ background: #a8a8a8;
+ }
+
+ .search_label {
+ font-size: 14px;
+ font-weight: 500;
+ color: #333;
+ margin-bottom: 8px;
+ margin-top: 12px;
+ }
+</style>
--
Gitblit v1.9.3