| | |
| | | import request from "@/utils/request"; |
| | | |
| | | // è·åæå¡è§åå表 |
| | | // è·åçæ¬¡å表 |
| | | export function getAttendanceRules(query) { |
| | | return request({ |
| | | url: "/personalAttendanceLocationConfig/listPage", |
| | |
| | | }); |
| | | } |
| | | |
| | | // æ°å¢æå¡è§å |
| | | // æ°å¢ç次 |
| | | export function addAttendanceRule(data) { |
| | | return request({ |
| | | url: "/personalAttendanceLocationConfig/add", |
| | |
| | | }); |
| | | } |
| | | |
| | | // æ´æ°æå¡è§å |
| | | // æ´æ°ç次 |
| | | export function updateAttendanceRule(data) { |
| | | return request({ |
| | | url: "/attendanceRules/update", |
| | |
| | | }); |
| | | } |
| | | |
| | | // å 餿å¡è§å |
| | | // å é¤ç次 |
| | | export function deleteAttendanceRule(ids) { |
| | | return request({ |
| | | url: `/personalAttendanceLocationConfig/del`, |
| | |
| | | }); |
| | | } |
| | | |
| | | // è·åå个æå¡è§å详æ
|
| | | // è·ååä¸ªçæ¬¡è¯¦æ
|
| | | export function getAttendanceRuleDetail(id) { |
| | | return request({ |
| | | url: `/attendanceRules/detail/${id}`, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | // çæ¬¡ç¸å
³æ¥å£ |
| | | |
| | | 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' |
| | | }) |
| | | } |
| | |
| | | }); |
| | | |
| | | 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 "æ¥ççæ¬¡"; |
| | | }); |
| | | |
| | | // è¡¨åæ°æ® |
| | |
| | | <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> |
| | |
| | | </el-button> |
| | | </el-form-item> |
| | | </el-form> --> |
| | | <!-- è§åå表 --> |
| | | <!-- çæ¬¡å表 --> |
| | | <el-card shadow="never" |
| | | class="mb16"> |
| | | <el-table :data="tableData" |
| | |
| | | @pagination="paginationChange" |
| | | class="mt10" /> |
| | | </el-card> |
| | | <!-- æ°å¢/ç¼è¾è§åå¼¹çª --> |
| | | <!-- æ°å¢/ç¼è¾çæ¬¡å¼¹çª --> |
| | | <rule-form ref="ruleFormRef" |
| | | v-model="dialogVisible" |
| | | :operation-type="operationType" |
| | |
| | | return ""; |
| | | }; |
| | | |
| | | // æ¥è¯¢è§åå表 |
| | | // æ¥è¯¢ç次å表 |
| | | const fetchData = () => { |
| | | tableLoading.value = true; |
| | | getAttendanceRules({ ...page, ...searchForm }) |
| | |
| | | dialogVisible.value = true; |
| | | }; |
| | | |
| | | // å é¤è§å |
| | | // å é¤ç次 |
| | | const handleDelete = id => { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¿æ¡è§ååï¼", "å é¤ç¡®è®¤", { |
| | | ElMessageBox.confirm("ç¡®å®è¦å é¤è¿æ¡ç次åï¼", "å é¤ç¡®è®¤", { |
| | | confirmButtonText: "ç¡®å®", |
| | | cancelButtonText: "åæ¶", |
| | | type: "warning", |
| | |
| | | </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" |
| | |
| | | |
| | | <script setup> |
| | | import { ref, reactive, computed, onMounted, onBeforeUnmount } from "vue"; |
| | | import { useRouter } from "vue-router"; |
| | | import { ElMessage, ElMessageBox } from "element-plus"; |
| | | import { |
| | | createPersonalAttendanceRecord, |
| | |
| | | } 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({ |
| | |
| | | fetchDeptOptions(); |
| | | }); |
| | | |
| | | // è¿åæç管çé¡µé¢ |
| | | const handleBack = () => { |
| | | router.push({ |
| | | path: "/personnelManagement/classsSheduling/index", |
| | | }); |
| | | }; |
| | | |
| | | onBeforeUnmount(() => { |
| | | if (timer) { |
| | | clearInterval(timer); |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <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> |