diff --git a/.env.development b/.env.development index 8b0f18b..b362568 100644 --- a/.env.development +++ b/.env.development @@ -4,8 +4,8 @@ VITE_API_PREFIX = '/dev-api' # 接口地址 # VITE_API_BASE_URL = 'http://pms.dtyx.net:9158/' -# VITE_API_BASE_URL = 'http://localhost:8888/' -VITE_API_BASE_URL = 'http://10.18.34.163:8888/' +VITE_API_BASE_URL = 'http://localhost:8888/' +# VITE_API_BASE_URL = 'http://10.18.34.163:8888/' # VITE_API_BASE_URL = 'http://10.18.34.213:8888/' # 接口地址 (WebSocket) diff --git a/src/apis/equipment/index.ts b/src/apis/equipment/index.ts index 79de61c..35e2089 100644 --- a/src/apis/equipment/index.ts +++ b/src/apis/equipment/index.ts @@ -49,4 +49,24 @@ export function returnEquipment(equipmentId: string) { } // 导出设备采购 API -export * from './procurement' \ No newline at end of file +export * from './procurement' + +// 设备盘库相关 API +/** @desc 分页查询设备盘库记录 */ +export function pageEquipmentInventory(query: T.EquipmentPageQuery) { + return http.get(`${BASE_URL}/inventory/page`, query) +} + +/** @desc 执行设备盘库 */ +export function executeEquipmentInventory(equipmentId: string, inventoryResult: string, remark?: string) { + return http.post(`${BASE_URL}/inventory/${equipmentId}`, null, { + params: { inventoryResult, remark } + }) +} + +/** @desc 批量执行设备盘库 */ +export function batchExecuteEquipmentInventory(equipmentIds: string[], inventoryResult: string, remark?: string) { + return http.post(`${BASE_URL}/inventory/batch`, null, { + params: { equipmentIds, inventoryResult, remark } + }) +} \ No newline at end of file diff --git a/src/apis/equipment/procurement.ts b/src/apis/equipment/procurement.ts index dd8b3f6..d58e7d1 100644 --- a/src/apis/equipment/procurement.ts +++ b/src/apis/equipment/procurement.ts @@ -99,6 +99,37 @@ export const equipmentProcurementApi = { return http.get>(`/equipment/procurement/detail/${equipmentId}`) }, + /** + * 确认收货(扩展版,支持完整设备数据) + */ + receiveGoods: (equipmentId: string, data: ReceiptRequest) => { + console.log('📦 收货API被调用,设备ID:', equipmentId) + console.log('📦 收货数据:', data) + + return http.post>(`/equipment/procurement/receipt/${equipmentId}`, data) + }, + + /** + * 获取收货详情 + */ + getReceiptDetail: (equipmentId: string) => { + return http.get>(`/equipment/procurement/receipt/${equipmentId}`) + }, + + /** + * 执行付款 + */ + makePayment: (equipmentId: string, data: PaymentRequest) => { + return http.post>(`/equipment/procurement/payment/${equipmentId}`, data) + }, + + /** + * 获取支付详情 + */ + getPaymentDetail: (equipmentId: string) => { + return http.get>(`/equipment/procurement/payment/${equipmentId}`) + }, + /** * 获取采购统计信息 */ @@ -117,9 +148,6 @@ export const equipmentProcurementApi = { * 导出设备采购记录 */ export: (params: EquipmentListReq) => { - return http.get('/equipment/procurement/export', { - params, - responseType: 'blob' - }) + return http.get('/equipment/procurement/export', params, { responseType: 'blob' }) } } \ No newline at end of file diff --git a/src/apis/equipment/type.ts b/src/apis/equipment/type.ts index 2bd5a1e..f9bf6d9 100644 --- a/src/apis/equipment/type.ts +++ b/src/apis/equipment/type.ts @@ -101,28 +101,28 @@ export interface EquipmentResp { /** 资产编号 */ assetCode?: string /** 设备名称 */ - equipmentName: string + equipmentName?: string /** 设备类型 */ - equipmentType: string - /** 设备类型描述 */ + equipmentType?: string + /** 设备类型标签 */ equipmentTypeLabel?: string /** 设备型号 */ - equipmentModel: string - /** 设备SN */ - equipmentSn: string + equipmentModel?: string + /** 设备序列号 */ + equipmentSn?: string /** 品牌 */ brand?: string /** 配置规格/参数 */ specification?: string /** 设备状态 */ - equipmentStatus: string - /** 设备状态描述 */ + equipmentStatus?: string + /** 设备状态标签 */ equipmentStatusLabel?: string /** 使用状态 */ - useStatus: string + useStatus?: string /** 位置状态 */ locationStatus?: string - /** 位置状态描述 */ + /** 位置状态标签 */ locationStatusLabel?: string /** 设备当前物理位置 */ physicalLocation?: string @@ -130,7 +130,7 @@ export interface EquipmentResp { responsiblePerson?: string /** 健康状态 */ healthStatus?: string - /** 健康状态描述 */ + /** 健康状态标签 */ healthStatusLabel?: string /** 采购时间 */ purchaseTime?: string @@ -138,13 +138,13 @@ export interface EquipmentResp { inStockTime?: string /** 启用时间 */ activationTime?: string - /** 预计报废时间 */ + /** 预期报废时间 */ expectedScrapTime?: string /** 实际报废时间 */ actualScrapTime?: string /** 状态变更时间 */ statusChangeTime?: string - /** 采购订单 */ + /** 采购订单号 */ purchaseOrder?: string /** 供应商名称 */ supplierName?: string @@ -158,9 +158,9 @@ export interface EquipmentResp { depreciationYears?: number /** 残值 */ salvageValue?: number - /** 保修截止日期 */ + /** 保修到期日期 */ warrantyExpireDate?: string - /** 上次维护日期 */ + /** 最后维护日期 */ lastMaintenanceDate?: string /** 下次维护日期 */ nextMaintenanceDate?: string @@ -176,7 +176,7 @@ export interface EquipmentResp { projectName?: string /** 使用人ID */ userId?: string - /** 使用人 */ + /** 使用人姓名 */ name?: string /** 创建时间 */ createTime?: string @@ -194,12 +194,14 @@ export interface EquipmentResp { inventoryBasis?: string /** 动态记录 */ dynamicRecord?: string - /** 采购状态 */ procurementStatus?: string - /** 审批状态 */ approvalStatus?: string + /** 收货状态 */ + receiptStatus?: string + /** 支付状态 */ + paymentStatus?: string } /** @@ -406,3 +408,221 @@ export interface EquipmentApprovalResp { /** 更新时间 */ updateTime: string } + +/** + * 收货请求参数(扩展版,包含完整设备信息) + */ +export interface ReceiptRequest { + // 收货特有信息 + receiptTime: string + receiptPerson: string + receiptQuantity: number + receiptRemark?: string + appearanceCheck: string + functionTest: string + packageIntegrity: string + accessoryIntegrity: string + checkResult: 'PASS' | 'FAIL' | 'CONDITIONAL' + checkRemark?: string + storageLocation: string + storageManager: string + + // 设备基本信息(从采购数据继承) + equipmentName?: string + equipmentModel?: string + equipmentType?: string + equipmentSn?: string + brand?: string + specification?: string + assetCode?: string + + // 采购信息(从采购数据继承) + purchaseOrder?: string + supplierName?: string + purchasePrice?: number + purchaseTime?: string + quantity?: number + unitPrice?: number + totalPrice?: number + + // 入库信息 + inStockTime?: string + physicalLocation?: string + locationStatus?: string + responsiblePerson?: string + inventoryBarcode?: string + + // 状态信息 + equipmentStatus?: string + useStatus?: string + healthStatus?: string + receiptStatus?: string + + // 其他管理信息 + depreciationMethod?: string + depreciationYears?: number + salvageValue?: number + currentNetValue?: number + + // 系统字段 + createTime?: string + updateTime?: string +} + +/** + * 收货详情响应 + */ +export interface ReceiptDetail { + /** 设备ID */ + equipmentId: string + /** 设备名称 */ + equipmentName: string + /** 设备类型 */ + equipmentType: string + /** 设备型号 */ + equipmentModel: string + /** 品牌 */ + brand: string + /** 供应商 */ + supplierName: string + /** 采购订单 */ + purchaseOrder: string + /** 收货状态 */ + receiptStatus: string + /** 收货时间 */ + receiptTime: string + /** 收货人 */ + receiptPerson: string + /** 收货数量 */ + receiptQuantity: number + /** 收货备注 */ + receiptRemark?: string + /** 外观检查 */ + appearanceCheck: string + /** 功能测试 */ + functionTest: string + /** 包装完整性 */ + packageIntegrity: string + /** 配件完整性 */ + accessoryIntegrity: string + /** 检查结果 */ + checkResult: string + /** 检查备注 */ + checkRemark?: string + /** 入库状态 */ + storageStatus: string + /** 入库时间 */ + storageTime: string + /** 入库位置 */ + storageLocation: string + /** 库管员 */ + storageManager: string +} + +/** + * 支付请求参数 + */ +export interface PaymentRequest { + /** 支付方式 */ + paymentMethod: string + /** 支付金额 */ + paymentAmount: number + /** 支付时间 */ + paymentTime: string + /** 支付人 */ + paymentPerson: string + /** 支付备注 */ + paymentRemark?: string + /** 发票类型 */ + invoiceType: string + /** 发票号码 */ + invoiceNumber: string + /** 开票日期 */ + invoiceDate: string + /** 发票金额 */ + invoiceAmount: number + /** 税率 */ + taxRate: number + /** 税额 */ + taxAmount: number + /** 不含税金额 */ + amountWithoutTax: number + /** 合同编号 */ + contractNumber: string + /** 合同金额 */ + contractAmount: number + /** 签订日期 */ + contractDate: string + /** 付款条件 */ + paymentTerms: string + /** 付款期限 */ + paymentDeadline: string +} + +/** + * 支付详情响应 + */ +export interface PaymentDetail { + /** 设备ID */ + equipmentId: string + /** 设备名称 */ + equipmentName: string + /** 设备类型 */ + equipmentType: string + /** 设备型号 */ + equipmentModel: string + /** 品牌 */ + brand: string + /** 供应商 */ + supplierName: string + /** 采购订单 */ + purchaseOrder: string + /** 采购价格 */ + purchasePrice: number + /** 采购数量 */ + quantity: number + /** 总金额 */ + totalPrice: number + /** 采购日期 */ + purchaseTime: string + /** 支付状态 */ + paymentStatus: string + /** 支付方式 */ + paymentMethod: string + /** 支付金额 */ + paymentAmount: number + /** 支付时间 */ + paymentTime: string + /** 支付人 */ + paymentPerson: string + /** 支付备注 */ + paymentRemark?: string + /** 发票状态 */ + invoiceStatus: string + /** 发票类型 */ + invoiceType: string + /** 发票号码 */ + invoiceNumber: string + /** 开票日期 */ + invoiceDate: string + /** 发票金额 */ + invoiceAmount: number + /** 税率 */ + taxRate: number + /** 税额 */ + taxAmount: number + /** 不含税金额 */ + amountWithoutTax: number + /** 合同编号 */ + contractNumber: string + /** 合同状态 */ + contractStatus: string + /** 合同金额 */ + contractAmount: number + /** 签订日期 */ + contractDate: string + /** 付款条件 */ + paymentTerms: string + /** 付款期限 */ + paymentDeadline: string +} diff --git a/src/apis/project/index.ts b/src/apis/project/index.ts index bde6b8a..3471f0c 100644 --- a/src/apis/project/index.ts +++ b/src/apis/project/index.ts @@ -15,6 +15,12 @@ export function getProject(id: string | number) { return http.get(`${BASE_URL}/${id}`) } +/** @desc 获取项目详情(标准详情接口) */ +export function getProjectDetail(id: string | number) { + return http.get(`${BASE_URL}/detail/${id}`) +} + + /** @desc 新增项目 */ export function addProject(data: any) { return http.post(`${BASE_URL}`, data) @@ -49,4 +55,4 @@ export function importProject(file: File) { /** @desc 导出项目 */ export function exportProject(query: T.ProjectQuery) { return http.download(`${BASE_URL}/export`, query) -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/apis/project/type.ts b/src/apis/project/type.ts index 506cb93..5d5f527 100644 --- a/src/apis/project/type.ts +++ b/src/apis/project/type.ts @@ -18,6 +18,8 @@ export interface ProjectResp { projectCategory?: string // 项目类型/服务 projectManagerId?: string // 项目经理ID projectManagerName?: string // 项目经理姓名 + projectOrigin?: string // 项目来源 + projectStaff?: string[] // 施工人员 startDate?: string // 开始日期 endDate?: string // 结束日期 @@ -28,10 +30,10 @@ export interface ProjectResp { coverUrl?: string // 封面URL createDt?: Date updateDt?: Date - + // 为了保持向后兼容,添加一些别名字段 id?: string // projectId的别名 - fieldName?: string // farmName的别名 + fieldName?: string // farmName的别名 fieldLocation?: string // farmAddress的别名 commissionUnit?: string // client的别名 commissionContact?: string // clientContact的别名 @@ -85,7 +87,7 @@ export interface TaskQuery { status?: string } -export interface TaskPageQuery extends TaskQuery, PageQuery {} +export interface TaskPageQuery extends TaskQuery, PageQuery {} // ==================== 人员调度相关类型 ==================== @@ -339,4 +341,4 @@ export interface PageRes { total: number page: number pageSize: number -} \ No newline at end of file +} \ No newline at end of file diff --git a/src/components/NotificationCenter/index.vue b/src/components/NotificationCenter/index.vue index 7fb4ccf..7230f61 100644 --- a/src/components/NotificationCenter/index.vue +++ b/src/components/NotificationCenter/index.vue @@ -19,7 +19,7 @@ :mask-closable="true" :closable="true" :destroy-on-close="false" - :z-index="999999" + :z-index="1000" class="notification-modal" > @@ -673,7 +673,7 @@ defineExpose({ diff --git a/src/router/route.ts b/src/router/route.ts index 72d5b7e..05536b6 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -1199,46 +1199,141 @@ export const systemRoutes: RouteRecordRaw[] = [ ], }, { - path: '/chat-platform', - name: 'ChatPlatform', - component: Layout, - redirect: '/chat-platform/options', - meta: { title: '聊天平台', icon: 'message', hidden: false, sort: 6 }, + path: '/image-detection', + name: 'ImageDetection', + component: Layout, + redirect: '/Image-detection/tower-monitoring/clearance-monitoring', + meta: { + title: '图像检测', + icon: 'monitor', + hidden: false, + sort: 6.5, + }, + children: [ - // { - // path: '/chat-platform/options', - // name: 'ChatOptions', - // component: () => import('@/views/default/redirect/index.vue'), // 临时使用一个组件,实际开发中需要替换 - // meta: { - // title: '二级选项1', - // icon: 'setting', - // hidden: false - // } - // } - ], + { + path: '/image-detection/image-analysis', + name: 'ImageAnalysis', + component: () => import('@/components/ParentView/index.vue'), + meta: { + title: '检查图像分析', + icon: 'line-chart', + hidden: false, + }, + redirect: '/image-detection/image-analysis/defect-detection', + children: [ + {path: '/image-detection/image-analysis/defect-detection', + name: 'DefectDetection', + component: () => import('@/views/construction-operation-platform/implementation-workflow/data-processing/intelligent-inspection/defect-algorithm/index.vue'), + meta: { + title: '缺陷检测', + icon: 'line-chart', + hidden: false, + } + }, + {path: '/image-detection/image-analysis/defect-edit', + name: 'DefectEdit', + component: () => import('@/components/ParentView/index.vue'), + meta: { + title: '缺陷编辑', + icon: 'line-chart', + hidden: false, + } + }, + {path: '/image-detection/image-analysis/generate-reports', + name: 'GenerateReports', + component: () => import('@/views/project-operation-platform/data-processing/report-generation/index.vue'), + meta: { + title: '生成报告', + icon: 'line-chart', + hidden: false, + } + }, + {path: '/image-detection/image-analysis/defect-base', + name: 'DefectBase', + component: () => import('@/views/project-operation-platform/data-processing/standard-info/index.vue'), + meta: { + title: '缺陷标准数据信息库', + icon: 'line-chart', + hidden: false, + } + }, + ] + }, + { + path: '/tower-monitoring', + name: 'TowerMonitoring', + component: () => import('@/components/ParentView/index.vue'), + redirect: '/tower-monitoring/clearance-monitoring', + meta: { + title: '音视频检测', + icon: 'monitor', + hidden: false, + sort: 6.5, }, + children: [ + { + path: '/tower-monitoring/clearance-monitoring', + name: 'ClearanceMonitoring', + component: () => import('@/views/tower-monitoring/deformation.vue'), + meta: { + title: '净空监测', + icon: 'fullscreen', + hidden: false, + }, + }, + { + path: '/tower-monitoring/deformation-monitoring', + name: 'DeformationMonitoring', + component: () => import('@/views/tower-monitoring/clearance.vue'), + meta: { + title: '形变监测', + icon: 'line-chart', + hidden: false, + }, + }, + { + path: '/tower-monitoring/whistle-monitoring', + name: 'WhistleMonitoring', + component: () => import('@/views/tower-monitoring/whistle.vue'), + meta: { + title: '哨声监测', + icon: 'sound', + hidden: false, + }, + }, + { + path: '/tower-monitoring/vibration-monitoring', + name: 'VibrationMonitoring', + component: () => import('@/views/tower-monitoring/vibration.vue'), + meta: { + title: '振动监测', + icon: 'shake', + hidden: false, + }, + }, + ], + }, + { + path: '/image-detection/reporting-center', + name: 'ReportingCenter', + component: () => import('@/views/tower-monitoring/vibration.vue'), + meta: { + title: '报告中心', + icon: 'shake', + hidden: false, + }, + } + ] +}, + // { - // path: '/user/profile', - // name: 'UserProfile', + // path: '/chat-platform', + // name: 'ChatPlatform', // component: Layout, - // redirect: '/user/profile', - // meta: { - // title: '个人中心', - // icon: 'user', - // hidden: false, - // sort: 100, - // }, + // redirect: '/chat-platform/options', + // meta: { title: '聊天平台', icon: 'message', hidden: false, sort: 6 }, // children: [ - // { - // path: '/user/profile', - // name: 'UsersProfile', - // component: () => import('@/views/user/profile/index.vue'), - // meta: { - // title: '个人中心', - // icon: 'user', - // hidden: false, - // }, - // }, // ], // }, { @@ -1356,6 +1451,16 @@ export const systemRoutes: RouteRecordRaw[] = [ hidden: false, }, }, + { + path: '/system-resource/device-management/inventory', + name: 'DeviceInventory', + component: () => import('@/views/system-resource/device-management/inventory.vue'), + meta: { + title: '设备盘库', + icon: 'inbox', + hidden: false, + }, + }, { path: '/system-resource/device-management/online', name: 'SystemResourceDeviceOnline', diff --git a/src/stores/modules/route.ts b/src/stores/modules/route.ts index 909490b..fb90fbd 100644 --- a/src/stores/modules/route.ts +++ b/src/stores/modules/route.ts @@ -226,6 +226,20 @@ const storeSetup = () => { { id: 2013, parentId: 2010, + title: '设备盘库', + type: 2, + path: '/asset-management/device-management/inventory', + name: 'DeviceInventory', + component: 'system-resource/device-management/inventory', + icon: 'inbox', + isExternal: false, + isCache: false, + isHidden: false, + sort: 3, + }, + { + id: 2014, + parentId: 2010, title: '审批台', type: 2, path: '/asset-management/device-management/approval', @@ -235,10 +249,10 @@ const storeSetup = () => { isExternal: false, isCache: false, isHidden: false, - sort: 3, + sort: 4, }, { - id: 2014, + id: 2015, parentId: 2010, title: '在线管理', type: 1, @@ -250,11 +264,11 @@ const storeSetup = () => { isExternal: false, isCache: false, isHidden: false, - sort: 4, + sort: 5, children: [ { - id: 20141, - parentId: 2014, + id: 20151, + parentId: 2015, title: '无人机', type: 2, path: '/asset-management/device-management/online/drone', @@ -267,8 +281,8 @@ const storeSetup = () => { sort: 1, }, { - id: 20142, - parentId: 2014, + id: 20152, + parentId: 2015, title: '机巢', type: 2, path: '/asset-management/device-management/online/nest', @@ -281,8 +295,8 @@ const storeSetup = () => { sort: 2, }, { - id: 20143, - parentId: 2014, + id: 20153, + parentId: 2015, title: '其他智能终端', type: 2, path: '/asset-management/device-management/online/smart-terminal', @@ -297,7 +311,7 @@ const storeSetup = () => { ], }, { - id: 2015, + id: 2016, parentId: 2010, title: '设备详情', type: 2, @@ -308,7 +322,7 @@ const storeSetup = () => { isExternal: false, isCache: false, isHidden: true, - sort: 5, + sort: 6, }, ], }, diff --git a/src/types/components.d.ts b/src/types/components.d.ts index a427ece..7fa6b1b 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -7,70 +7,7 @@ export {} declare module 'vue' { export interface GlobalComponents { - ApprovalAssistant: typeof import('./../components/ApprovalAssistant/index.vue')['default'] - ApprovalMessageItem: typeof import('./../components/NotificationCenter/ApprovalMessageItem.vue')['default'] - Avatar: typeof import('./../components/Avatar/index.vue')['default'] - Breadcrumb: typeof import('./../components/Breadcrumb/index.vue')['default'] - CellCopy: typeof import('./../components/CellCopy/index.vue')['default'] - Chart: typeof import('./../components/Chart/index.vue')['default'] - CircularProgress: typeof import('./../components/CircularProgress/index.vue')['default'] - ColumnSetting: typeof import('./../components/GiTable/src/components/ColumnSetting.vue')['default'] - CronForm: typeof import('./../components/GenCron/CronForm/index.vue')['default'] - CronModal: typeof import('./../components/GenCron/CronModal/index.vue')['default'] - DateRangePicker: typeof import('./../components/DateRangePicker/index.vue')['default'] - DayForm: typeof import('./../components/GenCron/CronForm/component/day-form.vue')['default'] - FilePreview: typeof import('./../components/FilePreview/index.vue')['default'] - GiCellAvatar: typeof import('./../components/GiCell/GiCellAvatar.vue')['default'] - GiCellGender: typeof import('./../components/GiCell/GiCellGender.vue')['default'] - GiCellStatus: typeof import('./../components/GiCell/GiCellStatus.vue')['default'] - GiCellTag: typeof import('./../components/GiCell/GiCellTag.vue')['default'] - GiCellTags: typeof import('./../components/GiCell/GiCellTags.vue')['default'] - GiCodeView: typeof import('./../components/GiCodeView/index.vue')['default'] - GiDot: typeof import('./../components/GiDot/index.tsx')['default'] - GiEditTable: typeof import('./../components/GiEditTable/GiEditTable.vue')['default'] - GiFooter: typeof import('./../components/GiFooter/index.vue')['default'] - GiForm: typeof import('./../components/GiForm/src/GiForm.vue')['default'] - GiIconBox: typeof import('./../components/GiIconBox/index.vue')['default'] - GiIconSelector: typeof import('./../components/GiIconSelector/index.vue')['default'] - GiIframe: typeof import('./../components/GiIframe/index.vue')['default'] - GiOption: typeof import('./../components/GiOption/index.vue')['default'] - GiOptionItem: typeof import('./../components/GiOptionItem/index.vue')['default'] - GiPageLayout: typeof import('./../components/GiPageLayout/index.vue')['default'] - GiSpace: typeof import('./../components/GiSpace/index.vue')['default'] - GiSplitButton: typeof import('./../components/GiSplitButton/index.vue')['default'] - GiSplitPane: typeof import('./../components/GiSplitPane/index.vue')['default'] - GiSplitPaneFlexibleBox: typeof import('./../components/GiSplitPane/components/GiSplitPaneFlexibleBox.vue')['default'] - GiSvgIcon: typeof import('./../components/GiSvgIcon/index.vue')['default'] - GiTable: typeof import('./../components/GiTable/src/GiTable.vue')['default'] - GiTag: typeof import('./../components/GiTag/index.tsx')['default'] - GiThemeBtn: typeof import('./../components/GiThemeBtn/index.vue')['default'] - HourForm: typeof import('./../components/GenCron/CronForm/component/hour-form.vue')['default'] - Icon403: typeof import('./../components/icons/Icon403.vue')['default'] - Icon404: typeof import('./../components/icons/Icon404.vue')['default'] - Icon500: typeof import('./../components/icons/Icon500.vue')['default'] - IconBorders: typeof import('./../components/icons/IconBorders.vue')['default'] - IconTableSize: typeof import('./../components/icons/IconTableSize.vue')['default'] - IconTreeAdd: typeof import('./../components/icons/IconTreeAdd.vue')['default'] - IconTreeReduce: typeof import('./../components/icons/IconTreeReduce.vue')['default'] - ImageImport: typeof import('./../components/ImageImport/index.vue')['default'] - ImageImportWizard: typeof import('./../components/ImageImportWizard/index.vue')['default'] - IndustrialImageList: typeof import('./../components/IndustrialImageList/index.vue')['default'] - JsonPretty: typeof import('./../components/JsonPretty/index.vue')['default'] - MinuteForm: typeof import('./../components/GenCron/CronForm/component/minute-form.vue')['default'] - MonthForm: typeof import('./../components/GenCron/CronForm/component/month-form.vue')['default'] - NotificationCenter: typeof import('./../components/NotificationCenter/index.vue')['default'] - ParentView: typeof import('./../components/ParentView/index.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] - SecondForm: typeof import('./../components/GenCron/CronForm/component/second-form.vue')['default'] - SplitPanel: typeof import('./../components/SplitPanel/index.vue')['default'] - TextCopy: typeof import('./../components/TextCopy/index.vue')['default'] - TurbineGrid: typeof import('./../components/TurbineGrid/index.vue')['default'] - UserSelect: typeof import('./../components/UserSelect/index.vue')['default'] - Verify: typeof import('./../components/Verify/index.vue')['default'] - VerifyPoints: typeof import('./../components/Verify/Verify/VerifyPoints.vue')['default'] - VerifySlide: typeof import('./../components/Verify/Verify/VerifySlide.vue')['default'] - WeekForm: typeof import('./../components/GenCron/CronForm/component/week-form.vue')['default'] - YearForm: typeof import('./../components/GenCron/CronForm/component/year-form.vue')['default'] } } diff --git a/src/views/bussiness-data/bussiness.vue b/src/views/bussiness-data/bussiness.vue index dcc7abf..9cebdba 100644 --- a/src/views/bussiness-data/bussiness.vue +++ b/src/views/bussiness-data/bussiness.vue @@ -143,19 +143,22 @@ - - - -
- + +
+
+ 文件列表 ({{ fileList.length }}) +
+
+ +
@@ -336,7 +339,7 @@
-
+
@@ -2453,8 +2458,6 @@ onMounted(() => { background-color: var(--color-bg-1); } - - /* 侧边栏样式 */ .folder-sidebar { box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); @@ -2629,6 +2632,7 @@ onMounted(() => { background: var(--color-bg-1); min-height: 0; max-height: calc(100vh - 120px); + position: relative; } .file-card { @@ -2640,6 +2644,7 @@ onMounted(() => { position: relative; height: 100%; overflow: hidden; + padding-bottom: 80px; /* 为分页器留出空间 */ } /* 表格容器 */ @@ -2654,7 +2659,7 @@ onMounted(() => { box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05); margin-bottom: 0; min-height: 300px; - max-height: calc(100vh - 300px); + max-height: calc(100vh - 380px); /* 调整高度为分页器留出空间 */ } /* 表头行样式 */ @@ -3100,14 +3105,65 @@ onMounted(() => { } /* 分页样式 */ -.pagination-container, .file-pagination { - margin-top: 16px; - text-align: right; - padding: 0 16px 16px; -} - -.file-pagination { +.pagination-container { + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: var(--color-bg-1); + padding: 16px 24px; border-top: 1px solid var(--color-border); + display: flex; + justify-content: flex-end; + align-items: center; + z-index: 10; + box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06); + margin-top: 0; + + .arco-pagination { + margin: 0; + + .arco-pagination-item { + border-radius: 6px; + margin: 0 4px; + transition: all 0.2s ease; + + &:hover { + border-color: var(--color-primary); + color: var(--color-primary); + } + + &.arco-pagination-item-active { + background: var(--color-primary); + border-color: var(--color-primary); + color: white; + } + } + + .arco-pagination-prev, + .arco-pagination-next { + border-radius: 6px; + transition: all 0.2s ease; + + &:hover { + border-color: var(--color-primary); + color: var(--color-primary); + } + } + + .arco-pagination-size-changer { + margin-left: 16px; + } + + .arco-pagination-jumper { + margin-left: 16px; + } + + .arco-pagination-total { + color: var(--color-text-2); + font-size: 14px; + } + } } @@ -3530,9 +3586,29 @@ onMounted(() => { 100% { transform: translateX(100%); } } +/* 文件头部容器样式 */ +.file-header-container { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 16px; + padding: 16px 0; +} + +.file-title { + display: flex; + align-items: center; +} + +.file-list-title { + font-size: 16px; + font-weight: 600; + color: var(--color-text-1); + margin: 0; +} + /* 文件搜索样式 */ .file-search-container { - margin: 16px 0; display: flex; align-items: center; gap: 12px; @@ -3601,55 +3677,7 @@ onMounted(() => { border-top-color: var(--color-primary); } -/* 文件分页样式 */ -.file-pagination { - position: sticky; - bottom: 0; - left: 0; - right: 0; - margin-top: 16px; - padding: 16px 0; - display: flex; - justify-content: center; - border-top: 1px solid var(--color-border); - background: var(--color-bg-1); - flex-shrink: 0; - z-index: 10; - - .arco-pagination { - .arco-pagination-total { - color: var(--color-text-2); - font-size: 14px; - } - - .arco-pagination-item { - border-radius: 6px; - transition: all 0.2s ease; - - &:hover { - border-color: var(--color-primary); - color: var(--color-primary); - } - - &.arco-pagination-item-active { - background: var(--color-primary); - border-color: var(--color-primary); - color: white; - } - } - - .arco-pagination-prev, - .arco-pagination-next { - border-radius: 6px; - transition: all 0.2s ease; - - &:hover { - border-color: var(--color-primary); - color: var(--color-primary); - } - } - } -} + /* 树形文件夹结构 */ .folder-tree-container { diff --git a/src/views/operation-platform/data-processing/data-storage/index.vue b/src/views/operation-platform/data-processing/data-storage/index.vue index 23de01b..a15755d 100644 --- a/src/views/operation-platform/data-processing/data-storage/index.vue +++ b/src/views/operation-platform/data-processing/data-storage/index.vue @@ -73,18 +73,8 @@
- -
- - - -
-
- - - @@ -107,8 +97,6 @@ import { } from '@/apis/industrial-image' import DeformationTap from './components/DeformationTap.vue' -// 预览弹窗引用(待重新设计) -// const previewModal = ref() // 活动选项卡 const activeTab = ref('image') diff --git a/src/views/project/detail/index.vue b/src/views/project/detail/index.vue index ed7aa2d..486f420 100644 --- a/src/views/project/detail/index.vue +++ b/src/views/project/detail/index.vue @@ -7,9 +7,9 @@

{{ projectTitle }}

- {{ - projectData.status - }} + + {{ projectData.statusLabel ?? projectData.status }} +
@@ -198,8 +198,8 @@ import { ref, reactive, computed, onMounted } from 'vue' import { useRoute, useRouter } from 'vue-router' import { Message, Modal } from '@arco-design/web-vue' -import { getProject, deleteProject } from '@/apis/project' -import { addTask, addTaskGroup, listTask, updateTaskProgress } from '@/apis/project/task' +import { getProjectDetail, deleteProject } from '@/apis/project' +import { addTask, addTaskGroup, updateTaskProgress } from '@/apis/project/task' import dayjs from 'dayjs' defineOptions({ name: 'ProjectDetail' }) @@ -257,10 +257,15 @@ const projectTitle = computed(() => { const projectInfos = computed(() => [ { label: '项目编号', value: projectData.value?.projectCode }, - { label: '项目负责人', value: projectData.value?.projectManager }, - { label: '参与人', value: projectData.value?.projectStaff?.join(', ') }, - { label: '项目周期', value: projectData.value?.projectPeriod ? `${projectData.value.projectPeriod[0]} 至 ${projectData.value.projectPeriod[1]}` : '' }, - { label: '客户', value: projectData.value?.commissionUnit }, + { label: '项目负责人', value: projectData.value?.projectManagerName || projectData.value?.projectManager }, + { label: '项目来源', value: projectData.value?.projectOrigin }, + { label: '风场名称', value: projectData.value?.farmName }, + { label: '风场地址', value: projectData.value?.farmAddress }, + { label: '开始时间', value: projectData.value?.startDate }, + { label: '结束时间', value: projectData.value?.endDate }, + { label: '项目规模', value: projectData.value?.scale }, + { label: '状态', value: (statusMap as any)[Number(projectData.value?.status)]?.label || projectData.value?.statusLabel }, + { label: '客户', value: projectData.value?.client }, { label: '备注', value: projectData.value?.projectIntro || '无' } ]) @@ -284,6 +289,15 @@ const taskDetailInfos = computed(() => { { label: '状态', value: currentTask.value.status }, { label: '描述', value: currentTask.value.description || '无' } ] + +const statusMap: Record = { + 0: { label: '待施工', color: 'gray' }, + 1: { label: '施工中', color: 'blue' }, + 2: { label: '已完工', color: 'green' }, + 3: { label: '已审核', color: 'orange' }, + 4: { label: '已验收', color: 'arcoblue' }, +} + }) const getStatusColor = (status: string) => { @@ -322,8 +336,14 @@ const formatDate = (date: string) => { const fetchProjectData = async () => { loading.value = true try { - const res = await getProject(projectId.value) - projectData.value = res.data + const res = await getProjectDetail(projectId.value) + const detail = (res as any).data || res + // 如果status是数字,补充statusLabel用于页面展示 + if (typeof detail.status === 'number' && !detail.statusLabel) { + const mapper = (statusMap as any)[detail.status] + if (mapper) detail.statusLabel = mapper.label + } + projectData.value = detail } catch (error) { console.error(error) Message.error('获取项目详情失败') @@ -332,34 +352,39 @@ const fetchProjectData = async () => { } } -const fetchTaskData = async () => { - try { - const res = await listTask({ - projectId: projectId.value, - page: 1, - size: 100 - }) +// 若任务未返回状态,依据计划时间简单推断状态 +const inferTaskStatus = (task: any): string => { + if (task.status) return task.status + const now = dayjs() + const start = task.planStartDate ? dayjs(task.planStartDate) : null + const end = task.planEndDate ? dayjs(task.planEndDate) : null + if (end && end.isBefore(now)) return '已完成' + if (start && start.isAfter(now)) return '计划中' + if (start && (!end || end.isAfter(now))) return '正在做' + return '其他' +} - // 重置任务列表 - taskColumns.value.forEach(column => { - column.tasks = [] - }) - const tasks = res.data?.list || [] +const fetchTaskData = () => { + // 使用详情接口返回的任务列表 + const detail = projectData.value || {} + const tasks = (detail.tasks || []) as any[] - // 分配任务到对应的列 - tasks.forEach((task: any) => { - const column = taskColumns.value.find(col => col.status === task.status) - if (column) { - column.tasks.push(task) - } else { - taskColumns.value.find(col => col.status === '其他')?.tasks.push(task) - } - }) - } catch (error) { - console.error(error) - Message.error('获取任务数据失败') - } + // 重置任务列表 + taskColumns.value.forEach(column => { + column.tasks = [] + }) + + // 分配任务到对应的列(按状态或推断状态) + tasks.forEach((task: any) => { + const st = inferTaskStatus(task) + const column = taskColumns.value.find(col => col.status === st) + if (column) { + column.tasks.push(task) + } else { + taskColumns.value.find(col => col.status === '其他')?.tasks.push(task) + } + }) } const goBack = () => { @@ -491,8 +516,7 @@ const submitProgressUpdate = async () => { } onMounted(() => { - fetchProjectData() - fetchTaskData() + fetchProjectData().then(() => fetchTaskData()) }) diff --git a/src/views/project/index.vue b/src/views/project/index.vue index b523e17..3c7d76f 100644 --- a/src/views/project/index.vue +++ b/src/views/project/index.vue @@ -2,19 +2,21 @@ 项目管理页面 已完成接口对接: 1. 项目列表查询 (listProject) - 支持分页和条件查询 - 2. 项目新增 (addProject) + 2. 项目新增 (addProject) 3. 项目修改 (updateProject) 4. 项目删除 (deleteProject) 5. 项目导出 (exportProject) 6. 项目导入 (importProject) - + 所有API调用都已添加错误处理和类型安全检查 --> + + + + + + @@ -271,6 +345,10 @@ import message from '@arco-design/web-vue/es/message' import ProcurementModal from './components/ProcurementModal.vue' import ProcurementSearch from './components/ProcurementSearch.vue' import ProcurementApplicationModal from './components/ProcurementApplicationModal.vue' +import ReceiptDetailModal from './components/ReceiptDetailModal.vue' +import PaymentDetailModal from './components/PaymentDetailModal.vue' +import ReceiptModal from './components/ReceiptModal.vue' +import PaymentModal from './components/PaymentModal.vue' import { equipmentProcurementApi } from '@/apis/equipment/procurement' import { equipmentApprovalApi } from '@/apis/equipment/approval' import type { EquipmentListReq, EquipmentResp } from '@/apis/equipment/type' @@ -307,6 +385,18 @@ const modalMode = ref<'add' | 'edit' | 'view'>('add') const applicationModalVisible = ref(false) const currentApplicationData = ref(null) +// 收货详情弹窗控制 +const receiptDetailModalVisible = ref(false) +const currentReceiptData = ref(null) + +// 支付详情弹窗控制 +const paymentDetailModalVisible = ref(false) +const currentPaymentData = ref(null) + +// 收货弹窗控制 +const receiptModalVisible = ref(false) +const paymentModalVisible = ref(false) + // 表格选择 const selectedRowKeys = ref([]) const rowSelection = reactive({ @@ -418,6 +508,20 @@ const columns = [ slotName: 'createTime', width: 160, }, + { + title: '收货状态', + dataIndex: 'receiptStatus', + key: 'receiptStatus', + slotName: 'receiptStatus', + width: 120, + }, + { + title: '支付状态', + dataIndex: 'paymentStatus', + key: 'paymentStatus', + slotName: 'paymentStatus', + width: 120, + }, { title: '操作', key: 'action', @@ -527,6 +631,50 @@ const getHealthStatusText = (status: string) => { return textMap[status] || '未知' } +// 获取收货状态颜色 +const getReceiptStatusColor = (status: string) => { + const colorMap: Record = { + NOT_RECEIVED: 'gray', + RECEIVED: 'green', + PARTIALLY_RECEIVED: 'orange', + REJECTED: 'red', + } + return colorMap[status] || 'blue' +} + +// 获取收货状态文本 +const getReceiptStatusText = (status: string) => { + const textMap: Record = { + NOT_RECEIVED: '未收货', + RECEIVED: '已收货', + PARTIALLY_RECEIVED: '部分收货', + REJECTED: '已拒收', + } + return textMap[status] || '未知' +} + +// 获取支付状态颜色 +const getPaymentStatusColor = (status: string) => { + const colorMap: Record = { + NOT_PAID: 'gray', + PAID: 'green', + PARTIALLY_PAID: 'orange', + REJECTED: 'red', + } + return colorMap[status] || 'blue' +} + +// 获取支付状态文本 +const getPaymentStatusText = (status: string) => { + const textMap: Record = { + NOT_PAID: '未支付', + PAID: '已支付', + PARTIALLY_PAID: '部分支付', + REJECTED: '已拒付', + } + return textMap[status] || '未知' +} + // 格式化价格 const formatPrice = (price: number) => { return price.toLocaleString('zh-CN', { @@ -601,6 +749,8 @@ const transformBackendData = (data: any[]): EquipmentResp[] => { inventoryBasis: item.inventoryBasis, dynamicRecord: item.dynamicRecord, procurementStatus: item.procurementStatus, + receiptStatus: item.receiptStatus || 'NOT_RECEIVED', + paymentStatus: item.paymentStatus || 'NOT_PAID', })) } @@ -850,6 +1000,54 @@ const canApplyProcurement = (record: EquipmentResp) => { return canApply } +// 检查是否可以收货 +const canReceiveGoods = (record: EquipmentResp) => { + const receiptStatus = (record as any).receiptStatus + return receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED' +} + +// 收货操作 +const handleReceiveGoods = async (record: EquipmentResp) => { + currentReceiptData.value = { ...record } + receiptModalVisible.value = true +} + +// 查看收货详情 +const handleViewReceipt = (record: EquipmentResp) => { + currentReceiptData.value = { ...record } + receiptDetailModalVisible.value = true +} + +// 收货成功回调 +const handleReceiptSuccess = () => { + receiptModalVisible.value = false + loadData(currentSearchParams.value) +} + +// 检查是否可以付款 +const canMakePayment = (record: EquipmentResp) => { + const paymentStatus = (record as any).paymentStatus + return paymentStatus === 'NOT_PAID' || paymentStatus === 'PARTIALLY_PAID' +} + +// 付款操作 +const handleMakePayment = async (record: EquipmentResp) => { + currentPaymentData.value = { ...record } + paymentModalVisible.value = true +} + +// 查看支付详情 +const handleViewPayment = (record: EquipmentResp) => { + currentPaymentData.value = { ...record } + paymentDetailModalVisible.value = true +} + +// 支付成功回调 +const handlePaymentSuccess = () => { + paymentModalVisible.value = false + loadData(currentSearchParams.value) +} + // 获取审批状态颜色 const getApprovalStatusColor = (status: string) => { const colorMap: Record = { diff --git a/src/views/task/task-approval/TaskApproval.vue b/src/views/task/task-approval/TaskApproval.vue index 67b89a4..8defe5c 100644 --- a/src/views/task/task-approval/TaskApproval.vue +++ b/src/views/task/task-approval/TaskApproval.vue @@ -6,7 +6,7 @@

审批转交的任务

- +
{ /* 待审批状态样式 */ .status-item.pending { - border-top-color: #f59e0b; - background-color: rgba(245, 158, 11, 0.1); /* 浅橙色背景 */ + background-color: #f59e0b; + background-image: linear-gradient(135deg, #f59e0b 0%, #d97706 100%); } .status-item.pending .count { - color: #f59e0b; + color: #fff; } /* 已通过状态样式 */ .status-item.approved { - border-top-color: #10b981; - background-color: rgba(16, 185, 129, 0.1); /* 浅绿色背景 */ + background-color: #10b981; + background-image: linear-gradient(135deg, #10b981 0%, #059669 100%); } .status-item.approved .count { - color: #10b981; + color: #fff; } /* 已拒绝状态样式 */ .status-item.rejected { - border-top-color: #ef4444; - background-color: rgba(239, 68, 68, 0.1); /* 浅红色背景 */ + background-color: #ef4444; + background-image: linear-gradient(135deg, #ef4444 0%, #dc2626 100%); } .status-item.rejected .count { - color: #ef4444; + color: #fff; } /* 状态文字样式 */ .status-text { - font-size: 14px; - color: #333; + font-size: 16px; + font-weight: 500; + color: #fff; + text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1); } /* 数字样式 */ .count { - font-size: 20px; - font-weight: bold; + font-size: 28px; + font-weight: 700; + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); + letter-spacing: 0.5px; } /* 激活态样式(可选,点击后高亮) */ .status-item.active { transform: scale(1.02); - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08); + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); } .content { diff --git a/src/views/task/task-progress/TaskProgress.vue b/src/views/task/task-progress/TaskProgress.vue index 0267e80..861daff 100644 --- a/src/views/task/task-progress/TaskProgress.vue +++ b/src/views/task/task-progress/TaskProgress.vue @@ -1,38 +1,711 @@ \ No newline at end of file diff --git a/src/views/task/task-publish/TaskPublish.vue b/src/views/task/task-publish/TaskPublish.vue index caf5def..f6a35fe 100644 --- a/src/views/task/task-publish/TaskPublish.vue +++ b/src/views/task/task-publish/TaskPublish.vue @@ -173,6 +173,7 @@ diff --git a/src/views/task/task-publish/components/AssigneeSelector.vue b/src/views/task/task-publish/components/AssigneeSelector.vue index b3dc176..808c512 100644 --- a/src/views/task/task-publish/components/AssigneeSelector.vue +++ b/src/views/task/task-publish/components/AssigneeSelector.vue @@ -56,7 +56,7 @@ const filteredUsers = ref([]); const filterUsersByDepartment = () => { if (!selectedDepartment.value) { filteredUsers.value = []; - assignees.value.leader = ''; + assignees.value.leader = -1; return; } @@ -66,7 +66,7 @@ const filterUsersByDepartment = () => { // 如果当前选择的负责人不在筛选后的列表中,则清空选择 if (assignees.value.leader && !filteredUsers.value.some(u => u.id === assignees.value.leader)) { - assignees.value.leader = ''; + assignees.value.leader = 0; } }; @@ -80,7 +80,7 @@ const departments = ref([ // 分配数据 const assignees = ref({ - leader: '' + leader: 0 }); // 暴露分配数据给父组件 diff --git a/src/views/task/task-publish/components/TaskForm.vue b/src/views/task/task-publish/components/TaskForm.vue index 024277a..0ede8cc 100644 --- a/src/views/task/task-publish/components/TaskForm.vue +++ b/src/views/task/task-publish/components/TaskForm.vue @@ -119,6 +119,34 @@ defineExpose({ diff --git a/src/views/tower-monitoring/deformation.vue b/src/views/tower-monitoring/deformation.vue new file mode 100644 index 0000000..1152c74 --- /dev/null +++ b/src/views/tower-monitoring/deformation.vue @@ -0,0 +1,665 @@ + + + + + + \ No newline at end of file diff --git a/src/views/tower-monitoring/vibration.vue b/src/views/tower-monitoring/vibration.vue new file mode 100644 index 0000000..07d9e49 --- /dev/null +++ b/src/views/tower-monitoring/vibration.vue @@ -0,0 +1,497 @@ + + + + + + diff --git a/src/views/tower-monitoring/whistle.vue b/src/views/tower-monitoring/whistle.vue new file mode 100644 index 0000000..07d9e49 --- /dev/null +++ b/src/views/tower-monitoring/whistle.vue @@ -0,0 +1,497 @@ + + + + + +