2 Commits

Author SHA1 Message Date
3749f4bbb9 Merge remote-tracking branch 'origin/master'
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run
2025-07-23 20:57:47 +08:00
4ff469f0ae 1、入住人员添加字段 2025-07-23 20:57:17 +08:00
5 changed files with 195 additions and 111 deletions

View File

@@ -274,4 +274,7 @@ export interface Person extends BaseEntity {
*/ */
remark: string remark: string
idCard: string
email: string
} }

View File

@@ -1,5 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import {computed, ref} from 'vue'; import {computed, reactive, ref} from 'vue';
import {useVbenModal} from '@vben/common-ui'; import {useVbenModal} from '@vben/common-ui';
import {$t} from '@vben/locales'; import {$t} from '@vben/locales';
@@ -20,7 +20,7 @@ import {
noClockingColumns, noClockingColumns,
weekdayColumns weekdayColumns
} from './data'; } from './data';
import {Tag, Button, Table, Checkbox, Select, SelectOption,message} from 'ant-design-vue' import {Tag, Button, Table, Checkbox, Select, SelectOption, message, Alert} from 'ant-design-vue'
import {getDictOptions} from "#/utils/dict"; import {getDictOptions} from "#/utils/dict";
import holidayCalendar from './holiday-calendar.vue' import holidayCalendar from './holiday-calendar.vue'
import changeShiftSchedule from './change-shift-schedule.vue' import changeShiftSchedule from './change-shift-schedule.vue'
@@ -31,12 +31,16 @@ import type {ShiftVO} from "#/api/property/attendanceManagement/shiftSetting/mod
const emit = defineEmits<{ reload: [] }>(); const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false); const isUpdate = ref(false);
const weekdayData = ref<any[]>([])
const title = computed(() => { const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add'); return isUpdate.value ? $t('pages.common.edit') : $t('pages.common.add');
}); });
const settingData = ref<any>({ const settingData = reactive({
isAutomatic: true, isAutomatic: true,
weekdayData: [],
cycleData: [],
unCheckInData: [],
checkInData: [],
shiftId: ''
}) })
const [BasicForm, formApi] = useVbenForm({ const [BasicForm, formApi] = useVbenForm({
commonConfig: { commonConfig: {
@@ -73,23 +77,26 @@ const [BasicModal, modalApi] = useVbenModal({
return null; return null;
} }
modalApi.modalLoading(true); modalApi.modalLoading(true);
const {id} = modalApi.getData() as { id?: number | string }; const {id} = modalApi.getData() as { id?: number | string };
isUpdate.value = !!id; isUpdate.value = !!id;
if (isUpdate.value && id) { if (isUpdate.value && id) {
const record = await groupInfo(id); const record = await groupInfo(id);
await formApi.setValues(record); await formApi.setValues(record);
} else { } else {
weekdayData.value = [] const dictOptions = getDictOptions('wy_kqgzr');
getDictOptions('wy_kqgzr').forEach(item => { console.log(dictOptions)
weekdayData.value.push({ if (dictOptions) {
dayOfWeek: item.value, dictOptions.forEach(item => {
label: item.label, settingData.weekdayData.push({
shiftValue: '休息', dayOfWeek: item.value,
isRest: true, label: item.label,
shiftId: null, shiftValue: '休息',
isRest: 1,
id: null,
})
}) })
}) }
settingData.cycleData = [{id: ''}, {id: ''}];
} }
await markInitialized(); await markInitialized();
modalApi.modalLoading(false); modalApi.modalLoading(false);
@@ -105,6 +112,24 @@ async function handleConfirm() {
} }
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次 // getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
const data = cloneDeep(await formApi.getValues()); 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)); await (isUpdate.value ? groupUpdate(data) : groupAdd(data));
resetInitialized(); resetInitialized();
emit('reload'); emit('reload');
@@ -119,9 +144,14 @@ async function handleConfirm() {
async function handleClosed() { async function handleClosed() {
await formApi.resetForm(); await formApi.resetForm();
resetInitialized(); resetInitialized();
cycleData.value = [] Object.assign(settingData, {
unCheckInData.value = [] isAutomatic: true,
checkInData.value = [] weekdayData: [],
cycleData: [],
unCheckInData: [],
checkInData: [],
shiftId: '',
});
} }
const [HolidayCalendar, holidayApi] = useVbenModal({ const [HolidayCalendar, holidayApi] = useVbenModal({
@@ -138,7 +168,7 @@ const [CheckInDate, checkInDateApi] = useVbenModal({
/** /**
* 查看法定节假日日历 * 查看法定节假日日历
*/ */
async function showHoliday() { function showHoliday() {
holidayApi.open() holidayApi.open()
} }
@@ -146,18 +176,20 @@ async function showHoliday() {
* 更改班次 * 更改班次
* @param type 1.设置班次 2.选择班次 * @param type 1.设置班次 2.选择班次
*/ */
async function shiftScheduleHandle(type: number) { function shiftScheduleHandle(type: number) {
shiftApi.setData({type}) shiftApi.setData({type})
shiftApi.open() shiftApi.open()
} }
const shiftInfo = ref<ShiftVO>() const shiftInfo = ref<ShiftVO>()
const shiftList = ref<ShiftVO[]>([]) const shiftList = ref<ShiftVO[]>([])
const handleShiftInfo = (info: ShiftVO) => {
function handleShiftInfo(info: ShiftVO) {
if (info) { if (info) {
settingData.shiftId = info.id
shiftInfo.value = info; shiftInfo.value = info;
weekdayData.value.forEach(item => { settingData.weekdayData.forEach(item => {
item.shiftId = info.id item.id = info.id
let str = '' let str = ''
if (info.isRest) { if (info.isRest) {
str = `${info.name}${info.startTime}~${info.restStartTime} ${info.restEndTime}~${info.endTime}`; str = `${info.name}${info.startTime}~${info.restStartTime} ${info.restEndTime}~${info.endTime}`;
@@ -165,102 +197,105 @@ const handleShiftInfo = (info: ShiftVO) => {
str = `${info.name}${info.startTime}~${info.endTime}`; str = `${info.name}${info.startTime}~${info.endTime}`;
} }
item.shiftValue = str item.shiftValue = str
item.isRest = false item.isRest = 0
}) })
} }
}; }
const handleShiftList = (list: any[]) => { function handleShiftList(list: any[]) {
shiftList.value = list; shiftList.value = list;
}; }
function addCycleHandle() {
const cycleData = ref<any[]>([]) if (settingData.cycleData.length < 31) {
const unCheckInData = ref<any[]>([]) settingData.cycleData.push({
const checkInData = ref<any[]>([]) id: '',
async function addCycleHandle() {
if(cycleData.value.length<31){
cycleData.value.push({
shiftId: '',
}) })
}else { } else {
message.warning('周期天数最多31天。'); message.warning('周期天数最多31天。');
} }
} }
async function deleteCycleHandle(index: number) { function deleteCycleHandle(index: number) {
if(cycleData.value.length>2){ if (settingData.cycleData.length > 2) {
cycleData.value.splice(index, 1) settingData.cycleData.splice(index, 1)
}else { } else {
message.warning('周期天数最少2天。'); message.warning('周期天数最少2天。');
} }
} }
async function deleteUnCheckInHandle(index: number) { function deleteUnCheckInHandle(index: number) {
unCheckInData.value.splice(index, 1) settingData.unCheckInData.splice(index, 1)
} }
async function deleteCheckInHandle(index: number) { function deleteCheckInHandle(index: number) {
checkInData.value.splice(index, 1) settingData.checkInData.splice(index, 1)
} }
const tableIndex = ref(-1) const tableIndex = ref(-1)
async function changeShiftHandle(type: number, index: number) { function changeShiftHandle(type: number, index: number) {
tableIndex.value = index tableIndex.value = index
shiftApi.setData({type})//3.更改班次 shiftApi.setData({type})//3.更改班次
shiftApi.open() shiftApi.open()
} }
async function restHandle(index: number) { function restHandle(index: number) {
weekdayData.value[index].isRest = true settingData.weekdayData[index].isRest = 1
weekdayData.value[index].shiftValue = '休息' settingData.weekdayData[index].shiftValue = '休息'
settingData.weekdayData[index].id = null
} }
const handleAfterValue = (val: ShiftVO) => { function handleAfterValue(val: ShiftVO) {
if (tableIndex.value > -1 && val) { if (tableIndex.value > -1 && val) {
weekdayData.value[tableIndex.value].shiftId = val.id settingData.weekdayData[tableIndex.value].id = val.id
let str = '' let str = ''
if (val.isRest) { if (val.isRest) {
str = `${val.name}${val.startTime}~${val.restStartTime} ${val.restEndTime}~${val.endTime}`; str = `${val.name}${val.startTime}~${val.restStartTime} ${val.restEndTime}~${val.endTime}`;
} else { } else {
str = `${val.name}${val.startTime}~${val.endTime}`; str = `${val.name}${val.startTime}~${val.endTime}`;
} }
weekdayData.value[tableIndex.value].shiftValue = str settingData.weekdayData[tableIndex.value].shiftValue = str
weekdayData.value[tableIndex.value].isRest = false settingData.weekdayData[tableIndex.value].isRest = 0
} }
}; }
const closeHandle = (i: number) => { function closeTagHandle(i: number) {
shiftList.value.splice(i, 1) shiftList.value.splice(i, 1)
}; }
const checkInIndex = ref(-1) const checkInIndex = ref(-1)
async function addCheckInHandle(index: number) { function addCheckInHandle(index: number) {
checkInIndex.value = index checkInIndex.value = index
checkInDateApi.setData({check: true}) checkInDateApi.setData({check: true})
checkInDateApi.open() checkInDateApi.open()
} }
const getCheckInData = (val: any) => { function getCheckInData(val: any) {
if (val) { if (val) {
checkInData.value.push(val) settingData.checkInData.push({
...val,
mustNoCheck: 1
})
} }
} }
const unCheckInIndex = ref(-1) const unCheckInIndex = ref(-1)
async function addUnCheckInHandle(index: number) { function addUnCheckInHandle(index: number) {
unCheckInIndex.value = index unCheckInIndex.value = index
checkInDateApi.setData({check: false}) checkInDateApi.setData({check: false})
checkInDateApi.open() checkInDateApi.open()
} }
const getUnCheckInData = (val: any) => { function getUnCheckInData(val: any) {
if (val) { if (val) {
unCheckInData.value.push(val) settingData.unCheckInData.push({
...val,
mustNoCheck: 0
})
} }
} }
@@ -268,7 +303,7 @@ const getUnCheckInData = (val: any) => {
<template> <template>
<BasicModal :title="title+'考勤组'"> <BasicModal :title="title+'考勤组'">
<BasicForm> <BasicForm class="form-content">
<template #weekdaySetting> <template #weekdaySetting>
<div class="item-font"> <div class="item-font">
<span>快捷设置班次</span> <span>快捷设置班次</span>
@@ -287,7 +322,8 @@ const getUnCheckInData = (val: any) => {
</template> </template>
<template #settingItem> <template #settingItem>
<div class="item-font" style="width: 100%;"> <div class="item-font" style="width: 100%;">
<Table style="width: 90%" bordered :columns="weekdayColumns" :data-source="weekdayData" <Table style="width: 90%" bordered :columns="weekdayColumns"
:data-source="settingData.weekdayData"
size="small" :pagination="false"> size="small" :pagination="false">
<template #bodyCell="{ column, record,index }"> <template #bodyCell="{ column, record,index }">
<template v-if="column.dataIndex==='action'"> <template v-if="column.dataIndex==='action'">
@@ -306,7 +342,7 @@ const getUnCheckInData = (val: any) => {
<p class="item-padding-top item-font-weight">特殊日期</p> <p class="item-padding-top item-font-weight">特殊日期</p>
<p class="item-padding">无需打卡日期</p> <p class="item-padding">无需打卡日期</p>
<Table style="width: 75%" bordered :columns="noClockingColumns" <Table style="width: 75%" bordered :columns="noClockingColumns"
:data-source="unCheckInData" :data-source="settingData.unCheckInData"
size="small" :pagination="false"> size="small" :pagination="false">
<template #headerCell="{ column }"> <template #headerCell="{ column }">
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
@@ -329,7 +365,8 @@ const getUnCheckInData = (val: any) => {
</template> </template>
</Table> </Table>
<p class="item-padding">必须打卡日期</p> <p class="item-padding">必须打卡日期</p>
<Table style="width: 75%" bordered :columns="clockingColumns" :data-source="checkInData" <Table style="width: 75%" bordered :columns="clockingColumns"
:data-source="settingData.checkInData"
size="small" :pagination="false"> size="small" :pagination="false">
<template #headerCell="{ column }"> <template #headerCell="{ column }">
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
@@ -354,24 +391,26 @@ const getUnCheckInData = (val: any) => {
</div> </div>
</template> </template>
<template #attendanceShift> <template #attendanceShift>
<Button size="small" @click="shiftScheduleHandle(2)" type="primary">选择班次</Button> <Button @click="shiftScheduleHandle(2)" type="primary">选择班次</Button>
<Alert type="info" message="请优先选择班次" banner/>
</template> </template>
<template #shiftData> <template #shiftData>
<div v-if="shiftList"> <div v-if="shiftList">
<Tag closable color="processing" v-for="(item,i) in shiftList" @close="closeHandle(i)"> <Tag closable color="processing" v-for="(item,i) in shiftList" @close="closeTagHandle(i)">
{{ item.name }} {{ item.name }}
</Tag> </Tag>
</div> </div>
</template> </template>
<template #schedulingCycle> <template #schedulingCycle>
<span class="item-font">周期天数 <span class="item-font">周期天数
<span class="item-font-weight item-font-color">{{ cycleData.length }}</span> <span class="item-font-weight item-font-color">{{ settingData.cycleData.length }}</span>
<span style="color:#b2b0b0;">周期最少2天最多31天</span> <span style="color:#b2b0b0;">周期最少2天最多31天</span>
</span> </span>
</template> </template>
<template #cycleData> <template #cycleData>
<Table style="width: 80%" bordered :columns="cycleColumns" :data-source="cycleData" <Table style="width: 80%" bordered :columns="cycleColumns"
:data-source="settingData.cycleData"
size="small" :pagination="false"> size="small" :pagination="false">
<template #headerCell="{ column }"> <template #headerCell="{ column }">
<template v-if="column.dataIndex === 'action'"> <template v-if="column.dataIndex === 'action'">
@@ -399,7 +438,9 @@ const getUnCheckInData = (val: any) => {
<SelectOption v-for="item in shiftList" :value="item.id"> <SelectOption v-for="item in shiftList" :value="item.id">
{{ item.name + '\xa0' }} {{ item.name + '\xa0' }}
<span <span
v-if="item.isRest">{{ item.startTime + '~' + item.restStartTime + '\xa0' + item.restEndTime + '~' + item.endTime }}</span> v-if="item.isRest">{{
item.startTime + '~' + item.restStartTime + '\xa0' + item.restEndTime + '~' + item.endTime
}}</span>
<span v-else>{{ item.startTime + '~' + item.endTime }}</span> <span v-else>{{ item.startTime + '~' + item.endTime }}</span>
</SelectOption> </SelectOption>
</Select> </Select>
@@ -419,24 +460,32 @@ const getUnCheckInData = (val: any) => {
</BasicModal> </BasicModal>
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
.item-font { .form-content {
font-size: 0.875rem; .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;
}
} }
.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;
}
</style> </style>

View File

@@ -136,12 +136,52 @@ export const modalSchema: FormSchemaGetter = () => [
}, },
}, },
{ {
label: '入住员工', label: '员工名称',
fieldName: 'userId', fieldName: 'userName',
component: "Select", component: "Input",
rules: 'selectRequired', rules: 'required',
formItemClass: 'col-span-2'
}, },
{
label: '联系电话',
fieldName: 'phone',
component: "Input",
rules: 'required',
},
{
label: '性别',
fieldName: 'gender',
component: "Select",
componentProps:{
options: getDictOptions('sys_user_sex')
},
rules: 'required',
},
{
label: '身份证号',
fieldName: 'idCard',
component: "Input",
},
{
label: '邮箱',
fieldName: 'email',
component: "Input",
},
{
label: '人员状态',
fieldName: 'state',
component: 'Select',
componentProps: {
options: getDictOptions('wy_rzryzt'),
},
rules: 'selectRequired'
},
// {
// label: '入住员工',
// fieldName: 'userId',
// component: "Select",
// rules: 'selectRequired',
// formItemClass: 'col-span-2'
// },
{ {
label: '所属单位', label: '所属单位',
fieldName: 'unitId', fieldName: 'unitId',
@@ -182,20 +222,6 @@ export const modalSchema: FormSchemaGetter = () => [
}, },
formItemClass: 'col-span-2', formItemClass: 'col-span-2',
}, },
{
label: '人员状态',
fieldName: 'state',
component: 'Select',
componentProps: {
options: getDictOptions('wy_rzryzt'),
},
rules: 'selectRequired'
},
{
label: '',
fieldName: 'time',
component: ''
},
{ {
label: '授权期限', label: '授权期限',
fieldName: 'authTime', fieldName: 'authTime',

View File

@@ -51,6 +51,12 @@ async function handleOpenChange(open: boolean) {
<DescriptionsItem label="入驻人员"> <DescriptionsItem label="入驻人员">
{{ personDetail.userName+'-'+renderDictValue(personDetail.gender,'sys_user_sex')+'-'+personDetail.phone}} {{ personDetail.userName+'-'+renderDictValue(personDetail.gender,'sys_user_sex')+'-'+personDetail.phone}}
</DescriptionsItem> </DescriptionsItem>
<DescriptionsItem label="身份证号">
{{ personDetail.idCard}}
</DescriptionsItem>
<DescriptionsItem label="邮箱">
{{ personDetail.email}}
</DescriptionsItem>
<DescriptionsItem label="所属单位"> <DescriptionsItem label="所属单位">
{{personDetail.unitName+'-'+personDetail.unitId }} {{personDetail.unitName+'-'+personDetail.unitId }}
</DescriptionsItem> </DescriptionsItem>

View File

@@ -86,11 +86,11 @@ async function handleConfirm() {
} }
// getValues获取为一个readonly的对象 需要修改必须先深拷贝一次 // getValues获取为一个readonly的对象 需要修改必须先深拷贝一次
let data = cloneDeep(await formApi.getValues()); let data = cloneDeep(await formApi.getValues());
if (userInfo) { // if (userInfo) {
data.userName = userInfo.userName // data.userName = userInfo.userName
data.phone = userInfo.phone // data.phone = userInfo.phone
data.gender = userInfo.gender // data.gender = userInfo.gender
} // }
if(unitName.value){ if(unitName.value){
data.unitName = unitName.value data.unitName = unitName.value
} }