feat(mes): 新增批次号字段并重命名收货地址字段

pull/871/MERGE
YunaiV 2026-03-30 20:56:41 +08:00
parent 7e3693d18c
commit 47355814a2
3 changed files with 84 additions and 41 deletions

View File

@ -42,6 +42,7 @@
v-model="formData.quantity"
:precision="2"
:min="0"
:max="quantityMax"
controls-position="right"
class="!w-1/1"
/>
@ -56,6 +57,7 @@
<script setup lang="ts">
import { WmProductSalesDetailApi, WmProductSalesDetailVO } from '@/api/mes/wm/productsales/detail'
import { WmMaterialStockVO } from '@/api/mes/wm/materialstock'
import MdItemSelect from '@/views/mes/md/item/components/MdItemSelect.vue'
import WmWarehouseSelect from '@/views/mes/wm/warehouse/components/WmWarehouseSelect.vue'
import WmWarehouseLocationSelect from '@/views/mes/wm/warehouse/components/WmWarehouseLocationSelect.vue'
@ -93,11 +95,10 @@ const formData = ref({
batchId: undefined as number | undefined,
batchCode: undefined as string | undefined
})
const quantityMax = ref<number | undefined>(undefined) //
const formRules = reactive({
itemId: [{ required: true, message: '物料不能为空', trigger: 'change' }],
warehouseId: [{ required: true, message: '出库仓库不能为空', trigger: 'change' }],
locationId: [{ required: true, message: '库区不能为空', trigger: 'change' }],
areaId: [{ required: true, message: '库位不能为空', trigger: 'change' }],
materialStockId: [{ required: true, message: '请选择库存记录', trigger: 'change' }],
quantity: [{ required: true, message: '数量不能为空', trigger: 'blur' }]
})
@ -127,16 +128,25 @@ const handleBatchChange = (batch: any) => {
formData.value.batchCode = batch?.code
}
/** 库存选中回调,自动填充仓库/库区/库位/批次 */
// TODO @AI handleStockChange
const handleStockChange = (stock: any) => {
if (stock) {
formData.value.warehouseId = stock.warehouseId
formData.value.locationId = stock.locationId
formData.value.areaId = stock.areaId
formData.value.batchId = stock.batchId
formData.value.batchCode = stock.batchCode
/** 库存选中回调 —— 自动回填仓库/库区/库位/批次/数量 */
const handleStockChange = (stock: WmMaterialStockVO | undefined) => {
if (!stock) {
formData.value.warehouseId = undefined
formData.value.locationId = undefined
formData.value.areaId = undefined
formData.value.batchId = undefined
formData.value.batchCode = undefined
formData.value.quantity = undefined
quantityMax.value = undefined
return
}
formData.value.warehouseId = stock.warehouseId
formData.value.locationId = stock.locationId
formData.value.areaId = stock.areaId
formData.value.batchId = stock.batchId
formData.value.batchCode = stock.batchCode
formData.value.quantity = stock.quantity
quantityMax.value = stock.quantity
}
/** 提交表单 */
@ -181,6 +191,7 @@ const resetForm = () => {
batchId: undefined,
batchCode: undefined
}
quantityMax.value = undefined
formRef.value?.resetFields()
}
</script>

View File

@ -30,10 +30,14 @@
/>
</el-form-item>
</el-col>
<!-- TODO @AI选择完自动填写 salesOrderCode客户 -->
<!-- 选择发货通知单自动填写 salesOrderCode客户收货人等 -->
<el-col :span="8">
<el-form-item label="发货通知单" prop="noticeId">
<WmSalesNoticeSelect v-model="formData.noticeId" :disabled="isHeaderReadonly" />
<WmSalesNoticeSelect
v-model="formData.noticeId"
:disabled="isHeaderReadonly"
@change="handleNoticeChange"
/>
</el-form-item>
</el-col>
</el-row>
@ -85,9 +89,9 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="收货地址" prop="address">
<el-form-item label="收货地址" prop="contactAddress">
<el-input
v-model="formData.address"
v-model="formData.contactAddress"
placeholder="请输入收货地址"
:disabled="isHeaderReadonly"
/>
@ -106,8 +110,9 @@
</el-form-item>
</el-col>
</el-row>
<!-- TODO @AI可能要某个状态下才进行展示 -->
<el-divider content-position="left">运输信息</el-divider>
<!-- 运输信息填写运单/详情模式下展示或已有运输数据时展示 -->
<template v-if="isShipping || formType === 'detail' || formData.carrier || formData.shippingNumber">
<el-divider content-position="left">运输信息</el-divider>
<el-row>
<el-col :span="8">
<el-form-item label="承运商" prop="carrier">
@ -128,6 +133,7 @@
</el-form-item>
</el-col>
</el-row>
</template>
</el-form>
<!-- 非新建模式展示行项目信息出库物料 -->
<template v-if="formData.id">
@ -148,6 +154,9 @@
<el-button v-if="isShipping" @click="handleShipping" type="primary" :disabled="formLoading">
确认填写
</el-button>
<el-button v-if="isFinish" @click="handleFinish" type="primary" :disabled="formLoading">
确认出库
</el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template>
</Dialog>
@ -159,6 +168,7 @@ import { AutoCodeRecordApi } from '@/api/mes/md/autocode/record'
import { MesAutoCodeRuleCode } from '@/views/mes/utils/constants'
import MdClientSelect from '@/views/mes/md/client/components/MdClientSelect.vue'
import WmSalesNoticeSelect from '@/views/mes/wm/salesnotice/components/WmSalesNoticeSelect.vue'
import { WmSalesNoticeVO } from '@/api/mes/wm/salesnotice'
import ProductSalesLineList from './ProductSalesLineList.vue'
defineOptions({ name: 'ProductSalesForm' })
@ -167,7 +177,7 @@ const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) //
const formLoading = ref(false) //
const formType = ref<string>('create') // 表单的类型create / update / pick / shipping / detail
const formType = ref<string>('create') // 表单的类型create / update / stock / shipping / finish / detail
const formData = ref({
id: undefined as number | undefined,
code: undefined,
@ -178,7 +188,7 @@ const formData = ref({
salesDate: undefined,
contactName: undefined,
contactTelephone: undefined,
address: undefined,
contactAddress: undefined,
carrier: undefined,
shippingNumber: undefined,
remark: undefined
@ -192,15 +202,17 @@ const formRules = reactive({
const formRef = ref() // Ref
const isUpdate = computed(() => ['create', 'update'].includes(formType.value)) //
const isPick = computed(() => formType.value === 'pick') //
const isPick = computed(() => formType.value === 'stock') //
const isShipping = computed(() => formType.value === 'shipping') //
const isHeaderReadonly = computed(() => ['pick', 'shipping', 'detail'].includes(formType.value)) //
const isFinish = computed(() => formType.value === 'finish') //
const isHeaderReadonly = computed(() => ['stock', 'shipping', 'finish', 'detail'].includes(formType.value)) //
const dialogTitle = computed(() => {
const titles = {
create: '新增销售出库单',
update: '编辑销售出库单',
pick: '执行拣货',
stock: '执行拣货',
shipping: '填写运单',
finish: '执行出库',
detail: '销售出库单详情'
}
return titles[formType.value] || formType.value
@ -213,6 +225,18 @@ const generateCode = async () => {
)
}
/** 发货通知单选中后,自动填充 salesOrderCode、客户、收货人信息 */
const handleNoticeChange = (notice: WmSalesNoticeVO | undefined) => {
if (!notice) {
return
}
formData.value.salesOrderCode = notice.salesOrderCode
formData.value.clientId = notice.clientId
formData.value.contactName = notice.recipientName
formData.value.contactTelephone = notice.recipientTelephone
formData.value.contactAddress = notice.recipientAddress
}
/** 打开弹窗 */
const open = async (type: string, id?: number) => {
dialogVisible.value = true
@ -294,6 +318,21 @@ const handleShipping = async () => {
}
}
/** 执行出库 */
const handleFinish = async () => {
try {
await message.confirm('确认执行出库?执行后将扣减库存。')
formLoading.value = true
await WmProductSalesApi.finishProductSales(formData.value.id!)
message.success('出库成功')
dialogVisible.value = false
emit('success')
} catch {
} finally {
formLoading.value = false
}
}
/** 重置表单 */
const resetForm = () => {
formData.value = {
@ -306,7 +345,7 @@ const resetForm = () => {
salesDate: undefined,
contactName: undefined,
contactTelephone: undefined,
address: undefined,
contactAddress: undefined,
carrier: undefined,
shippingNumber: undefined,
remark: undefined

View File

@ -89,8 +89,13 @@
<ContentWrap>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
<!-- TODO @AI增加详情通过 code 打开 -->
<el-table-column label="出库单编号" align="center" prop="code" min-width="160" />
<el-table-column label="出库单编号" align="center" prop="code" min-width="160">
<template #default="scope">
<el-button link type="primary" @click="openForm('detail', scope.row.id)">
{{ scope.row.code }}
</el-button>
</template>
</el-table-column>
<el-table-column label="出库单名称" align="center" prop="name" min-width="150" />
<el-table-column label="发货通知单号" align="center" prop="noticeCode" min-width="160" />
<el-table-column label="销售订单编号" align="center" prop="salesOrderCode" min-width="160" />
@ -98,7 +103,7 @@
<el-table-column label="客户名称" align="center" prop="clientName" min-width="120" />
<el-table-column label="收货人" align="center" prop="contactName" min-width="100" />
<el-table-column label="联系方式" align="center" prop="contactTelephone" min-width="120" />
<el-table-column label="收货地址" align="center" prop="address" min-width="180" />
<el-table-column label="收货地址" align="center" prop="contactAddress" min-width="180" />
<el-table-column label="承运商" align="center" prop="carrier" min-width="120" />
<el-table-column label="运输单号" align="center" prop="shippingNumber" min-width="160" />
<el-table-column
@ -125,7 +130,6 @@
>
编辑
</el-button>
<!-- TODO @AI对齐 /Users/yunai/Java/yudao-all-in-one/yudao-ui-admin-vue3/src/views/mes/wm/itemreceipt 交互 -->
<el-button
link
type="warning"
@ -165,11 +169,10 @@
填写运单
</el-button>
<!-- 待出库执行出库取消 -->
<!-- TODO @AI对齐 /Users/yunai/Java/yudao-all-in-one/yudao-ui-admin-vue3/src/views/mes/wm/itemreceipt 交互 -->
<el-button
link
type="primary"
@click="handleFinish(scope.row.id)"
type="success"
@click="openForm('finish', scope.row.id)"
v-hasPermi="['mes:wm-product-sales:finish']"
v-if="scope.row.status === MesWmProductSalesStatusEnum.APPROVED"
>
@ -275,16 +278,6 @@ const handleSubmit = async (id: number) => {
} catch {}
}
/** 执行出库 */
const handleFinish = async (id: number) => {
try {
await message.confirm('确认执行出库?执行后将扣减库存。')
await WmProductSalesApi.finishProductSales(id)
message.success('出库成功')
await getList()
} catch {}
}
/** 取消按钮操作 */
const handleCancel = async (id: number) => {
try {