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

View File

@ -30,10 +30,14 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!-- TODO @AI选择完自动填写 salesOrderCode客户 --> <!-- 选择发货通知单自动填写 salesOrderCode客户收货人等 -->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="发货通知单" prop="noticeId"> <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-form-item>
</el-col> </el-col>
</el-row> </el-row>
@ -85,9 +89,9 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="收货地址" prop="address"> <el-form-item label="收货地址" prop="contactAddress">
<el-input <el-input
v-model="formData.address" v-model="formData.contactAddress"
placeholder="请输入收货地址" placeholder="请输入收货地址"
:disabled="isHeaderReadonly" :disabled="isHeaderReadonly"
/> />
@ -106,8 +110,9 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </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-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label="承运商" prop="carrier"> <el-form-item label="承运商" prop="carrier">
@ -128,6 +133,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</template>
</el-form> </el-form>
<!-- 非新建模式展示行项目信息出库物料 --> <!-- 非新建模式展示行项目信息出库物料 -->
<template v-if="formData.id"> <template v-if="formData.id">
@ -148,6 +154,9 @@
<el-button v-if="isShipping" @click="handleShipping" type="primary" :disabled="formLoading"> <el-button v-if="isShipping" @click="handleShipping" type="primary" :disabled="formLoading">
确认填写 确认填写
</el-button> </el-button>
<el-button v-if="isFinish" @click="handleFinish" type="primary" :disabled="formLoading">
确认出库
</el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button @click="dialogVisible = false"> </el-button>
</template> </template>
</Dialog> </Dialog>
@ -159,6 +168,7 @@ import { AutoCodeRecordApi } from '@/api/mes/md/autocode/record'
import { MesAutoCodeRuleCode } from '@/views/mes/utils/constants' import { MesAutoCodeRuleCode } from '@/views/mes/utils/constants'
import MdClientSelect from '@/views/mes/md/client/components/MdClientSelect.vue' import MdClientSelect from '@/views/mes/md/client/components/MdClientSelect.vue'
import WmSalesNoticeSelect from '@/views/mes/wm/salesnotice/components/WmSalesNoticeSelect.vue' import WmSalesNoticeSelect from '@/views/mes/wm/salesnotice/components/WmSalesNoticeSelect.vue'
import { WmSalesNoticeVO } from '@/api/mes/wm/salesnotice'
import ProductSalesLineList from './ProductSalesLineList.vue' import ProductSalesLineList from './ProductSalesLineList.vue'
defineOptions({ name: 'ProductSalesForm' }) defineOptions({ name: 'ProductSalesForm' })
@ -167,7 +177,7 @@ const message = useMessage() // 消息弹窗
const dialogVisible = ref(false) // const dialogVisible = ref(false) //
const formLoading = 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({ const formData = ref({
id: undefined as number | undefined, id: undefined as number | undefined,
code: undefined, code: undefined,
@ -178,7 +188,7 @@ const formData = ref({
salesDate: undefined, salesDate: undefined,
contactName: undefined, contactName: undefined,
contactTelephone: undefined, contactTelephone: undefined,
address: undefined, contactAddress: undefined,
carrier: undefined, carrier: undefined,
shippingNumber: undefined, shippingNumber: undefined,
remark: undefined remark: undefined
@ -192,15 +202,17 @@ const formRules = reactive({
const formRef = ref() // Ref const formRef = ref() // Ref
const isUpdate = computed(() => ['create', 'update'].includes(formType.value)) // 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 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 dialogTitle = computed(() => {
const titles = { const titles = {
create: '新增销售出库单', create: '新增销售出库单',
update: '编辑销售出库单', update: '编辑销售出库单',
pick: '执行拣货', stock: '执行拣货',
shipping: '填写运单', shipping: '填写运单',
finish: '执行出库',
detail: '销售出库单详情' detail: '销售出库单详情'
} }
return titles[formType.value] || formType.value 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) => { const open = async (type: string, id?: number) => {
dialogVisible.value = true 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 = () => { const resetForm = () => {
formData.value = { formData.value = {
@ -306,7 +345,7 @@ const resetForm = () => {
salesDate: undefined, salesDate: undefined,
contactName: undefined, contactName: undefined,
contactTelephone: undefined, contactTelephone: undefined,
address: undefined, contactAddress: undefined,
carrier: undefined, carrier: undefined,
shippingNumber: undefined, shippingNumber: undefined,
remark: undefined remark: undefined

View File

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