510 lines
16 KiB
Vue
510 lines
16 KiB
Vue
<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"
|
|
value-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: '',
|
|
|
|
// 设备基本信息(从采购数据继承)
|
|
equipmentName: '',
|
|
equipmentModel: '',
|
|
equipmentType: '',
|
|
equipmentSn: '',
|
|
brand: '',
|
|
specification: '',
|
|
assetCode: '',
|
|
|
|
// 采购信息(从采购数据继承)
|
|
purchaseOrder: '',
|
|
supplierName: '',
|
|
purchasePrice: 0,
|
|
purchaseTime: '',
|
|
quantity: 1,
|
|
unitPrice: 0,
|
|
totalPrice: 0,
|
|
|
|
// 入库信息
|
|
inStockTime: '',
|
|
physicalLocation: '',
|
|
locationStatus: '',
|
|
responsiblePerson: '',
|
|
inventoryBarcode: '',
|
|
|
|
// 状态信息
|
|
equipmentStatus: '',
|
|
useStatus: '',
|
|
healthStatus: '',
|
|
receiptStatus: '',
|
|
|
|
// 其他管理信息
|
|
depreciationMethod: '',
|
|
depreciationYears: 5,
|
|
salvageValue: 0,
|
|
currentNetValue: 0,
|
|
|
|
// 系统字段
|
|
createTime: '',
|
|
updateTime: ''
|
|
})
|
|
|
|
// 表单验证规则
|
|
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: '请选择检查结果' }
|
|
],
|
|
}
|
|
|
|
// 初始化表单数据
|
|
const initFormData = () => {
|
|
if (props.equipmentData) {
|
|
// 从设备数据中复制相关字段
|
|
Object.keys(formData).forEach((key) => {
|
|
const formKey = key as keyof ReceiptRequest
|
|
const equipmentKey = key as keyof EquipmentResp
|
|
if (formKey in formData && equipmentKey in props.equipmentData!) {
|
|
const value = props.equipmentData![equipmentKey]
|
|
if (value !== undefined) {
|
|
(formData[formKey] as any) = value
|
|
}
|
|
}
|
|
})
|
|
|
|
// 设置默认值
|
|
formData.receiptQuantity = props.equipmentData.quantity || 1
|
|
formData.storageLocation = props.equipmentData.physicalLocation || ''
|
|
formData.storageManager = props.equipmentData.responsiblePerson || ''
|
|
|
|
// 设置收货时间默认为当前时间
|
|
formData.receiptTime = formatDateTime(new Date())
|
|
}
|
|
}
|
|
|
|
// 监听弹窗显示状态
|
|
watch(() => props.visible, (visible) => {
|
|
if (visible) {
|
|
initFormData()
|
|
formRef.value?.clearValidate()
|
|
}
|
|
})
|
|
|
|
// 监听设备数据变化
|
|
watch(() => props.equipmentData, () => {
|
|
if (props.visible && props.equipmentData) {
|
|
initFormData()
|
|
}
|
|
}, { deep: true })
|
|
|
|
// 提交表单
|
|
const handleSubmit = async () => {
|
|
try {
|
|
await formRef.value?.validate()
|
|
loading.value = true
|
|
|
|
if (!props.equipmentData?.equipmentId) {
|
|
throw new Error('设备ID不能为空')
|
|
}
|
|
|
|
console.log('📦 开始提交收货数据...')
|
|
console.log('📦 设备数据:', props.equipmentData)
|
|
console.log('📦 表单数据:', formData)
|
|
|
|
// 构建收货请求数据
|
|
const receiptData: ReceiptRequest = {
|
|
// 收货特有信息
|
|
receiptTime: formData.receiptTime ? formatDateTime(formData.receiptTime) : formatDateTime(new Date()),
|
|
receiptPerson: formData.receiptPerson,
|
|
receiptQuantity: formData.receiptQuantity,
|
|
receiptRemark: formData.receiptRemark,
|
|
appearanceCheck: formData.appearanceCheck,
|
|
functionTest: formData.functionTest,
|
|
packageIntegrity: formData.packageIntegrity,
|
|
accessoryIntegrity: formData.accessoryIntegrity,
|
|
checkResult: formData.checkResult,
|
|
checkRemark: formData.checkRemark,
|
|
storageLocation: formData.storageLocation,
|
|
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',
|
|
useStatus: '0',
|
|
healthStatus: 'good',
|
|
receiptStatus: 'RECEIVED',
|
|
|
|
// 其他管理信息
|
|
depreciationMethod: props.equipmentData.depreciationMethod || 'straight_line',
|
|
depreciationYears: props.equipmentData.depreciationYears || 5,
|
|
salvageValue: props.equipmentData.salvageValue || 0,
|
|
currentNetValue: props.equipmentData.purchasePrice || 0,
|
|
|
|
// 系统字段
|
|
createTime: formatDateTime(new Date()),
|
|
updateTime: formatDateTime(new Date())
|
|
}
|
|
|
|
console.log('📦 构建的收货数据:', receiptData)
|
|
|
|
// 调用收货API
|
|
await equipmentProcurementApi.receiveGoods(
|
|
props.equipmentData.equipmentId,
|
|
receiptData
|
|
)
|
|
|
|
Message.success('收货成功,设备已自动入库')
|
|
emit('success')
|
|
emit('update:visible', false)
|
|
} catch (error: any) {
|
|
console.error('收货失败:', error)
|
|
Message.error(error?.message || '收货失败,请检查表单信息')
|
|
} finally {
|
|
loading.value = false
|
|
}
|
|
}
|
|
|
|
// 生成库存条码的辅助函数
|
|
const generateInventoryBarcode = () => {
|
|
const timestamp = Date.now().toString(36)
|
|
const random = Math.random().toString(36).substr(2, 5)
|
|
return `INV-${timestamp}-${random}`.toUpperCase()
|
|
}
|
|
|
|
// 格式化日期时间
|
|
const formatDateTime = (date: string | Date) => {
|
|
const d = new Date(date);
|
|
let month = '' + (d.getMonth() + 1);
|
|
let day = '' + d.getDate();
|
|
const year = d.getFullYear();
|
|
if (month.length < 2)
|
|
month = '0' + month;
|
|
if (day.length < 2)
|
|
day = '0' + day;
|
|
return [year, month, day].join('-') + ' ' + [d.getHours(), d.getMinutes(), d.getSeconds()].join(':');
|
|
}
|
|
|
|
// 取消
|
|
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>
|