Commit f181e6a1 by 杨子

feat(ware): 重构入库单和出库单表单组件

将入库单和出库单的表单逻辑提取为独立组件
移除库存任务表单中不必要的字段验证
优化表单代码结构和复用性
parent 12f9f517
......@@ -88,12 +88,6 @@ const data = reactive({
warehouseId: [
{ required: true, message: "仓库不能为空", trigger: "change" }
],
areaIds: [
{ required: true, message: "库区不能为空", trigger: "change" }
],
materialIds: [
{ required: true, message: "物资不能为空", trigger: "change" }
]
}
})
......
<template>
<el-dialog :title="title" v-model="dialogVisible" width="1500px" append-to-body>
<el-form ref="wmsOutboundOrderRef" :model="form" :rules="rules" label-width="120px">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="出库单号" prop="orderNo">
<el-input v-model="form.orderNo" placeholder="请输入出库单号" disabled/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="出库类型" prop="orderType">
<el-radio-group v-model="form.orderType">
<el-radio v-for="item in outbound_type" :key="item.value" :label="item.value">{{ item.label }}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="仓库" prop="warehouseId">
<el-row :gutter="10">
<el-col :span="18">
<el-input v-model="form.warehouseName" placeholder="请选择仓库" readonly />
</el-col>
<el-col :span="6">
<el-button type="primary" @click="$emit('openWarehouseSelect')">选择仓库</el-button>
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="客户" prop="customerId">
<el-row :gutter="10">
<el-col :span="18">
<el-input v-model="form.customerName" placeholder="请选择客户" readonly />
</el-col>
<el-col :span="6">
<el-button type="primary" @click="$emit('openCustomerSelect')">选择客户</el-button>
</el-col>
</el-row>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总数量" prop="totalQuantity">
<el-input v-model="form.totalQuantity" placeholder="请输入总数量" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="总金额" prop="totalAmount">
<el-input v-model="form.totalAmount" placeholder="请输入总金额" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="操作人" prop="applicantId">
<el-input v-model="form.applicantName" placeholder="请输入申请人" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="操作时间" prop="applyTime">
<el-date-picker clearable
v-model="form.applyTime"
type="date"
value-format="YYYY-MM-DD"
disabled
placeholder="请选择操作时间">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="预计发货日期" prop="expectedDeliveryDate">
<el-date-picker clearable
v-model="form.expectedDeliveryDate"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择预计发货日期">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="出库原因" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
</el-row>
<!-- 出库单明细 -->
<el-divider>出库单明细</el-divider>
<el-row :gutter="20" style="margin-bottom: 10px;">
<el-col :span="24" style="text-align: right;">
<el-button type="primary" size="small" icon="Plus" @click="$emit('openMaterialSelect')">添加明细</el-button>
</el-col>
</el-row>
<el-table :data="form.items" border style="width: 100%">
<el-table-column prop="materialName" label="物资名称" width="150">
<template #default="scope">
<el-input v-model="scope.row.materialName" placeholder="请输入物资名称" size="small" disabled />
</template>
</el-table-column>
<el-table-column prop="planQuantity" label="计划数量" width="120">
<template #default="scope">
<el-input v-model.number="scope.row.planQuantity" placeholder="请输入计划数量" size="small" @change="calculateAmount(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="unit" label="单位" width="80">
<template #default="scope">
<el-input v-model="scope.row.unit" placeholder="请输入单位" size="small" disabled />
</template>
</el-table-column>
<el-table-column prop="unitPrice" label="单价" width="100">
<template #default="scope">
<el-input v-model.number="scope.row.unitPrice" placeholder="请输入单价" size="small" @change="calculateAmount(scope.row)" />
</template>
</el-table-column>
<el-table-column prop="amount" label="金额" width="100">
<template #default="scope">
<el-input v-model.number="scope.row.amount" placeholder="请输入金额" size="small" disabled />
</template>
</el-table-column>
<el-table-column prop="remark" label="备注">
<template #default="scope">
<el-input type="textarea" v-model="scope.row.remark" placeholder="请输入备注" size="small" />
</template>
</el-table-column>
<el-table-column label="操作" width="100" align="center" fixed="right">
<template #default="scope">
<el-button type="danger" size="small" icon="Delete" @click="deleteDetail(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
</template>
<script setup name="EditForm">
import { ref, reactive, watch } from 'vue'
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: ''
},
form: {
type: Object,
default: () => ({})
},
rules: {
type: Object,
default: () => ({})
},
outbound_type: {
type: Array,
default: () => []
}
})
const emit = defineEmits(['update:visible', 'submitSuccess', 'openWarehouseSelect', 'openCustomerSelect', 'openMaterialSelect', 'showError', 'showSuccess'])
const dialogVisible = ref(false)
const form = computed({
get() {
if (!props.form.items) {
props.form.items = []
}
return props.form
},
set(value) {
}
})
// 监听visible属性变化,更新对话框显示状态
watch(() => props.visible, (newVal) => {
dialogVisible.value = newVal
})
// 监听对话框显示状态变化,通知父组件
watch(dialogVisible, (newVal) => {
emit('update:visible', newVal)
})
/** 提交按钮 */
function submitForm() {
// 表单基础验证
if (wmsOutboundOrderRef.value) {
wmsOutboundOrderRef.value.validate(valid => {
if (valid) {
// 验证出库单明细
if (!form.value.items || form.value.items.length === 0) {
emit('showError', "请至少添加一条出库单明细")
return
}
// 验证每条明细的必填字段
for (let i = 0; i < form.value.items.length; i++) {
const detail = form.value.items[i]
if (!detail.materialId) {
emit('showError', `第${i + 1}条明细的物资ID不能为空`)
return
}
if (!detail.planQuantity) {
emit('showError', `第${i + 1}条明细的计划数量不能为空`)
return
}
// 确保数量为正数
if (detail.planQuantity <= 0) {
emit('showError', `第${i + 1}条明细的计划数量必须大于0`)
return
}
}
// 提交成功,通知父组件
emit('submitSuccess')
}
})
}
}
/** 计算明细金额 */
function calculateAmount(row) {
// 计划数量 * 单价 = 金额
if (row.planQuantity && row.unitPrice) {
// 计算金额并保留2位小数
row.amount = Number((row.planQuantity * row.unitPrice).toFixed(2))
} else {
row.amount = null
}
// 更新主表总数量和总金额
updateTotal()
}
/** 删除明细 */
function deleteDetail(index) {
form.value.items.splice(index, 1)
updateTotal()
}
/** 更新主表总数量和总金额 */
function updateTotal() {
if (!form.value.items || form.value.items.length === 0) {
form.value.totalQuantity = 0
form.value.totalAmount = 0
return
}
// 计算总数量(实际数量之和)
const totalQuantity = form.value.items.reduce((sum, item) => {
return sum + (item.planQuantity || 0)
}, 0)
// 计算总金额(金额之和)
const totalAmount = form.value.items.reduce((sum, item) => {
return sum + (item.amount || 0)
}, 0)
form.value.totalQuantity = totalQuantity
form.value.totalAmount = totalAmount
}
/** 取消按钮 */
function cancel() {
dialogVisible.value = false
}
/** 重置表单 */
function resetForm() {
if (wmsOutboundOrderRef.value) {
wmsOutboundOrderRef.value.resetFields()
}
}
// 获取当前组件实例
const { proxy } = getCurrentInstance()
// 暴露方法给父组件
const wmsOutboundOrderRef = ref(null)
defineExpose({
calculateAmount,
updateTotal,
resetForm
})
</script>
<style scoped>
/* 样式保持不变 */
</style>
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment