|
@@ -1,15 +1,25 @@
|
|
|
<template>
|
|
|
<div class="work-attendance flex flex-col h-full">
|
|
|
- <SearchForm :fields="fields" :params="params"></SearchForm>
|
|
|
+ <SearchForm :fields="fields" :params="params">
|
|
|
+ <template #service="{ item, params }">
|
|
|
+ <select-service-unit v-model="params[item.prop]"></select-service-unit>
|
|
|
+ </template>
|
|
|
+ <template #supplier="{ item, params }">
|
|
|
+ <select-supplier v-model="params[item.prop]"> </select-supplier>
|
|
|
+ </template>
|
|
|
+ <template #creator="{ item, params }">
|
|
|
+ <select-filter-user v-model="params[item.prop]"> </select-filter-user>
|
|
|
+ </template>
|
|
|
+ </SearchForm>
|
|
|
|
|
|
<div class="flex-1 page-wrap">
|
|
|
<div class="flex justify-between items-center">
|
|
|
<t-space>
|
|
|
- <span>考勤总计:{{ statisticsInfo.a }}</span>
|
|
|
- <span>已提交:{{ statisticsInfo.b }}</span>
|
|
|
- <span>待提交:{{ statisticsInfo.c }}</span>
|
|
|
- <span>累计人天:{{ statisticsInfo.d }}天</span>
|
|
|
- <span>累计工时:{{ statisticsInfo.e }}小时</span>
|
|
|
+ <span>考勤总计:{{ statisticsInfo.total }}</span>
|
|
|
+ <span>已提交:{{ statisticsInfo.submitted }}</span>
|
|
|
+ <span>待提交:{{ statisticsInfo.unSubmitted }}</span>
|
|
|
+ <span>累计人天:{{ statisticsInfo.allDays }}天</span>
|
|
|
+ <span>累计工时:{{ statisticsInfo.allHours }}小时</span>
|
|
|
</t-space>
|
|
|
<div class="btn-group">
|
|
|
<t-button
|
|
@@ -44,6 +54,38 @@
|
|
|
select-on-row-click
|
|
|
@select-change="selectChange"
|
|
|
>
|
|
|
+ <template #user="{ row }">
|
|
|
+ {{ row.userName }}({{ row.userNo }})
|
|
|
+ </template>
|
|
|
+ <template #enter-time="{ col, row }">
|
|
|
+ {{ timestampFilter(row[col.colKey]) }}
|
|
|
+ </template>
|
|
|
+ <template #outer-time="{ col, row }">
|
|
|
+ {{ timestampFilter(row[col.colKey]) }}
|
|
|
+ </template>
|
|
|
+ <template #submit-time="{ col, row }">
|
|
|
+ {{ timestampFilter(row[col.colKey]) }}
|
|
|
+ </template>
|
|
|
+ <template #status="{ col, row }">
|
|
|
+ {{ flowStatusFilter(row[col.colKey]) }}
|
|
|
+ </template>
|
|
|
+ <template #operate="{ row }">
|
|
|
+ <div class="table-operations" @click.stop>
|
|
|
+ <t-link theme="primary" hover="color" @click="handleSubmit(row)">
|
|
|
+ 提交
|
|
|
+ </t-link>
|
|
|
+ <t-link theme="danger" hover="color" @click="handleWithdraw(row)">
|
|
|
+ 撤回
|
|
|
+ </t-link>
|
|
|
+ <t-link
|
|
|
+ theme="danger"
|
|
|
+ hover="color"
|
|
|
+ @click="handleCancelWithdraw(row)"
|
|
|
+ >
|
|
|
+ 取消撤回
|
|
|
+ </t-link>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
</t-table>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -55,134 +97,61 @@ import { DialogPlugin, MessagePlugin } from 'tdesign-vue-next';
|
|
|
import useFetchTable from '@/hooks/useFetchTable';
|
|
|
import {
|
|
|
workAttendanceListApi,
|
|
|
- workAttendanceInfoApi,
|
|
|
+ workStatisticsInfoApi,
|
|
|
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';
|
|
|
|
|
|
const selectedRowKeys = ref([]);
|
|
|
const selectChange = (value) => {
|
|
|
selectedRowKeys.value = value;
|
|
|
};
|
|
|
-const columns = [
|
|
|
- {
|
|
|
- colKey: 'row-select',
|
|
|
- type: 'multiple',
|
|
|
- width: 50,
|
|
|
- fixed: 'left',
|
|
|
- },
|
|
|
- { colKey: 'a', title: '服务单元' },
|
|
|
- { colKey: 'b', title: 'SOP流水号' },
|
|
|
- { colKey: 'c', title: '客户名称' },
|
|
|
- { colKey: 'd', title: '省份' },
|
|
|
- { colKey: 'e', title: '城市' },
|
|
|
- { colKey: 'f', title: '进场时间', width: 170 },
|
|
|
- { colKey: 'g', title: '撤场时间', width: 170 },
|
|
|
- { colKey: 'h', title: '姓名(人员档案号)', width: 150 },
|
|
|
- { colKey: 'i', title: '项目角色' },
|
|
|
- { colKey: 'j', title: '供应商' },
|
|
|
- { colKey: 'k', title: '实际出勤(天)', width: 120 },
|
|
|
- { colKey: 'l', title: '工作日(天)', width: 110 },
|
|
|
- { colKey: 'm', title: '周末(天)', width: 100 },
|
|
|
- { colKey: 'n', title: '法定节假日(天)', width: 140 },
|
|
|
- { colKey: 'o', title: '累计工时(天)', width: 120 },
|
|
|
- { colKey: 'p', title: '违规工时(天)', width: 120 },
|
|
|
- { colKey: 'q', title: '考勤异常数(天)', width: 140 },
|
|
|
- { colKey: 'r', title: '剩余补卡次数', width: 110 },
|
|
|
- { colKey: 's', title: '待处理异常数', width: 110 },
|
|
|
- { colKey: 't', title: '提交状态' },
|
|
|
- { colKey: 'u', title: '提交人' },
|
|
|
- { colKey: 'v', title: '提交时间', width: 170 },
|
|
|
- {
|
|
|
- title: '操作',
|
|
|
- colKey: 'operate',
|
|
|
- fixed: 'right',
|
|
|
- width: 120,
|
|
|
- cell: (h, { row }) => {
|
|
|
- return (
|
|
|
- <div class="table-operations">
|
|
|
- <t-link
|
|
|
- theme="primary"
|
|
|
- hover="color"
|
|
|
- onClick={(e) => {
|
|
|
- e.stopPropagation();
|
|
|
- handleSubmit(row);
|
|
|
- }}
|
|
|
- >
|
|
|
- 提交
|
|
|
- </t-link>
|
|
|
- <t-link
|
|
|
- theme="danger"
|
|
|
- hover="color"
|
|
|
- onClick={(e) => {
|
|
|
- e.stopPropagation();
|
|
|
- handleWithdraw(row);
|
|
|
- }}
|
|
|
- >
|
|
|
- 撤回
|
|
|
- </t-link>
|
|
|
- <t-link
|
|
|
- theme="danger"
|
|
|
- hover="color"
|
|
|
- onClick={(e) => {
|
|
|
- e.stopPropagation();
|
|
|
- handleCancelWithdraw(row);
|
|
|
- }}
|
|
|
- >
|
|
|
- 取消撤回
|
|
|
- </t-link>
|
|
|
- </div>
|
|
|
- );
|
|
|
- },
|
|
|
- },
|
|
|
-];
|
|
|
-const { pagination, tableData, fetchData, search, onChange } = useFetchTable(
|
|
|
- workAttendanceListApi,
|
|
|
- {
|
|
|
- fetchDataHandle: () => {
|
|
|
- selectedRowKeys.value = [];
|
|
|
- },
|
|
|
- }
|
|
|
-);
|
|
|
-let statisticsInfo = ref({ a: 1, b: 2, c: 3, d: 4, e: 5 });
|
|
|
-const getStatisticsInfo = async () => {
|
|
|
- const res = await workAttendanceInfoApi(params);
|
|
|
- statisticsInfo.value = res || {};
|
|
|
-};
|
|
|
|
|
|
const fields = ref([
|
|
|
{
|
|
|
- prop: 'a',
|
|
|
+ prop: 'serviceId',
|
|
|
label: '服务单元',
|
|
|
type: 'select',
|
|
|
- labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ labelWidth: 100,
|
|
|
+ colSpan: 5,
|
|
|
+ cell: 'service',
|
|
|
},
|
|
|
{
|
|
|
- prop: 'b',
|
|
|
+ prop: 'status',
|
|
|
label: '提交状态',
|
|
|
type: 'select',
|
|
|
- labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ labelWidth: 100,
|
|
|
+ colSpan: 5,
|
|
|
+ options: dictToOptionList(FLOW_STATUS),
|
|
|
+ attrs: {
|
|
|
+ clearable: true,
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
- prop: 'c',
|
|
|
+ prop: 'createId',
|
|
|
label: '提交人',
|
|
|
type: 'select',
|
|
|
- labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ labelWidth: 100,
|
|
|
+ colSpan: 5,
|
|
|
+ cell: 'creator',
|
|
|
},
|
|
|
{
|
|
|
- prop: 'd',
|
|
|
+ prop: 'userName',
|
|
|
label: '姓名',
|
|
|
- labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ labelWidth: 100,
|
|
|
+ colSpan: 5,
|
|
|
+ attrs: {
|
|
|
+ clearable: true,
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
type: 'buttons',
|
|
|
- colSpan: 2,
|
|
|
+ colSpan: 3,
|
|
|
children: [
|
|
|
{
|
|
|
type: 'button',
|
|
@@ -195,63 +164,159 @@ const fields = ref([
|
|
|
],
|
|
|
},
|
|
|
{
|
|
|
- prop: 'e',
|
|
|
+ prop: 'supplierId',
|
|
|
label: '所属供应商',
|
|
|
type: 'select',
|
|
|
labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ colSpan: 5,
|
|
|
+ cell: 'supplier',
|
|
|
},
|
|
|
{
|
|
|
- prop: 'f',
|
|
|
+ prop: 'custom',
|
|
|
label: '客户名称',
|
|
|
- labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ labelWidth: 100,
|
|
|
+ colSpan: 5,
|
|
|
+ attrs: {
|
|
|
+ clearable: true,
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
- prop: 'g',
|
|
|
+ prop: 'sopNo',
|
|
|
label: 'SOP流水号',
|
|
|
- labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ labelWidth: 100,
|
|
|
+ colSpan: 5,
|
|
|
+ attrs: {
|
|
|
+ clearable: true,
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
- prop: 'h',
|
|
|
+ prop: 'days',
|
|
|
+ type: 'number',
|
|
|
label: '违规工时>',
|
|
|
- labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ labelWidth: 100,
|
|
|
+ colSpan: 5,
|
|
|
+ attrs: {
|
|
|
+ theme: 'column',
|
|
|
+ decimalPlaces: 0,
|
|
|
+ max: 1000000,
|
|
|
+ min: 0,
|
|
|
+ style: 'width: 120px',
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
prop: 'i',
|
|
|
+ type: 'number',
|
|
|
label: '考勤异常数>',
|
|
|
labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ colSpan: 5,
|
|
|
+ attrs: {
|
|
|
+ theme: 'column',
|
|
|
+ decimalPlaces: 0,
|
|
|
+ max: 1000000,
|
|
|
+ min: 0,
|
|
|
+ style: 'width: 120px',
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
prop: 'j',
|
|
|
+ type: 'number',
|
|
|
label: '剩余补卡次数>',
|
|
|
labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ colSpan: 5,
|
|
|
+ attrs: {
|
|
|
+ theme: 'column',
|
|
|
+ decimalPlaces: 0,
|
|
|
+ max: 1000000,
|
|
|
+ min: 0,
|
|
|
+ style: 'width: 120px',
|
|
|
+ },
|
|
|
},
|
|
|
{
|
|
|
prop: 'k',
|
|
|
+ type: 'number',
|
|
|
label: '待处理异常数>',
|
|
|
labelWidth: 120,
|
|
|
- colSpan: 5.4,
|
|
|
+ colSpan: 5,
|
|
|
+ attrs: {
|
|
|
+ theme: 'column',
|
|
|
+ decimalPlaces: 0,
|
|
|
+ max: 1000000,
|
|
|
+ min: 0,
|
|
|
+ style: 'width: 120px',
|
|
|
+ },
|
|
|
},
|
|
|
]);
|
|
|
const params = reactive({
|
|
|
- a: '',
|
|
|
- b: '',
|
|
|
- c: '',
|
|
|
- d: '',
|
|
|
- e: '',
|
|
|
- f: '',
|
|
|
- g: '',
|
|
|
- h: '',
|
|
|
- i: '',
|
|
|
- j: '',
|
|
|
- k: '',
|
|
|
+ serviceId: '',
|
|
|
+ status: '',
|
|
|
+ createId: '',
|
|
|
+ userName: '',
|
|
|
+ supplierId: '',
|
|
|
+ custom: '',
|
|
|
+ sopNo: '',
|
|
|
+ days: null,
|
|
|
+ i: null,
|
|
|
+ j: null,
|
|
|
+ k: null,
|
|
|
});
|
|
|
|
|
|
+const columns = [
|
|
|
+ {
|
|
|
+ colKey: 'row-select',
|
|
|
+ type: 'multiple',
|
|
|
+ width: 50,
|
|
|
+ fixed: 'left',
|
|
|
+ },
|
|
|
+ { colKey: 'serviceUnitName', title: '服务单元' },
|
|
|
+ { colKey: 'sopNo', title: 'SOP流水号' },
|
|
|
+ { colKey: 'customName', title: '客户名称' },
|
|
|
+ { colKey: 'province', title: '省份', minWidth: 60 },
|
|
|
+ { colKey: 'city', title: '城市', minWidth: 60 },
|
|
|
+ { colKey: 'enterTime', title: '进场时间', cell: 'enter-time', width: 170 },
|
|
|
+ { colKey: 'outerTime', title: '撤场时间', cell: 'outer-time', width: 170 },
|
|
|
+ { colKey: 'userName', title: '姓名(人员档案号)', cell: 'user', width: 150 },
|
|
|
+ { colKey: 'roleName', title: '项目角色' },
|
|
|
+ { colKey: 'supplier', title: '供应商' },
|
|
|
+ { colKey: 'attendance', title: '实际出勤(天)', width: 120 },
|
|
|
+ { colKey: 'weekdays', title: '工作日(天)', width: 110 },
|
|
|
+ { colKey: 'weekends', title: '周末(天)', width: 100 },
|
|
|
+ { colKey: 'holidays', title: '法定节假日(天)', width: 140 },
|
|
|
+ { colKey: 'workHours', title: '累计工时(天)', width: 120 },
|
|
|
+ { colKey: 'violationDays', title: '违规工时(天)', width: 120 },
|
|
|
+ { colKey: 'q', title: '考勤异常数(天)', width: 140 },
|
|
|
+ { colKey: 'r', title: '剩余补卡次数', width: 110 },
|
|
|
+ { colKey: 's', title: '待处理异常数', width: 110 },
|
|
|
+ { colKey: 'status', title: '提交状态', cell: 'status', width: 100 },
|
|
|
+ { colKey: 'submitter', title: '提交人' },
|
|
|
+ {
|
|
|
+ colKey: 'submissionTime',
|
|
|
+ title: '提交时间',
|
|
|
+ cell: 'submit-time',
|
|
|
+ width: 170,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '操作',
|
|
|
+ colKey: 'operate',
|
|
|
+ cell: 'operate',
|
|
|
+ fixed: 'right',
|
|
|
+ width: 120,
|
|
|
+ },
|
|
|
+];
|
|
|
+const { pagination, tableData, fetchData, search, onChange } = useFetchTable(
|
|
|
+ workAttendanceListApi,
|
|
|
+ {
|
|
|
+ fetchDataHandle: () => {
|
|
|
+ selectedRowKeys.value = [];
|
|
|
+ },
|
|
|
+ params,
|
|
|
+ }
|
|
|
+);
|
|
|
+let statisticsInfo = ref({});
|
|
|
+const getStatisticsInfo = async () => {
|
|
|
+ const res = await workStatisticsInfoApi(params);
|
|
|
+ statisticsInfo.value = res || {};
|
|
|
+};
|
|
|
+
|
|
|
const multSubmit = () => {
|
|
|
if (!selectedRowKeys.value.length) {
|
|
|
MessagePlugin.error('请选择要提交的记录');
|