|
@@ -2,39 +2,75 @@
|
|
|
<div class="attendanceCenterDep">
|
|
|
<h1>考勤统计表</h1>
|
|
|
<div class="depSearch">
|
|
|
- <div class="searBox">
|
|
|
- <span class="span">月份:</span>
|
|
|
- <el-date-picker v-model="fromParams.month" type="month" placeholder="请选择月份" />
|
|
|
- </div>
|
|
|
- <div class="searBox">
|
|
|
- <span class="span">部门:</span>
|
|
|
- <el-tree-select
|
|
|
- v-model="fromParams.deptId"
|
|
|
- :data="deptList"
|
|
|
- :props="defaultProps"
|
|
|
- check-strictly
|
|
|
- node-key="id"
|
|
|
- placeholder="请选择部门"
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class="searBox">
|
|
|
- <span class="span">人员:</span>
|
|
|
- <el-input v-model="fromParams.userName" placeholder="请输入人员名称" />
|
|
|
- </div>
|
|
|
- <div class="searBtns">
|
|
|
- <el-button @click="querysClick" type="primary" style="background: #3485ff">
|
|
|
- <img src="@/assets/imgs/OA/search.png" class="mr-8px" alt="" />
|
|
|
- 查询</el-button
|
|
|
- >
|
|
|
- <el-button type="primary">
|
|
|
- <img src="@/assets/imgs/OA/open.png" class="mr-8px" alt="" />
|
|
|
- 导出</el-button
|
|
|
- >
|
|
|
+ <div class="depSearchFlex">
|
|
|
+ <div class="searBox">
|
|
|
+ <span class="span">月份:</span>
|
|
|
+ <el-date-picker v-model="fromParams.month" type="month" placeholder="请选择月份" />
|
|
|
+ </div>
|
|
|
+ <div class="searBox">
|
|
|
+ <span class="span">部门:</span>
|
|
|
+ <el-tree-select
|
|
|
+ v-model="fromParams.deptId"
|
|
|
+ :data="deptList"
|
|
|
+ :props="defaultProps"
|
|
|
+ check-strictly
|
|
|
+ node-key="id"
|
|
|
+ placeholder="请选择部门"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="searBox">
|
|
|
+ <span class="span">人员:</span>
|
|
|
+ <el-input v-model="fromParams.userName" placeholder="请输入人员名称" />
|
|
|
+ </div>
|
|
|
+ <div class="searBtns">
|
|
|
+ <el-button @click="querysClick" type="primary" style="background: #3485ff">
|
|
|
+ <img src="@/assets/imgs/OA/search.png" class="mr-8px" alt="" />
|
|
|
+ 查询</el-button
|
|
|
+ >
|
|
|
+ <el-button type="primary">
|
|
|
+ <img src="@/assets/imgs/OA/open.png" class="mr-8px" alt="" />
|
|
|
+ 导出</el-button
|
|
|
+ >
|
|
|
+ </div>
|
|
|
</div>
|
|
|
+
|
|
|
+ <el-popover :width="50">
|
|
|
+ <template #reference>
|
|
|
+ <div class="depStateBox">
|
|
|
+ <p>?</p>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ <template #default>
|
|
|
+ <div class="depStateContent">
|
|
|
+ <ul class="">
|
|
|
+ <li class="flex" v-for="(l, i) in depStateContentList" :key="i">
|
|
|
+ <div v-if="i == 0" class="flex">
|
|
|
+ <img src="@/assets/imgs/OA/kq/gouzi.png" alt="" />:
|
|
|
+ <p>{{ l.name }}</p>
|
|
|
+ </div>
|
|
|
+ <div v-else class="flex">
|
|
|
+ <h4>{{ l.deps }}:</h4>
|
|
|
+ <p>{{ l.name }}</p>
|
|
|
+ </div>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-popover>
|
|
|
</div>
|
|
|
<div class="depTable">
|
|
|
- <el-table :data="tableData" style="width: 100%">
|
|
|
- <el-table-column prop="index" label="序号" width="40" />
|
|
|
+ <el-table
|
|
|
+ :data="
|
|
|
+ tableData.slice(
|
|
|
+ (pagesList.pageNo - 1) * pagesList.pageSize,
|
|
|
+ pagesList.pageSize * pagesList.pageNo
|
|
|
+ )
|
|
|
+ "
|
|
|
+ height="620"
|
|
|
+ style="width: 100%"
|
|
|
+ stripe
|
|
|
+ >
|
|
|
+ <!-- <el-table-column type="index" width="50" /> -->
|
|
|
<el-table-column prop="deptName" label="部门" />
|
|
|
<el-table-column prop="nickName" label="姓名" width="80" />
|
|
|
<el-table-column
|
|
@@ -42,24 +78,86 @@
|
|
|
:key="index"
|
|
|
:label="item.dayOfWeek"
|
|
|
width="30"
|
|
|
+ :label-class-name="item.isworkday == 1 ? '' : 'workday'"
|
|
|
>
|
|
|
- <el-table-column :label="item.day" width="30">
|
|
|
- <template #default="scope">{{ sco(scope.row, item) }}</template>
|
|
|
+ <el-table-column
|
|
|
+ :label-class-name="item.isworkday == 1 ? '' : 'workday'"
|
|
|
+ :label="item.day"
|
|
|
+ width="30"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <div class="iconsFlex" v-if="item.isworkday == 1">
|
|
|
+ <div class="sw">
|
|
|
+ <img
|
|
|
+ v-if="sco(scope.row, item, 1) == '1'"
|
|
|
+ src="@/assets/imgs/OA/kq/gouzi.png"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '2'"> 迟 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '3'"> 早 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '4'"> 旷 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '5'"> 差 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '6'"> 事 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '7'"> 病 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '8'"> 婚 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '9'"> 产 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '10'"> 陪 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '11'"> 丧 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '12'"> 伤 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '13'"> 年 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '14'"> 调 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 1) == '20'"> 他 </div>
|
|
|
+ <div class="spans" v-else> </div>
|
|
|
+ </div>
|
|
|
+ <div class="xw">
|
|
|
+ <img
|
|
|
+ v-if="sco(scope.row, item, 2) == '1'"
|
|
|
+ src="@/assets/imgs/OA/kq/gouzi.png"
|
|
|
+ alt=""
|
|
|
+ />
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '2'"> 迟 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '3'"> 早 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '4'"> 旷 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '5'"> 差 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '6'"> 事 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '7'"> 病 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '8'"> 婚 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '9'"> 产 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '10'"> 陪 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '11'"> 丧 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '12'"> 伤 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '13'"> 年 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '14'"> 调 </div>
|
|
|
+ <div class="spans" v-else-if="sco(scope.row, item, 2) == '20'"> 他 </div>
|
|
|
+ <div class="spans" v-else> </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</el-table-column>
|
|
|
</el-table-column>
|
|
|
|
|
|
- <el-table-column prop="1" label="旷工" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="迟到" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="早退" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="出差" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="事假" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="调休" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="病假" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="年假" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="产假" width="40" label-class-name="labelModeRl" />
|
|
|
- <el-table-column prop="1" label="其他" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="kg" label="旷工" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="cd" label="迟到" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="zt" label="早退" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="cc" label="出差" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="sj" label="事假" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="tx" label="调休" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="bj" label="病假" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="nj" label="年假" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="cj" label="产假" width="40" label-class-name="labelModeRl" />
|
|
|
+ <el-table-column prop="qt" label="其他" width="40" label-class-name="labelModeRl" />
|
|
|
</el-table>
|
|
|
</div>
|
|
|
+ <div class="depPages">
|
|
|
+ <el-pagination
|
|
|
+ :current-page="pagesList.pageNo"
|
|
|
+ :page-size="pagesList.pageSize"
|
|
|
+ background
|
|
|
+ layout="total, prev, pager, next, jumper"
|
|
|
+ :total="pagesList.total"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
<script setup lang="ts">
|
|
@@ -69,6 +167,12 @@ import { defaultProps, handleTree } from '@/utils/tree'
|
|
|
import * as MineApi from '@/api/oa/attendanceCenter'
|
|
|
import { isArrayDelOrNickname, allDeptsArr, dayOfWeekCall } from './attendAuth'
|
|
|
import moment from 'moment'
|
|
|
+import { depsState } from './depsState'
|
|
|
+const pagesList: any = ref({
|
|
|
+ pageNo: 1,
|
|
|
+ pageSize: 12,
|
|
|
+ total: 0
|
|
|
+})
|
|
|
const fromParams: any = ref({
|
|
|
deptId: '0a168fe9-2ba8-4302-b6b6-a524c1aef967',
|
|
|
month: '',
|
|
@@ -79,6 +183,15 @@ const tableData = ref([])
|
|
|
const initTreeDeps = async () => {
|
|
|
deptList.value = handleTree(await DeptApi.getSimpleDeptList())
|
|
|
}
|
|
|
+const depStateContentList = ref()
|
|
|
+depStateContentList.value = depsState
|
|
|
+const handleCurrentChange = async (page) => {
|
|
|
+ pagesList.value.pageNo = page
|
|
|
+ let toMoseMonths: any = []
|
|
|
+ toMoseMonths[0] = moment().startOf('months').format('YYYY-MM-DD') + ' 00:00:00'
|
|
|
+ toMoseMonths[1] = moment().endOf('months').format('YYYY-MM-DD') + ' 23:59:59'
|
|
|
+ initInsMouth(toMoseMonths)
|
|
|
+}
|
|
|
const querysClick = async () => {
|
|
|
// initInsMouth()
|
|
|
let month = fromParams.value.month
|
|
@@ -89,7 +202,7 @@ const querysClick = async () => {
|
|
|
}
|
|
|
const initInsMouth = async (date: any) => {
|
|
|
let params = {
|
|
|
- attendanceTime: date, // 考勤时间
|
|
|
+ attendanceDate: date, // 考勤时间
|
|
|
attendanceStatus: '', // 考勤状态,示例值(2)
|
|
|
attendanceType: '', // 考勤类型(1:上午;2:下午),示例值(1)
|
|
|
otherMinute: '', // 其他考勤状态分钟(除了出勤)
|
|
@@ -101,28 +214,38 @@ const initInsMouth = async (date: any) => {
|
|
|
let namesArr: any = isArrayDelOrNickname(JSON.parse(JSON.stringify(res)))
|
|
|
let resArr: any = res
|
|
|
resArr.forEach((item: any) => {
|
|
|
- item.date = moment(item.attendanceTime).format('YYYY-MM-DD')
|
|
|
+ if (item.attendanceTime) {
|
|
|
+ item.date = moment(item.attendanceTime).format('YYYY-MM-DD')
|
|
|
+ } else {
|
|
|
+ item.date = moment(item.attendanceDate).format('YYYY-MM-DD')
|
|
|
+ }
|
|
|
})
|
|
|
let arr = allDeptsArr(restall, resArr, namesArr)
|
|
|
tableData.value = arr
|
|
|
+ pagesList.value.total = arr.length
|
|
|
})
|
|
|
})
|
|
|
}
|
|
|
-const sco = (row, item) => {
|
|
|
- let swkq = ''
|
|
|
- let xwkq = ''
|
|
|
- row.attendArray.forEach((k) => {
|
|
|
- if (k.date == item.date) {
|
|
|
- if (k.swAttendanceStatus) {
|
|
|
- swkq = k.swAttendanceStatus
|
|
|
+const sco = (row, item, index) => {
|
|
|
+ let kq = ''
|
|
|
+ if (index == 1) {
|
|
|
+ row.attendArray.forEach((k) => {
|
|
|
+ if (k.date == item.date) {
|
|
|
+ if (k.swAttendanceStatus) {
|
|
|
+ kq = k.swAttendanceStatus
|
|
|
+ }
|
|
|
}
|
|
|
- if (k.xwAttendanceStatus) {
|
|
|
- xwkq = k.xwAttendanceStatus
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ row.attendArray.forEach((k) => {
|
|
|
+ if (k.date == item.date) {
|
|
|
+ if (k.xwAttendanceStatus) {
|
|
|
+ kq = k.xwAttendanceStatus
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- return swkq + '' + xwkq
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return kq
|
|
|
}
|
|
|
const tableHeadList: any = ref([])
|
|
|
const initWorkDay = async (date: any) => {
|
|
@@ -166,6 +289,7 @@ onMounted(() => {
|
|
|
border-radius: 10px;
|
|
|
margin-top: 15px;
|
|
|
padding: 15px 30px;
|
|
|
+ position: relative;
|
|
|
h1 {
|
|
|
font-size: 20px;
|
|
|
color: #121518;
|
|
@@ -176,34 +300,129 @@ onMounted(() => {
|
|
|
width: 100%;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
margin-bottom: 20px;
|
|
|
- .searBox {
|
|
|
+ .depSearchFlex {
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- margin-right: 25px;
|
|
|
- .span {
|
|
|
- white-space: nowrap;
|
|
|
+ .searBox {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-right: 25px;
|
|
|
+ .span {
|
|
|
+ white-space: nowrap;
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .depStateBox {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ border: 2px solid #e1e4ea;
|
|
|
+ border-radius: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ cursor: pointer;
|
|
|
+ p {
|
|
|
+ color: #e1e4ea;
|
|
|
font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
.depTable {
|
|
|
width: 100%;
|
|
|
- height: calc(100% - 100px);
|
|
|
- overflow-y: auto;
|
|
|
+ height: calc(100% - 140px);
|
|
|
+ }
|
|
|
+ .depPages {
|
|
|
+ position: absolute;
|
|
|
+ right: 30px;
|
|
|
+ bottom: 10px;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
:deep(.depTable) {
|
|
|
.el-table {
|
|
|
+ .workDayClass {
|
|
|
+ color: pink;
|
|
|
+ }
|
|
|
+ .is-group {
|
|
|
+ height: 80px;
|
|
|
+ tr {
|
|
|
+ background-color: #edf2fc;
|
|
|
+ th {
|
|
|
+ background-color: #edf2fc;
|
|
|
+ border-color: #fff;
|
|
|
+ color: #4c525b;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
.cell {
|
|
|
- font-size: 14px !important;
|
|
|
+ font-size: 16px !important;
|
|
|
padding: 0 !important;
|
|
|
text-align: center;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+ .el-table__cell {
|
|
|
+ padding: 0px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-table__body-wrapper {
|
|
|
+ tr {
|
|
|
+ td {
|
|
|
+ border: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-table__row--striped {
|
|
|
+ td {
|
|
|
+ background-color: #e1e4ea;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .iconsFlex {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ .spans {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ color: #f23c3c;
|
|
|
+ font-size: 14px !important;
|
|
|
+ font-weight: 800;
|
|
|
+ cursor: pointer;
|
|
|
+ user-select: none;
|
|
|
+ }
|
|
|
+
|
|
|
+ .sw {
|
|
|
+ width: 100%;
|
|
|
+ height: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ user-select: none;
|
|
|
+ }
|
|
|
+ .xw {
|
|
|
+ width: 100%;
|
|
|
+ height: 50%;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ user-select: none;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
.labelModeRl {
|
|
|
writing-mode: vertical-rl;
|
|
|
}
|
|
|
}
|
|
|
+:deep(.workday) {
|
|
|
+ color: #989fa8 !important;
|
|
|
+}
|
|
|
</style>
|