Merge branch 'master' of http://47.109.37.87:3000/by2025/admin-vben5
Some checks are pending
Gitea Actions Demo / Explore-Gitea-Actions (push) Waiting to run

This commit is contained in:
FLL
2025-07-30 11:09:59 +08:00
11 changed files with 159 additions and 59 deletions

View File

@@ -19,9 +19,17 @@ export interface GroupVO {
/**
* 考勤类型(0:固定班制,1:排班制)
*/
attendanceType: number;
attendanceType: number| string;
isAutomatic: number;
isAutomatic: boolean;
clockDateList: any[];
weekList: any[];
attendanceList:any[];
scheduleCycleList:any[];
}

View File

@@ -61,6 +61,8 @@ export interface MaintainPlanVO {
userId: string[];
machineMaintainPlanStaffBoList:any[];
machineMaintainPlanStaffVos:any[];
}
export interface MaintainPlanForm extends BaseEntity {

View File

@@ -19,7 +19,7 @@ export interface InspectionPlanVO {
/**
* 巡检周期
*/
inspectionPlanPeriod: number;
inspectionPlanPeriod: string;
/**
* 任务提前分组

View File

@@ -45,7 +45,7 @@ async function handleOpenChange(open: boolean) {
}
modalApi.modalLoading(true);
const {id,attendanceType} = modalApi.getData() as { id?: number | string,attendanceType?:string };
const res = await groupInfo(id,attendanceType);
const res = await groupInfo(id as string,attendanceType as string);
groupDetail.value=res;
if(res.attendanceType==0){
unCheckInData.value=res.clockDateList.filter(item=>item.mustNoCheck==0)
@@ -65,7 +65,19 @@ async function handleOpenChange(open: boolean) {
})
groupDetail.value.isAutomatic=true
}else {
cycleData.value=res;
cycleData.value=res.scheduleCycleList;
cycleData.value.forEach(item => {
if(item.shiftId){
const shift = res.attendanceList.find(i => item.shiftId == i.id);
let str = ''
if (shift.isRest) {
str = `${shift.name}${shift.startTime}~${shift.restStartTime} ${shift.restEndTime}~${shift.endTime}`;
} else {
str = `${shift.name}${shift.startTime}~${shift.endTime}`;
}
item.shiftValue=str
}
})
}
modalApi.modalLoading(false);
}
@@ -115,7 +127,7 @@ async function showHoliday() {
size="small"
:pagination="false"
>
<template #bodyCell="{ column, record, index }">
<template #bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'dayOfWeek'">
<component :is="renderDict(record.dayOfWeek,'wy_kqgzr')"></component>
</template>
@@ -201,7 +213,7 @@ async function showHoliday() {
<span>{{ '第' + (index + 1) + '天' }}</span>
</template>
<template v-if="column.dataIndex === 'shiftId'">
{{record.shiftId}}
{{record.shiftValue}}
</template>
</template>
</Table>

View File

@@ -89,13 +89,27 @@ const [BasicModal, modalApi] = useVbenModal({
};
isUpdate.value = !!id;
if (isUpdate.value && id) {
const record = await groupInfo(id, attendanceType);
const record = await groupInfo(id, attendanceType as string);
record.attendanceType = record.attendanceType.toString()
if (record.attendanceType == '0') {
settingData.unCheckInData = record.clockDateList.filter(item => item.mustNoCheck == 0)
settingData.checkInData = record.clockDateList.filter(item => item.mustNoCheck == 1)
settingData.weekdayData = record.weekList
settingData.weekdayData.forEach(item => {
if (item.shiftId) {
const shift = record.attendanceList.find(i => item.shiftId == i.id);
let str = ''
if (shift.isRest) {
str = `${shift.name}${shift.startTime}~${shift.restStartTime} ${shift.restEndTime}~${shift.endTime}`;
} else {
str = `${shift.name}${shift.startTime}~${shift.endTime}`;
}
item.shiftValue = str
}
})
} else {
settingData.cycleData=record.scheduleCycleList
settingData.cycleData.forEach(item => {
if(item.shiftId){
const shift = record.attendanceList.find(i => item.shiftId == i.id);
let str = ''
@@ -107,8 +121,7 @@ const [BasicModal, modalApi] = useVbenModal({
item.shiftValue=str
}
})
} else {
shiftList.value=record.attendanceList
}
await formApi.setValues(record);
} else {
@@ -121,7 +134,7 @@ const [BasicModal, modalApi] = useVbenModal({
shiftId: null,
})
})
settingData.cycleData = [{scheduleId: ''}, {scheduleId: ''}];
settingData.cycleData = [{shiftId: ''}, {shiftId: ''}];
}
await markInitialized();
modalApi.modalLoading(false);
@@ -140,7 +153,7 @@ async function handleConfirm() {
if (data.attendanceType == 1) {
let hasError = true;
settingData.cycleData.some((item, index) => {
if (!item.scheduleId) {
if (!item.shiftId) {
hasError = false
message.warning('请选择周期天数对应班次。');
return;
@@ -179,6 +192,8 @@ async function handleClosed() {
checkInData: [],
shiftId: '',
});
shiftInfo.value = undefined
shiftList.value = []
}
const [HolidayCalendar, holidayApi] = useVbenModal({
@@ -236,7 +251,7 @@ function handleShiftList(list: any[]) {
function addCycleHandle() {
if (settingData.cycleData.length < 31) {
settingData.cycleData.push({
scheduleId: '',
shiftId: '',
})
} else {
message.warning('周期天数最多31天。');
@@ -476,7 +491,7 @@ function getUnCheckInData(val: any) {
<Select
ref="select"
style="width: 100%"
v-model:value="record.scheduleId"
v-model:value="record.shiftId"
placeholder="请选择班次"
>
<SelectOption v-for="item in shiftList" :value="item.id">

View File

@@ -64,8 +64,10 @@ const [BasicModal, modalApi] = useVbenModal({
isUpdate.value = !!id;
if (isUpdate.value && id) {
const record = await communityInfo(id);
await formApi.setValues(record);
await formApi.setValues({
...record,
communityType: String(record.communityType),
});
}
setupDeptSelect();

View File

@@ -177,7 +177,7 @@ export const modalSchema: FormSchemaGetter = () => [
rules:'required'
},
{
label: '巡检人员',
label: '保养人员',
fieldName: 'userId',
component: 'ApiSelect',
componentProps:{

View File

@@ -15,8 +15,8 @@ import {defaultFormValueGetter, useBeforeCloseDiff} from '#/utils/popup';
import {modalSchema} from './data';
import {getMachineTypeTree} from "#/api/property/machineType";
import {personList} from "#/api/property/resident/person";
import {renderDictValue} from "#/utils/render";
import {userList} from "#/api/system/user";
const emit = defineEmits<{ reload: [] }>();
@@ -72,8 +72,8 @@ const [BasicModal, modalApi] = useVbenModal({
record.maintainMonth = record.maintainMonth?.split(',')
record.maintainDay = record.maintainDay?.split(',')
}
if (record.machineMaintainPlanStaffBoList) {
record.userId = record.machineMaintainPlanStaffBoList.map(item=>item.userId)
if (record.machineMaintainPlanStaffVos) {
record.userId = record.machineMaintainPlanStaffVos.map(item=>item.userId.toString())
}
await formApi.setValues(record);
}
@@ -161,11 +161,11 @@ async function queryPersonData() {
pageSize: 1000,
pageNum: 1,
}
const res = await personList(params);
const res = await userList(params);
const options = res.rows.map((user) => ({
label: user.userName + '-' + renderDictValue(user.gender, 'sys_user_sex')
+ '-' + user.phone + '-' + user.unitName,
value: user.id,
label: user.nickName + '-' + renderDictValue(user.sex, 'sys_user_sex')
+ '-' + user.phonenumber,
value: user.userId.toString(),
}));
formApi.updateSchema([{
componentProps: () => ({

View File

@@ -10,7 +10,6 @@ import {renderDict} from "#/utils/render";
dayjs.extend(duration);
dayjs.extend(relativeTime);
import {CheckboxGroup} from 'ant-design-vue'
import {getDictOptions} from "#/utils/dict";
import {maintainPlanInfo} from "#/api/property/equipmentManagement/maintainPlan";
import type {MaintainPlanVO} from "#/api/property/equipmentManagement/maintainPlan/model";
@@ -78,11 +77,16 @@ const monthArr=Array.from({ length: 12 }, (_, i) => ({
<DescriptionsItem label="计划日期" :span="2">
{{ maintainPlanDetail.startDate + '\xa0至\xa0' + maintainPlanDetail.endDate }}
</DescriptionsItem>
<DescriptionsItem label="状态" v-if="maintainPlanDetail.state!=null">
<DescriptionsItem label="状态" v-if="maintainPlanDetail.state!=null" :span="2">
<component
:is="renderDict(maintainPlanDetail.state,'wy_state')"
/>
</DescriptionsItem>
<DescriptionsItem label="保养人员" :span="2">
<span style="margin-right: 10px;" v-for="item in maintainPlanDetail.machineMaintainPlanStaffVos">
{{item.userName}}
</span>
</DescriptionsItem>
</Descriptions>
</BasicModal>
</template>

View File

@@ -1,12 +1,16 @@
<script setup lang="ts">
import { computed, ref } from 'vue';
import { Button, Table } from 'ant-design-vue';
import { Button, message, Table } from 'ant-design-vue';
import { useVbenModal } from '@vben/common-ui';
import { $t } from '@vben/locales';
import { cloneDeep } from '@vben/utils';
import { useVbenForm } from '#/adapter/form';
import { rentalPlanAdd, rentalPlanInfo, rentalPlanUpdate } from '#/api/property/rentalPlan';
import {
rentalPlanAdd,
rentalPlanInfo,
rentalPlanUpdate,
} from '#/api/property/rentalPlan';
import { defaultFormValueGetter, useBeforeCloseDiff } from '#/utils/popup';
import { modalSchema } from './data';
@@ -19,9 +23,13 @@ const emit = defineEmits<{ reload: [] }>();
const isUpdate = ref(false);
const isReadonly = ref(false);
const title = computed(() => {
return isUpdate.value ? $t('pages.common.edit') : isReadonly.value ? '详情' : $t('pages.common.add');
return isUpdate.value
? $t('pages.common.edit')
: isReadonly.value
? '详情'
: $t('pages.common.add');
});
const editId = ref<string | number | undefined>('')
const editId = ref<string | number | undefined>('');
const [BasicForm, formApi] = useVbenForm({
commonConfig: {
// 默认占满两列
@@ -58,12 +66,15 @@ const [BasicModal, modalApi] = useVbenModal({
return null;
}
modalApi.modalLoading(true);
const { id, readonly } = modalApi.getData() as { id?: number | string, readonly?: boolean; };
const { id, readonly } = modalApi.getData() as {
id?: number | string;
readonly?: boolean;
};
editId.value = id || '';
isReadonly.value = !!readonly;
if(isReadonly.value){
if (isReadonly.value) {
isUpdate.value = false;
}else{
} else {
isUpdate.value = !!id;
}
// 查看与编辑时需要获取详情
@@ -71,7 +82,11 @@ const [BasicModal, modalApi] = useVbenModal({
const record = await rentalPlanInfo(id);
// 后端返回绿植产品包列表结构处理
// detailTable.value = record.productList.map((item:any) => {...item.product,item.productNum,});
detailTable.value = record.productList.map((item: any) => ({ ...item.product, productNum: item.productNum,productId: item.productId }));
detailTable.value = record.productList.map((item: any) => ({
...item.product,
productNum: item.productNum,
productId: item.productId,
}));
await formApi.setValues(record);
}
@@ -93,7 +108,13 @@ async function handleConfirm() {
const data = cloneDeep(await formApi.getValues());
// data.productIds = detailTable.value.map((item:any) => item.productId);
data.productList = detailTable.value;
await (isUpdate.value ? rentalPlanUpdate({...data,id:editId.value}) : rentalPlanAdd(data));
if (data.productList.length == 0) {
message.error('请添加植物组合包产品');
return;
}
await (isUpdate.value
? rentalPlanUpdate({ ...data, id: editId.value })
: rentalPlanAdd(data));
resetInitialized();
emit('reload');
modalApi.close();
@@ -146,18 +167,19 @@ const detailColumns = [
];
function handleAddDetail() {
// 传递已选产品id列表
const selectedIds = detailTable.value.map((item: any) => item.productId || item.plantName);
detailModalApi.setData({ selectedIds,add:true });
const selectedIds = detailTable.value.map(
(item: any) => item.productId || item.plantName,
);
detailModalApi.setData({ selectedIds, add: true });
detailModalApi.open();
}
//添加植物组合包产品
function handleDetailReload (data: any) {
function handleDetailReload(data: any) {
detailTable.value.push(data);
}
// 编辑植物组合包产品
function handleEditDetailReload (data: any) {
function handleEditDetailReload(data: any) {
detailTable.value[data.index] = data;
}
// 删除植物组合包产品
function handleDeleteDetail(record: any, index: number) {
@@ -171,14 +193,16 @@ function handleViewDetail(record: any) {
// 编辑产品详情
function handleEditDetail(record: any, index: number) {
// 编辑时排除当前项id
const selectedIds = detailTable.value.filter((_: any, i: number) => i !== index).map((item: any) => item.productId || item.plantName);
detailModalApi.setData({ ...record, index, selectedIds,edit:true });
const selectedIds = detailTable.value
.filter((_: any, i: number) => i !== index)
.map((item: any) => item.productId || item.plantName);
detailModalApi.setData({ ...record, index, selectedIds, edit: true });
detailModalApi.open();
}
//分类字典
function getPlantTypeLabel(value: string | number) {
const opts = getDictOptions('pro_product_classification');
const found = opts.find(opt => opt.value == value);
const found = opts.find((opt) => opt.value == value);
return found ? found.label : value;
}
</script>
@@ -186,10 +210,18 @@ function getPlantTypeLabel(value: string | number) {
<template>
<BasicModal :title="title">
<BasicForm />
<!-- 添加产品部分 -->
<!-- 添加产品部分 -->
<div class="mt-4">
<div class="mb-2 flex items-center justify-between">
<h3 class="text-lg font-medium">{{ isUpdate ? '编辑植物组合包产品' : isReadonly ? '查看植物组合包产品' : '添加植物组合包产品' }} </h3>
<h3 class="text-lg font-medium">
{{
isUpdate
? '编辑植物组合包产品'
: isReadonly
? '查看植物组合包产品'
: '添加植物组合包产品'
}}
</h3>
<a-button v-if="!isReadonly" type="primary" @click="handleAddDetail">
{{ $t('pages.common.add') }}
</a-button>
@@ -204,16 +236,38 @@ function getPlantTypeLabel(value: string | number) {
{{ index + 1 }}
</template>
<template v-else-if="column.key === 'plantType'">
<div>{{getPlantTypeLabel(record.plantType)}}</div>
<div>{{ getPlantTypeLabel(record.plantType) }}</div>
</template>
<template v-else-if="column.key === 'action'">
<template v-if="isReadonly">
<Button type="primary" size="small" style="margin-right: 5px;" @click="handleViewDetail(record)">查看</Button>
<template v-if="isReadonly">
<Button
type="primary"
size="small"
style="margin-right: 5px"
@click="handleViewDetail(record)"
>查看</Button
>
</template>
<template v-else >
<Button type="primary" size="small" style="margin-right: 5px;" @click="handleViewDetail(record)">查看</Button>
<Button type="primary" size="small" style="margin-right: 5px;" @click="handleEditDetail(record, index)">编辑</Button>
<Button danger size="small" @click="handleDeleteDetail(record, index)">
<template v-else>
<Button
type="primary"
size="small"
style="margin-right: 5px"
@click="handleViewDetail(record)"
>查看</Button
>
<Button
type="primary"
size="small"
style="margin-right: 5px"
@click="handleEditDetail(record, index)"
>编辑</Button
>
<Button
danger
size="small"
@click="handleDeleteDetail(record, index)"
>
删除
</Button>
</template>
@@ -222,7 +276,10 @@ function getPlantTypeLabel(value: string | number) {
</Table>
<!-- <div>费用合计{{ totalSumPeices }}</div> -->
</div>
<ProductDetailModal @reload="handleDetailReload" @editReload="handleEditDetailReload"/>
<ProductDetailModal
@reload="handleDetailReload"
@editReload="handleEditDetailReload"
/>
</BasicModal>
</template>

View File

@@ -14,10 +14,10 @@ import {
import {defaultFormValueGetter, useBeforeCloseDiff} from '#/utils/popup';
import {modalSchema} from './data';
import {personList} from "#/api/property/resident/person";
import {renderDictValue} from "#/utils/render";
import {inspectionRouteList} from "#/api/property/inspectionManagement/inspectionRoute";
import {InputNumber} from 'ant-design-vue'
import {userList} from "#/api/system/user";
const emit = defineEmits<{ reload: [] }>();
@@ -75,7 +75,7 @@ const [BasicModal, modalApi] = useVbenModal({
record.inspectionWorkday = record.inspectionWorkday?.split(',')
}
if (record.inspectionPlanStaffVoList && record.inspectionPlanStaffVoList.length) {
record.userId = record.inspectionPlanStaffVoList.map(item => item.userId)
record.userId = record.inspectionPlanStaffVoList.map(item => item.userId.toString())
}
await formApi.setValues(record);
}
@@ -140,11 +140,11 @@ async function queryPersonData() {
pageSize: 1000,
pageNum: 1,
}
const res = await personList(params);
const res = await userList(params);
const options = res.rows.map((user) => ({
label: user.userName + '-' + renderDictValue(user.gender, 'sys_user_sex')
+ '-' + user.phone + '-' + user.unitName,
value: user.id,
label: user.nickName + '-' + renderDictValue(user.sex, 'sys_user_sex')
+ '-' + user.phonenumber,
value: user.userId.toString(),
}));
formApi.updateSchema([{
componentProps: () => ({