From bac2e99f0d190ccf0c3d9837d7dee80bafb88f19 Mon Sep 17 00:00:00 2001 From: "Mr.j" <2221464500@qq.com> Date: Wed, 13 Aug 2025 10:17:19 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E4=B8=AD=E5=BF=83=E6=B7=BB=E5=8A=A0=E8=AE=BE=E5=A4=87=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E5=BC=B9=E7=AA=97=E9=A1=B5=E9=9D=A2=E4=BB=A5=E5=8F=8A?= =?UTF-8?q?=E5=8F=A6=E5=A4=96=E6=90=AD=E5=BB=BA=E5=AE=8C=E6=88=90=E8=AE=BE?= =?UTF-8?q?=E5=A4=87=E7=9B=98=E5=BA=93=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/apis/equipment/index.ts | 22 +- src/router/route.ts | 10 + src/stores/modules/route.ts | 36 +- src/types/components.d.ts | 1 + .../components/EquipmentTypeModal.vue | 201 +++++++++++ .../device-management/index.vue | 34 ++ .../device-management/inventory.vue | 330 ++++++++++++++++++ 7 files changed, 622 insertions(+), 12 deletions(-) create mode 100644 src/views/system-resource/device-management/components/EquipmentTypeModal.vue create mode 100644 src/views/system-resource/device-management/inventory.vue 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/router/route.ts b/src/router/route.ts index 2f749c1..5a06e43 100644 --- a/src/router/route.ts +++ b/src/router/route.ts @@ -1282,6 +1282,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 7fa6b1b..81c6b77 100644 --- a/src/types/components.d.ts +++ b/src/types/components.d.ts @@ -7,6 +7,7 @@ export {} declare module 'vue' { export interface GlobalComponents { + CircularProgress: typeof import('./../components/CircularProgress/index.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] } diff --git a/src/views/system-resource/device-management/components/EquipmentTypeModal.vue b/src/views/system-resource/device-management/components/EquipmentTypeModal.vue new file mode 100644 index 0000000..a28ee9e --- /dev/null +++ b/src/views/system-resource/device-management/components/EquipmentTypeModal.vue @@ -0,0 +1,201 @@ + + + + + diff --git a/src/views/system-resource/device-management/index.vue b/src/views/system-resource/device-management/index.vue index 7e731a2..908d55a 100644 --- a/src/views/system-resource/device-management/index.vue +++ b/src/views/system-resource/device-management/index.vue @@ -19,6 +19,12 @@ @search="handleSearch" @reset="handleReset" /> + + + 添加设备类型 + @@ -250,9 +264,11 @@ import { IconPlus, IconRefresh, IconSearch, + IconTag, } from '@arco-design/web-vue/es/icon' import message from '@arco-design/web-vue/es/message' import DeviceModal from './components/DeviceModal.vue' +import EquipmentTypeModal from './components/EquipmentTypeModal.vue' import EquipmentSearch from './components/EquipmentSearch.vue' import router from '@/router' import { EquipmentAPI } from '@/apis' @@ -287,6 +303,11 @@ const modalVisible = ref(false) const currentEquipment = ref(null) const modalMode = ref<'add' | 'edit' | 'view'>('add') +// 设备类型弹窗控制 +const equipmentTypeModalVisible = ref(false) +const currentEquipmentType = ref(null) +const equipmentTypeModalMode = ref<'add' | 'edit'>('add') + // 表格列配置 const columns = [ { @@ -913,6 +934,19 @@ const handleModalSuccess = () => { loadData() } +// 新增设备类型 +const handleAddEquipmentType = () => { + equipmentTypeModalMode.value = 'add' + currentEquipmentType.value = null + equipmentTypeModalVisible.value = true +} + +// 设备类型弹窗成功回调 +const handleEquipmentTypeModalSuccess = () => { + equipmentTypeModalVisible.value = false + loadData() +} + // 监听表格数据变化 watch(tableData, (_newData) => { // 数据变化监听 diff --git a/src/views/system-resource/device-management/inventory.vue b/src/views/system-resource/device-management/inventory.vue new file mode 100644 index 0000000..bb08cfe --- /dev/null +++ b/src/views/system-resource/device-management/inventory.vue @@ -0,0 +1,330 @@ + + + + + From da6e158cc3037f447a09ab129a84c245641af860 Mon Sep 17 00:00:00 2001 From: "Mr.j" <2221464500@qq.com> Date: Wed, 13 Aug 2025 11:25:55 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E8=AE=BE=E5=A4=87=E9=87=87=E8=B4=AD?= =?UTF-8?q?=E6=A8=A1=E5=9D=97=E6=B7=BB=E5=8A=A0=E6=94=B6=E8=B4=A7=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=92=8C=E6=94=AF=E4=BB=98=E7=8A=B6=E6=80=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/PaymentDetailModal.vue | 249 ++++++++++++++++++ .../components/ReceiptDetailModal.vue | 211 +++++++++++++++ .../device-management/procurement/index.vue | 184 +++++++++++++ 3 files changed, 644 insertions(+) create mode 100644 src/views/system-resource/device-management/procurement/components/PaymentDetailModal.vue create mode 100644 src/views/system-resource/device-management/procurement/components/ReceiptDetailModal.vue diff --git a/src/views/system-resource/device-management/procurement/components/PaymentDetailModal.vue b/src/views/system-resource/device-management/procurement/components/PaymentDetailModal.vue new file mode 100644 index 0000000..879f86c --- /dev/null +++ b/src/views/system-resource/device-management/procurement/components/PaymentDetailModal.vue @@ -0,0 +1,249 @@ + + + + + diff --git a/src/views/system-resource/device-management/procurement/components/ReceiptDetailModal.vue b/src/views/system-resource/device-management/procurement/components/ReceiptDetailModal.vue new file mode 100644 index 0000000..2e8e7b7 --- /dev/null +++ b/src/views/system-resource/device-management/procurement/components/ReceiptDetailModal.vue @@ -0,0 +1,211 @@ + + + + + diff --git a/src/views/system-resource/device-management/procurement/index.vue b/src/views/system-resource/device-management/procurement/index.vue index b3f4431..5155506 100644 --- a/src/views/system-resource/device-management/procurement/index.vue +++ b/src/views/system-resource/device-management/procurement/index.vue @@ -178,6 +178,20 @@ - + + + + + + @@ -271,6 +331,8 @@ 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 { equipmentProcurementApi } from '@/apis/equipment/procurement' import { equipmentApprovalApi } from '@/apis/equipment/approval' import type { EquipmentListReq, EquipmentResp } from '@/apis/equipment/type' @@ -307,6 +369,14 @@ 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 selectedRowKeys = ref([]) const rowSelection = reactive({ @@ -418,6 +488,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 +611,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 +729,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 +980,60 @@ 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) => { + try { + // 暂时模拟API调用 + // await equipmentProcurementApi.receiveGoods(record.equipmentId) + message.success('收货成功') + // 模拟状态更新 + (record as any).receiptStatus = 'RECEIVED' + loadData(currentSearchParams.value) + } catch (error: any) { + console.error('收货失败:', error) + message.error(error?.message || '收货失败') + } +} + +// 查看收货详情 +const handleViewReceipt = (record: EquipmentResp) => { + currentReceiptData.value = { ...record } + receiptDetailModalVisible.value = true +} + +// 检查是否可以付款 +const canMakePayment = (record: EquipmentResp) => { + const paymentStatus = (record as any).paymentStatus + return paymentStatus === 'NOT_PAID' || paymentStatus === 'PARTIALLY_PAID' +} + +// 付款操作 +const handleMakePayment = async (record: EquipmentResp) => { + try { + // 暂时模拟API调用 + // await equipmentProcurementApi.makePayment(record.equipmentId) + message.success('付款成功') + // 模拟状态更新 + (record as any).paymentStatus = 'PAID' + loadData(currentSearchParams.value) + } catch (error: any) { + console.error('付款失败:', error) + message.error(error?.message || '付款失败') + } +} + +// 查看支付详情 +const handleViewPayment = (record: EquipmentResp) => { + currentPaymentData.value = { ...record } + paymentDetailModalVisible.value = true +} + // 获取审批状态颜色 const getApprovalStatusColor = (status: string) => { const colorMap: Record = { From aa40502f824d4f91cf62a4d171da03a206486772 Mon Sep 17 00:00:00 2001 From: "Mr.j" <2221464500@qq.com> Date: Wed, 13 Aug 2025 14:22:11 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E5=BC=B9=E7=AA=97=E5=92=8C=E5=88=B0=E8=B4=A7=E5=BC=B9=E7=AA=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.development | 4 +- src/apis/equipment/procurement.ts | 33 +- src/apis/equipment/type.ts | 226 +++++++- src/types/components.d.ts | 63 --- .../procurement/components/PaymentModal.vue | 505 ++++++++++++++++++ .../procurement/components/ReceiptModal.vue | 368 +++++++++++++ .../device-management/procurement/index.vue | 58 +- 7 files changed, 1148 insertions(+), 109 deletions(-) create mode 100644 src/views/system-resource/device-management/procurement/components/PaymentModal.vue create mode 100644 src/views/system-resource/device-management/procurement/components/ReceiptModal.vue 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/procurement.ts b/src/apis/equipment/procurement.ts index dd8b3f6..2aab76b 100644 --- a/src/apis/equipment/procurement.ts +++ b/src/apis/equipment/procurement.ts @@ -99,6 +99,34 @@ export const equipmentProcurementApi = { return http.get>(`/equipment/procurement/detail/${equipmentId}`) }, + /** + * 确认收货 + */ + receiveGoods: (equipmentId: string, data: ReceiptRequest) => { + 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 +145,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..a7fdf57 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,191 @@ 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 +} + +/** + * 收货详情响应 + */ +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/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/system-resource/device-management/procurement/components/PaymentModal.vue b/src/views/system-resource/device-management/procurement/components/PaymentModal.vue new file mode 100644 index 0000000..81b7d52 --- /dev/null +++ b/src/views/system-resource/device-management/procurement/components/PaymentModal.vue @@ -0,0 +1,505 @@ + + + + + diff --git a/src/views/system-resource/device-management/procurement/components/ReceiptModal.vue b/src/views/system-resource/device-management/procurement/components/ReceiptModal.vue new file mode 100644 index 0000000..1d8a437 --- /dev/null +++ b/src/views/system-resource/device-management/procurement/components/ReceiptModal.vue @@ -0,0 +1,368 @@ + + + + + diff --git a/src/views/system-resource/device-management/procurement/index.vue b/src/views/system-resource/device-management/procurement/index.vue index 5155506..91f57f1 100644 --- a/src/views/system-resource/device-management/procurement/index.vue +++ b/src/views/system-resource/device-management/procurement/index.vue @@ -312,6 +312,20 @@ v-model:visible="paymentDetailModalVisible" :payment-data="currentPaymentData" /> + + + + + + @@ -333,6 +347,8 @@ 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' @@ -377,6 +393,10 @@ 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({ @@ -988,17 +1008,8 @@ const canReceiveGoods = (record: EquipmentResp) => { // 收货操作 const handleReceiveGoods = async (record: EquipmentResp) => { - try { - // 暂时模拟API调用 - // await equipmentProcurementApi.receiveGoods(record.equipmentId) - message.success('收货成功') - // 模拟状态更新 - (record as any).receiptStatus = 'RECEIVED' - loadData(currentSearchParams.value) - } catch (error: any) { - console.error('收货失败:', error) - message.error(error?.message || '收货失败') - } + currentReceiptData.value = { ...record } + receiptModalVisible.value = true } // 查看收货详情 @@ -1007,6 +1018,12 @@ const handleViewReceipt = (record: EquipmentResp) => { receiptDetailModalVisible.value = true } +// 收货成功回调 +const handleReceiptSuccess = () => { + receiptModalVisible.value = false + loadData(currentSearchParams.value) +} + // 检查是否可以付款 const canMakePayment = (record: EquipmentResp) => { const paymentStatus = (record as any).paymentStatus @@ -1015,17 +1032,8 @@ const canMakePayment = (record: EquipmentResp) => { // 付款操作 const handleMakePayment = async (record: EquipmentResp) => { - try { - // 暂时模拟API调用 - // await equipmentProcurementApi.makePayment(record.equipmentId) - message.success('付款成功') - // 模拟状态更新 - (record as any).paymentStatus = 'PAID' - loadData(currentSearchParams.value) - } catch (error: any) { - console.error('付款失败:', error) - message.error(error?.message || '付款失败') - } + currentPaymentData.value = { ...record } + paymentModalVisible.value = true } // 查看支付详情 @@ -1034,6 +1042,12 @@ const handleViewPayment = (record: EquipmentResp) => { paymentDetailModalVisible.value = true } +// 支付成功回调 +const handlePaymentSuccess = () => { + paymentModalVisible.value = false + loadData(currentSearchParams.value) +} + // 获取审批状态颜色 const getApprovalStatusColor = (status: string) => { const colorMap: Record = {