diff --git a/apps/web-antd/src/api/property/assetManage/application/index.ts b/apps/web-antd/src/api/property/assetManage/application/index.ts index 677eb0c6..6c31ff59 100644 --- a/apps/web-antd/src/api/property/assetManage/application/index.ts +++ b/apps/web-antd/src/api/property/assetManage/application/index.ts @@ -42,6 +42,14 @@ export function applicationAdd(data: ApplicationForm) { return requestClient.postWithMsg('/property/application', data); } +/** + * 领用审核 + * @param data + */ +export function applicationVerified(data: ApplicationForm) { + return requestClient.postWithMsg('/property/application/verified', data); +} + /** * 更新资产领用 * @param data diff --git a/apps/web-antd/src/api/property/businessManagement/workOrdersType/index.ts b/apps/web-antd/src/api/property/businessManagement/workOrdersType/index.ts index 4cfbd81f..acc9be74 100644 --- a/apps/web-antd/src/api/property/businessManagement/workOrdersType/index.ts +++ b/apps/web-antd/src/api/property/businessManagement/workOrdersType/index.ts @@ -12,6 +12,22 @@ import { requestClient } from '#/api/request'; export function workOrdersTypeList(params?: WorkOrdersTypeQuery) { return requestClient.get>('/property/workOrdersType/list', { params }); } +/** + * 查询工单类型不分页 + * @param params + * @returns 工单类型管理列表 + */ +export function workOrdersTypeListAll(params?: WorkOrdersTypeQuery) { + return requestClient.get('/property/workOrdersType/queryList', { params }); +} + +/** + * 查询工单类型树结构 + * @param params + */ +export function workOrdersTypeTree(params?: WorkOrdersTypeQuery) { + return requestClient.get('/property/workOrdersType/typeTree', { params }); +} /** * 导出工单类型管理列表 diff --git a/apps/web-antd/src/api/property/businessManagement/workOrdersType/model.d.ts b/apps/web-antd/src/api/property/businessManagement/workOrdersType/model.d.ts index f1f10907..ce780780 100644 --- a/apps/web-antd/src/api/property/businessManagement/workOrdersType/model.d.ts +++ b/apps/web-antd/src/api/property/businessManagement/workOrdersType/model.d.ts @@ -1,4 +1,4 @@ -import type { PageQuery, BaseEntity } from '#/api/common'; +import type {PageQuery, BaseEntity} from '#/api/common'; export interface WorkOrdersTypeVO { /** @@ -34,7 +34,9 @@ export interface WorkOrdersTypeVO { /** * 是否支持转单(0支持,1不支持) */ - isTransfers: number; + isTransfers: string; + + excludeId: string; } export interface WorkOrdersTypeForm extends BaseEntity { @@ -72,6 +74,11 @@ export interface WorkOrdersTypeForm extends BaseEntity { * 是否支持转单(0支持,1不支持) */ isTransfers?: number; + + /** + * 上级类型id + */ + parentId?: string; } export interface WorkOrdersTypeQuery extends PageQuery { @@ -106,7 +113,12 @@ export interface WorkOrdersTypeQuery extends PageQuery { isTransfers?: number; /** - * 日期范围参数 - */ + * 日期范围参数 + */ params?: any; + + /** + * 是否过滤子级 + */ + filterSubNodes?: boolean; } diff --git a/apps/web-antd/src/views/property/assetManage/application/application-modal.vue b/apps/web-antd/src/views/property/assetManage/application/application-modal.vue index 0ba82bec..93d7f91c 100644 --- a/apps/web-antd/src/views/property/assetManage/application/application-modal.vue +++ b/apps/web-antd/src/views/property/assetManage/application/application-modal.vue @@ -109,6 +109,7 @@ async function setupPackageSelect() { const assets = await assetList({ pageNum: 1, pageSize: 1000, + params: {stock: 1} //库存不为0 }); assetsData.value = assets.rows const options = users.rows.map((item) => ({ @@ -145,7 +146,8 @@ async function setupPackageSelect() { if (assetInfo) { formApi.updateSchema([{ componentProps: { - max:assetInfo.stock + max: assetInfo.stock, + min: 1 }, fieldName: 'number', }]) diff --git a/apps/web-antd/src/views/property/assetManage/application/data.ts b/apps/web-antd/src/views/property/assetManage/application/data.ts index 8afff06c..855878e0 100644 --- a/apps/web-antd/src/views/property/assetManage/application/data.ts +++ b/apps/web-antd/src/views/property/assetManage/application/data.ts @@ -28,7 +28,7 @@ export const querySchema: FormSchemaGetter = () => [ options:getDictOptions(DictEnum.WY_ZCSHZT) }, fieldName: 'state', - label: '领用状态', + label: '审核状态', }, // { // component: 'Input', @@ -78,7 +78,7 @@ export const columns: VxeGridProps['columns'] = [ field: 'applicationTime', }, { - title: '领用状态', + title: '审核状态', field: 'state', slots: { default: ({ row }) => { diff --git a/apps/web-antd/src/views/property/assetManage/application/index.vue b/apps/web-antd/src/views/property/assetManage/application/index.vue index 2569b981..df7c3417 100644 --- a/apps/web-antd/src/views/property/assetManage/application/index.vue +++ b/apps/web-antd/src/views/property/assetManage/application/index.vue @@ -14,7 +14,7 @@ import { import { applicationExport, applicationList, - applicationRemove, applicationUpdate, + applicationRemove, applicationVerified, } from '#/api/property/assetManage/application'; import type {ApplicationForm} from '#/api/property/assetManage/application/model'; import {commonDownloadExcel} from '#/utils/file/download'; @@ -98,7 +98,7 @@ async function handleAudit(row: Required, status: number) { info.state = status info.acceptanceTime = new Date() info.acceptanceUserId = userStore.userInfo?.userId - await applicationUpdate(info) + await applicationVerified(info) await tableApi.query(); } diff --git a/apps/web-antd/src/views/property/assetManage/log/data.ts b/apps/web-antd/src/views/property/assetManage/log/data.ts index 96bed83e..c40ad90e 100644 --- a/apps/web-antd/src/views/property/assetManage/log/data.ts +++ b/apps/web-antd/src/views/property/assetManage/log/data.ts @@ -1,6 +1,7 @@ import type { FormSchemaGetter } from '#/adapter/form'; import type { VxeGridProps } from '#/adapter/vxe-table'; import {getDictOptions} from "#/utils/dict"; +import {renderDict} from "#/utils/render"; export const querySchema: FormSchemaGetter = () => [ @@ -69,19 +70,24 @@ export const querySchema: FormSchemaGetter = () => [ export const columns: VxeGridProps['columns'] = [ { type: 'checkbox', width: 60 }, { - title: '仓库id', - field: 'depotId', + title: '仓库', + field: 'depotName', minWidth:150, }, { - title: '资产id', - field: 'assetId', + title: '资产', + field: 'assetName', width:180, }, { title: '流转类型', field: 'type', width:120, + slots:{ + default:({row})=>{ + return renderDict(row.type,'wy_cklzlx') + } + } }, { @@ -95,8 +101,8 @@ export const columns: VxeGridProps['columns'] = [ width:150, }, { - title: '操作人id', - field: 'userId', + title: '操作人', + field: 'userName', width:150, }, { diff --git a/apps/web-antd/src/views/property/attendanceManagement/workforceManagement/calendarView.vue b/apps/web-antd/src/views/property/attendanceManagement/workforceManagement/calendarView.vue index 774f9aa0..b60874bf 100644 --- a/apps/web-antd/src/views/property/attendanceManagement/workforceManagement/calendarView.vue +++ b/apps/web-antd/src/views/property/attendanceManagement/workforceManagement/calendarView.vue @@ -7,6 +7,7 @@ import dayjs from 'dayjs'; import arrangementModal from './arrangement-modal.vue'; import { useVbenModal } from '@vben/common-ui'; import { arrangementCalender } from '#/api/property/attendanceManagement/arrangement'; // 导入接口 +import { Modal } from 'ant-design-vue'; const emit = defineEmits<{ (e: 'changeView', value: boolean): void; @@ -19,6 +20,8 @@ const calendarData = reactive([]); const loading = ref(false); // 查询日历数据 const fetchCalendarData = async (month?: string) => { + console.log(123); + try { loading.value = true; const params = { @@ -32,47 +35,150 @@ const fetchCalendarData = async (month?: string) => { month || selectedDate.value?.format('YYYY-MM') || dayjs().format('YYYY-MM'); //当前月份的开始日期 + + // 清空之前的数据 + calendarData.length = 0; + // 生成日历渲染数据结构 for (const row of res.rows) { if (row.endDate) { + const startDate = dayjs(row.startDate); + const endDate = dayjs(row.endDate); + const currentMonthStart = dayjs(currentMonth).startOf('month'); + const currentMonthEnd = dayjs(currentMonth).endOf('month'); + //当开始时间小于当前月份的开始日期 - if (row.startDate <= currentMonth) { - console.log(row, '小'); - + if (startDate.isBefore(currentMonthStart) || startDate.isSame(currentMonthStart, 'day')) { + console.log(row, '小 - 开始时间小于等于当前月份开始时间'); + console.log('开始时间:', row.startDate); + console.log('结束时间:', row.endDate); + console.log('当前月份开始:', currentMonthStart.format('YYYY-MM-DD')); + console.log('当前月份结束:', currentMonthEnd.format('YYYY-MM-DD')); + //如果结束时间小于当前月份的结束时间,则生成当前月份开始时间到row.endDate结束时间的n条数据 //如果结束时间大于等于当前月份的结束时间,则生成当前月份开始时间到当前月份结束时间(即当前月份天数)的n条数据 + + // 确定结束日期:取row.endDate和当前月份结束日期的较小值 + const actualEndDate = endDate.isBefore(currentMonthEnd) ? endDate : currentMonthEnd; + console.log('实际结束日期:', actualEndDate.format('YYYY-MM-DD')); + + // 生成从当前月份开始到实际结束日期的数据 + let currentDate = currentMonthStart; + let generatedCount = 0; + while (currentDate.isSame(actualEndDate, 'day') || currentDate.isBefore(actualEndDate, 'day')) { + calendarData.push({ + date: currentDate.format('YYYY-MM-DD'), + item: { + id: row.id, + groupName: row.attendanceGroup.groupName, + groupId: row.attendanceGroup.id, + startDate: row.startDate, + endDate: row.endDate, + }, + }); + generatedCount++; + currentDate = currentDate.add(1, 'day'); + } + console.log(`生成了 ${generatedCount} 条数据`); } else { //当开始时间大于当前月份的开始日期 //如果结束时间小于当前月份的结束时间,则生成开始时间到结束时间的n条数据 - console.log(row, '大'); + console.log(row, '大 - 开始时间大于当前月份开始时间'); + console.log('开始时间:', row.startDate); + console.log('结束时间:', row.endDate); + console.log('当前月份开始:', currentMonthStart.format('YYYY-MM-DD')); + console.log('当前月份结束:', currentMonthEnd.format('YYYY-MM-DD')); + + // 确定结束日期:取row.endDate和当前月份结束日期的较小值 + const actualEndDate = endDate.isBefore(currentMonthEnd) ? endDate : currentMonthEnd; + console.log('实际结束日期:', actualEndDate.format('YYYY-MM-DD')); + + // 生成从开始日期到实际结束日期的数据 + let currentDate = startDate; + let generatedCount = 0; + while (currentDate.isSame(actualEndDate, 'day') || currentDate.isBefore(actualEndDate, 'day')) { + calendarData.push({ + date: currentDate.format('YYYY-MM-DD'), + item: { + id: row.id, + groupName: row.attendanceGroup.groupName, + groupId: row.attendanceGroup.id, + startDate: row.startDate, + endDate: row.endDate, + }, + }); + generatedCount++; + currentDate = currentDate.add(1, 'day'); + } + console.log(`生成了 ${generatedCount} 条数据`); } } else { + // 没有结束日期的情况,只在开始日期添加一条数据 calendarData.push({ - data: row.startDate, + date: row.startDate, item: { id: row.id, groupName: row.attendanceGroup.groupName, groupId: row.attendanceGroup.id, + startDate: row.startDate, + endDate: row.endDate, }, }); } } - // if (response) { - // calendarData.value = response.data || []; - // console.log('日历数据:', calendarData.value); - // } + console.log('日历数据:', calendarData); + //变量calendarData,日期相同的数据放到一个对象中,数据结构为scheduleData + + // 将calendarData按日期分组,形成scheduleData结构 + const groupedData = new Map(); + + // 遍历calendarData,按日期分组 + calendarData.forEach(item => { + const date = item.date; + if (!groupedData.has(date)) { + groupedData.set(date, []); + } + groupedData.get(date)!.push(item.item); + }); + + // 转换为scheduleData格式 + scheduleData.length = 0; // 清空原有数据 + groupedData.forEach((items, date) => { + scheduleData.push({ + date: date, + list: items.map(item => ({ + type: 'success' as BadgeProps['status'], + content: item.groupName || '排班安排', + item: item + })) + }); + }); + + console.log('处理后的scheduleData:', scheduleData); + + // 测试:验证生成的日历数据 + console.log('=== 日历数据验证 ==='); + console.log('当前月份:', currentMonth); + console.log('原始数据条数:', res.rows.length); + console.log('生成的日历数据条数:', calendarData.length); + console.log('分组后的数据条数:', scheduleData.length); + + // 验证是否有重复日期 + const dateCounts = new Map(); + calendarData.forEach(item => { + const count = dateCounts.get(item.date) || 0; + dateCounts.set(item.date, count + 1); + }); + + console.log('日期分布:', Object.fromEntries(dateCounts)); + console.log('=== 验证完成 ==='); + } catch (error) { + console.error('获取日历数据失败:', error); + message.error('获取日历数据失败'); } finally { loading.value = false; } }; - -// 切换视图模式 -function handleViewModeChange(e: RadioChangeEvent): void { - // 将父组件的isCalenderView变为true - emit('changeView', e.target.value); -} - -// 日历模拟数据 const scheduleData: { date: string; list: { type: BadgeProps['status']; content: string }[]; @@ -81,18 +187,25 @@ const scheduleData: { { date: '2025-07-06', list: [{ type: 'success', content: '8月8日事件' }] }, // ... ]; +// 切换视图模式 +function handleViewModeChange(e: RadioChangeEvent): void { + // 将父组件的isCalenderView变为true + emit('changeView', e.target.value); +} const getListData2 = ( current: Dayjs, -): { type: BadgeProps['status']; content: string }[] => { +): { type: BadgeProps['status']; content: string; item?: any }[] => { const dateStr = current.format('YYYY-MM-DD'); - // 优先使用接口数据 - if (calendarData.length > 0) { - const found = calendarData.find((item) => item.date === dateStr); + + // 使用scheduleData结构 + if (scheduleData.length > 0) { + const found = scheduleData.find((item) => item.date === dateStr); if (found) { - return found.list || []; + return found.list; } } + // 如果没有找到数据,返回空数组 return []; }; @@ -130,13 +243,8 @@ const getListData = ( return listData || []; }; -const getMonthData = (value: Dayjs) => { - if (value.month() === 8) { - return 1394; - } -}; function customHeader() { - // 返回你想要的VNode或null + // 返回想要的VNode或null return null; // 什么都不显示 } const [ArrangementModal, modalApi] = useVbenModal({ @@ -147,6 +255,57 @@ function handleAdd() { modalApi.open(); } +// 编辑排班 +function handleEdit(item: any) { +console.log(815328); + + // modalApi.setData({ + // id: item.id, + // groupId: item.groupId, + // startDate: item.startDate, + // endDate: item.endDate, + // }); + // modalApi.open(); +} + +// 删除排班 +function handleDelete(item: any) { + Modal.confirm({ + title: '确认删除', + content: '确定要删除这个排班安排吗?', + onOk: async () => { + try { + // 这里需要调用删除接口 + // await deleteArrangement(item.id); + message.success('删除成功'); + fetchCalendarData(); + } catch (error) { + console.error('删除失败:', error); + message.error('删除失败'); + } + }, + }); +} + +// 查看详情 +function handleViewDetails(item: any) { + // 这里可以打开详情弹窗或跳转到详情页面 + console.log('查看详情:', item); +} + +// 获取指定日期的所有排班项目 +function getScheduleItemsByDate(date: string) { + const found = scheduleData.find((item) => item.date === date); + return found ? found.list : []; +} + +// 查看某日期的所有排班详情 +function handleViewDateDetails(date: string) { + const items = getScheduleItemsByDate(date); + console.log(`${date} 的所有排班安排:`, items); + // 这里可以打开详情弹窗显示该日期的所有排班 +} + // 页面初始化时加载数据 onMounted(() => { fetchCalendarData(); @@ -169,6 +328,7 @@ onMounted(() => { picker="month" v-model:value="selectedDate" @change="fetchCalendarData()" + @select="fetchCalendarData()" /> @@ -187,29 +347,32 @@ onMounted(() => { - @@ -228,6 +391,32 @@ onMounted(() => { text-overflow: ellipsis; font-size: 12px; } +.events li { + margin-bottom: 4px; + padding: 4px; + /* background-color: #f6ffed; */ + /* border: 1px solid #b7eb8f; */ + border-radius: 4px; + font-size: 12px; +} +.events li span { + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; +} +.events li .action-buttons { + display: flex; + gap: 4px; + margin-top: 2px; +} +.events li a { + font-size: 11px; + text-decoration: none; +} +.events li a:hover { + text-decoration: underline; +} .notes-month { text-align: center; font-size: 28px; diff --git a/apps/web-antd/src/views/property/businessManagement/workOrders/data.ts b/apps/web-antd/src/views/property/businessManagement/workOrders/data.ts index 5ecf2907..0b7b199a 100644 --- a/apps/web-antd/src/views/property/businessManagement/workOrders/data.ts +++ b/apps/web-antd/src/views/property/businessManagement/workOrders/data.ts @@ -152,8 +152,7 @@ export const modalSchema: FormSchemaGetter = () => [ { label: '工单类型', fieldName: 'type', - component: 'ApiSelect', - componentProps: {}, + component: 'TreeSelect', rules: 'selectRequired', }, { diff --git a/apps/web-antd/src/views/property/businessManagement/workOrders/index.vue b/apps/web-antd/src/views/property/businessManagement/workOrders/index.vue index 26ac66cb..fef94b5f 100644 --- a/apps/web-antd/src/views/property/businessManagement/workOrders/index.vue +++ b/apps/web-antd/src/views/property/businessManagement/workOrders/index.vue @@ -17,7 +17,10 @@ import workOrdersDetail from './work-orders-detail.vue'; import ordersModal from './orders-modal.vue'; import {columns, querySchema} from './data'; import {onMounted, ref} from "vue"; -import {workOrdersTypeList} from "#/api/property/businessManagement/workOrdersType"; +import { + workOrdersTypeList, + workOrdersTypeListAll +} from "#/api/property/businessManagement/workOrdersType"; const ordersTypeList = ref([]); const ordersType = ref('0'); @@ -130,11 +133,10 @@ function handleMultiDelete() { async function queryOrderType() { let params = { - pageSize: 1000, - pageNum: 1 + filterSubNodes:true } - const res = await workOrdersTypeList(params) - ordersTypeList.value = res.rows.map((item) => ({ + const res = await workOrdersTypeListAll(params) + ordersTypeList.value = res.map((item) => ({ label: item.orderTypeName, value: item.id, })); diff --git a/apps/web-antd/src/views/property/businessManagement/workOrders/workOrders-modal.vue b/apps/web-antd/src/views/property/businessManagement/workOrders/workOrders-modal.vue index a641283f..7712c344 100644 --- a/apps/web-antd/src/views/property/businessManagement/workOrders/workOrders-modal.vue +++ b/apps/web-antd/src/views/property/businessManagement/workOrders/workOrders-modal.vue @@ -14,9 +14,7 @@ import { import {defaultFormValueGetter, useBeforeCloseDiff} from '#/utils/popup'; import {modalSchema} from './data'; -import {personList} from "#/api/property/resident/person"; -import {renderDictValue} from "#/utils/render"; -import {workOrdersTypeList} from "#/api/property/businessManagement/workOrdersType"; +import {workOrdersTypeTree} from "#/api/property/businessManagement/workOrdersType"; const emit = defineEmits<{ reload: [] }>(); @@ -61,7 +59,7 @@ const [BasicModal, modalApi] = useVbenModal({ return null; } modalApi.modalLoading(true); - await queryPersonData() + await queryWorkOrdersType() const {id} = modalApi.getData() as { id?: number | string }; isUpdate.value = !!id; @@ -106,34 +104,35 @@ async function handleClosed() { resetInitialized(); } -async function queryPersonData() { - let params = { - pageSize: 1000, - pageNum: 1, - } - const res = await personList(params); - const options = res.rows.map((user) => ({ - label: user.userName + '-' + renderDictValue(user.gender, 'sys_user_sex') + '-' + user.phone, - value: user.id, - })); - formApi.updateSchema([{ - componentProps: () => ({ - options: options, - showSearch:true, - filterOption: filterOption - }), - fieldName: 'initiatorName', - }, +async function queryWorkOrdersType() { + const options = await workOrdersTypeTree() + formApi.updateSchema([ { componentProps: () => ({ - options: options, - showSearch:true, - filterOption: filterOption + class: 'w-full', + fieldNames: { + key: 'id', + label: 'orderTypeName', + value: 'id', + children: 'children', + }, + placeholder: '请选择工单类型', + showSearch: true, + treeData: options, + treeDefaultExpandAll: true, + treeLine: { showLeafIcon: false }, + treeNodeFilterProp: 'orderTypeName', + treeNodeLabelProp: 'orderTypeName', }), - fieldName: 'handler', - }]) + fieldName: 'type', + }, + ]); } +const filterOption = (input: string, option: any) => { + return option.label.toLowerCase().indexOf(input.toLowerCase()) >= 0; +}; +