完善收货状态随着流程变化,确保在采购审批后通过后才出现收货状态,添加支付状态和收获状态字段

This commit is contained in:
Mr.j 2025-08-14 15:22:55 +08:00
parent f3fa274e18
commit 2feea5fd8f
4 changed files with 233 additions and 71 deletions

View File

@ -457,6 +457,7 @@ export interface ReceiptRequest {
useStatus?: string useStatus?: string
healthStatus?: string healthStatus?: string
receiptStatus?: string receiptStatus?: string
paymentStatus?: string
// 其他管理信息 // 其他管理信息
depreciationMethod?: string depreciationMethod?: string

View File

@ -87,11 +87,15 @@
<a-form-item label="序列号" field="equipmentSn"> <a-form-item label="序列号" field="equipmentSn">
<a-input <a-input
v-model="formData.equipmentSn" v-model="formData.equipmentSn"
placeholder="请输入序列号" placeholder="选择设备类型后自动生成"
:disabled="isView" :disabled="true"
show-word-limit show-word-limit
:max-length="100" :max-length="100"
/> />
<div class="field-tip">
<IconInfoCircle style="color: #1890ff; margin-right: 4px;" />
选择设备类型后自动生成格式设备类型+顺序号+日期
</div>
</a-form-item> </a-form-item>
</a-col> </a-col>
</a-row> </a-row>
@ -528,6 +532,7 @@ import { Message } from '@arco-design/web-vue'
import type { FormInstance } from '@arco-design/web-vue' import type { FormInstance } from '@arco-design/web-vue'
import { equipmentProcurementApi } from '@/apis/equipment/procurement' import { equipmentProcurementApi } from '@/apis/equipment/procurement'
import type { EquipmentResp, EquipmentReq } from '@/apis/equipment/type' import type { EquipmentResp, EquipmentReq } from '@/apis/equipment/type'
import { IconInfoCircle } from '@arco-design/web-vue/es/icon'
interface Props { interface Props {
visible: boolean visible: boolean
@ -692,6 +697,40 @@ watch([() => formData.unitPrice, () => formData.quantity], ([newUnitPrice, newQu
} }
}) })
//
const generateEquipmentSn = (equipmentType: string) => {
//
const timestamp = Date.now()
const orderNumber = timestamp.toString().slice(-6) // 6
//
const typeMap: Record<string, string> = {
'detection': 'DET',
'security': 'SEC',
'office': 'OFF',
'car': 'CAR',
'other': 'OTH'
}
const typeCode = typeMap[equipmentType] || 'OTH'
//
const now = new Date()
const dateStr = now.getFullYear().toString().slice(-2) +
(now.getMonth() + 1).toString().padStart(2, '0') +
now.getDate().toString().padStart(2, '0')
// ++
return `${typeCode}${orderNumber}${dateStr}`
}
//
watch(() => formData.equipmentType, (newType) => {
if (newType && !formData.equipmentSn) {
//
formData.equipmentSn = generateEquipmentSn(newType)
}
})
// //
const initFormData = () => { const initFormData = () => {
if (props.procurementData) { if (props.procurementData) {
@ -841,7 +880,7 @@ const fillTestData = () => {
const nextMaintenanceTime = nextMaintenanceDate.toISOString().slice(0, 19).replace('T', ' ') const nextMaintenanceTime = nextMaintenanceDate.toISOString().slice(0, 19).replace('T', ' ')
// //
const randomSn = 'SN' + Math.random().toString(36).substr(2, 8).toUpperCase() const randomSn = generateEquipmentSn('detection')
// //
const randomAssetCode = 'ZC' + Math.random().toString(36).substr(2, 6).toUpperCase() const randomAssetCode = 'ZC' + Math.random().toString(36).substr(2, 6).toUpperCase()
@ -949,6 +988,15 @@ const handleCancel = () => {
color: var(--color-text-1); color: var(--color-text-1);
margin-bottom: 8px; margin-bottom: 8px;
} }
.field-tip {
margin-top: 4px;
font-size: 12px;
color: var(--color-text-3);
display: flex;
align-items: center;
line-height: 1.4;
}
} }
.arco-input, .arco-input,

View File

@ -27,9 +27,15 @@
<a-descriptions-item label="设备型号"> <a-descriptions-item label="设备型号">
{{ equipmentData?.equipmentModel || '-' }} {{ equipmentData?.equipmentModel || '-' }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="设备序列号">
{{ equipmentData?.equipmentSn || '-' }}
</a-descriptions-item>
<a-descriptions-item label="品牌"> <a-descriptions-item label="品牌">
{{ equipmentData?.brand || '-' }} {{ equipmentData?.brand || '-' }}
</a-descriptions-item> </a-descriptions-item>
<a-descriptions-item label="配置规格">
{{ equipmentData?.specification || '-' }}
</a-descriptions-item>
<a-descriptions-item label="供应商"> <a-descriptions-item label="供应商">
{{ equipmentData?.supplierName || '-' }} {{ equipmentData?.supplierName || '-' }}
</a-descriptions-item> </a-descriptions-item>
@ -370,6 +376,32 @@ watch(() => props.equipmentData, () => {
} }
}, { deep: true }) }, { deep: true })
//
const generateEquipmentSn = (equipmentType: string, inStockTime: string) => {
//
const timestamp = Date.now()
const orderNumber = timestamp.toString().slice(-6) // 6
//
const typeMap: Record<string, string> = {
'detection': 'DET',
'security': 'SEC',
'office': 'OFF',
'car': 'CAR',
'other': 'OTH'
}
const typeCode = typeMap[equipmentType] || 'OTH'
//
const date = new Date(inStockTime)
const dateStr = date.getFullYear().toString().slice(-2) +
(date.getMonth() + 1).toString().padStart(2, '0') +
date.getDate().toString().padStart(2, '0')
// ++
return `${typeCode}${orderNumber}${dateStr}`
}
// //
const handleSubmit = async () => { const handleSubmit = async () => {
try { try {
@ -380,13 +412,37 @@ const handleSubmit = async () => {
throw new Error('设备ID不能为空') throw new Error('设备ID不能为空')
} }
console.log('📦 开始提交收货数据...') // 1.
console.log('📦 设备数据:', props.equipmentData) const procurementData = props.equipmentData
console.log('📦 表单数据:', formData)
// 2.
// const equipmentSn = generateEquipmentSn(
const receiptData: ReceiptRequest = { procurementData.equipmentType || 'other',
// formData.receiptTime || new Date().toISOString()
)
// 3.
const equipmentData = {
//
equipmentId: procurementData.equipmentId,
equipmentName: procurementData.equipmentName,
equipmentModel: procurementData.equipmentModel,
equipmentType: procurementData.equipmentType,
equipmentSn: equipmentSn, // 使
brand: procurementData.brand,
specification: procurementData.specification,
assetCode: procurementData.assetCode,
//
purchaseOrder: procurementData.purchaseOrder,
supplierName: procurementData.supplierName,
purchasePrice: procurementData.purchasePrice,
purchaseTime: procurementData.purchaseTime,
quantity: procurementData.quantity,
unitPrice: procurementData.unitPrice,
totalPrice: procurementData.totalPrice,
//
receiptTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()), receiptTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()),
receiptPerson: formData.receiptPerson, receiptPerson: formData.receiptPerson,
receiptQuantity: formData.receiptQuantity, receiptQuantity: formData.receiptQuantity,
@ -400,62 +456,31 @@ const handleSubmit = async () => {
storageLocation: formData.storageLocation, storageLocation: formData.storageLocation,
storageManager: formData.storageManager, storageManager: formData.storageManager,
// //
equipmentName: props.equipmentData.equipmentName,
equipmentModel: props.equipmentData.equipmentModel,
equipmentType: props.equipmentData.equipmentType,
equipmentSn: props.equipmentData.equipmentSn,
brand: props.equipmentData.brand,
specification: props.equipmentData.specification,
assetCode: props.equipmentData.assetCode,
//
purchaseOrder: props.equipmentData.purchaseOrder,
supplierName: props.equipmentData.supplierName,
purchasePrice: props.equipmentData.purchasePrice,
purchaseTime: props.equipmentData.purchaseTime,
quantity: props.equipmentData.quantity,
unitPrice: props.equipmentData.unitPrice,
totalPrice: props.equipmentData.totalPrice,
//
inStockTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()),
physicalLocation: formData.storageLocation,
locationStatus: 'in_stock',
responsiblePerson: formData.storageManager,
inventoryBarcode: props.equipmentData.inventoryBarcode || generateInventoryBarcode(),
//
equipmentStatus: 'normal', equipmentStatus: 'normal',
useStatus: '0', useStatus: '0', //
healthStatus: 'good', locationStatus: 'in_stock', //
receiptStatus: 'RECEIVED', healthStatus: 'excellent',
responsiblePerson: formData.storageManager,
// physicalLocation: formData.storageLocation,
depreciationMethod: props.equipmentData.depreciationMethod || 'straight_line', inStockTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()),
depreciationYears: props.equipmentData.depreciationYears || 5, inventoryBarcode: `BC${Date.now()}${Math.random().toString(36).substr(2, 4).toUpperCase()}`,
salvageValue: props.equipmentData.salvageValue || 0, depreciationMethod: 'straight_line',
currentNetValue: props.equipmentData.purchasePrice || 0, warrantyExpireDate: procurementData.warrantyExpireDate,
assetRemark: `设备已收货入库,收货人:${formData.receiptPerson},入库时间:${formData.receiptTime}`
//
createTime: formatDateTime(new Date()),
updateTime: formatDateTime(new Date())
} }
console.log('📦 构建的收货数据:', receiptData)
// API
await equipmentProcurementApi.receiveGoods(
props.equipmentData.equipmentId,
receiptData
)
Message.success('收货成功,设备已自动入库') console.log('📦 准备提交收货数据:', equipmentData)
// 4. API
await equipmentProcurementApi.receiveGoods(procurementData.equipmentId, equipmentData)
Message.success('收货成功!设备已自动入库')
emit('success') emit('success')
emit('update:visible', false)
} catch (error: any) { } catch (error: any) {
console.error('收货失败:', error) console.error('收货失败:', error)
Message.error(error?.message || '收货失败,请检查表单信息') Message.error(error?.message || '收货失败,请重试')
} finally { } finally {
loading.value = false loading.value = false
} }

