admin-vben5/apps/web-antd/src/views/property/attendanceManagement/attendanceGroupSettings/group-modal.vue

492 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script setup lang="ts">
import {computed, reactive, ref} from 'vue';
import {useVbenModal} from '@vben/common-ui';
import {$t} from '@vben/locales';
import {cloneDeep} from '@vben/utils';
import {useVbenForm} from '#/adapter/form';
import {
groupAdd,
groupInfo,
groupUpdate
} from '#/api/property/attendanceManagement/attendanceGroupSettings';
import {defaultFormValueGetter, useBeforeCloseDiff} from '#/utils/popup';
import {
clockingColumns,
cycleColumns,
modalSchema,
noClockingColumns,
weekdayColumns
} from './data';
import {Tag, Button, Table, Checkbox, Select, SelectOption, message, Alert} from 'ant-design-vue'
import {getDictOptions} from "#/utils/dict";
import holidayCalendar from './holiday-calendar.vue'
import changeShiftSchedule from './change-shift-schedule.vue'
import checkInDate from './check-in-date.vue'
import {h} from 'vue';
import {PlusOutlined, MinusOutlined} from '@ant-design/icons-vue';
import type {ShiftVO} from "#/api/property/attendanceManagement/shiftSetting/model";
const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
});
const settingData = reactive({
isAutomatic: true,
weekdayData: [],
cycleData: [],
unCheckInData: [],
checkInData: [],
shiftId: ''
})
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
// 默认占满两列
formItemClass: 'col-span-2',
// 默认label宽度 px
labelWidth: 80,
// 通用配置项 会影响到所有表单项
componentProps: {
class: 'w-full',
}
},
schema: modalSchema(),
showDefaultActions: false,
wrapperClass: 'grid-cols-2',
});
const {onBeforeClose, markInitialized, resetInitialized} = useBeforeCloseDiff(
{
initializedGetter: defaultFormValueGetter(formApi),
currentGetter: defaultFormValueGetter(formApi),
},
);
const [BasicModal, modalApi] = useVbenModal({
fullscreenButton: false,
fullscreen: true,
// class:'w-[80%]',
onBeforeClose,
onClosed: handleClosed,
onConfirm: handleConfirm,
onOpenChange: async (isOpen) => {
if (!isOpen) {
return null;
}
modalApi.modalLoading(true);
const {id} = modalApi.getData() as { id?: number | string };
isUpdate.value = !!id;
if (isUpdate.value && id) {
const record = await groupInfo(id);
await formApi.setValues(record);
} else {
const dictOptions = getDictOptions('wy_kqgzr');
console.log(dictOptions)
if (dictOptions) {
dictOptions.forEach(item => {
settingData.weekdayData.push({
dayOfWeek: item.value,
label: item.label,
shiftValue: '休息',
isRest: 1,
id: null,
})
})
}
settingData.cycleData = [{id: ''}, {id: ''}];
}
await markInitialized();
modalApi.modalLoading(false);
},
});
async function handleConfirm() {
try {
modalApi.lock(true);
const {valid} = await formApi.validate();
if (!valid) {
return;
}
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues());
if (data.attendanceType == 1) {
let hasError = false;
settingData.cycleData.forEach((item, index) => {
if (!item.id) {
message.warning('请选择周期天数对应班次。');
return;
}
item.dayNumber = index + 1
})
if (!hasError) {
return;
}
data.numList = settingData.cycleData
} else {
data.weekSetList = settingData.weekdayData
data.clockDate = settingData.checkInData.concat(settingData.unCheckInData)
}
await (isUpdate.value ? groupUpdate(data) : groupAdd(data));
resetInitialized();
emit('reload');
modalApi.close();
} catch (error) {
console.error(error);
} finally {
modalApi.lock(false);
}
}
async function handleClosed() {
await formApi.resetForm();
resetInitialized();
Object.assign(settingData, {
isAutomatic: true,
weekdayData: [],
cycleData: [],
unCheckInData: [],
checkInData: [],
shiftId: '',
});
}
const [HolidayCalendar, holidayApi] = useVbenModal({
connectedComponent: holidayCalendar,
});
const [ChangeShiftSchedule, shiftApi] = useVbenModal({
connectedComponent: changeShiftSchedule,
});
const [CheckInDate, checkInDateApi] = useVbenModal({
connectedComponent: checkInDate,
});
/**
* 查看法定节假日日历
*/
function showHoliday() {
holidayApi.open()
}
/**
* 更改班次
* @param type 1.设置班次 2.选择班次
*/
function shiftScheduleHandle(type: number) {
shiftApi.setData({type})
shiftApi.open()
}
const shiftInfo = ref<ShiftVO>()
const shiftList = ref<ShiftVO[]>([])
function handleShiftInfo(info: ShiftVO) {
if (info) {
settingData.shiftId = info.id
shiftInfo.value = info;
settingData.weekdayData.forEach(item => {
item.id = info.id
let str = ''
if (info.isRest) {
str = `${info.name}${info.startTime}~${info.restStartTime} ${info.restEndTime}~${info.endTime}`;
} else {
str = `${info.name}${info.startTime}~${info.endTime}`;
}
item.shiftValue = str
item.isRest = 0
})
}
}
function handleShiftList(list: any[]) {
shiftList.value = list;
}
function addCycleHandle() {
if (settingData.cycleData.length < 31) {
settingData.cycleData.push({
id: '',
})
} else {
message.warning('周期天数最多31天。');
}
}
function deleteCycleHandle(index: number) {
if (settingData.cycleData.length > 2) {
settingData.cycleData.splice(index, 1)
} else {
message.warning('周期天数最少2天。');
}
}
function deleteUnCheckInHandle(index: number) {
settingData.unCheckInData.splice(index, 1)
}
function deleteCheckInHandle(index: number) {
settingData.checkInData.splice(index, 1)
}
const tableIndex = ref(-1)
function changeShiftHandle(type: number, index: number) {
tableIndex.value = index
shiftApi.setData({type})//3.更改班次
shiftApi.open()
}
function restHandle(index: number) {
settingData.weekdayData[index].isRest = 1
settingData.weekdayData[index].shiftValue = '休息'
settingData.weekdayData[index].id = null
}
function handleAfterValue(val: ShiftVO) {
if (tableIndex.value > -1 && val) {
settingData.weekdayData[tableIndex.value].id = val.id
let str = ''
if (val.isRest) {
str = `${val.name}${val.startTime}~${val.restStartTime} ${val.restEndTime}~${val.endTime}`;
} else {
str = `${val.name}${val.startTime}~${val.endTime}`;
}
settingData.weekdayData[tableIndex.value].shiftValue = str
settingData.weekdayData[tableIndex.value].isRest = 0
}
}
function closeTagHandle(i: number) {
shiftList.value.splice(i, 1)
}
const checkInIndex = ref(-1)
function addCheckInHandle(index: number) {
checkInIndex.value = index
checkInDateApi.setData({check: true})
checkInDateApi.open()
}
function getCheckInData(val: any) {
if (val) {
settingData.checkInData.push({
...val,
mustNoCheck: 1
})
}
}
const unCheckInIndex = ref(-1)
function addUnCheckInHandle(index: number) {
unCheckInIndex.value = index
checkInDateApi.setData({check: false})
checkInDateApi.open()
}
function getUnCheckInData(val: any) {
if (val) {
settingData.unCheckInData.push({
...val,
mustNoCheck: 0
})
}
}
</script>
<template>
<BasicModal :title="title+'考勤组'">
<BasicForm class="form-content">
<template #weekdaySetting>
<div class="item-font">
<span>快捷设置班次</span>
<Tag color="processing" v-if="shiftInfo">
<span>{{ shiftInfo.name }}</span>&nbsp;
<span v-if="shiftInfo.isRest">
{{ shiftInfo.startTime + '~' + shiftInfo.restStartTime }}&nbsp;
{{ shiftInfo.restEndTime + '~' + shiftInfo.endTime }}
</span>
<span v-else>
{{ shiftInfo.startTime + '~' + shiftInfo.endTime }}
</span>
</Tag>
<Button type="link" @click="shiftScheduleHandle(1)">设置班次</Button>
</div>
</template>
<template #settingItem>
<div class="item-font" style="width: 100%;">
<Table style="width: 90%" bordered :columns="weekdayColumns"
:data-source="settingData.weekdayData"
size="small" :pagination="false">
<template #bodyCell="{ column, record,index }">
<template v-if="column.dataIndex==='action'">
<Button type="link" size="small" @click="changeShiftHandle(3,index)">更改班次
</Button>
<Button type="link" size="small" @click="restHandle(index)" v-if="!record.isRest">
休息
</Button>
</template>
</template>
</Table>
<Checkbox class="item-padding-top" v-model:checked="settingData.isAutomatic">
法定节假日自动排休
</Checkbox>
<Button type="link" @click="showHoliday">查看法定节假日日历</Button>
<p class="item-padding-top item-font-weight">特殊日期:</p>
<p class="item-padding">无需打卡日期:</p>
<Table style="width: 75%" bordered :columns="noClockingColumns"
:data-source="settingData.unCheckInData"
size="small" :pagination="false">
<template #headerCell="{ column }">
<template v-if="column.dataIndex === 'action'">
<Button size="small" type="primary" shape="circle"
@click="addUnCheckInHandle"
:icon="h(PlusOutlined)">
</Button>
</template>
</template>
<template #bodyCell="{ column,record,index }">
<template v-if="column.dataIndex==='action'">
<Button size="small" type="primary" shape="circle"
danger :icon="h(MinusOutlined)" @click="deleteUnCheckInHandle(index)">
</Button>
</template>
<template v-if="column.dataIndex==='dateTime'">
<span v-if="record.dateType==0">{{ record.startDate }}</span>
<span v-else>{{ record.startDate + '~' + record.endDate }}</span>
</template>
</template>
</Table>
<p class="item-padding">必须打卡日期:</p>
<Table style="width: 75%" bordered :columns="clockingColumns"
:data-source="settingData.checkInData"
size="small" :pagination="false">
<template #headerCell="{ column }">
<template v-if="column.dataIndex === 'action'">
<Button size="small" type="primary" shape="circle"
@click="addCheckInHandle"
:icon="h(PlusOutlined)">
</Button>
</template>
</template>
<template #bodyCell="{ column,record,index }">
<template v-if="column.dataIndex==='dateTime'">
<span v-if="record.dateType==0">{{ record.startDate }}</span>
<span v-else>{{ record.startDate + '~' + record.endDate }}</span>
</template>
<template v-if="column.dataIndex==='action'">
<Button size="small" type="primary" shape="circle"
danger :icon="h(MinusOutlined)" @click="deleteCheckInHandle(index)">
</Button>
</template>
</template>
</Table>
</div>
</template>
<template #attendanceShift>
<Button @click="shiftScheduleHandle(2)" type="primary">选择班次</Button>
<Alert type="info" message="请优先选择班次" banner/>
</template>
<template #shiftData>
<div v-if="shiftList">
<Tag closable color="processing" v-for="(item,i) in shiftList" @close="closeTagHandle(i)">
{{ item.name }}
</Tag>
</div>
</template>
<template #schedulingCycle>
<span class="item-font">周期天数
<span class="item-font-weight item-font-color">{{ settingData.cycleData.length }}</span>
<span style="color:#b2b0b0;">周期最少2天最多31天</span>
</span>
</template>
<template #cycleData>
<Table style="width: 80%" bordered :columns="cycleColumns"
:data-source="settingData.cycleData"
size="small" :pagination="false">
<template #headerCell="{ column }">
<template v-if="column.dataIndex === 'action'">
<Button size="small" type="primary" shape="circle"
:icon="h(PlusOutlined)" @click="addCycleHandle">
</Button>
</template>
</template>
<template #bodyCell="{ column,record,index }">
<template v-if="column.dataIndex==='action'">
<Button size="small" type="primary" shape="circle"
danger :icon="h(MinusOutlined)" @click="deleteCycleHandle(index)">
</Button>
</template>
<template v-if="column.dataIndex==='day'">
<span>{{ '第' + (index + 1) + '天' }}</span>
</template>
<template v-if="column.dataIndex==='shiftId'">
<Select
ref="select"
style="width: 100%"
v-model:value="record.shiftId"
placeholder="请选择班次"
>
<SelectOption v-for="item in shiftList" :value="item.id">
{{ item.name + '\xa0' }}
<span
v-if="item.isRest">{{
item.startTime + '~' + item.restStartTime + '\xa0' + item.restEndTime + '~' + item.endTime
}}</span>
<span v-else>{{ item.startTime + '~' + item.endTime }}</span>
</SelectOption>
</Select>
</template>
</template>
</Table>
</template>
</BasicForm>
<HolidayCalendar></HolidayCalendar>
<ChangeShiftSchedule @shiftInfo="handleShiftInfo"
@shiftList="handleShiftList"
@afterValue="handleAfterValue"
></ChangeShiftSchedule>
<CheckInDate @checkIn="getCheckInData"
@unCheckIn="getUnCheckInData"
></CheckInDate>
</BasicModal>
</template>
<style lang="scss" scoped>
.form-content {
.item-font {
font-size: 0.875rem;
}
.item-font-weight {
font-weight: 500;
}
.item-font-color {
color: red;
}
.item-padding-top {
padding-top: 1.1rem;
}
.item-padding {
padding: 1.1rem 0 0.5rem 0;
}
:deep(.ant-alert) {
padding: 5px 12px;
margin-left: 20px;
}
}
</style>