Merge branch 'devlopment' of http://pms.dtyx.net:3000/wuxueyu/Industrial-image-management-system---web into devlopment
This commit is contained in:
commit
3675669f76
|
@ -4,8 +4,8 @@ VITE_API_PREFIX = '/dev-api'
|
||||||
|
|
||||||
# 接口地址
|
# 接口地址
|
||||||
# VITE_API_BASE_URL = 'http://pms.dtyx.net:9158/'
|
# VITE_API_BASE_URL = 'http://pms.dtyx.net:9158/'
|
||||||
# VITE_API_BASE_URL = 'http://localhost: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.163:8888/'
|
||||||
# VITE_API_BASE_URL = 'http://10.18.34.213:8888/'
|
# VITE_API_BASE_URL = 'http://10.18.34.213:8888/'
|
||||||
|
|
||||||
# 接口地址 (WebSocket)
|
# 接口地址 (WebSocket)
|
||||||
|
|
|
@ -49,4 +49,24 @@ export function returnEquipment(equipmentId: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出设备采购 API
|
// 导出设备采购 API
|
||||||
export * from './procurement'
|
export * from './procurement'
|
||||||
|
|
||||||
|
// 设备盘库相关 API
|
||||||
|
/** @desc 分页查询设备盘库记录 */
|
||||||
|
export function pageEquipmentInventory(query: T.EquipmentPageQuery) {
|
||||||
|
return http.get<T.EquipmentResp[]>(`${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 }
|
||||||
|
})
|
||||||
|
}
|
|
@ -99,6 +99,34 @@ export const equipmentProcurementApi = {
|
||||||
return http.get<ApiRes<EquipmentResp>>(`/equipment/procurement/detail/${equipmentId}`)
|
return http.get<ApiRes<EquipmentResp>>(`/equipment/procurement/detail/${equipmentId}`)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确认收货
|
||||||
|
*/
|
||||||
|
receiveGoods: (equipmentId: string, data: ReceiptRequest) => {
|
||||||
|
return http.post<ApiRes<null>>(`/equipment/procurement/receipt/${equipmentId}`, data)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取收货详情
|
||||||
|
*/
|
||||||
|
getReceiptDetail: (equipmentId: string) => {
|
||||||
|
return http.get<ApiRes<ReceiptDetail>>(`/equipment/procurement/receipt/${equipmentId}`)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行付款
|
||||||
|
*/
|
||||||
|
makePayment: (equipmentId: string, data: PaymentRequest) => {
|
||||||
|
return http.post<ApiRes<null>>(`/equipment/procurement/payment/${equipmentId}`, data)
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取支付详情
|
||||||
|
*/
|
||||||
|
getPaymentDetail: (equipmentId: string) => {
|
||||||
|
return http.get<ApiRes<PaymentDetail>>(`/equipment/procurement/payment/${equipmentId}`)
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取采购统计信息
|
* 获取采购统计信息
|
||||||
*/
|
*/
|
||||||
|
@ -117,9 +145,6 @@ export const equipmentProcurementApi = {
|
||||||
* 导出设备采购记录
|
* 导出设备采购记录
|
||||||
*/
|
*/
|
||||||
export: (params: EquipmentListReq) => {
|
export: (params: EquipmentListReq) => {
|
||||||
return http.get<Blob>('/equipment/procurement/export', {
|
return http.get('/equipment/procurement/export', params, { responseType: 'blob' })
|
||||||
params,
|
|
||||||
responseType: 'blob'
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -101,28 +101,28 @@ export interface EquipmentResp {
|
||||||
/** 资产编号 */
|
/** 资产编号 */
|
||||||
assetCode?: string
|
assetCode?: string
|
||||||
/** 设备名称 */
|
/** 设备名称 */
|
||||||
equipmentName: string
|
equipmentName?: string
|
||||||
/** 设备类型 */
|
/** 设备类型 */
|
||||||
equipmentType: string
|
equipmentType?: string
|
||||||
/** 设备类型描述 */
|
/** 设备类型标签 */
|
||||||
equipmentTypeLabel?: string
|
equipmentTypeLabel?: string
|
||||||
/** 设备型号 */
|
/** 设备型号 */
|
||||||
equipmentModel: string
|
equipmentModel?: string
|
||||||
/** 设备SN */
|
/** 设备序列号 */
|
||||||
equipmentSn: string
|
equipmentSn?: string
|
||||||
/** 品牌 */
|
/** 品牌 */
|
||||||
brand?: string
|
brand?: string
|
||||||
/** 配置规格/参数 */
|
/** 配置规格/参数 */
|
||||||
specification?: string
|
specification?: string
|
||||||
/** 设备状态 */
|
/** 设备状态 */
|
||||||
equipmentStatus: string
|
equipmentStatus?: string
|
||||||
/** 设备状态描述 */
|
/** 设备状态标签 */
|
||||||
equipmentStatusLabel?: string
|
equipmentStatusLabel?: string
|
||||||
/** 使用状态 */
|
/** 使用状态 */
|
||||||
useStatus: string
|
useStatus?: string
|
||||||
/** 位置状态 */
|
/** 位置状态 */
|
||||||
locationStatus?: string
|
locationStatus?: string
|
||||||
/** 位置状态描述 */
|
/** 位置状态标签 */
|
||||||
locationStatusLabel?: string
|
locationStatusLabel?: string
|
||||||
/** 设备当前物理位置 */
|
/** 设备当前物理位置 */
|
||||||
physicalLocation?: string
|
physicalLocation?: string
|
||||||
|
@ -130,7 +130,7 @@ export interface EquipmentResp {
|
||||||
responsiblePerson?: string
|
responsiblePerson?: string
|
||||||
/** 健康状态 */
|
/** 健康状态 */
|
||||||
healthStatus?: string
|
healthStatus?: string
|
||||||
/** 健康状态描述 */
|
/** 健康状态标签 */
|
||||||
healthStatusLabel?: string
|
healthStatusLabel?: string
|
||||||
/** 采购时间 */
|
/** 采购时间 */
|
||||||
purchaseTime?: string
|
purchaseTime?: string
|
||||||
|
@ -138,13 +138,13 @@ export interface EquipmentResp {
|
||||||
inStockTime?: string
|
inStockTime?: string
|
||||||
/** 启用时间 */
|
/** 启用时间 */
|
||||||
activationTime?: string
|
activationTime?: string
|
||||||
/** 预计报废时间 */
|
/** 预期报废时间 */
|
||||||
expectedScrapTime?: string
|
expectedScrapTime?: string
|
||||||
/** 实际报废时间 */
|
/** 实际报废时间 */
|
||||||
actualScrapTime?: string
|
actualScrapTime?: string
|
||||||
/** 状态变更时间 */
|
/** 状态变更时间 */
|
||||||
statusChangeTime?: string
|
statusChangeTime?: string
|
||||||
/** 采购订单 */
|
/** 采购订单号 */
|
||||||
purchaseOrder?: string
|
purchaseOrder?: string
|
||||||
/** 供应商名称 */
|
/** 供应商名称 */
|
||||||
supplierName?: string
|
supplierName?: string
|
||||||
|
@ -158,9 +158,9 @@ export interface EquipmentResp {
|
||||||
depreciationYears?: number
|
depreciationYears?: number
|
||||||
/** 残值 */
|
/** 残值 */
|
||||||
salvageValue?: number
|
salvageValue?: number
|
||||||
/** 保修截止日期 */
|
/** 保修到期日期 */
|
||||||
warrantyExpireDate?: string
|
warrantyExpireDate?: string
|
||||||
/** 上次维护日期 */
|
/** 最后维护日期 */
|
||||||
lastMaintenanceDate?: string
|
lastMaintenanceDate?: string
|
||||||
/** 下次维护日期 */
|
/** 下次维护日期 */
|
||||||
nextMaintenanceDate?: string
|
nextMaintenanceDate?: string
|
||||||
|
@ -176,7 +176,7 @@ export interface EquipmentResp {
|
||||||
projectName?: string
|
projectName?: string
|
||||||
/** 使用人ID */
|
/** 使用人ID */
|
||||||
userId?: string
|
userId?: string
|
||||||
/** 使用人 */
|
/** 使用人姓名 */
|
||||||
name?: string
|
name?: string
|
||||||
/** 创建时间 */
|
/** 创建时间 */
|
||||||
createTime?: string
|
createTime?: string
|
||||||
|
@ -194,12 +194,14 @@ export interface EquipmentResp {
|
||||||
inventoryBasis?: string
|
inventoryBasis?: string
|
||||||
/** 动态记录 */
|
/** 动态记录 */
|
||||||
dynamicRecord?: string
|
dynamicRecord?: string
|
||||||
|
|
||||||
/** 采购状态 */
|
/** 采购状态 */
|
||||||
procurementStatus?: string
|
procurementStatus?: string
|
||||||
|
|
||||||
/** 审批状态 */
|
/** 审批状态 */
|
||||||
approvalStatus?: string
|
approvalStatus?: string
|
||||||
|
/** 收货状态 */
|
||||||
|
receiptStatus?: string
|
||||||
|
/** 支付状态 */
|
||||||
|
paymentStatus?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -406,3 +408,191 @@ export interface EquipmentApprovalResp {
|
||||||
/** 更新时间 */
|
/** 更新时间 */
|
||||||
updateTime: string
|
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
|
||||||
|
}
|
||||||
|
|
|
@ -1356,6 +1356,16 @@ export const systemRoutes: RouteRecordRaw[] = [
|
||||||
hidden: false,
|
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',
|
path: '/system-resource/device-management/online',
|
||||||
name: 'SystemResourceDeviceOnline',
|
name: 'SystemResourceDeviceOnline',
|
||||||
|
|
|
@ -226,6 +226,20 @@ const storeSetup = () => {
|
||||||
{
|
{
|
||||||
id: 2013,
|
id: 2013,
|
||||||
parentId: 2010,
|
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: '审批台',
|
title: '审批台',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/approval',
|
path: '/asset-management/device-management/approval',
|
||||||
|
@ -235,10 +249,10 @@ const storeSetup = () => {
|
||||||
isExternal: false,
|
isExternal: false,
|
||||||
isCache: false,
|
isCache: false,
|
||||||
isHidden: false,
|
isHidden: false,
|
||||||
sort: 3,
|
sort: 4,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2014,
|
id: 2015,
|
||||||
parentId: 2010,
|
parentId: 2010,
|
||||||
title: '在线管理',
|
title: '在线管理',
|
||||||
type: 1,
|
type: 1,
|
||||||
|
@ -250,11 +264,11 @@ const storeSetup = () => {
|
||||||
isExternal: false,
|
isExternal: false,
|
||||||
isCache: false,
|
isCache: false,
|
||||||
isHidden: false,
|
isHidden: false,
|
||||||
sort: 4,
|
sort: 5,
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
id: 20141,
|
id: 20151,
|
||||||
parentId: 2014,
|
parentId: 2015,
|
||||||
title: '无人机',
|
title: '无人机',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/online/drone',
|
path: '/asset-management/device-management/online/drone',
|
||||||
|
@ -267,8 +281,8 @@ const storeSetup = () => {
|
||||||
sort: 1,
|
sort: 1,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 20142,
|
id: 20152,
|
||||||
parentId: 2014,
|
parentId: 2015,
|
||||||
title: '机巢',
|
title: '机巢',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/online/nest',
|
path: '/asset-management/device-management/online/nest',
|
||||||
|
@ -281,8 +295,8 @@ const storeSetup = () => {
|
||||||
sort: 2,
|
sort: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 20143,
|
id: 20153,
|
||||||
parentId: 2014,
|
parentId: 2015,
|
||||||
title: '其他智能终端',
|
title: '其他智能终端',
|
||||||
type: 2,
|
type: 2,
|
||||||
path: '/asset-management/device-management/online/smart-terminal',
|
path: '/asset-management/device-management/online/smart-terminal',
|
||||||
|
@ -297,7 +311,7 @@ const storeSetup = () => {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 2015,
|
id: 2016,
|
||||||
parentId: 2010,
|
parentId: 2010,
|
||||||
title: '设备详情',
|
title: '设备详情',
|
||||||
type: 2,
|
type: 2,
|
||||||
|
@ -308,7 +322,7 @@ const storeSetup = () => {
|
||||||
isExternal: false,
|
isExternal: false,
|
||||||
isCache: false,
|
isCache: false,
|
||||||
isHidden: true,
|
isHidden: true,
|
||||||
sort: 5,
|
sort: 6,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -7,70 +7,7 @@ export {}
|
||||||
|
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
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']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
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']
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,201 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
title="设备类型管理"
|
||||||
|
width="600px"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<a-form-item label="类型名称" field="typeName" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.typeName"
|
||||||
|
placeholder="请输入设备类型名称"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="50"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="类型编码" field="typeCode" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.typeCode"
|
||||||
|
placeholder="请输入设备类型编码"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="20"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="类型描述" field="description">
|
||||||
|
<a-textarea
|
||||||
|
v-model="formData.description"
|
||||||
|
placeholder="请输入设备类型描述"
|
||||||
|
:rows="4"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="200"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="排序" field="sort">
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.sort"
|
||||||
|
placeholder="请输入排序值"
|
||||||
|
:min="0"
|
||||||
|
:max="999"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="状态" field="status">
|
||||||
|
<a-select
|
||||||
|
v-model="formData.status"
|
||||||
|
placeholder="请选择状态"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="1">启用</a-option>
|
||||||
|
<a-option value="0">禁用</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, watch } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import type { FormInstance } from '@arco-design/web-vue'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
typeData?: any
|
||||||
|
mode: 'add' | 'edit'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface FormDataType {
|
||||||
|
typeName: string
|
||||||
|
typeCode: string
|
||||||
|
description: string
|
||||||
|
sort: number
|
||||||
|
status: string
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
visible: false,
|
||||||
|
typeData: null,
|
||||||
|
mode: 'add',
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:visible': [value: boolean]
|
||||||
|
'success': []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive<FormDataType>({
|
||||||
|
typeName: '',
|
||||||
|
typeCode: '',
|
||||||
|
description: '',
|
||||||
|
sort: 0,
|
||||||
|
status: '1'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
typeName: [
|
||||||
|
{ required: true, message: '请输入设备类型名称' },
|
||||||
|
{ min: 2, max: 50, message: '类型名称长度应在2-50个字符之间' }
|
||||||
|
],
|
||||||
|
typeCode: [
|
||||||
|
{ required: true, message: '请输入设备类型编码' },
|
||||||
|
{ min: 2, max: 20, message: '类型编码长度应在2-20个字符之间' },
|
||||||
|
{ pattern: /^[A-Z_]+$/, message: '类型编码只能包含大写字母和下划线' }
|
||||||
|
],
|
||||||
|
description: [
|
||||||
|
{ max: 200, message: '类型描述不能超过200个字符' }
|
||||||
|
],
|
||||||
|
sort: [
|
||||||
|
{ type: 'number', min: 0, max: 999, message: '排序值应在0-999之间' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听数据变化
|
||||||
|
watch(() => props.typeData, (newData) => {
|
||||||
|
if (newData) {
|
||||||
|
Object.assign(formData, {
|
||||||
|
typeName: newData.typeName || '',
|
||||||
|
typeCode: newData.typeCode || '',
|
||||||
|
description: newData.description || '',
|
||||||
|
sort: newData.sort || 0,
|
||||||
|
status: newData.status || '1'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
// 监听弹窗显示状态
|
||||||
|
watch(() => props.visible, (visible) => {
|
||||||
|
if (visible && props.mode === 'add') {
|
||||||
|
// 新增模式时重置表单
|
||||||
|
Object.assign(formData, {
|
||||||
|
typeName: '',
|
||||||
|
typeCode: '',
|
||||||
|
description: '',
|
||||||
|
sort: 0,
|
||||||
|
status: '1'
|
||||||
|
})
|
||||||
|
formRef.value?.clearValidate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
// 这里应该调用API保存数据
|
||||||
|
// 暂时模拟保存成功
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||||
|
|
||||||
|
Message.success(props.mode === 'add' ? '设备类型添加成功' : '设备类型更新成功')
|
||||||
|
emit('success')
|
||||||
|
emit('update:visible', false)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存失败:', error)
|
||||||
|
Message.error('保存失败,请检查表单信息')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-input,
|
||||||
|
.arco-textarea,
|
||||||
|
.arco-select,
|
||||||
|
.arco-input-number {
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -19,6 +19,12 @@
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@reset="handleReset"
|
@reset="handleReset"
|
||||||
/>
|
/>
|
||||||
|
<a-button type="outline" @click="handleAddEquipmentType" size="large">
|
||||||
|
<template #icon>
|
||||||
|
<IconTag />
|
||||||
|
</template>
|
||||||
|
添加设备类型
|
||||||
|
</a-button>
|
||||||
<a-button type="primary" @click="handleAdd" size="large">
|
<a-button type="primary" @click="handleAdd" size="large">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<IconPlus />
|
<IconPlus />
|
||||||
|
@ -235,6 +241,14 @@
|
||||||
:mode="modalMode"
|
:mode="modalMode"
|
||||||
@success="handleModalSuccess"
|
@success="handleModalSuccess"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 设备类型管理弹窗 -->
|
||||||
|
<EquipmentTypeModal
|
||||||
|
v-model:visible="equipmentTypeModalVisible"
|
||||||
|
:type-data="currentEquipmentType"
|
||||||
|
:mode="equipmentTypeModalMode"
|
||||||
|
@success="handleEquipmentTypeModalSuccess"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -250,9 +264,11 @@ import {
|
||||||
IconPlus,
|
IconPlus,
|
||||||
IconRefresh,
|
IconRefresh,
|
||||||
IconSearch,
|
IconSearch,
|
||||||
|
IconTag,
|
||||||
} from '@arco-design/web-vue/es/icon'
|
} from '@arco-design/web-vue/es/icon'
|
||||||
import message from '@arco-design/web-vue/es/message'
|
import message from '@arco-design/web-vue/es/message'
|
||||||
import DeviceModal from './components/DeviceModal.vue'
|
import DeviceModal from './components/DeviceModal.vue'
|
||||||
|
import EquipmentTypeModal from './components/EquipmentTypeModal.vue'
|
||||||
import EquipmentSearch from './components/EquipmentSearch.vue'
|
import EquipmentSearch from './components/EquipmentSearch.vue'
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { EquipmentAPI } from '@/apis'
|
import { EquipmentAPI } from '@/apis'
|
||||||
|
@ -287,6 +303,11 @@ const modalVisible = ref(false)
|
||||||
const currentEquipment = ref<EquipmentResp | null>(null)
|
const currentEquipment = ref<EquipmentResp | null>(null)
|
||||||
const modalMode = ref<'add' | 'edit' | 'view'>('add')
|
const modalMode = ref<'add' | 'edit' | 'view'>('add')
|
||||||
|
|
||||||
|
// 设备类型弹窗控制
|
||||||
|
const equipmentTypeModalVisible = ref(false)
|
||||||
|
const currentEquipmentType = ref<any>(null)
|
||||||
|
const equipmentTypeModalMode = ref<'add' | 'edit'>('add')
|
||||||
|
|
||||||
// 表格列配置
|
// 表格列配置
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
@ -913,6 +934,19 @@ const handleModalSuccess = () => {
|
||||||
loadData()
|
loadData()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 新增设备类型
|
||||||
|
const handleAddEquipmentType = () => {
|
||||||
|
equipmentTypeModalMode.value = 'add'
|
||||||
|
currentEquipmentType.value = null
|
||||||
|
equipmentTypeModalVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设备类型弹窗成功回调
|
||||||
|
const handleEquipmentTypeModalSuccess = () => {
|
||||||
|
equipmentTypeModalVisible.value = false
|
||||||
|
loadData()
|
||||||
|
}
|
||||||
|
|
||||||
// 监听表格数据变化
|
// 监听表格数据变化
|
||||||
watch(tableData, (_newData) => {
|
watch(tableData, (_newData) => {
|
||||||
// 数据变化监听
|
// 数据变化监听
|
||||||
|
|
|
@ -0,0 +1,330 @@
|
||||||
|
<template>
|
||||||
|
<div class="equipment-inventory">
|
||||||
|
<a-card title="设备盘库管理" :bordered="false">
|
||||||
|
<template #extra>
|
||||||
|
<a-button type="primary" @click="handleBatchInventory">
|
||||||
|
<template #icon>
|
||||||
|
<IconPlus />
|
||||||
|
</template>
|
||||||
|
批量盘库
|
||||||
|
</a-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 搜索区域 -->
|
||||||
|
<div class="search-container">
|
||||||
|
<a-form layout="inline" :model="searchForm" class="search-form">
|
||||||
|
<a-form-item label="设备名称">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.equipmentName"
|
||||||
|
placeholder="请输入设备名称"
|
||||||
|
allow-clear
|
||||||
|
style="width: 200px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="资产编号">
|
||||||
|
<a-input
|
||||||
|
v-model="searchForm.assetCode"
|
||||||
|
placeholder="请输入资产编号"
|
||||||
|
allow-clear
|
||||||
|
style="width: 200px"
|
||||||
|
@input="debouncedSearch"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item label="设备类型">
|
||||||
|
<a-select
|
||||||
|
v-model="searchForm.equipmentType"
|
||||||
|
placeholder="请选择类型"
|
||||||
|
allow-clear
|
||||||
|
style="width: 150px"
|
||||||
|
@change="debouncedSearch"
|
||||||
|
>
|
||||||
|
<a-option value="">全部</a-option>
|
||||||
|
<a-option value="COMPUTER">计算机设备</a-option>
|
||||||
|
<a-option value="NETWORK">网络设备</a-option>
|
||||||
|
<a-option value="STORAGE">存储设备</a-option>
|
||||||
|
<a-option value="SECURITY">安防设备</a-option>
|
||||||
|
<a-option value="OTHER">其他设备</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
|
||||||
|
<a-form-item>
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" @click="search">
|
||||||
|
<template #icon><IconSearch /></template>
|
||||||
|
搜索
|
||||||
|
</a-button>
|
||||||
|
<a-button @click="reset">
|
||||||
|
<template #icon><IconRefresh /></template>
|
||||||
|
重置
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</a-form-item>
|
||||||
|
</a-form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a-table
|
||||||
|
:columns="columns"
|
||||||
|
:data="tableData"
|
||||||
|
:loading="loading"
|
||||||
|
:pagination="pagination"
|
||||||
|
:row-selection="rowSelection"
|
||||||
|
@page-change="handlePageChange"
|
||||||
|
@page-size-change="handlePageSizeChange"
|
||||||
|
>
|
||||||
|
<template #toolbar-left>
|
||||||
|
<span class="search-result-info">
|
||||||
|
共找到 <strong>{{ pagination.total }}</strong> 条记录
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #equipmentStatus="{ record }">
|
||||||
|
<a-tag :color="getStatusColor(record.equipmentStatus)">
|
||||||
|
{{ getStatusText(record.equipmentStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #operations="{ record }">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="text" size="small" @click="handleView(record)">
|
||||||
|
查看详情
|
||||||
|
</a-button>
|
||||||
|
<a-button type="text" size="small" @click="handleInventory(record)">
|
||||||
|
执行盘库
|
||||||
|
</a-button>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
</a-table>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, onMounted, computed } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import { IconSearch, IconRefresh, IconPlus } from '@arco-design/web-vue/es/icon'
|
||||||
|
import { pageEquipmentInventory } from '@/apis/equipment'
|
||||||
|
import type { EquipmentResp } from '@/types/equipment.d'
|
||||||
|
|
||||||
|
// 防抖函数
|
||||||
|
const debounce = (func: Function, delay: number) => {
|
||||||
|
let timeoutId: NodeJS.Timeout
|
||||||
|
return (...args: any[]) => {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
timeoutId = setTimeout(() => func.apply(null, args), delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineOptions({ name: 'EquipmentInventory' })
|
||||||
|
|
||||||
|
// 表格列定义
|
||||||
|
const columns = [
|
||||||
|
{ title: '设备名称', dataIndex: 'equipmentName', key: 'equipmentName', width: 180 },
|
||||||
|
{ title: '资产编号', dataIndex: 'assetCode', key: 'assetCode', width: 150 },
|
||||||
|
{ title: '设备类型', dataIndex: 'equipmentType', key: 'equipmentType', width: 120 },
|
||||||
|
{ title: '品牌', dataIndex: 'brand', key: 'brand', width: 100 },
|
||||||
|
{ title: '型号', dataIndex: 'equipmentModel', key: 'equipmentModel', width: 120 },
|
||||||
|
{ title: '设备状态', dataIndex: 'equipmentStatus', key: 'equipmentStatus', slotName: 'equipmentStatus', width: 100 },
|
||||||
|
{ title: '负责人', dataIndex: 'responsiblePerson', key: 'responsiblePerson', width: 100 },
|
||||||
|
{ title: '创建时间', dataIndex: 'createTime', key: 'createTime', width: 180 },
|
||||||
|
{ title: '操作', key: 'operations', slotName: 'operations', width: 200 }
|
||||||
|
]
|
||||||
|
|
||||||
|
// 搜索表单
|
||||||
|
const searchForm = reactive({
|
||||||
|
equipmentName: '',
|
||||||
|
assetCode: '',
|
||||||
|
equipmentType: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表格数据
|
||||||
|
const tableData = ref<EquipmentResp[]>([])
|
||||||
|
const loading = ref(false)
|
||||||
|
const pagination = reactive({
|
||||||
|
current: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0,
|
||||||
|
showTotal: true,
|
||||||
|
showJumper: true,
|
||||||
|
showPageSize: true
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表格选择
|
||||||
|
const selectedRowKeys = ref<string[]>([])
|
||||||
|
const rowSelection = computed(() => ({
|
||||||
|
selectedRowKeys: selectedRowKeys.value,
|
||||||
|
onChange: (keys: string[]) => {
|
||||||
|
selectedRowKeys.value = keys
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
|
||||||
|
// 获取状态颜色
|
||||||
|
const getStatusColor = (status: string) => {
|
||||||
|
const colors: Record<string, string> = {
|
||||||
|
'IDLE': 'blue',
|
||||||
|
'IN_USE': 'green',
|
||||||
|
'MAINTENANCE': 'orange',
|
||||||
|
'REPAIR': 'red',
|
||||||
|
'SCRAPPED': 'gray'
|
||||||
|
}
|
||||||
|
return colors[status] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取状态文本
|
||||||
|
const getStatusText = (status: string) => {
|
||||||
|
const texts: Record<string, string> = {
|
||||||
|
'IDLE': '空闲中',
|
||||||
|
'IN_USE': '使用中',
|
||||||
|
'MAINTENANCE': '保养中',
|
||||||
|
'REPAIR': '维修中',
|
||||||
|
'SCRAPPED': '已报废'
|
||||||
|
}
|
||||||
|
return texts[status] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取表格数据
|
||||||
|
const getTableData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const response = await pageEquipmentInventory({
|
||||||
|
pageNum: pagination.current,
|
||||||
|
pageSize: pagination.pageSize,
|
||||||
|
equipmentName: searchForm.equipmentName || undefined,
|
||||||
|
assetCode: searchForm.assetCode || undefined,
|
||||||
|
equipmentType: searchForm.equipmentType || undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
// 检查响应数据结构
|
||||||
|
if (response.data && Array.isArray(response.data)) {
|
||||||
|
// 如果直接返回数组,说明没有分页信息
|
||||||
|
tableData.value = response.data
|
||||||
|
pagination.total = response.data.length
|
||||||
|
} else if (response.data && typeof response.data === 'object' && 'records' in response.data) {
|
||||||
|
// 如果有分页信息
|
||||||
|
const pageData = response.data as any
|
||||||
|
tableData.value = pageData.records || []
|
||||||
|
pagination.total = pageData.total || pageData.records?.length || 0
|
||||||
|
pagination.current = pageData.current || 1
|
||||||
|
} else {
|
||||||
|
tableData.value = []
|
||||||
|
pagination.total = 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Message.error('获取数据失败')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取设备盘库列表失败:', error)
|
||||||
|
Message.error('获取数据失败')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防抖搜索函数
|
||||||
|
const debouncedSearch = debounce(() => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}, 300)
|
||||||
|
|
||||||
|
// 搜索
|
||||||
|
const search = () => {
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 重置
|
||||||
|
const reset = () => {
|
||||||
|
Object.assign(searchForm, {
|
||||||
|
equipmentName: '',
|
||||||
|
assetCode: '',
|
||||||
|
equipmentType: ''
|
||||||
|
})
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情
|
||||||
|
const handleView = (record: EquipmentResp) => {
|
||||||
|
console.log('查看设备详情:', record)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 执行盘库
|
||||||
|
const handleInventory = (record: EquipmentResp) => {
|
||||||
|
console.log('执行设备盘库:', record)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量盘库
|
||||||
|
const handleBatchInventory = () => {
|
||||||
|
if (selectedRowKeys.value.length === 0) {
|
||||||
|
Message.warning('请先选择要盘库的设备')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
console.log('批量盘库设备:', selectedRowKeys.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 分页事件
|
||||||
|
const handlePageChange = (page: number) => {
|
||||||
|
pagination.current = page
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePageSizeChange = (pageSize: number) => {
|
||||||
|
pagination.pageSize = pageSize
|
||||||
|
pagination.current = 1
|
||||||
|
getTableData()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getTableData()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.equipment-inventory {
|
||||||
|
.arco-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-container {
|
||||||
|
padding: 16px;
|
||||||
|
background: var(--color-bg-2);
|
||||||
|
border-radius: 6px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.search-form {
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 0;
|
||||||
|
margin-right: 16px;
|
||||||
|
|
||||||
|
.arco-form-item-label {
|
||||||
|
font-weight: 500;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-input,
|
||||||
|
.arco-select {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-btn {
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-result-info {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
font-size: 14px;
|
||||||
|
|
||||||
|
strong {
|
||||||
|
color: var(--color-text-1);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,249 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
title="支付详情"
|
||||||
|
width="800px"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
:footer="false"
|
||||||
|
>
|
||||||
|
<div class="payment-detail">
|
||||||
|
<!-- 基本信息 -->
|
||||||
|
<a-card title="基本信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="设备名称">
|
||||||
|
{{ paymentData?.equipmentName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备类型">
|
||||||
|
{{ paymentData?.equipmentType || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备型号">
|
||||||
|
{{ paymentData?.equipmentModel || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="品牌">
|
||||||
|
{{ paymentData?.brand || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="供应商">
|
||||||
|
{{ paymentData?.supplierName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购订单">
|
||||||
|
{{ paymentData?.purchaseOrder || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 采购信息 -->
|
||||||
|
<a-card title="采购信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="采购价格">
|
||||||
|
¥{{ paymentData?.purchasePrice || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购数量">
|
||||||
|
{{ paymentData?.quantity || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="总金额">
|
||||||
|
¥{{ paymentData?.totalPrice || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购日期">
|
||||||
|
{{ paymentData?.purchaseTime || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 支付信息 -->
|
||||||
|
<a-card title="支付信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="支付状态">
|
||||||
|
<a-tag :color="getPaymentStatusColor(paymentData?.paymentStatus)">
|
||||||
|
{{ getPaymentStatusText(paymentData?.paymentStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="支付方式">
|
||||||
|
{{ paymentData?.paymentMethod || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="支付金额">
|
||||||
|
¥{{ paymentData?.paymentAmount || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="支付时间">
|
||||||
|
{{ paymentData?.paymentTime || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="支付人">
|
||||||
|
{{ paymentData?.paymentPerson || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="支付备注">
|
||||||
|
{{ paymentData?.paymentRemark || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 发票信息 -->
|
||||||
|
<a-card title="发票信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="发票状态">
|
||||||
|
<a-tag :color="getInvoiceStatusColor(paymentData?.invoiceStatus)">
|
||||||
|
{{ getInvoiceStatusText(paymentData?.invoiceStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="发票类型">
|
||||||
|
{{ paymentData?.invoiceType || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="发票号码">
|
||||||
|
{{ paymentData?.invoiceNumber || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="开票日期">
|
||||||
|
{{ paymentData?.invoiceDate || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="发票金额">
|
||||||
|
¥{{ paymentData?.invoiceAmount || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="税率">
|
||||||
|
{{ paymentData?.taxRate || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="税额">
|
||||||
|
¥{{ paymentData?.taxAmount || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="不含税金额">
|
||||||
|
¥{{ paymentData?.amountWithoutTax || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 合同信息 -->
|
||||||
|
<a-card title="合同信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="合同编号">
|
||||||
|
{{ paymentData?.contractNumber || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="合同状态">
|
||||||
|
<a-tag :color="getContractStatusColor(paymentData?.contractStatus)">
|
||||||
|
{{ getContractStatusText(paymentData?.contractStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="合同金额">
|
||||||
|
¥{{ paymentData?.contractAmount || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="签订日期">
|
||||||
|
{{ paymentData?.contractDate || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="付款条件">
|
||||||
|
{{ paymentData?.paymentTerms || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="付款期限">
|
||||||
|
{{ paymentData?.paymentDeadline || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import type { EquipmentResp } from '@/apis/equipment/type'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
paymentData?: EquipmentResp | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
visible: false,
|
||||||
|
paymentData: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:visible': [value: boolean]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 获取支付状态颜色
|
||||||
|
const getPaymentStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
NOT_PAID: 'gray',
|
||||||
|
PAID: 'green',
|
||||||
|
PARTIALLY_PAID: 'orange',
|
||||||
|
REJECTED: 'red',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取支付状态文本
|
||||||
|
const getPaymentStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
NOT_PAID: '未支付',
|
||||||
|
PAID: '已支付',
|
||||||
|
PARTIALLY_PAID: '部分支付',
|
||||||
|
REJECTED: '已拒付',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取发票状态颜色
|
||||||
|
const getInvoiceStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
NOT_ISSUED: 'gray',
|
||||||
|
ISSUED: 'green',
|
||||||
|
PENDING: 'orange',
|
||||||
|
REJECTED: 'red',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取发票状态文本
|
||||||
|
const getInvoiceStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
NOT_ISSUED: '未开票',
|
||||||
|
ISSUED: '已开票',
|
||||||
|
PENDING: '待开票',
|
||||||
|
REJECTED: '已拒开',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取合同状态颜色
|
||||||
|
const getContractStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
DRAFT: 'gray',
|
||||||
|
SIGNED: 'green',
|
||||||
|
EXECUTING: 'blue',
|
||||||
|
COMPLETED: 'purple',
|
||||||
|
TERMINATED: 'red',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取合同状态文本
|
||||||
|
const getContractStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
DRAFT: '草稿',
|
||||||
|
SIGNED: '已签订',
|
||||||
|
EXECUTING: '执行中',
|
||||||
|
COMPLETED: '已完成',
|
||||||
|
TERMINATED: '已终止',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.payment-detail {
|
||||||
|
.detail-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-descriptions-item-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-descriptions-item-value {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,505 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
title="设备付款"
|
||||||
|
width="900px"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<!-- 基本信息 -->
|
||||||
|
<a-card title="设备信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="设备名称">
|
||||||
|
{{ equipmentData?.equipmentName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备类型">
|
||||||
|
{{ equipmentData?.equipmentType || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备型号">
|
||||||
|
{{ equipmentData?.equipmentModel || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="品牌">
|
||||||
|
{{ equipmentData?.brand || '-' }}
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-descriptions-item label="供应商">
|
||||||
|
{{ equipmentData?.supplierName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购订单">
|
||||||
|
{{ equipmentData?.purchaseOrder || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购价格">
|
||||||
|
¥{{ equipmentData?.purchasePrice || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购数量">
|
||||||
|
{{ equipmentData?.quantity || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 支付信息 -->
|
||||||
|
<a-card title="支付信息" class="detail-card" :bordered="false">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="支付方式" field="paymentMethod" required>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.paymentMethod"
|
||||||
|
placeholder="请选择支付方式"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="银行转账">银行转账</a-option>
|
||||||
|
<a-option value="现金">现金</a-option>
|
||||||
|
<a-option value="支票">支票</a-option>
|
||||||
|
<a-option value="信用卡">信用卡</a-option>
|
||||||
|
<a-option value="其他">其他</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="支付金额" field="paymentAmount" required>
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.paymentAmount"
|
||||||
|
placeholder="请输入支付金额"
|
||||||
|
:min="0.01"
|
||||||
|
:max="999999.99"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="支付时间" field="paymentTime" required>
|
||||||
|
<a-date-picker
|
||||||
|
v-model="formData.paymentTime"
|
||||||
|
show-time
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
placeholder="请选择支付时间"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="支付人" field="paymentPerson" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.paymentPerson"
|
||||||
|
placeholder="请输入支付人姓名"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="50"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="24">
|
||||||
|
<a-form-item label="支付备注" field="paymentRemark">
|
||||||
|
<a-textarea
|
||||||
|
v-model="formData.paymentRemark"
|
||||||
|
placeholder="请输入支付备注"
|
||||||
|
:rows="3"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="200"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 发票信息 -->
|
||||||
|
<a-card title="发票信息" class="detail-card" :bordered="false">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="发票类型" field="invoiceType" required>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.invoiceType"
|
||||||
|
placeholder="请选择发票类型"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="增值税专用发票">增值税专用发票</a-option>
|
||||||
|
<a-option value="增值税普通发票">增值税普通发票</a-option>
|
||||||
|
<a-option value="电子发票">电子发票</a-option>
|
||||||
|
<a-option value="其他">其他</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="发票号码" field="invoiceNumber" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.invoiceNumber"
|
||||||
|
placeholder="请输入发票号码"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="50"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="开票日期" field="invoiceDate" required>
|
||||||
|
<a-date-picker
|
||||||
|
v-model="formData.invoiceDate"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择开票日期"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="发票金额" field="invoiceAmount" required>
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.invoiceAmount"
|
||||||
|
placeholder="请输入发票金额"
|
||||||
|
:min="0.01"
|
||||||
|
:max="999999.99"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="税率(%)" field="taxRate" required>
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.taxRate"
|
||||||
|
placeholder="请输入税率"
|
||||||
|
:min="0"
|
||||||
|
:max="100"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="税额" field="taxAmount" required>
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.taxAmount"
|
||||||
|
placeholder="请输入税额"
|
||||||
|
:min="0"
|
||||||
|
:max="999999.99"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="不含税金额" field="amountWithoutTax" required>
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.amountWithoutTax"
|
||||||
|
placeholder="请输入不含税金额"
|
||||||
|
:min="0.01"
|
||||||
|
:max="999999.99"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 合同信息 -->
|
||||||
|
<a-card title="合同信息" class="detail-card" :bordered="false">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="合同编号" field="contractNumber" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.contractNumber"
|
||||||
|
placeholder="请输入合同编号"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="50"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="合同金额" field="contractAmount" required>
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.contractAmount"
|
||||||
|
placeholder="请输入合同金额"
|
||||||
|
:min="0.01"
|
||||||
|
:max="999999.99"
|
||||||
|
:precision="2"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="签订日期" field="contractDate" required>
|
||||||
|
<a-date-picker
|
||||||
|
v-model="formData.contractDate"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择签订日期"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="付款条件" field="paymentTerms" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.paymentTerms"
|
||||||
|
placeholder="请输入付款条件"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="100"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="付款期限" field="paymentDeadline" required>
|
||||||
|
<a-date-picker
|
||||||
|
v-model="formData.paymentDeadline"
|
||||||
|
format="YYYY-MM-DD"
|
||||||
|
placeholder="请选择付款期限"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, watch, computed } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import type { FormInstance } from '@arco-design/web-vue'
|
||||||
|
import type { EquipmentResp, PaymentRequest } from '@/apis/equipment/type'
|
||||||
|
import { equipmentProcurementApi } from '@/apis/equipment/procurement'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
equipmentData?: EquipmentResp | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
visible: false,
|
||||||
|
equipmentData: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:visible': [value: boolean]
|
||||||
|
'success': []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive<PaymentRequest>({
|
||||||
|
paymentMethod: '',
|
||||||
|
paymentAmount: 0,
|
||||||
|
paymentTime: '',
|
||||||
|
paymentPerson: '',
|
||||||
|
paymentRemark: '',
|
||||||
|
invoiceType: '',
|
||||||
|
invoiceNumber: '',
|
||||||
|
invoiceDate: '',
|
||||||
|
invoiceAmount: 0,
|
||||||
|
taxRate: 13,
|
||||||
|
taxAmount: 0,
|
||||||
|
amountWithoutTax: 0,
|
||||||
|
contractNumber: '',
|
||||||
|
contractAmount: 0,
|
||||||
|
contractDate: '',
|
||||||
|
paymentTerms: '',
|
||||||
|
paymentDeadline: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算税额和不含税金额
|
||||||
|
const calculatedTaxAmount = computed(() => {
|
||||||
|
if (formData.invoiceAmount && formData.taxRate) {
|
||||||
|
return (formData.invoiceAmount * formData.taxRate) / 100
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const calculatedAmountWithoutTax = computed(() => {
|
||||||
|
if (formData.invoiceAmount && formData.taxAmount) {
|
||||||
|
return formData.invoiceAmount - formData.taxAmount
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
})
|
||||||
|
|
||||||
|
// 监听发票金额和税率变化,自动计算税额和不含税金额
|
||||||
|
watch([() => formData.invoiceAmount, () => formData.taxRate], () => {
|
||||||
|
formData.taxAmount = calculatedTaxAmount.value
|
||||||
|
formData.amountWithoutTax = calculatedAmountWithoutTax.value
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
paymentMethod: [
|
||||||
|
{ required: true, message: '请选择支付方式' }
|
||||||
|
],
|
||||||
|
paymentAmount: [
|
||||||
|
{ required: true, message: '请输入支付金额' },
|
||||||
|
{ type: 'number', min: 0.01, message: '支付金额必须大于0' }
|
||||||
|
],
|
||||||
|
paymentTime: [
|
||||||
|
{ required: true, message: '请选择支付时间' }
|
||||||
|
],
|
||||||
|
paymentPerson: [
|
||||||
|
{ required: true, message: '请输入支付人姓名' },
|
||||||
|
{ min: 2, max: 50, message: '支付人姓名长度应在2-50个字符之间' }
|
||||||
|
],
|
||||||
|
invoiceType: [
|
||||||
|
{ required: true, message: '请选择发票类型' }
|
||||||
|
],
|
||||||
|
invoiceNumber: [
|
||||||
|
{ required: true, message: '请输入发票号码' },
|
||||||
|
{ min: 2, max: 50, message: '发票号码长度应在2-50个字符之间' }
|
||||||
|
],
|
||||||
|
invoiceDate: [
|
||||||
|
{ required: true, message: '请选择开票日期' }
|
||||||
|
],
|
||||||
|
invoiceAmount: [
|
||||||
|
{ required: true, message: '请输入发票金额' },
|
||||||
|
{ type: 'number', min: 0.01, message: '发票金额必须大于0' }
|
||||||
|
],
|
||||||
|
taxRate: [
|
||||||
|
{ required: true, message: '请输入税率' },
|
||||||
|
{ type: 'number', min: 0, max: 100, message: '税率应在0-100之间' }
|
||||||
|
],
|
||||||
|
contractNumber: [
|
||||||
|
{ required: true, message: '请输入合同编号' },
|
||||||
|
{ min: 2, max: 50, message: '合同编号长度应在2-50个字符之间' }
|
||||||
|
],
|
||||||
|
contractAmount: [
|
||||||
|
{ required: true, message: '请输入合同金额' },
|
||||||
|
{ type: 'number', min: 0.01, message: '合同金额必须大于0' }
|
||||||
|
],
|
||||||
|
contractDate: [
|
||||||
|
{ required: true, message: '请选择签订日期' }
|
||||||
|
],
|
||||||
|
paymentTerms: [
|
||||||
|
{ required: true, message: '请输入付款条件' },
|
||||||
|
{ min: 2, max: 100, message: '付款条件长度应在2-100个字符之间' }
|
||||||
|
],
|
||||||
|
paymentDeadline: [
|
||||||
|
{ required: true, message: '请选择付款期限' }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听弹窗显示状态
|
||||||
|
watch(() => props.visible, (visible) => {
|
||||||
|
if (visible && props.equipmentData) {
|
||||||
|
// 重置表单并设置默认值
|
||||||
|
Object.assign(formData, {
|
||||||
|
paymentMethod: '',
|
||||||
|
paymentAmount: props.equipmentData.purchasePrice || 0,
|
||||||
|
paymentTime: '',
|
||||||
|
paymentPerson: '',
|
||||||
|
paymentRemark: '',
|
||||||
|
invoiceType: '增值税专用发票',
|
||||||
|
invoiceNumber: '',
|
||||||
|
invoiceDate: '',
|
||||||
|
invoiceAmount: props.equipmentData.purchasePrice || 0,
|
||||||
|
taxRate: 13,
|
||||||
|
taxAmount: 0,
|
||||||
|
amountWithoutTax: 0,
|
||||||
|
contractNumber: props.equipmentData.purchaseOrder || '',
|
||||||
|
contractAmount: props.equipmentData.purchasePrice || 0,
|
||||||
|
contractDate: '',
|
||||||
|
paymentTerms: '货到付款',
|
||||||
|
paymentDeadline: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算税额和不含税金额
|
||||||
|
formData.taxAmount = calculatedTaxAmount.value
|
||||||
|
formData.amountWithoutTax = calculatedAmountWithoutTax.value
|
||||||
|
|
||||||
|
formRef.value?.clearValidate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
if (!props.equipmentData?.equipmentId) {
|
||||||
|
throw new Error('设备ID不能为空')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
const paymentTime = formData.paymentTime ? new Date(formData.paymentTime).toISOString() : new Date().toISOString()
|
||||||
|
const invoiceDate = formData.invoiceDate ? new Date(formData.invoiceDate).toISOString() : new Date().toISOString()
|
||||||
|
const contractDate = formData.contractDate ? new Date(formData.contractDate).toISOString() : new Date().toISOString()
|
||||||
|
const paymentDeadline = formData.paymentDeadline ? new Date(formData.paymentDeadline).toISOString() : new Date().toISOString()
|
||||||
|
|
||||||
|
const requestData: PaymentRequest = {
|
||||||
|
...formData,
|
||||||
|
paymentTime,
|
||||||
|
invoiceDate,
|
||||||
|
contractDate,
|
||||||
|
paymentDeadline,
|
||||||
|
}
|
||||||
|
|
||||||
|
await equipmentProcurementApi.makePayment(props.equipmentData.equipmentId, requestData)
|
||||||
|
|
||||||
|
Message.success('付款成功')
|
||||||
|
emit('success')
|
||||||
|
emit('update:visible', false)
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('付款失败:', error)
|
||||||
|
Message.error(error?.message || '付款失败,请检查表单信息')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.detail-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-input,
|
||||||
|
.arco-select,
|
||||||
|
.arco-input-number,
|
||||||
|
.arco-date-picker,
|
||||||
|
.arco-textarea {
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-textarea {
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,211 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
title="收货详情"
|
||||||
|
width="800px"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
:footer="false"
|
||||||
|
>
|
||||||
|
<div class="receipt-detail">
|
||||||
|
<!-- 基本信息 -->
|
||||||
|
<a-card title="基本信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="设备名称">
|
||||||
|
{{ receiptData?.equipmentName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备类型">
|
||||||
|
{{ receiptData?.equipmentType || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备型号">
|
||||||
|
{{ receiptData?.equipmentModel || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="品牌">
|
||||||
|
{{ receiptData?.brand || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="供应商">
|
||||||
|
{{ receiptData?.supplierName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购订单">
|
||||||
|
{{ receiptData?.purchaseOrder || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 收货信息 -->
|
||||||
|
<a-card title="收货信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="收货状态">
|
||||||
|
<a-tag :color="getReceiptStatusColor(receiptData?.receiptStatus)">
|
||||||
|
{{ getReceiptStatusText(receiptData?.receiptStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="收货时间">
|
||||||
|
{{ receiptData?.receiptTime || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="收货人">
|
||||||
|
{{ receiptData?.receiptPerson || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="收货数量">
|
||||||
|
{{ receiptData?.receiptQuantity || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="收货备注" :span="2">
|
||||||
|
{{ receiptData?.receiptRemark || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 质量检查 -->
|
||||||
|
<a-card title="质量检查" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="外观检查">
|
||||||
|
{{ receiptData?.appearanceCheck || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="功能测试">
|
||||||
|
{{ receiptData?.functionTest || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="包装完整性">
|
||||||
|
{{ receiptData?.packageIntegrity || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="配件完整性">
|
||||||
|
{{ receiptData?.accessoryIntegrity || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="检查结果" :span="2">
|
||||||
|
<a-tag :color="getCheckResultColor(receiptData?.checkResult)">
|
||||||
|
{{ getCheckResultText(receiptData?.checkResult) }}
|
||||||
|
</a-tag>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="检查备注" :span="2">
|
||||||
|
{{ receiptData?.checkRemark || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 入库信息 -->
|
||||||
|
<a-card title="入库信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="入库状态">
|
||||||
|
<a-tag :color="getStorageStatusColor(receiptData?.storageStatus)">
|
||||||
|
{{ getStorageStatusText(receiptData?.storageStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="入库时间">
|
||||||
|
{{ receiptData?.storageTime || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="入库位置">
|
||||||
|
{{ receiptData?.storageLocation || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="库管员">
|
||||||
|
{{ receiptData?.storageManager || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
</div>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import type { EquipmentResp } from '@/apis/equipment/type'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
receiptData?: EquipmentResp | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
visible: false,
|
||||||
|
receiptData: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:visible': [value: boolean]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
// 获取收货状态颜色
|
||||||
|
const getReceiptStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
NOT_RECEIVED: 'gray',
|
||||||
|
RECEIVED: 'green',
|
||||||
|
PARTIALLY_RECEIVED: 'orange',
|
||||||
|
REJECTED: 'red',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取收货状态文本
|
||||||
|
const getReceiptStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
NOT_RECEIVED: '未收货',
|
||||||
|
RECEIVED: '已收货',
|
||||||
|
PARTIALLY_RECEIVED: '部分收货',
|
||||||
|
REJECTED: '已拒收',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取检查结果颜色
|
||||||
|
const getCheckResultColor = (result?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
PASS: 'green',
|
||||||
|
FAIL: 'red',
|
||||||
|
CONDITIONAL: 'orange',
|
||||||
|
}
|
||||||
|
return colorMap[result || ''] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取检查结果文本
|
||||||
|
const getCheckResultText = (result?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
PASS: '通过',
|
||||||
|
FAIL: '不通过',
|
||||||
|
CONDITIONAL: '有条件通过',
|
||||||
|
}
|
||||||
|
return textMap[result || ''] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取入库状态颜色
|
||||||
|
const getStorageStatusColor = (status?: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
NOT_STORED: 'gray',
|
||||||
|
STORED: 'green',
|
||||||
|
PARTIALLY_STORED: 'orange',
|
||||||
|
}
|
||||||
|
return colorMap[status || ''] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取入库状态文本
|
||||||
|
const getStorageStatusText = (status?: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
NOT_STORED: '未入库',
|
||||||
|
STORED: '已入库',
|
||||||
|
PARTIALLY_STORED: '部分入库',
|
||||||
|
}
|
||||||
|
return textMap[status || ''] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.receipt-detail {
|
||||||
|
.detail-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-descriptions-item-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: var(--color-text-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-descriptions-item-value {
|
||||||
|
color: var(--color-text-2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,368 @@
|
||||||
|
<template>
|
||||||
|
<a-modal
|
||||||
|
:visible="visible"
|
||||||
|
title="确认收货"
|
||||||
|
width="800px"
|
||||||
|
:confirm-loading="loading"
|
||||||
|
@cancel="handleCancel"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
>
|
||||||
|
<a-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="rules"
|
||||||
|
:label-col="{ span: 6 }"
|
||||||
|
:wrapper-col="{ span: 18 }"
|
||||||
|
layout="vertical"
|
||||||
|
>
|
||||||
|
<!-- 基本信息 -->
|
||||||
|
<a-card title="设备信息" class="detail-card" :bordered="false">
|
||||||
|
<a-descriptions :column="2" bordered>
|
||||||
|
<a-descriptions-item label="设备名称">
|
||||||
|
{{ equipmentData?.equipmentName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备类型">
|
||||||
|
{{ equipmentData?.equipmentType || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="设备型号">
|
||||||
|
{{ equipmentData?.equipmentModel || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="品牌">
|
||||||
|
{{ equipmentData?.brand || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="供应商">
|
||||||
|
{{ equipmentData?.supplierName || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
<a-descriptions-item label="采购订单">
|
||||||
|
{{ equipmentData?.purchaseOrder || '-' }}
|
||||||
|
</a-descriptions-item>
|
||||||
|
</a-descriptions>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 收货信息 -->
|
||||||
|
<a-card title="收货信息" class="detail-card" :bordered="false">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="收货时间" field="receiptTime" required>
|
||||||
|
<a-date-picker
|
||||||
|
v-model="formData.receiptTime"
|
||||||
|
show-time
|
||||||
|
format="YYYY-MM-DD HH:mm:ss"
|
||||||
|
placeholder="请选择收货时间"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="收货人" field="receiptPerson" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.receiptPerson"
|
||||||
|
placeholder="请输入收货人姓名"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="50"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="收货数量" field="receiptQuantity" required>
|
||||||
|
<a-input-number
|
||||||
|
v-model="formData.receiptQuantity"
|
||||||
|
placeholder="请输入收货数量"
|
||||||
|
:min="1"
|
||||||
|
:max="9999"
|
||||||
|
style="width: 100%"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="入库位置" field="storageLocation" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.storageLocation"
|
||||||
|
placeholder="请输入入库位置"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="100"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="库管员" field="storageManager" required>
|
||||||
|
<a-input
|
||||||
|
v-model="formData.storageManager"
|
||||||
|
placeholder="请输入库管员姓名"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="50"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="收货备注" field="receiptRemark">
|
||||||
|
<a-input
|
||||||
|
v-model="formData.receiptRemark"
|
||||||
|
placeholder="请输入收货备注"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="200"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
|
||||||
|
<!-- 质量检查 -->
|
||||||
|
<a-card title="质量检查" class="detail-card" :bordered="false">
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="外观检查" field="appearanceCheck" required>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.appearanceCheck"
|
||||||
|
placeholder="请选择外观检查结果"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="正常">正常</a-option>
|
||||||
|
<a-option value="轻微划痕">轻微划痕</a-option>
|
||||||
|
<a-option value="明显划痕">明显划痕</a-option>
|
||||||
|
<a-option value="变形">变形</a-option>
|
||||||
|
<a-option value="其他">其他</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="功能测试" field="functionTest" required>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.functionTest"
|
||||||
|
placeholder="请选择功能测试结果"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="正常">正常</a-option>
|
||||||
|
<a-option value="部分正常">部分正常</a-option>
|
||||||
|
<a-option value="异常">异常</a-option>
|
||||||
|
<a-option value="未测试">未测试</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="包装完整性" field="packageIntegrity" required>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.packageIntegrity"
|
||||||
|
placeholder="请选择包装完整性"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="完整">完整</a-option>
|
||||||
|
<a-option value="轻微破损">轻微破损</a-option>
|
||||||
|
<a-option value="明显破损">明显破损</a-option>
|
||||||
|
<a-option value="严重破损">严重破损</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="配件完整性" field="accessoryIntegrity" required>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.accessoryIntegrity"
|
||||||
|
placeholder="请选择配件完整性"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="完整">完整</a-option>
|
||||||
|
<a-option value="部分缺失">部分缺失</a-option>
|
||||||
|
<a-option value="严重缺失">严重缺失</a-option>
|
||||||
|
<a-option value="无配件">无配件</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
|
||||||
|
<a-row :gutter="16">
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="检查结果" field="checkResult" required>
|
||||||
|
<a-select
|
||||||
|
v-model="formData.checkResult"
|
||||||
|
placeholder="请选择检查结果"
|
||||||
|
style="width: 100%"
|
||||||
|
>
|
||||||
|
<a-option value="PASS">通过</a-option>
|
||||||
|
<a-option value="FAIL">不通过</a-option>
|
||||||
|
<a-option value="CONDITIONAL">有条件通过</a-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="12">
|
||||||
|
<a-form-item label="检查备注" field="checkRemark">
|
||||||
|
<a-input
|
||||||
|
v-model="formData.checkRemark"
|
||||||
|
placeholder="请输入检查备注"
|
||||||
|
show-word-limit
|
||||||
|
:max-length="200"
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
</a-card>
|
||||||
|
</a-form>
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, watch } from 'vue'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import type { FormInstance } from '@arco-design/web-vue'
|
||||||
|
import type { EquipmentResp, ReceiptRequest } from '@/apis/equipment/type'
|
||||||
|
import { equipmentProcurementApi } from '@/apis/equipment/procurement'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
visible: boolean
|
||||||
|
equipmentData?: EquipmentResp | null
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
visible: false,
|
||||||
|
equipmentData: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:visible': [value: boolean]
|
||||||
|
'success': []
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>()
|
||||||
|
const loading = ref(false)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive<ReceiptRequest>({
|
||||||
|
receiptTime: '',
|
||||||
|
receiptPerson: '',
|
||||||
|
receiptQuantity: 1,
|
||||||
|
receiptRemark: '',
|
||||||
|
appearanceCheck: '',
|
||||||
|
functionTest: '',
|
||||||
|
packageIntegrity: '',
|
||||||
|
accessoryIntegrity: '',
|
||||||
|
checkResult: 'PASS',
|
||||||
|
checkRemark: '',
|
||||||
|
storageLocation: '',
|
||||||
|
storageManager: '',
|
||||||
|
})
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
receiptTime: [
|
||||||
|
{ required: true, message: '请选择收货时间' }
|
||||||
|
],
|
||||||
|
receiptPerson: [
|
||||||
|
{ required: true, message: '请输入收货人姓名' },
|
||||||
|
{ min: 2, max: 50, message: '收货人姓名长度应在2-50个字符之间' }
|
||||||
|
],
|
||||||
|
receiptQuantity: [
|
||||||
|
{ required: true, message: '请输入收货数量' },
|
||||||
|
{ type: 'number', min: 1, max: 9999, message: '收货数量应在1-9999之间' }
|
||||||
|
],
|
||||||
|
storageLocation: [
|
||||||
|
{ required: true, message: '请输入入库位置' },
|
||||||
|
{ min: 2, max: 100, message: '入库位置长度应在2-100个字符之间' }
|
||||||
|
],
|
||||||
|
storageManager: [
|
||||||
|
{ required: true, message: '请输入库管员姓名' },
|
||||||
|
{ min: 2, max: 50, message: '库管员姓名长度应在2-50个字符之间' }
|
||||||
|
],
|
||||||
|
appearanceCheck: [
|
||||||
|
{ required: true, message: '请选择外观检查结果' }
|
||||||
|
],
|
||||||
|
functionTest: [
|
||||||
|
{ required: true, message: '请选择功能测试结果' }
|
||||||
|
],
|
||||||
|
packageIntegrity: [
|
||||||
|
{ required: true, message: '请选择包装完整性' }
|
||||||
|
],
|
||||||
|
accessoryIntegrity: [
|
||||||
|
{ required: true, message: '请选择配件完整性' }
|
||||||
|
],
|
||||||
|
checkResult: [
|
||||||
|
{ required: true, message: '请选择检查结果' }
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听弹窗显示状态
|
||||||
|
watch(() => props.visible, (visible) => {
|
||||||
|
if (visible) {
|
||||||
|
// 重置表单
|
||||||
|
Object.assign(formData, {
|
||||||
|
receiptTime: '',
|
||||||
|
receiptPerson: '',
|
||||||
|
receiptQuantity: props.equipmentData?.quantity || 1,
|
||||||
|
receiptRemark: '',
|
||||||
|
appearanceCheck: '',
|
||||||
|
functionTest: '',
|
||||||
|
packageIntegrity: '',
|
||||||
|
accessoryIntegrity: '',
|
||||||
|
checkResult: 'PASS',
|
||||||
|
checkRemark: '',
|
||||||
|
storageLocation: '',
|
||||||
|
storageManager: '',
|
||||||
|
})
|
||||||
|
formRef.value?.clearValidate()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
loading.value = true
|
||||||
|
|
||||||
|
if (!props.equipmentData?.equipmentId) {
|
||||||
|
throw new Error('设备ID不能为空')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化时间
|
||||||
|
const receiptTime = formData.receiptTime ? new Date(formData.receiptTime).toISOString() : new Date().toISOString()
|
||||||
|
|
||||||
|
const requestData: ReceiptRequest = {
|
||||||
|
...formData,
|
||||||
|
receiptTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
await equipmentProcurementApi.receiveGoods(props.equipmentData.equipmentId, requestData)
|
||||||
|
|
||||||
|
Message.success('收货成功')
|
||||||
|
emit('success')
|
||||||
|
emit('update:visible', false)
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('收货失败:', error)
|
||||||
|
Message.error(error?.message || '收货失败,请检查表单信息')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消
|
||||||
|
const handleCancel = () => {
|
||||||
|
emit('update:visible', false)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.detail-card {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-form-item {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.arco-input,
|
||||||
|
.arco-select,
|
||||||
|
.arco-input-number,
|
||||||
|
.arco-date-picker {
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -178,6 +178,20 @@
|
||||||
<span v-else class="no-data">-</span>
|
<span v-else class="no-data">-</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- 收货状态 -->
|
||||||
|
<template #receiptStatus="{ record }">
|
||||||
|
<a-tag :color="getReceiptStatusColor(record.receiptStatus)">
|
||||||
|
{{ getReceiptStatusText(record.receiptStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 支付状态 -->
|
||||||
|
<template #paymentStatus="{ record }">
|
||||||
|
<a-tag :color="getPaymentStatusColor(record.paymentStatus)">
|
||||||
|
{{ getPaymentStatusText(record.paymentStatus) }}
|
||||||
|
</a-tag>
|
||||||
|
</template>
|
||||||
|
|
||||||
<!-- 操作 -->
|
<!-- 操作 -->
|
||||||
<template #action="{ record }">
|
<template #action="{ record }">
|
||||||
<a-space>
|
<a-space>
|
||||||
|
@ -196,6 +210,40 @@
|
||||||
>
|
>
|
||||||
申请采购
|
申请采购
|
||||||
</a-button>
|
</a-button>
|
||||||
|
<!-- 收货操作按钮 -->
|
||||||
|
<a-button
|
||||||
|
v-if="canReceiveGoods(record)"
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
@click="handleReceiveGoods(record)"
|
||||||
|
>
|
||||||
|
确认收货
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="record.receiptStatus === 'RECEIVED'"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
@click="handleViewReceipt(record)"
|
||||||
|
>
|
||||||
|
查看收货
|
||||||
|
</a-button>
|
||||||
|
<!-- 支付操作按钮 -->
|
||||||
|
<a-button
|
||||||
|
v-if="canMakePayment(record)"
|
||||||
|
type="outline"
|
||||||
|
size="small"
|
||||||
|
@click="handleMakePayment(record)"
|
||||||
|
>
|
||||||
|
付款
|
||||||
|
</a-button>
|
||||||
|
<a-button
|
||||||
|
v-if="record.paymentStatus === 'PAID'"
|
||||||
|
type="text"
|
||||||
|
size="small"
|
||||||
|
@click="handleViewPayment(record)"
|
||||||
|
>
|
||||||
|
查看支付详情
|
||||||
|
</a-button>
|
||||||
<!-- 显示采购状态 - 优先显示采购状态 -->
|
<!-- 显示采购状态 - 优先显示采购状态 -->
|
||||||
<a-tag
|
<a-tag
|
||||||
v-if="record.procurementStatus && record.procurementStatus !== 'NOT_STARTED'"
|
v-if="record.procurementStatus && record.procurementStatus !== 'NOT_STARTED'"
|
||||||
|
@ -252,6 +300,32 @@
|
||||||
:equipment-data="currentApplicationData"
|
:equipment-data="currentApplicationData"
|
||||||
@success="handleApplicationSuccess"
|
@success="handleApplicationSuccess"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<!-- 收货详情弹窗 -->
|
||||||
|
<ReceiptDetailModal
|
||||||
|
v-model:visible="receiptDetailModalVisible"
|
||||||
|
:receipt-data="currentReceiptData"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 支付详情弹窗 -->
|
||||||
|
<PaymentDetailModal
|
||||||
|
v-model:visible="paymentDetailModalVisible"
|
||||||
|
:payment-data="currentPaymentData"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 收货弹窗 -->
|
||||||
|
<ReceiptModal
|
||||||
|
v-model:visible="receiptModalVisible"
|
||||||
|
:equipment-data="currentReceiptData"
|
||||||
|
@success="handleReceiptSuccess"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 支付弹窗 -->
|
||||||
|
<PaymentModal
|
||||||
|
v-model:visible="paymentModalVisible"
|
||||||
|
:equipment-data="currentPaymentData"
|
||||||
|
@success="handlePaymentSuccess"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -271,6 +345,10 @@ import message from '@arco-design/web-vue/es/message'
|
||||||
import ProcurementModal from './components/ProcurementModal.vue'
|
import ProcurementModal from './components/ProcurementModal.vue'
|
||||||
import ProcurementSearch from './components/ProcurementSearch.vue'
|
import ProcurementSearch from './components/ProcurementSearch.vue'
|
||||||
import ProcurementApplicationModal from './components/ProcurementApplicationModal.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 { equipmentProcurementApi } from '@/apis/equipment/procurement'
|
||||||
import { equipmentApprovalApi } from '@/apis/equipment/approval'
|
import { equipmentApprovalApi } from '@/apis/equipment/approval'
|
||||||
import type { EquipmentListReq, EquipmentResp } from '@/apis/equipment/type'
|
import type { EquipmentListReq, EquipmentResp } from '@/apis/equipment/type'
|
||||||
|
@ -307,6 +385,18 @@ const modalMode = ref<'add' | 'edit' | 'view'>('add')
|
||||||
const applicationModalVisible = ref(false)
|
const applicationModalVisible = ref(false)
|
||||||
const currentApplicationData = ref<EquipmentResp | null>(null)
|
const currentApplicationData = ref<EquipmentResp | null>(null)
|
||||||
|
|
||||||
|
// 收货详情弹窗控制
|
||||||
|
const receiptDetailModalVisible = ref(false)
|
||||||
|
const currentReceiptData = ref<EquipmentResp | null>(null)
|
||||||
|
|
||||||
|
// 支付详情弹窗控制
|
||||||
|
const paymentDetailModalVisible = ref(false)
|
||||||
|
const currentPaymentData = ref<EquipmentResp | null>(null)
|
||||||
|
|
||||||
|
// 收货弹窗控制
|
||||||
|
const receiptModalVisible = ref(false)
|
||||||
|
const paymentModalVisible = ref(false)
|
||||||
|
|
||||||
// 表格选择
|
// 表格选择
|
||||||
const selectedRowKeys = ref<string[]>([])
|
const selectedRowKeys = ref<string[]>([])
|
||||||
const rowSelection = reactive({
|
const rowSelection = reactive({
|
||||||
|
@ -418,6 +508,20 @@ const columns = [
|
||||||
slotName: 'createTime',
|
slotName: 'createTime',
|
||||||
width: 160,
|
width: 160,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: '收货状态',
|
||||||
|
dataIndex: 'receiptStatus',
|
||||||
|
key: 'receiptStatus',
|
||||||
|
slotName: 'receiptStatus',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '支付状态',
|
||||||
|
dataIndex: 'paymentStatus',
|
||||||
|
key: 'paymentStatus',
|
||||||
|
slotName: 'paymentStatus',
|
||||||
|
width: 120,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
key: 'action',
|
key: 'action',
|
||||||
|
@ -527,6 +631,50 @@ const getHealthStatusText = (status: string) => {
|
||||||
return textMap[status] || '未知'
|
return textMap[status] || '未知'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取收货状态颜色
|
||||||
|
const getReceiptStatusColor = (status: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
NOT_RECEIVED: 'gray',
|
||||||
|
RECEIVED: 'green',
|
||||||
|
PARTIALLY_RECEIVED: 'orange',
|
||||||
|
REJECTED: 'red',
|
||||||
|
}
|
||||||
|
return colorMap[status] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取收货状态文本
|
||||||
|
const getReceiptStatusText = (status: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
NOT_RECEIVED: '未收货',
|
||||||
|
RECEIVED: '已收货',
|
||||||
|
PARTIALLY_RECEIVED: '部分收货',
|
||||||
|
REJECTED: '已拒收',
|
||||||
|
}
|
||||||
|
return textMap[status] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取支付状态颜色
|
||||||
|
const getPaymentStatusColor = (status: string) => {
|
||||||
|
const colorMap: Record<string, string> = {
|
||||||
|
NOT_PAID: 'gray',
|
||||||
|
PAID: 'green',
|
||||||
|
PARTIALLY_PAID: 'orange',
|
||||||
|
REJECTED: 'red',
|
||||||
|
}
|
||||||
|
return colorMap[status] || 'blue'
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取支付状态文本
|
||||||
|
const getPaymentStatusText = (status: string) => {
|
||||||
|
const textMap: Record<string, string> = {
|
||||||
|
NOT_PAID: '未支付',
|
||||||
|
PAID: '已支付',
|
||||||
|
PARTIALLY_PAID: '部分支付',
|
||||||
|
REJECTED: '已拒付',
|
||||||
|
}
|
||||||
|
return textMap[status] || '未知'
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化价格
|
// 格式化价格
|
||||||
const formatPrice = (price: number) => {
|
const formatPrice = (price: number) => {
|
||||||
return price.toLocaleString('zh-CN', {
|
return price.toLocaleString('zh-CN', {
|
||||||
|
@ -601,6 +749,8 @@ const transformBackendData = (data: any[]): EquipmentResp[] => {
|
||||||
inventoryBasis: item.inventoryBasis,
|
inventoryBasis: item.inventoryBasis,
|
||||||
dynamicRecord: item.dynamicRecord,
|
dynamicRecord: item.dynamicRecord,
|
||||||
procurementStatus: item.procurementStatus,
|
procurementStatus: item.procurementStatus,
|
||||||
|
receiptStatus: item.receiptStatus || 'NOT_RECEIVED',
|
||||||
|
paymentStatus: item.paymentStatus || 'NOT_PAID',
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,6 +1000,54 @@ const canApplyProcurement = (record: EquipmentResp) => {
|
||||||
return canApply
|
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 getApprovalStatusColor = (status: string) => {
|
||||||
const colorMap: Record<string, string> = {
|
const colorMap: Record<string, string> = {
|
||||||
|
|
Loading…
Reference in New Issue