feat(wms): 优化发货单编辑页面的表单控制逻辑

- 将硬编码的路由参数条件判断替换为计算属性
- 新增抄送人员表单验证规则和动态显示逻辑
- 重构到货确认相关的表单和验证逻辑
- 移除未使用的到货确认接口导入
- 优化明细表格的编辑权限控制
- 调整流程变量传递逻辑,移除冗余的tManagerId字段
- 修复到货确认节点的审批流程处理方式
dev
zangch@mesnac.com 1 week ago
parent 69aeb3c17d
commit c862a2860b

@ -50,14 +50,7 @@
<template #header> <template #header>
<div style="text-align: left; font-weight: bold; font-size: 18px">基本信息</div> <div style="text-align: left; font-weight: bold; font-size: 18px">基本信息</div>
</template> </template>
<el-form <el-form ref="shippingBillFormRef" :model="form" :loading="buttonLoading" :disabled="mainFormDisabled" :rules="rules" label-width="120px">
ref="shippingBillFormRef"
:model="form"
:loading="buttonLoading"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
:rules="rules"
label-width="120px"
>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="发货单号" prop="shippingCode"> <el-form-item label="发货单号" prop="shippingCode">
@ -205,10 +198,10 @@
</el-col> </el-col>
</el-row> </el-row>
</el-form> </el-form>
<el-form label-width="120px"> <el-form v-if="isArrivalConfirmApprover" ref="copyManagerFormRef" :model="form" label-width="120px">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="抄送人员" prop="tManagerId"> <el-form-item label="抄送人员" prop="tManagerId" :rules="copyManagerRules">
<el-select <el-select
v-model="form.tManagerId" v-model="form.tManagerId"
placeholder="请选择抄送人员" placeholder="请选择抄送人员"
@ -261,20 +254,13 @@
</el-col> </el-col>
<el-col :span="3"> <el-col :span="3">
<!-- 物料来源切换 --> <!-- 物料来源切换 -->
<el-radio-group <el-radio-group v-model="materialSourceType" size="small" @change="handleMaterialSourceChange" :disabled="detailFormDisabled">
v-model="materialSourceType"
size="small"
@change="handleMaterialSourceChange"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
>
<!-- <el-radio-button value="1">ERP物料</el-radio-button>--> <!-- <el-radio-button value="1">ERP物料</el-radio-button>-->
<el-radio-button value="2">WMS物料</el-radio-button> <el-radio-button value="2">WMS物料</el-radio-button>
</el-radio-group> </el-radio-group>
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" icon="Plus" @click="handleAddDetail" v-if="routeParams.type !== 'view' && routeParams.type !== 'approval'"> <el-button type="primary" icon="Plus" @click="handleAddDetail" v-if="canEditDetailFields"> </el-button>
新增物料
</el-button>
</el-col> </el-col>
</el-row> </el-row>
</template> </template>
@ -294,7 +280,7 @@
size="small" size="small"
style="width: 100%" style="width: 100%"
@change="calculateTotalPrice(scope.row)" @change="calculateTotalPrice(scope.row)"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'" :disabled="detailFormDisabled"
/> />
</template> </template>
</el-table-column> </el-table-column>
@ -308,7 +294,7 @@
:controls="false" :controls="false"
size="small" size="small"
style="width: 100%" style="width: 100%"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'" :disabled="detailFormDisabled"
@change="calculateTotalPrice(scope.row)" @change="calculateTotalPrice(scope.row)"
/> />
</template> </template>
@ -320,15 +306,10 @@
</el-table-column> </el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="120"> <el-table-column label="备注" align="center" prop="remark" min-width="120">
<template #default="scope"> <template #default="scope">
<el-input <el-input v-model="scope.row.remark" placeholder="备注" size="small" :disabled="detailFormDisabled" />
v-model="scope.row.remark"
placeholder="备注"
size="small"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
/>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="80" fixed="right" v-if="routeParams.type !== 'view' && routeParams.type !== 'approval'"> <el-table-column label="操作" align="center" width="80" fixed="right" v-if="canEditDetailFields">
<template #default="scope"> <template #default="scope">
<el-button link type="danger" icon="Delete" @click="handleDeleteDetail(scope.$index)"></el-button> <el-button link type="danger" icon="Delete" @click="handleDeleteDetail(scope.$index)"></el-button>
</template> </template>
@ -457,14 +438,8 @@
</template> </template>
<script setup name="WmsShippingBillEdit" lang="ts"> <script setup name="WmsShippingBillEdit" lang="ts">
import { import { addWmsShippingBill, getWmsShippingBill, shippingBillSubmitAndFlowStart, updateWmsShippingBill } from '@/api/wms/wmsShippingBill';
addWmsShippingBill, import { WmsShippingBillForm } from '@/api/wms/wmsShippingBill/types';
arrivalConfirmShippingBill,
getWmsShippingBill,
shippingBillSubmitAndFlowStart,
updateWmsShippingBill
} from '@/api/wms/wmsShippingBill';
import { WmsShippingArrivalConfirmForm, WmsShippingBillForm } from '@/api/wms/wmsShippingBill/types';
import { useUserStore } from '@/store/modules/user'; import { useUserStore } from '@/store/modules/user';
import { getTask } from '@/api/workflow/task'; import { getTask } from '@/api/workflow/task';
import type { FlowTaskVO } from '@/api/workflow/task/types'; import type { FlowTaskVO } from '@/api/workflow/task/types';
@ -506,13 +481,19 @@ const { shipping_mode, shipping_status, shipping_bill_status, material_source_ty
const buttonLoading = ref(false); const buttonLoading = ref(false);
const shippingBillFormRef = ref<ElFormInstance>(); const shippingBillFormRef = ref<ElFormInstance>();
const arrivalConfirmFormRef = ref<ElFormInstance>(); const arrivalConfirmFormRef = ref<ElFormInstance>();
const copyManagerFormRef = ref<ElFormInstance>();
type ArrivalConfirmFormModel = {
shippingBillId: string | number;
isAllReceiving: string;
arrivalReceiptOssId: string;
};
// //
const arrivalConfirmForm = ref<WmsShippingArrivalConfirmForm>({ const arrivalConfirmForm = ref<ArrivalConfirmFormModel>({
shippingBillId: '', shippingBillId: '',
isAllReceiving: '0', isAllReceiving: '0',
arrivalReceiptOssId: '', arrivalReceiptOssId: ''
taskId: ''
}); });
watch( watch(
@ -524,32 +505,69 @@ watch(
const currentTask = ref<FlowTaskVO | null>(null); const currentTask = ref<FlowTaskVO | null>(null);
const isArrivalConfirmTask = computed(() => currentTask.value?.nodeCode === 'arrival-confirm');
const isCurrentTaskBusinessMatched = computed(() => {
const taskBusinessId = String(currentTask.value?.businessId || '').trim();
const shippingBillId = String(form.value.shippingBillId || '').trim();
if (!taskBusinessId) {
return true;
}
return taskBusinessId === shippingBillId;
});
// + + // + +
const isArrivalConfirmApprover = computed(() => { const isArrivalConfirmApprover = computed(() => {
return ( return (
routeParams.value.type === 'approval' && routeParams.value.type === 'approval' &&
form.value.needArrivalConfirm === '1' && String(form.value.needArrivalConfirm || '') === '1' &&
currentTask.value?.nodeCode === 'arrival-confirm' && isArrivalConfirmTask.value &&
String(currentTask.value?.businessId || '') === String(form.value.shippingBillId || '') && isCurrentTaskBusinessMatched.value &&
String(userStore.userId) === String(form.value.createBy) String(userStore.userId || '') === String(form.value.createBy || '')
); );
}); });
const isArrivalConfirmNode = computed(() => { const isViewMode = computed(() => routeParams.value.type === 'view');
return (
routeParams.value.type === 'approval' && const isDraftFlowStatus = computed(() => {
currentTask.value?.nodeCode === 'arrival-confirm' && if (!form.value.shippingBillId) {
String(currentTask.value?.businessId || '') === String(form.value.shippingBillId || '') return true;
); }
return String(form.value.flowStatus || '') === 'draft';
}); });
const canEditBusinessFields = computed(() => {
// 稿
return !isViewMode.value && routeParams.value.type !== 'approval' && isDraftFlowStatus.value;
});
const mainFormDisabled = computed(() => !canEditBusinessFields.value);
const canEditDetailFields = computed(() => canEditBusinessFields.value);
const detailFormDisabled = computed(() => !canEditDetailFields.value);
const validateCopyManager = (rule: any, value: unknown, callback: (error?: Error) => void) => {
if (!isArrivalConfirmApprover.value) {
callback();
return;
}
const selectedIds = toWorkflowUserIdArray(value);
if (!selectedIds || selectedIds.length === 0) {
callback(new Error('请选择抄送人员'));
return;
}
callback();
};
const copyManagerRules = [{ validator: validateCopyManager, trigger: 'change' }];
const canEditCopyManager = computed(() => { const canEditCopyManager = computed(() => {
if (routeParams.value.type === 'view') { if (isViewMode.value) {
return false; return false;
} }
const flowStatus = String(form.value.flowStatus || ''); //
// Why稿 return isArrivalConfirmApprover.value;
return flowStatus === 'draft' || isArrivalConfirmNode.value;
}); });
const copyManagerDisabled = computed(() => !canEditCopyManager.value); const copyManagerDisabled = computed(() => !canEditCopyManager.value);
@ -709,7 +727,7 @@ const buildFlowCopyVariables = async (submitData: WmsShippingBillForm) => {
} }
// //
// Why tManagerId // tManagerId
if (bindType === '2' && !tManagerId && submitData.contractId) { if (bindType === '2' && !tManagerId && submitData.contractId) {
try { try {
const contractRes = await getContractInfo(submitData.contractId); const contractRes = await getContractInfo(submitData.contractId);
@ -733,18 +751,21 @@ const buildFlowCopyVariables = async (submitData: WmsShippingBillForm) => {
}; };
const prepareTaskVariables = async () => { const prepareTaskVariables = async () => {
const { tManagerId } = await buildFlowCopyVariables(form.value as WmsShippingBillForm); if (!isArrivalConfirmApprover.value) {
if (tManagerId) { taskVariables.value = {};
// Why ${tManagerId}
taskVariables.value = { tManagerId };
return true; return true;
} }
// tManagerId const valid = await copyManagerFormRef.value?.validate().catch(() => false);
if (currentTask.value?.nodeCode === 'dept-leader') { if (!valid) {
proxy?.$modal.msgError('未获取到到货确认抄送人ID(tManagerId),请先维护合同负责人或项目抄送人员');
return false; return false;
} }
taskVariables.value = {}; const tManagerId = normalizeWorkflowUserIds((form.value as any).tManagerId);
if (!tManagerId) {
proxy?.$modal.msgError('请选择抄送人员');
return false;
}
// Why
taskVariables.value = { tManagerId };
return true; return true;
}; };
@ -755,7 +776,7 @@ const syncCopyManagerSelection = async () => {
} }
const { tManagerId } = await buildFlowCopyVariables(form.value as WmsShippingBillForm); const { tManagerId } = await buildFlowCopyVariables(form.value as WmsShippingBillForm);
if (tManagerId) { if (tManagerId) {
// Why orderActivate // orderActivate
(form.value as any).tManagerId = toWorkflowUserIdArray(tManagerId); (form.value as any).tManagerId = toWorkflowUserIdArray(tManagerId);
} }
}; };
@ -802,13 +823,13 @@ const submitContractSelect = () => {
/** 打开项目选择弹窗 */ /** 打开项目选择弹窗 */
const openProjectSelect = () => { const openProjectSelect = () => {
if (routeParams.value.type === 'view' || routeParams.value.type === 'approval') return; if (!canEditBusinessFields.value) return;
projectSelectRef.value?.open(); projectSelectRef.value?.open();
}; };
/** 打开合同选择弹窗 */ /** 打开合同选择弹窗 */
const openContractSelect = () => { const openContractSelect = () => {
if (routeParams.value.type === 'view' || routeParams.value.type === 'approval') return; if (!canEditBusinessFields.value) return;
contractDialog.visible = true; contractDialog.visible = true;
contractQueryParams.value.pageNum = 1; contractQueryParams.value.pageNum = 1;
getContractList(); getContractList();
@ -903,6 +924,9 @@ const handleMaterialSourceChange = () => {
/** 新增物料 */ /** 新增物料 */
const handleAddDetail = () => { const handleAddDetail = () => {
if (!canEditDetailFields.value) {
return;
}
if (materialSourceType.value === '1') { if (materialSourceType.value === '1') {
// ERP // ERP
saleMaterialSelectRef.value?.openDialog(); saleMaterialSelectRef.value?.openDialog();
@ -993,6 +1017,9 @@ const confirmWmsMaterialSelect = () => {
/** 删除明细 */ /** 删除明细 */
const handleDeleteDetail = (index: number) => { const handleDeleteDetail = (index: number) => {
if (!canEditDetailFields.value) {
return;
}
detailsList.value.splice(index, 1); detailsList.value.splice(index, 1);
}; };
@ -1017,19 +1044,12 @@ const submitForm = async (status: string, mode: boolean) => {
// //
// - // -
submitData.flowCode = FlowCodeEnum.SHIPPING_BILL_CODE; submitData.flowCode = FlowCodeEnum.SHIPPING_BILL_CODE;
const { tManagerId } = await buildFlowCopyVariables(submitData);
if (!tManagerId) {
proxy?.$modal.msgError('未获取到到货确认抄送人ID(tManagerId),请先维护合同负责人或项目抄送人员');
return;
}
submitData.tManagerId = tManagerId;
// //
submitData.variables = { submitData.variables = {
shippingBillId: submitData.shippingBillId, shippingBillId: submitData.shippingBillId,
shippingCode: submitData.shippingCode, shippingCode: submitData.shippingCode,
projectName: submitData.projectName, projectName: submitData.projectName,
customerName: submitData.customerName, customerName: submitData.customerName
tManagerId
}; };
// //
submitData.bizExt = { submitData.bizExt = {
@ -1158,11 +1178,28 @@ const handleApprovalRecord = () => {
// //
const submitCallback = async () => { const submitCallback = async () => {
if (isArrivalConfirmApprover.value) {
const valid = await arrivalConfirmFormRef.value?.validate().catch(() => false);
if (!valid) return;
const saveData: WmsShippingBillForm = {
shippingBillId: form.value.shippingBillId,
projectId: form.value.projectId,
contractId: form.value.contractId,
isAllReceiving: arrivalConfirmForm.value.isAllReceiving,
arrivalReceiptOssId: arrivalConfirmForm.value.arrivalReceiptOssId,
//
shippingStatus: arrivalConfirmForm.value.isAllReceiving === '0' ? '3' : '2'
};
await updateWmsShippingBill(saveData);
form.value.isAllReceiving = saveData.isAllReceiving;
form.value.arrivalReceiptOssId = saveData.arrivalReceiptOssId;
form.value.shippingStatus = saveData.shippingStatus;
}
await proxy?.$tab.closePage(route); await proxy?.$tab.closePage(route);
router.go(-1); router.go(-1);
}; };
// //
const approvalVerifyOpen = async () => { const approvalVerifyOpen = async () => {
if (routeParams.value.type === 'approval' && routeParams.value.taskId) { if (routeParams.value.type === 'approval' && routeParams.value.taskId) {
const taskLoaded = await loadCurrentTask(); const taskLoaded = await loadCurrentTask();
@ -1172,22 +1209,9 @@ const approvalVerifyOpen = async () => {
} }
} }
if (isArrivalConfirmApprover.value) { if (isArrivalConfirmApprover.value) {
// // submitCallback
//
const valid = await arrivalConfirmFormRef.value?.validate().catch(() => false); const valid = await arrivalConfirmFormRef.value?.validate().catch(() => false);
if (!valid) return; if (!valid) return;
//
arrivalConfirmForm.value.shippingBillId = form.value.shippingBillId!;
arrivalConfirmForm.value.taskId = String(routeParams.value.taskId);
try {
const res = await arrivalConfirmShippingBill(arrivalConfirmForm.value);
Object.assign(form.value, res.data);
arrivalConfirmForm.value.isAllReceiving = res.data.isAllReceiving || arrivalConfirmForm.value.isAllReceiving;
arrivalConfirmForm.value.arrivalReceiptOssId = res.data.arrivalReceiptOssId || arrivalConfirmForm.value.arrivalReceiptOssId;
} catch (error) {
console.error('到货确认保存失败:', error);
return;
}
} }
const prepared = await prepareTaskVariables(); const prepared = await prepareTaskVariables();
if (!prepared) return; if (!prepared) return;

@ -33,7 +33,7 @@
<el-option v-for="dict in need_arrival_confirm" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in need_arrival_confirm" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item label="到货标识" prop="isAllReceiving"> <el-form-item label="是否全部到货" prop="isAllReceiving">
<el-select v-model="queryParams.isAllReceiving" placeholder="请选择到货标识" clearable style="width: 180px"> <el-select v-model="queryParams.isAllReceiving" placeholder="请选择到货标识" clearable style="width: 180px">
<el-option v-for="dict in is_all_receiving" :key="dict.value" :label="dict.label" :value="dict.value" /> <el-option v-for="dict in is_all_receiving" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select> </el-select>

Loading…
Cancel
Save