View File

@ -244,6 +244,18 @@
> >
查看支付详情 查看支付详情
</a-button> </a-button>
<!-- 手动刷新按钮 - 用于调试状态更新 -->
<a-button
type="text"
size="small"
@click="handleRefreshRecord(record)"
title="刷新此条记录状态"
>
<template #icon>
<IconRefresh />
</template>
刷新
</a-button>
<!-- 显示采购状态 - 优先显示采购状态 --> <!-- 显示采购状态 - 优先显示采购状态 -->
<a-tag <a-tag
v-if="record.procurementStatus && record.procurementStatus !== 'NOT_STARTED'" v-if="record.procurementStatus && record.procurementStatus !== 'NOT_STARTED'"
@ -936,13 +948,42 @@ const handleModalSuccess = () => {
// //
const handleApplicationSuccess = async () => { const handleApplicationSuccess = async () => {
applicationModalVisible.value = false applicationModalVisible.value = false
console.log('采购申请成功,准备刷新数据...') console.log('✅ 采购申请成功,准备更新本地数据...')
//
//
if (currentApplicationData.value) {
const equipmentId = currentApplicationData.value.equipmentId
//
const recordIndex = tableData.value.findIndex(item => item.equipmentId === equipmentId)
if (recordIndex !== -1) {
//
tableData.value[recordIndex] = {
...tableData.value[recordIndex],
procurementStatus: 'PENDING_APPROVAL'
}
console.log('✅ 本地数据已更新,申请采购按钮应该消失')
console.log('🔍 更新后的记录:', tableData.value[recordIndex])
message.success('采购申请已提交,请等待审批')
} else {
console.warn('⚠️ 未找到对应的记录,无法更新本地状态')
message.warning('状态更新失败,请手动刷新页面')
}
}
//
setTimeout(async () => { setTimeout(async () => {
console.log('开始刷新数据...') try {
await loadData(currentSearchParams.value) console.log('🔄 延迟刷新数据,确保后端状态同步...')
message.success('采购申请已提交,请等待审批') await loadData(currentSearchParams.value)
}, 1000) console.log('✅ 后端数据同步完成')
} catch (error) {
console.error('❌ 后端数据同步失败:', error)
//
}
}, 1000) // 1
} }
// //
@ -993,17 +1034,37 @@ const getTotalAmount = () => {
// //
const canApplyProcurement = (record: EquipmentResp) => { const canApplyProcurement = (record: EquipmentResp) => {
// //
// //
const allowedStatuses = ['NOT_STARTED', 'REJECTED', 'COMPLETED', null, undefined] //
const allowedStatuses = ['NOT_STARTED', 'REJECTED', null, undefined]
const canApply = allowedStatuses.includes(record.procurementStatus) const canApply = allowedStatuses.includes(record.procurementStatus)
console.log(`设备 ${record.equipmentName} 采购状态: ${record.procurementStatus}, 可申请: ${canApply}`)
//
console.log(`🔍 申请采购按钮显示检查 - 设备: ${record.equipmentName}`)
console.log(`🔍 当前采购状态: ${record.procurementStatus}`)
console.log(`🔍 允许申请的状态: ${allowedStatuses.join(', ')}`)
console.log(`🔍 是否显示按钮: ${canApply}`)
console.log(`🔍 完整记录:`, record)
return canApply return canApply
} }
// //
const canReceiveGoods = (record: EquipmentResp) => { const canReceiveGoods = (record: EquipmentResp) => {
const receiptStatus = (record as any).receiptStatus //
return receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED' const procurementStatus = record.procurementStatus
const receiptStatus = record.receiptStatus
console.log('🔍 canReceiveGoods 检查:', {
equipmentName: record.equipmentName,
procurementStatus,
receiptStatus,
canReceive: procurementStatus === 'APPROVED' &&
(receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED')
})
return procurementStatus === 'APPROVED' &&
(receiptStatus === 'NOT_RECEIVED' || receiptStatus === 'PARTIALLY_RECEIVED')
} }
// //
@ -1021,7 +1082,10 @@ const handleViewReceipt = (record: EquipmentResp) => {
// //
const handleReceiptSuccess = () => { const handleReceiptSuccess = () => {
receiptModalVisible.value = false receiptModalVisible.value = false
//
//
loadData(currentSearchParams.value) loadData(currentSearchParams.value)
message.success('收货成功!设备已自动入库')
} }
// //
@ -1072,6 +1136,30 @@ const getApprovalStatusText = (status: string) => {
return textMap[status] || '未知' return textMap[status] || '未知'
} }
//
const handleRefreshRecord = async (record: EquipmentResp) => {
console.log('🔄 手动刷新记录:', record.equipmentId)
try {
//
const loadingMessage = message.loading('正在刷新数据...')
//
await loadData(currentSearchParams.value)
//
if (loadingMessage && typeof loadingMessage.close === 'function') {
loadingMessage.close()
}
message.success('记录状态已刷新')
console.log('✅ 表格数据刷新完成')
} catch (error: any) {
console.error('❌ 刷新失败:', error)
message.error(error?.message || '刷新失败')
}
}
onMounted(() => { onMounted(() => {
loadData() loadData()
}) })