|
@@ -29,11 +29,11 @@
|
|
|
<div class="flex-1 page-wrap">
|
|
|
<p class="page-wrap-tips">
|
|
|
<ErrorCircleFilledIcon /> 考勤总计:{{
|
|
|
- statisticsInfo.total
|
|
|
- }},已提交:{{ statisticsInfo.submitted }},待提交:{{
|
|
|
- statisticsInfo.unSubmitted
|
|
|
- }},累计人天:{{ statisticsInfo.allDays }}天,累计工时:{{
|
|
|
- statisticsInfo.allHours
|
|
|
+ statisticsInfo.dingCount
|
|
|
+ }},已提交:{{ statisticsInfo.submitCount }},待提交:{{
|
|
|
+ statisticsInfo.willSubmitCount
|
|
|
+ }},累计人天:{{ statisticsInfo.totalActualDays }}天,累计工时:{{
|
|
|
+ statisticsInfo.totalWorkHours
|
|
|
}}小时
|
|
|
</p>
|
|
|
|
|
@@ -41,7 +41,7 @@
|
|
|
size="small"
|
|
|
row-key="id"
|
|
|
:columns="columns"
|
|
|
- :data="tableData"
|
|
|
+ :data="tableList"
|
|
|
bordered
|
|
|
:pagination="{
|
|
|
defaultCurrent: 1,
|
|
@@ -55,8 +55,8 @@
|
|
|
:selected-row-keys="selectedRowKeys"
|
|
|
@select-change="selectChange"
|
|
|
>
|
|
|
- <template #user="{ row }">
|
|
|
- {{ row.userName }}({{ row.userNo }})
|
|
|
+ <template #role="{ col, row }">
|
|
|
+ {{ roleTypeFilter(row[col.colKey]) }}
|
|
|
</template>
|
|
|
<template #enter-time="{ col, row }">
|
|
|
{{ timestampFilter(row[col.colKey]) }}
|
|
@@ -68,18 +68,29 @@
|
|
|
{{ timestampFilter(row[col.colKey]) }}
|
|
|
</template>
|
|
|
<template #status="{ col, row }">
|
|
|
- {{ flowStatusFilter(row[col.colKey]) }}
|
|
|
+ {{ attendanceSubmitStatusFilter(row[col.colKey]) }}
|
|
|
</template>
|
|
|
<template #operate="{ row }">
|
|
|
<div class="table-operations" @click.stop>
|
|
|
- <t-link theme="primary" hover="color" @click="handleSubmit(row)">
|
|
|
+ <t-link
|
|
|
+ v-if="row.submitStatus === 'WILL_SUBMIT'"
|
|
|
+ theme="primary"
|
|
|
+ hover="color"
|
|
|
+ @click="handleSubmit(row)"
|
|
|
+ >
|
|
|
提交
|
|
|
</t-link>
|
|
|
- <t-link theme="danger" hover="color" @click="handleWithdraw(row)">
|
|
|
+ <t-link
|
|
|
+ v-if="row.submitStatus === 'ALREADY_SUBMIT'"
|
|
|
+ theme="primary"
|
|
|
+ hover="color"
|
|
|
+ @click="handleWithdraw(row)"
|
|
|
+ >
|
|
|
撤回
|
|
|
</t-link>
|
|
|
<t-link
|
|
|
- theme="danger"
|
|
|
+ v-if="row.submitStatus === 'APPLY_WITHDRAW'"
|
|
|
+ theme="primary"
|
|
|
hover="color"
|
|
|
@click="handleCancelWithdraw(row)"
|
|
|
>
|
|
@@ -93,30 +104,43 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup name="WorkAttendance">
|
|
|
-import { reactive, ref } from 'vue';
|
|
|
+import { computed, onMounted, reactive, ref } from 'vue';
|
|
|
import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
|
|
|
import { ErrorCircleFilledIcon } from 'tdesign-icons-vue-next';
|
|
|
import useFetchTable from '@/hooks/useFetchTable';
|
|
|
import {
|
|
|
workAttendanceListApi,
|
|
|
- workStatisticsInfoApi,
|
|
|
+ workAttendanceInfoApi,
|
|
|
workAttendanceSubmitApi,
|
|
|
workAttendanceExportApi,
|
|
|
workAttendanceWithdrawApi,
|
|
|
workAttendanceCancelWithdrawApi,
|
|
|
} from '@/api/work-hours';
|
|
|
-import { timestampFilter, flowStatusFilter } from '@/utils/filter';
|
|
|
-import { FLOW_STATUS } from '@/config/constants';
|
|
|
-import { dictToOptionList } from '@/utils/tool';
|
|
|
+import {
|
|
|
+ timestampFilter,
|
|
|
+ attendanceSubmitStatusFilter,
|
|
|
+ roleTypeFilter,
|
|
|
+} from '@/utils/filter';
|
|
|
+import { randomCode } from '@/utils/tool';
|
|
|
|
|
|
const selectedRowKeys = ref([]);
|
|
|
-const selectChange = (value) => {
|
|
|
+const selectedRowDatas = ref([]);
|
|
|
+const selectChange = (value, { selectedRowData }) => {
|
|
|
selectedRowKeys.value = value;
|
|
|
+ selectedRowDatas.value = selectedRowData.map((item) => getSelectedData(item));
|
|
|
};
|
|
|
|
|
|
+function getSelectedData(data) {
|
|
|
+ return {
|
|
|
+ serviceUnitId: data.serviceUnitId,
|
|
|
+ sopNo: data.sopNo,
|
|
|
+ userArchivesId: data.archivesId,
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
const fields = ref([
|
|
|
{
|
|
|
- prop: 'serviceId',
|
|
|
+ prop: 'serviceUnitId',
|
|
|
label: '服务单元',
|
|
|
type: 'select',
|
|
|
labelWidth: 100,
|
|
@@ -124,18 +148,27 @@ const fields = ref([
|
|
|
cell: 'service',
|
|
|
},
|
|
|
{
|
|
|
- prop: 'status',
|
|
|
+ prop: 'dingSubmitStatusDesc',
|
|
|
label: '提交状态',
|
|
|
type: 'select',
|
|
|
labelWidth: 100,
|
|
|
colSpan: 5,
|
|
|
- options: dictToOptionList(FLOW_STATUS),
|
|
|
+ options: [
|
|
|
+ {
|
|
|
+ value: '已提交',
|
|
|
+ label: '已提交',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: '未提交',
|
|
|
+ label: '未提交',
|
|
|
+ },
|
|
|
+ ],
|
|
|
attrs: {
|
|
|
clearable: true,
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
- prop: 'createId',
|
|
|
+ prop: 'submitUserId',
|
|
|
label: '提交人',
|
|
|
type: 'select',
|
|
|
labelWidth: 100,
|
|
@@ -143,7 +176,7 @@ const fields = ref([
|
|
|
cell: 'creator',
|
|
|
},
|
|
|
{
|
|
|
- prop: 'userName',
|
|
|
+ prop: 'archivesName',
|
|
|
label: '姓名',
|
|
|
labelWidth: 100,
|
|
|
colSpan: 5,
|
|
@@ -157,7 +190,7 @@ const fields = ref([
|
|
|
children: [
|
|
|
{
|
|
|
type: 'button',
|
|
|
- text: '查询',
|
|
|
+ text: '搜索',
|
|
|
onClick: () => {
|
|
|
search();
|
|
|
getStatisticsInfo();
|
|
@@ -174,7 +207,7 @@ const fields = ref([
|
|
|
cell: 'supplier',
|
|
|
},
|
|
|
{
|
|
|
- prop: 'custom',
|
|
|
+ prop: 'customName',
|
|
|
label: '客户名称',
|
|
|
labelWidth: 100,
|
|
|
colSpan: 5,
|
|
@@ -192,9 +225,9 @@ const fields = ref([
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
- prop: 'days',
|
|
|
+ prop: 'violationHoursLimit',
|
|
|
type: 'number',
|
|
|
- label: '违规工时>',
|
|
|
+ label: '违规工时',
|
|
|
labelWidth: 100,
|
|
|
colSpan: 5,
|
|
|
attrs: {
|
|
@@ -202,64 +235,68 @@ const fields = ref([
|
|
|
decimalPlaces: 0,
|
|
|
max: 1000000,
|
|
|
min: 0,
|
|
|
+ label: '>',
|
|
|
style: 'width: 100%',
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
- prop: 'i',
|
|
|
+ prop: 'dingExceptionLimit',
|
|
|
type: 'number',
|
|
|
- label: '考勤异常数>',
|
|
|
- labelWidth: 120,
|
|
|
+ label: '考勤异常数',
|
|
|
+ labelWidth: 100,
|
|
|
colSpan: 5,
|
|
|
attrs: {
|
|
|
theme: 'column',
|
|
|
decimalPlaces: 0,
|
|
|
max: 1000000,
|
|
|
min: 0,
|
|
|
+ label: '>',
|
|
|
style: 'width: 100%',
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
- prop: 'j',
|
|
|
+ prop: 'remainLimit',
|
|
|
type: 'number',
|
|
|
- label: '剩余补卡次数>',
|
|
|
- labelWidth: 120,
|
|
|
+ label: '剩余补卡次数',
|
|
|
+ labelWidth: 100,
|
|
|
colSpan: 5,
|
|
|
attrs: {
|
|
|
theme: 'column',
|
|
|
decimalPlaces: 0,
|
|
|
max: 1000000,
|
|
|
min: 0,
|
|
|
+ label: '>',
|
|
|
style: 'width: 100%',
|
|
|
},
|
|
|
},
|
|
|
{
|
|
|
- prop: 'k',
|
|
|
+ prop: 'exceptionLimit',
|
|
|
type: 'number',
|
|
|
- label: '待处理异常数>',
|
|
|
- labelWidth: 120,
|
|
|
+ label: '待处理异常数',
|
|
|
+ labelWidth: 100,
|
|
|
colSpan: 5,
|
|
|
attrs: {
|
|
|
theme: 'column',
|
|
|
decimalPlaces: 0,
|
|
|
max: 1000000,
|
|
|
min: 0,
|
|
|
+ label: '>',
|
|
|
style: 'width: 100%',
|
|
|
},
|
|
|
},
|
|
|
]);
|
|
|
const params = reactive({
|
|
|
- serviceId: '',
|
|
|
- status: '',
|
|
|
- createId: '',
|
|
|
- userName: '',
|
|
|
+ serviceUnitId: '',
|
|
|
+ dingSubmitStatusDesc: '',
|
|
|
+ submitUserId: '',
|
|
|
+ archivesName: '',
|
|
|
supplierId: '',
|
|
|
- custom: '',
|
|
|
+ customName: '',
|
|
|
sopNo: '',
|
|
|
- days: null,
|
|
|
- i: null,
|
|
|
- j: null,
|
|
|
- k: null,
|
|
|
+ violationHoursLimit: null,
|
|
|
+ dingExceptionLimit: null,
|
|
|
+ remainLimit: null,
|
|
|
+ exceptionLimit: null,
|
|
|
});
|
|
|
|
|
|
const columns = [
|
|
@@ -274,24 +311,33 @@ const columns = [
|
|
|
{ colKey: 'customName', title: '客户名称', width: 120 },
|
|
|
{ colKey: 'province', title: '省份', width: 120 },
|
|
|
{ colKey: 'city', title: '城市', width: 120 },
|
|
|
- { colKey: 'enterTime', title: '进场时间', cell: 'enter-time', width: 180 },
|
|
|
- { colKey: 'outerTime', title: '撤场时间', cell: 'outer-time', width: 180 },
|
|
|
- { colKey: 'userName', title: '姓名(人员档案号)', cell: 'user', width: 170 },
|
|
|
- { colKey: 'roleName', title: '项目角色' },
|
|
|
- { colKey: 'supplier', title: '供应商' },
|
|
|
- { colKey: 'attendance', title: '实际出勤(天)', width: 140 },
|
|
|
+ { colKey: 'approachTime', title: '进场时间', cell: 'enter-time', width: 180 },
|
|
|
+ {
|
|
|
+ colKey: 'departureTime',
|
|
|
+ title: '撤场时间',
|
|
|
+ cell: 'outer-time',
|
|
|
+ width: 180,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ colKey: 'archivesInfo',
|
|
|
+ title: '姓名(人员档案号)',
|
|
|
+ width: 260,
|
|
|
+ },
|
|
|
+ { colKey: 'roleType', title: '项目角色', width: 120, cell: 'role' },
|
|
|
+ { colKey: 'supplierName', title: '供应商' },
|
|
|
+ { colKey: 'actualDays', title: '实际出勤(天)', width: 140 },
|
|
|
{ colKey: 'weekdays', title: '工作日(天)', width: 130 },
|
|
|
{ colKey: 'weekends', title: '周末(天)', width: 120 },
|
|
|
- { colKey: 'holidays', title: '法定节假日(天)', width: 160 },
|
|
|
+ { colKey: 'legalHolidays', title: '法定节假日(天)', width: 160 },
|
|
|
{ colKey: 'workHours', title: '累计工时(天)', width: 140 },
|
|
|
{ colKey: 'violationDays', title: '违规工时(天)', width: 140 },
|
|
|
- { colKey: 'q', title: '考勤异常数(天)', width: 150 },
|
|
|
- { colKey: 'r', title: '剩余补卡次数', width: 120 },
|
|
|
- { colKey: 's', title: '待处理异常数', width: 120 },
|
|
|
- { colKey: 'status', title: '提交状态', cell: 'status', width: 120 },
|
|
|
- { colKey: 'submitter', title: '提交人', width: 120 },
|
|
|
+ { colKey: 'dingExceptionCount', title: '考勤异常数(天)', width: 150 },
|
|
|
+ { colKey: 'remainCount', title: '剩余补卡次数', width: 120 },
|
|
|
+ { colKey: 'exceptionCount', title: '待处理异常数', width: 120 },
|
|
|
+ { colKey: 'submitStatus', title: '提交状态', cell: 'status', width: 120 },
|
|
|
+ { colKey: 'submitUserName', title: '提交人', width: 120 },
|
|
|
{
|
|
|
- colKey: 'submissionTime',
|
|
|
+ colKey: 'submitTime',
|
|
|
title: '提交时间',
|
|
|
cell: 'submit-time',
|
|
|
width: 180,
|
|
@@ -300,9 +346,10 @@ const columns = [
|
|
|
title: '管理',
|
|
|
colKey: 'operate',
|
|
|
fixed: 'right',
|
|
|
- width: 160,
|
|
|
+ width: 120,
|
|
|
},
|
|
|
];
|
|
|
+
|
|
|
const { pagination, tableData, fetchData, search, onChange } = useFetchTable(
|
|
|
workAttendanceListApi,
|
|
|
{
|
|
@@ -312,9 +359,16 @@ const { pagination, tableData, fetchData, search, onChange } = useFetchTable(
|
|
|
params,
|
|
|
}
|
|
|
);
|
|
|
+
|
|
|
+const tableList = computed(() => {
|
|
|
+ return tableData.value.map((item) => {
|
|
|
+ return { ...item, id: randomCode() };
|
|
|
+ });
|
|
|
+});
|
|
|
+
|
|
|
let statisticsInfo = ref({});
|
|
|
const getStatisticsInfo = async () => {
|
|
|
- const res = await workStatisticsInfoApi(params);
|
|
|
+ const res = await workAttendanceInfoApi(params);
|
|
|
statisticsInfo.value = res || {};
|
|
|
};
|
|
|
|
|
@@ -331,7 +385,7 @@ const multSubmit = () => {
|
|
|
theme: 'success',
|
|
|
onConfirm: async () => {
|
|
|
confirmDia.hide();
|
|
|
- const res = await workAttendanceSubmitApi(selectedRowKeys.value).catch(
|
|
|
+ const res = await workAttendanceSubmitApi(selectedRowDatas.value).catch(
|
|
|
() => {}
|
|
|
);
|
|
|
if (!res) return;
|
|
@@ -341,21 +395,19 @@ const multSubmit = () => {
|
|
|
});
|
|
|
};
|
|
|
const multExport = () => {
|
|
|
- if (!selectedRowKeys.value.length) {
|
|
|
- MessagePlugin.error('请选择要导出的记录');
|
|
|
- return;
|
|
|
- }
|
|
|
+ // if (!selectedRowKeys.value.length) {
|
|
|
+ // MessagePlugin.error('请选择要导出的记录');
|
|
|
+ // return;
|
|
|
+ // }
|
|
|
const confirmDia = DialogPlugin({
|
|
|
header: '操作提示',
|
|
|
- body: `确定要导出选择的所有记录吗?`,
|
|
|
+ body: `确定要导出查询的所有记录吗?`,
|
|
|
confirmBtn: '确定',
|
|
|
cancelBtn: '取消',
|
|
|
theme: 'info',
|
|
|
onConfirm: async () => {
|
|
|
confirmDia.hide();
|
|
|
- const res = await workAttendanceExportApi(selectedRowKeys.value).catch(
|
|
|
- () => {}
|
|
|
- );
|
|
|
+ const res = await workAttendanceExportApi(params).catch(() => {});
|
|
|
if (!res) return;
|
|
|
MessagePlugin.success('导出任务提交成功,请前往任务管理中下载');
|
|
|
},
|
|
@@ -371,7 +423,9 @@ const handleSubmit = (row) => {
|
|
|
theme: 'success',
|
|
|
onConfirm: async () => {
|
|
|
confirmDia.hide();
|
|
|
- const res = await workAttendanceSubmitApi([row.id]).catch(() => {});
|
|
|
+ const res = await workAttendanceSubmitApi([getSelectedData(row)]).catch(
|
|
|
+ () => {}
|
|
|
+ );
|
|
|
if (!res) return;
|
|
|
MessagePlugin.success('操作成功');
|
|
|
fetchData();
|
|
@@ -387,7 +441,9 @@ const handleWithdraw = (row) => {
|
|
|
theme: 'warning',
|
|
|
onConfirm: async () => {
|
|
|
confirmDia.hide();
|
|
|
- const res = await workAttendanceWithdrawApi(row.id).catch(() => {});
|
|
|
+ const res = await workAttendanceWithdrawApi(getSelectedData(row)).catch(
|
|
|
+ () => {}
|
|
|
+ );
|
|
|
if (!res) return;
|
|
|
MessagePlugin.success('操作成功');
|
|
|
fetchData();
|
|
@@ -403,11 +459,17 @@ const handleCancelWithdraw = (row) => {
|
|
|
theme: 'warning',
|
|
|
onConfirm: async () => {
|
|
|
confirmDia.hide();
|
|
|
- const res = await workAttendanceCancelWithdrawApi(row.id).catch(() => {});
|
|
|
+ const res = await workAttendanceCancelWithdrawApi(
|
|
|
+ getSelectedData(row)
|
|
|
+ ).catch(() => {});
|
|
|
if (!res) return;
|
|
|
MessagePlugin.success('操作成功');
|
|
|
fetchData();
|
|
|
},
|
|
|
});
|
|
|
};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getStatisticsInfo();
|
|
|
+});
|
|
|
</script>
|