feat(wmsShippingBill): 新增发货单管理功能页面和编辑页

- 实现发货单编辑页面,支持发货单号生成及多种发货方式选择
- 实现项目和合同绑定,支持项目选择和合同选择弹窗
- 支持客户、供应商、仓库等基础信息联动与自动带入
- 提供物流信息录入,包括物流公司、运单号和联系电话
- 实现发货明细管理,支持ERP和WMS物料切换和物料新增删除
- 增加审批相关功能,集成审批按钮、提交审批及审批记录组件
- 实现发货单列表查询页面,支持多条件搜索和数据表格展示
- 列表增加权限控制,支持新增、修改、删除和导出操作按钮
- 加载并显示下拉选项数据,提高表单交互体验
- 实现暂存和提交审批不同状态处理逻辑,确保业务流程正确
dev
zangch@mesnac.com 2 months ago
parent ad81d2028e
commit d830fd551d

@ -0,0 +1,903 @@
<template>
<div class="p-2">
<!-- 审批按钮组件 -->
<el-card shadow="never" style="margin-top: 0">
<approvalButton
@submitForm="submitForm"
@approvalVerifyOpen="approvalVerifyOpen"
@handleApprovalRecord="handleApprovalRecord"
:buttonLoading="buttonLoading"
:id="form.shippingBillId"
:status="form.flowStatus"
:pageType="routeParams.type"
:mode="false"
/>
</el-card>
<!-- 基本信息区域 -->
<el-card shadow="never" style="margin-top: 0">
<template #header>
<div style="text-align: left; font-weight: bold; font-size: 18px">基本信息</div>
</template>
<el-form
ref="shippingBillFormRef"
:model="form"
:loading="buttonLoading"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
:rules="rules"
label-width="120px"
>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="发货单号" prop="shippingCode">
<el-input v-model="form.shippingCode" placeholder="请输入发货单号">
<template #append>
<el-button type="primary" @click="generateShippingCode" :disabled="isCodeGenerated">生成单号</el-button>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="发货方式" prop="shippingMode">
<el-select v-model="form.shippingMode" placeholder="请选择发货方式" style="width: 100%">
<el-option v-for="dict in shipping_mode" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="绑定类型" prop="bindType">
<el-radio-group v-model="form.bindType">
<el-radio-button label="1">按项目</el-radio-button>
<el-radio-button label="2">按合同</el-radio-button>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.bindType === '1'">
<el-form-item label="项目" prop="projectId">
<el-input v-model="selectedProjectName" placeholder="请选择项目" readonly>
<template #suffix>
<el-icon style="cursor: pointer" @click="openProjectSelect">
<Search />
</el-icon>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.bindType === '1'">
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="form.projectCode" disabled placeholder="自动带入" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.bindType === '2'">
<el-form-item label="合同" prop="contractId">
<el-input v-model="selectedContractName" placeholder="请选择合同" readonly>
<template #suffix>
<el-icon style="cursor: pointer" @click="openContractSelect">
<Search />
</el-icon>
</template>
</el-input>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.bindType === '2'">
<el-form-item label="合同编号" prop="contractCode">
<el-input v-model="form.contractCode" disabled placeholder="自动带入" />
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.bindType === '2' && selectedSapOrderCode">
<el-form-item label="SAP订单号">
<el-input v-model="selectedSapOrderCode" disabled placeholder="自动带入" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="客户" prop="customerId">
<el-select v-model="form.customerId" placeholder="请选择客户" filterable style="width: 100%" @change="handleCustomerChange">
<el-option v-for="item in customerList" :key="item.customerId" :label="item.customerName" :value="item.customerId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="收货地址" prop="shippingAddress">
<el-input v-model="form.shippingAddress" placeholder="请输入收货地址" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="收货联系人" prop="receiverName">
<el-input v-model="form.receiverName" placeholder="请输入收货联系人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="收货联系电话" prop="receiverPhone">
<el-input v-model="form.receiverPhone" placeholder="请输入收货联系电话" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计划到货时间" prop="planArrivalTime">
<el-date-picker
v-model="form.planArrivalTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择计划到货时间"
style="width: 100%"
/>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.shippingMode === '2'">
<el-form-item label="供应商" prop="supplierId">
<el-select v-model="form.supplierId" placeholder="请选择供应商" filterable style="width: 100%" @change="handleSupplierChange">
<el-option v-for="item in supplierList" :key="item.supplierId" :label="item.supplierName" :value="item.supplierId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12" v-if="form.shippingMode === '1'">
<el-form-item label="发货仓库" prop="warehouseId">
<el-select v-model="form.warehouseId" placeholder="请选择仓库" filterable style="width: 100%" @change="handleWarehouseChange">
<el-option v-for="item in warehouseList" :key="item.warehouseId" :label="item.warehouseName" :value="item.warehouseId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="24">
<el-form-item label="发货说明" prop="directions">
<el-input v-model="form.directions" type="textarea" placeholder="请输入发货说明" :rows="2" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 物流信息区域 -->
<el-card shadow="never" style="margin-top: 0">
<template #header>
<div style="text-align: left; font-weight: bold; font-size: 18px">物流信息</div>
</template>
<el-form :model="form" :disabled="routeParams.type === 'view' || routeParams.type === 'approval'" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物流公司" prop="logisticsCompany">
<el-input v-model="form.logisticsCompany" placeholder="请输入物流公司" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="运单号" prop="trackingNo">
<el-input v-model="form.trackingNo" placeholder="请输入运单号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物流联系电话" prop="logisticsPhone">
<el-input v-model="form.logisticsPhone" placeholder="请输入物流联系电话" />
</el-form-item>
</el-col>
</el-row>
</el-form>
</el-card>
<!-- 发货明细区域 -->
<el-card shadow="never" style="margin-top: 0">
<template #header>
<el-row :gutter="10" type="flex" align="middle">
<el-col :span="1.5">
<span style="font-weight: bold; font-size: 18px">发货明细</span>
</el-col>
<el-col :span="3">
<!-- 物料来源切换 -->
<el-radio-group
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="2">WMS物料</el-radio-button>
</el-radio-group>
</el-col>
<el-col :span="1.5">
<el-button type="primary" icon="Plus" @click="handleAddDetail" v-if="routeParams.type !== 'view' && routeParams.type !== 'approval'">
新增物料
</el-button>
</el-col>
</el-row>
</template>
<el-table :data="detailsList" v-loading="buttonLoading" border>
<el-table-column type="index" label="序号" width="60" align="center" />
<el-table-column label="物料编码" align="center" prop="materialCode" min-width="120" />
<el-table-column label="物料名称" align="center" prop="materialName" min-width="150" />
<el-table-column label="规格型号" align="center" prop="materielSpecification" min-width="120" />
<el-table-column label="批次号" align="center" prop="batchNumber" width="120" />
<el-table-column label="发货数量" align="center" prop="shippingStockAmount" width="120">
<template #default="scope">
<el-input-number
v-model="scope.row.shippingStockAmount"
:min="0"
:precision="2"
size="small"
style="width: 100%"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
/>
</template>
</el-table-column>
<el-table-column label="单位" align="center" prop="unitName" width="80" />
<el-table-column label="单价" align="center" prop="unitPrice" width="100">
<template #default="scope">
<el-input-number
v-model="scope.row.unitPrice"
:min="0"
:precision="2"
:controls="false"
size="small"
style="width: 100%"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
@change="calculateTotalPrice(scope.row)"
/>
</template>
</el-table-column>
<el-table-column label="总价" align="center" prop="totalPrice" width="100">
<template #default="scope">
{{ scope.row.totalPrice ? Number(scope.row.totalPrice).toFixed(2) : '0.00' }}
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="120">
<template #default="scope">
<el-input
v-model="scope.row.remark"
placeholder="备注"
size="small"
:disabled="routeParams.type === 'view' || routeParams.type === 'approval'"
/>
</template>
</el-table-column>
<el-table-column label="操作" align="center" width="80" fixed="right" v-if="routeParams.type !== 'view' && routeParams.type !== 'approval'">
<template #default="scope">
<el-button link type="danger" icon="Delete" @click="handleDeleteDetail(scope.$index)"></el-button>
</template>
</el-table-column>
</el-table>
</el-card>
<!-- ERP物料选择对话框 -->
<SaleMaterialSelect ref="saleMaterialSelectRef" :multiple="true" @confirm-call-back="erpMaterialSelectCallBack" />
<!-- 项目选择对话框 -->
<ProjectSelect ref="projectSelectRef" :multiple="false" @confirm-call-back="projectInfoSelectCallBack" />
<!-- 合同选择对话框 -->
<el-dialog title="选择合同" v-model="contractDialog.visible" width="900px" append-to-body>
<el-form :model="contractQueryParams" :inline="true" label-width="100px">
<el-form-item label="合同编号">
<el-input
v-model="contractQueryParams.contractCode"
placeholder="请输入合同编号"
clearable
style="width: 200px"
@keyup.enter="getContractList"
/>
</el-form-item>
<el-form-item label="合同名称">
<el-input
v-model="contractQueryParams.contractName"
placeholder="请输入合同名称"
clearable
style="width: 200px"
@keyup.enter="getContractList"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="getContractList"></el-button>
<el-button icon="Refresh" @click="resetContractQuery"></el-button>
</el-form-item>
</el-form>
<el-table v-loading="contractLoading" :data="contractList" border @row-click="handleContractRowClick" max-height="400">
<el-table-column label="合同编号" align="center" prop="contractCode" min-width="120" />
<el-table-column label="合同名称" align="center" prop="contractName" min-width="180" show-overflow-tooltip />
<el-table-column label="合同总价" align="center" prop="totalPrice" min-width="120" />
</el-table>
<pagination
v-show="contractTotal > 0"
:total="contractTotal"
v-model:page="contractQueryParams.pageNum"
v-model:limit="contractQueryParams.pageSize"
@pagination="getContractList"
/>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitContractSelect"> </el-button>
<el-button @click="contractDialog.visible = false"> </el-button>
</div>
</template>
</el-dialog>
<!-- WMS物料选择对话框 -->
<el-dialog title="选择WMS物料" v-model="wmsMaterialDialog.visible" width="900px" append-to-body>
<el-form :model="wmsMaterialQueryParams" :inline="true" label-width="100px">
<el-form-item label="物料编码">
<el-input
v-model="wmsMaterialQueryParams.productCode"
placeholder="请输入物料编码"
clearable
style="width: 180px"
@keyup.enter="getWmsMaterialList"
/>
</el-form-item>
<el-form-item label="物料名称">
<el-input
v-model="wmsMaterialQueryParams.productName"
placeholder="请输入物料名称"
clearable
style="width: 180px"
@keyup.enter="getWmsMaterialList"
/>
</el-form-item>
<el-form-item label="仓库">
<el-select v-model="wmsMaterialQueryParams.warehouseId" placeholder="请选择仓库" clearable style="width: 180px">
<el-option v-for="item in warehouseList" :key="item.warehouseId" :label="item.warehouseName" :value="item.warehouseId" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="getWmsMaterialList"></el-button>
</el-form-item>
</el-form>
<el-table
ref="wmsMaterialTableRef"
:data="wmsMaterialList"
v-loading="wmsMaterialLoading"
border
@selection-change="handleWmsMaterialSelectionChange"
>
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="物料编码" align="center" prop="productCode" min-width="120" />
<el-table-column label="物料名称" align="center" prop="productName" min-width="150" />
<el-table-column label="规格型号" align="center" prop="productSpe" min-width="120" />
<el-table-column label="仓库" align="center" prop="warehouseName" width="100" />
<el-table-column label="批次号" align="center" prop="batchNumber" width="120" />
<el-table-column label="库存数量" align="center" prop="inventoryAmount" width="100" />
<el-table-column label="单价" align="center" prop="unitPrice" width="80" />
</el-table>
<pagination
v-show="wmsMaterialTotal > 0"
:total="wmsMaterialTotal"
v-model:page="wmsMaterialQueryParams.pageNum"
v-model:limit="wmsMaterialQueryParams.pageSize"
@pagination="getWmsMaterialList"
/>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="confirmWmsMaterialSelect"> </el-button>
<el-button @click="wmsMaterialDialog.visible = false"> </el-button>
</div>
</template>
</el-dialog>
<!-- 提交审批组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
<!-- 审批记录 -->
<approvalRecord ref="approvalRecordRef" />
</div>
</template>
<script setup name="WmsShippingBillEdit" lang="ts">
import { addWmsShippingBill, getWmsShippingBill, shippingBillSubmitAndFlowStart, updateWmsShippingBill } from '@/api/wms/wmsShippingBill';
import { WmsShippingBillForm } from '@/api/wms/wmsShippingBill/types';
import { WmsShippingDetailsForm } from '@/api/wms/wmsShippingDetails/types';
import { listInventoryDetails } from '@/api/wms/inventoryDetails';
import { InventoryDetailsQuery, InventoryDetailsVO } from '@/api/wms/inventoryDetails/types';
import { getWmsWarehouseInfoList } from '@/api/wms/warehouseInfo';
import { getCrmCustomerInfoList } from '@/api/oa/crm/customerInfo';
import { getCrmSupplierInfoList } from '@/api/oa/crm/crmSupplierInfo';
import { getRuleGenerateCode } from '@/api/system/codeRule';
import SaleMaterialSelect from '@/components/SaleMaterialSelect/index.vue';
import SubmitVerify from '@/components/Process/submitVerify.vue';
import ApprovalRecord from '@/components/Process/approvalRecord.vue';
import ApprovalButton from '@/components/Process/approvalButton.vue';
import ProjectSelect from '@/components/ProjectSelect/index.vue';
import type { ProjectInfoVO } from '@/api/oa/erp/projectInfo/types';
import { listContractInfo } from '@/api/oa/erp/contractInfo';
import type { ContractInfoQuery, ContractInfoVO } from '@/api/oa/erp/contractInfo/types';
import { CodeRuleEnum, FlowCodeEnum } from '@/enums/OAEnum';
import { Search } from '@element-plus/icons-vue';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const route = useRoute();
const router = useRouter();
//
const routeParams = ref<Record<string, any>>({});
//
const { shipping_mode, shipping_status, shipping_bill_status, material_source_type } = toRefs<any>(
proxy?.useDict('shipping_mode', 'shipping_status', 'shipping_bill_status', 'material_source_type')
);
const buttonLoading = ref(false);
const shippingBillFormRef = ref<ElFormInstance>();
//
const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>();
const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>();
//
const taskVariables = ref<Record<string, any>>({});
//
const isCodeGenerated = ref(false);
// 1-ERP2-WMS使WMS
const materialSourceType = ref('2');
//
const customerList = ref<any[]>([]);
const supplierList = ref<any[]>([]);
const warehouseList = ref<any[]>([]);
//
const selectedProjectName = ref<string>('');
const projectSelectRef = ref<InstanceType<typeof ProjectSelect>>();
//
const selectedContractName = ref<string>('');
const selectedSapOrderCode = ref<string>(''); // SAP
const contractDialog = reactive({ visible: false });
const contractLoading = ref(false);
const contractList = ref<ContractInfoVO[]>([]);
const contractTotal = ref(0);
const contractQueryParams = ref<ContractInfoQuery>({
pageNum: 1,
pageSize: 10,
contractStatus: '3'
});
const selectedContract = ref<ContractInfoVO | null>(null);
//
const detailsList = ref<WmsShippingDetailsForm[]>([]);
// ERP
const saleMaterialSelectRef = ref();
// WMS
const wmsMaterialDialog = reactive({ visible: false });
const wmsMaterialLoading = ref(false);
const wmsMaterialList = ref<InventoryDetailsVO[]>([]);
const wmsMaterialTotal = ref(0);
const selectedWmsMaterials = ref<InventoryDetailsVO[]>([]);
const wmsMaterialQueryParams = ref<InventoryDetailsQuery>({
pageNum: 1,
pageSize: 10,
productCode: undefined,
productName: undefined,
warehouseId: undefined
});
//
const initFormData: WmsShippingBillForm = {
shippingBillId: undefined,
shippingCode: undefined,
shippingType: undefined,
shippingMode: '1', //
bindType: '1',
projectId: undefined,
projectCode: undefined,
projectName: undefined,
customerId: undefined,
customerName: undefined,
shippingAddress: undefined,
receiverName: undefined,
receiverPhone: undefined,
supplierId: undefined,
supplier: undefined,
contactUser: undefined,
contactNumber: undefined,
logisticsCompany: undefined,
trackingNo: undefined,
logisticsPhone: undefined,
directions: undefined,
planArrivalTime: undefined,
shippingTime: undefined,
warehouseId: undefined,
warehouseName: undefined,
outStockBillStatus: '1', //
flowStatus: 'draft',
shippingStatus: '1', //
remark: undefined,
detailsList: []
};
const validateProjectOrContract = (rule: any, value: any, callback: any) => {
if (form.value.bindType === '1' && !form.value.projectId) {
callback(new Error('项目不能为空'));
return;
}
callback();
};
const validateContractWhenBind = (rule: any, value: any, callback: any) => {
if (form.value.bindType === '2' && !form.value.contractId) {
callback(new Error('合同不能为空'));
return;
}
callback();
};
const data = reactive<{ form: WmsShippingBillForm; rules: any }>({
form: { ...initFormData },
rules: {
shippingCode: [{ required: true, message: '发货单号不能为空', trigger: 'blur' }],
shippingMode: [{ required: true, message: '发货方式不能为空', trigger: 'change' }],
bindType: [{ required: true, message: '绑定类型不能为空', trigger: 'change' }],
projectId: [{ validator: validateProjectOrContract, trigger: 'change' }],
contractId: [{ validator: validateContractWhenBind, trigger: 'change' }],
customerId: [{ required: true, message: '客户不能为空', trigger: 'change' }]
}
});
const { form, rules } = toRefs(data);
/** 生成发货单号 */
const generateShippingCode = async () => {
if (isCodeGenerated.value) return; //
try {
const params = { codeRuleCode: CodeRuleEnum.SHIPPING_BILL } as any;
const res = await getRuleGenerateCode(params);
form.value.shippingCode = res.msg;
isCodeGenerated.value = true;
proxy?.$modal.msgSuccess('发货单号生成成功');
} catch (error) {
console.error('生成发货单号失败:', error);
}
};
const getContractList = async () => {
try {
contractLoading.value = true;
const res = await listContractInfo(contractQueryParams.value);
contractList.value = res.rows || [];
contractTotal.value = (res.total as number) || contractList.value.length;
} catch (error) {
console.error('查询合同列表失败:', error);
} finally {
contractLoading.value = false;
}
};
const resetContractQuery = () => {
contractQueryParams.value.contractCode = undefined;
contractQueryParams.value.contractName = undefined;
contractQueryParams.value.pageNum = 1;
getContractList();
};
const handleContractRowClick = (row: ContractInfoVO) => {
selectedContract.value = row;
};
const submitContractSelect = () => {
if (selectedContract.value) {
const contract = selectedContract.value;
form.value.contractId = contract.contractId as any;
form.value.contractCode = contract.contractCode || '';
form.value.contractName = contract.contractName || '';
selectedContractName.value = contract.contractName || '';
// SAP orderContractCode
selectedSapOrderCode.value = (contract as any).orderContractCode || '';
}
contractDialog.visible = false;
};
/** 打开项目选择弹窗 */
const openProjectSelect = () => {
if (routeParams.value.type === 'view' || routeParams.value.type === 'approval') return;
projectSelectRef.value?.open();
};
/** 打开合同选择弹窗 */
const openContractSelect = () => {
if (routeParams.value.type === 'view' || routeParams.value.type === 'approval') return;
contractDialog.visible = true;
contractQueryParams.value.pageNum = 1;
getContractList();
};
/** 项目选择回调 */
const projectInfoSelectCallBack = (data: ProjectInfoVO[]) => {
if (data && data.length > 0) {
const project = data[0];
form.value.projectId = project.projectId;
form.value.projectCode = project.projectCode || '';
form.value.projectName = project.projectName || '';
selectedProjectName.value = project.projectName || '';
//
if (project.customerId) {
form.value.customerId = project.customerId;
handleCustomerChange(project.customerId);
}
}
};
/** 客户选择变化 */
const handleCustomerChange = (customerId: any) => {
const customer = customerList.value.find((c) => c.customerId === customerId);
if (customer) {
form.value.customerName = customer.customerName;
form.value.shippingAddress = customer.address;
form.value.receiverName = customer.contactPerson;
form.value.receiverPhone = customer.contactPhone;
}
};
/** 供应商选择变化 */
const handleSupplierChange = (supplierId: any) => {
const supplier = supplierList.value.find((s) => s.supplierId === supplierId);
if (supplier) {
form.value.supplier = supplier.supplierName;
form.value.contactUser = supplier.contactPerson;
form.value.contactNumber = supplier.contactPhone;
}
};
/** 仓库选择变化 */
const handleWarehouseChange = (warehouseId: any) => {
const warehouse = warehouseList.value.find((w) => w.warehouseId === warehouseId);
if (warehouse) {
form.value.warehouseName = warehouse.warehouseName;
}
};
/** 物料来源切换 */
const handleMaterialSourceChange = () => {
//
//
};
/** 新增物料 */
const handleAddDetail = () => {
if (materialSourceType.value === '1') {
// ERP
saleMaterialSelectRef.value?.openDialog();
} else {
// WMS
wmsMaterialDialog.visible = true;
getWmsMaterialList();
}
};
/** ERP物料选择回调 */
const erpMaterialSelectCallBack = (materials: any[]) => {
if (materials && materials.length > 0) {
materials.forEach((material) => {
//
const exists = detailsList.value.some((d) => d.materialSourceType === '1' && d.erpMaterialId === material.materialId);
if (!exists) {
detailsList.value.push({
shippingDetailsId: undefined,
shippingBillId: form.value.shippingBillId,
materialSourceType: '1', // ERP
erpMaterialId: material.materialId,
wmsMaterialId: undefined,
materialCode: material.materialCode,
materialName: material.materialName,
materielSpecification: material.specificationModel,
batchNumber: undefined,
unitPrice: material.unitPrice || 0,
shippingStockAmount: 1,
unitId: material.unitId,
unitName: material.unitName,
totalPrice: material.unitPrice || 0,
remark: undefined
});
}
});
}
};
/** 获取WMS物料列表 */
const getWmsMaterialList = async () => {
wmsMaterialLoading.value = true;
try {
const res = await listInventoryDetails(wmsMaterialQueryParams.value);
wmsMaterialList.value = res.rows;
wmsMaterialTotal.value = res.total;
} finally {
wmsMaterialLoading.value = false;
}
};
/** WMS物料选择变化 */
const handleWmsMaterialSelectionChange = (selection: InventoryDetailsVO[]) => {
selectedWmsMaterials.value = selection;
};
/** 确认WMS物料选择 */
const confirmWmsMaterialSelect = () => {
if (selectedWmsMaterials.value.length > 0) {
selectedWmsMaterials.value.forEach((material) => {
//
const exists = detailsList.value.some((d) => d.materialSourceType === '2' && d.wmsMaterialId === material.inventoryDetailsId);
if (!exists) {
detailsList.value.push({
shippingDetailsId: undefined,
shippingBillId: form.value.shippingBillId,
materialSourceType: '2', // WMS
erpMaterialId: undefined,
wmsMaterialId: material.inventoryDetailsId,
warehouseId: material.warehouseId,
materielId: material.materielId,
materialCode: material.productCode,
materialName: material.productName,
materielSpecification: material.materialModel,
batchNumber: material.batchNumber,
unitPrice: material.unitPrice || 0,
shippingStockAmount: 1,
unitId: undefined,
unitName: undefined,
totalPrice: material.unitPrice || 0,
remark: undefined
});
}
});
}
wmsMaterialDialog.visible = false;
};
/** 删除明细 */
const handleDeleteDetail = (index: number) => {
detailsList.value.splice(index, 1);
};
/** 计算总价 */
const calculateTotalPrice = (row: WmsShippingDetailsForm) => {
row.totalPrice = (row.unitPrice || 0) * (row.shippingStockAmount || 0);
};
/** 提交表单 */
const submitForm = async (status: string, mode: boolean) => {
try {
await shippingBillFormRef.value?.validate();
buttonLoading.value = true;
//
form.value.detailsList = detailsList.value;
//
const submitData = { ...form.value };
if (status !== 'draft') {
// -
submitData.flowCode = FlowCodeEnum.SHIPPING_BILL_CODE;
//
submitData.variables = {
shippingBillId: submitData.shippingBillId,
shippingCode: submitData.shippingCode,
projectName: submitData.projectName,
customerName: submitData.customerName
};
//
submitData.bizExt = {
businessTitle: '发货单审批',
businessCode: submitData.shippingCode
};
submitData.outStockBillStatus = '2'; //
submitData.flowStatus = 'waiting';
//
const res = await shippingBillSubmitAndFlowStart(submitData);
form.value = res.data;
proxy?.$modal.msgSuccess('提交成功');
} else {
//
submitData.outStockBillStatus = '1';
submitData.flowStatus = 'draft';
if (submitData.shippingBillId) {
await updateWmsShippingBill(submitData);
} else {
await addWmsShippingBill(submitData);
}
proxy?.$modal.msgSuccess('暂存成功');
}
proxy?.$tab.closePage();
router.go(-1);
} catch (error) {
console.error('提交失败:', error);
} finally {
buttonLoading.value = false;
}
};
/** 加载下拉数据 */
const loadSelectOptions = async () => {
try {
//
const customerRes = await getCrmCustomerInfoList(null);
customerList.value = customerRes.data || [];
//
const supplierRes = await getCrmSupplierInfoList(null);
supplierList.value = supplierRes.data || [];
//
const warehouseRes = await getWmsWarehouseInfoList(null);
warehouseList.value = warehouseRes.data || [];
} catch (error) {
console.error('加载下拉数据失败:', error);
}
};
/** 加载表单数据 */
const loadFormData = async (id: string | number) => {
try {
const res = await getWmsShippingBill(id);
Object.assign(form.value, res.data);
selectedProjectName.value = form.value.projectName || '';
selectedContractName.value = form.value.contractName || '';
// SAP
selectedSapOrderCode.value = (res.data as any).orderContractCode || '';
//
if (res.data.itemsVo && res.data.itemsVo.length > 0) {
detailsList.value = res.data.itemsVo.map((item: any) => ({
shippingDetailsId: item.shippingDetailsId,
shippingBillId: item.shippingBillId,
materialSourceType: item.materialSourceType,
erpMaterialId: item.erpMaterialId,
wmsMaterialId: item.wmsMaterialId,
warehouseId: item.warehouseId,
materielId: item.materielId,
materialCode: item.materialCode,
materialName: item.materialName,
materielSpecification: item.materielSpecification,
batchNumber: item.batchNumber,
unitPrice: item.unitPrice,
shippingStockAmount: item.shippingStockAmount,
unitId: item.unitId,
unitName: item.unitName,
totalPrice: item.totalPrice,
remark: item.remark
}));
}
//
if (form.value.shippingCode) {
isCodeGenerated.value = true;
}
} catch (error) {
console.error('加载表单数据失败:', error);
}
};
//
const handleApprovalRecord = () => {
approvalRecordRef.value?.init(form.value.shippingBillId);
};
//
const submitCallback = async () => {
await proxy?.$tab.closePage(route);
router.go(-1);
};
//
const approvalVerifyOpen = async () => {
await submitVerifyRef.value?.openDialog(routeParams.value.taskId);
};
onMounted(async () => {
nextTick(async () => {
routeParams.value = route.query;
proxy?.$modal.loading('正在加载数据,请稍后...');
await loadSelectOptions();
const id = routeParams.value.id as string | number;
if (id && (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval')) {
await loadFormData(id);
}
proxy?.$modal.closeLoading();
});
});
</script>
<style scoped>
.card-title {
font-weight: bold;
font-size: 18px;
}
</style>

@ -0,0 +1,457 @@
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="90px">
<el-form-item label="发货单号" prop="shippingCode">
<el-input v-model="queryParams.shippingCode" placeholder="请输入发货单号" clearable style="width: 180px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="发货方式" prop="shippingMode">
<el-select v-model="queryParams.shippingMode" placeholder="请选择发货方式" clearable style="width: 180px">
<el-option v-for="dict in shipping_mode" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="queryParams.projectName" placeholder="请输入项目名称" clearable style="width: 180px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="客户名称" prop="customerName">
<el-input v-model="queryParams.customerName" placeholder="请输入客户名称" clearable style="width: 180px" @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="发货状态" prop="shippingStatus">
<el-select v-model="queryParams.shippingStatus" placeholder="请选择发货状态" clearable style="width: 180px">
<el-option v-for="dict in shipping_status" :key="dict.value" :label="dict.label" :value="dict.value" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['wms:wmsShippingBill:add']"></el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['wms:wmsShippingBill:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['wms:wmsShippingBill:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['wms:wmsShippingBill:export']"></el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" :columns="columns" :search="true" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="wmsShippingBillList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="发货单号" align="center" prop="shippingCode" min-width="140" v-if="columns[0].visible" />
<el-table-column label="SAP订单号" align="center" prop="orderContractCode" min-width="140" show-overflow-tooltip v-if="columns[1].visible" />
<el-table-column label="发货方式" align="center" prop="shippingMode" width="120" v-if="columns[2].visible">
<template #default="scope">
<dict-tag :options="shipping_mode" :value="scope.row.shippingMode" />
</template>
</el-table-column>
<el-table-column label="项目名称" align="center" prop="projectName" min-width="160" show-overflow-tooltip v-if="columns[3].visible" />
<el-table-column label="客户名称" align="center" prop="customerName" min-width="140" show-overflow-tooltip v-if="columns[4].visible" />
<el-table-column label="供应商" align="center" prop="supplier" min-width="120" show-overflow-tooltip v-if="columns[5].visible" />
<el-table-column label="发货单状态" align="center" prop="outStockBillStatus" width="110" v-if="columns[6].visible">
<template #default="scope">
<dict-tag :options="shipping_bill_status" :value="scope.row.outStockBillStatus" />
</template>
</el-table-column>
<el-table-column label="发货状态" align="center" prop="shippingStatus" width="100" v-if="columns[7].visible">
<template #default="scope">
<dict-tag :options="shipping_status" :value="scope.row.shippingStatus" />
</template>
</el-table-column>
<el-table-column label="计划到货时间" align="center" prop="planArrivalTime" width="110" v-if="columns[8].visible">
<template #default="scope">
<span>{{ proxy?.parseTime(scope.row.planArrivalTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="实际发货时间" align="center" prop="shippingTime" width="110" v-if="columns[9].visible">
<template #default="scope">
<span>{{ proxy?.parseTime(scope.row.shippingTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="110" v-if="columns[10].visible">
<template #default="scope">
<span>{{ proxy?.parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="150" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="查看" placement="top">
<el-button link type="primary" icon="View" @click="handleView(scope.row)" v-hasPermi="['wms:wmsShippingBill:query']"></el-button>
</el-tooltip>
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['wms:wmsShippingBill:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['wms:wmsShippingBill:remove']"></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改发货单对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="wmsShippingBillFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="发货单号" prop="shippingCode">
<el-input v-model="form.shippingCode" placeholder="请输入发货单号" />
</el-form-item>
<el-form-item label="发货方式1公司仓库发货 2供应商代发货" prop="shippingMode">
<el-input v-model="form.shippingMode" placeholder="请输入发货方式1公司仓库发货 2供应商代发货" />
</el-form-item>
<el-form-item label="项目ID" prop="projectId">
<el-input v-model="form.projectId" placeholder="请输入项目ID" />
</el-form-item>
<el-form-item label="项目编号" prop="projectCode">
<el-input v-model="form.projectCode" placeholder="请输入项目编号" />
</el-form-item>
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="form.projectName" placeholder="请输入项目名称" />
</el-form-item>
<el-form-item label="客户ID" prop="customerId">
<el-input v-model="form.customerId" placeholder="请输入客户ID" />
</el-form-item>
<el-form-item label="客户名称" prop="customerName">
<el-input v-model="form.customerName" placeholder="请输入客户名称" />
</el-form-item>
<el-form-item label="收货地址" prop="shippingAddress">
<el-input v-model="form.shippingAddress" placeholder="请输入收货地址" />
</el-form-item>
<el-form-item label="关联单号" prop="inventoryAmount">
<el-input v-model="form.inventoryAmount" placeholder="请输入关联单号" />
</el-form-item>
<el-form-item label="来源单据ID" prop="sourceBillId">
<el-input v-model="form.sourceBillId" placeholder="请输入来源单据ID" />
</el-form-item>
<el-form-item label="来源单据编号" prop="sourceBillCode">
<el-input v-model="form.sourceBillCode" placeholder="请输入来源单据编号" />
</el-form-item>
<el-form-item label="合同ID" prop="contractId">
<el-input v-model="form.contractId" placeholder="请输入合同ID" />
</el-form-item>
<el-form-item label="合同编号" prop="contractCode">
<el-input v-model="form.contractCode" placeholder="请输入合同编号" />
</el-form-item>
<el-form-item label="合同名称" prop="contractName">
<el-input v-model="form.contractName" placeholder="请输入合同名称" />
</el-form-item>
<el-form-item label="供应商" prop="supplier">
<el-input v-model="form.supplier" placeholder="请输入供应商" />
</el-form-item>
<el-form-item label="供应商ID" prop="supplierId">
<el-input v-model="form.supplierId" placeholder="请输入供应商ID" />
</el-form-item>
<el-form-item label="联系人" prop="contactUser">
<el-input v-model="form.contactUser" placeholder="请输入联系人" />
</el-form-item>
<el-form-item label="联系电话" prop="contactNumber">
<el-input v-model="form.contactNumber" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="收货联系人" prop="receiverName">
<el-input v-model="form.receiverName" placeholder="请输入收货联系人" />
</el-form-item>
<el-form-item label="收货联系电话" prop="receiverPhone">
<el-input v-model="form.receiverPhone" placeholder="请输入收货联系电话" />
</el-form-item>
<el-form-item label="物流公司" prop="logisticsCompany">
<el-input v-model="form.logisticsCompany" placeholder="请输入物流公司" />
</el-form-item>
<el-form-item label="运单号" prop="trackingNo">
<el-input v-model="form.trackingNo" placeholder="请输入运单号" />
</el-form-item>
<el-form-item label="物流联系电话" prop="logisticsPhone">
<el-input v-model="form.logisticsPhone" placeholder="请输入物流联系电话" />
</el-form-item>
<el-form-item label="发货说明" prop="directions">
<el-input v-model="form.directions" placeholder="请输入发货说明" />
</el-form-item>
<el-form-item label="计划到货时间" prop="planArrivalTime">
<el-date-picker
clearable
v-model="form.planArrivalTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择计划到货时间"
>
</el-date-picker>
</el-form-item>
<el-form-item label="实际发货时间" prop="shippingTime">
<el-date-picker clearable v-model="form.shippingTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择实际发货时间">
</el-date-picker>
</el-form-item>
<el-form-item label="客户收货时间" prop="receivedTime">
<el-date-picker clearable v-model="form.receivedTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择客户收货时间">
</el-date-picker>
</el-form-item>
<el-form-item label="业务完成时间" prop="completedTime">
<el-date-picker clearable v-model="form.completedTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择业务完成时间">
</el-date-picker>
</el-form-item>
<el-form-item label="仓库ID" prop="warehouseId">
<el-input v-model="form.warehouseId" placeholder="请输入仓库ID" />
</el-form-item>
<el-form-item label="仓库名称" prop="warehouseName">
<el-input v-model="form.warehouseName" placeholder="请输入仓库名称" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="WmsShippingBill" lang="ts">
import { addWmsShippingBill, delWmsShippingBill, listWmsShippingBill, updateWmsShippingBill } from '@/api/wms/wmsShippingBill';
import { WmsShippingBillForm, WmsShippingBillQuery, WmsShippingBillVO } from '@/api/wms/wmsShippingBill/types';
const router = useRouter();
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
//
const { shipping_mode, shipping_status, shipping_bill_status } = toRefs<any>(
proxy?.useDict('shipping_mode', 'shipping_status', 'shipping_bill_status')
);
const wmsShippingBillList = ref<WmsShippingBillVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const wmsShippingBillFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
//
const columns = ref<FieldOption[]>([
{ key: 0, label: '发货单号', visible: true },
{ key: 1, label: 'SAP订单号', visible: true },
{ key: 2, label: '发货方式', visible: true },
{ key: 3, label: '项目名称', visible: true },
{ key: 4, label: '客户名称', visible: true },
{ key: 5, label: '供应商', visible: true },
{ key: 6, label: '发货单状态', visible: true },
{ key: 7, label: '发货状态', visible: true },
{ key: 8, label: '计划到货时间', visible: true },
{ key: 9, label: '实际发货时间', visible: true },
{ key: 10, label: '创建时间', visible: true }
]);
const initFormData: WmsShippingBillForm = {
shippingBillId: undefined,
shippingCode: undefined,
shippingType: undefined,
shippingMode: undefined,
projectId: undefined,
projectCode: undefined,
projectName: undefined,
customerId: undefined,
customerName: undefined,
shippingAddress: undefined,
inventoryAmount: undefined,
sourceBillType: undefined,
sourceBillId: undefined,
sourceBillCode: undefined,
contractId: undefined,
contractCode: undefined,
contractName: undefined,
supplier: undefined,
supplierId: undefined,
contactUser: undefined,
contactNumber: undefined,
receiverName: undefined,
receiverPhone: undefined,
logisticsCompany: undefined,
trackingNo: undefined,
logisticsPhone: undefined,
directions: undefined,
planArrivalTime: undefined,
shippingTime: undefined,
receivedTime: undefined,
completedTime: undefined,
outStockBillStatus: undefined,
flowStatus: undefined,
shippingStatus: undefined,
warehouseId: undefined,
warehouseName: undefined,
remark: undefined
};
const data = reactive<PageData<WmsShippingBillForm, WmsShippingBillQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
shippingCode: undefined,
shippingType: undefined,
shippingMode: undefined,
projectId: undefined,
projectCode: undefined,
projectName: undefined,
customerId: undefined,
customerName: undefined,
shippingAddress: undefined,
inventoryAmount: undefined,
sourceBillType: undefined,
sourceBillId: undefined,
sourceBillCode: undefined,
contractId: undefined,
contractCode: undefined,
contractName: undefined,
supplier: undefined,
supplierId: undefined,
contactUser: undefined,
contactNumber: undefined,
receiverName: undefined,
receiverPhone: undefined,
logisticsCompany: undefined,
trackingNo: undefined,
logisticsPhone: undefined,
directions: undefined,
planArrivalTime: undefined,
shippingTime: undefined,
receivedTime: undefined,
completedTime: undefined,
outStockBillStatus: undefined,
flowStatus: undefined,
shippingStatus: undefined,
warehouseId: undefined,
warehouseName: undefined,
params: {}
},
rules: {
shippingBillId: [{ required: true, message: '发货单ID不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询发货单列表 */
const getList = async () => {
loading.value = true;
const res = await listWmsShippingBill(queryParams.value);
wmsShippingBillList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
wmsShippingBillFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: WmsShippingBillVO[]) => {
ids.value = selection.map((item) => item.shippingBillId);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
router.push({ path: '/shipping/wmsShippingBill/edit', query: { type: 'add' } });
};
/** 查看按钮操作 */
const handleView = (row: WmsShippingBillVO) => {
router.push({ path: '/shipping/wmsShippingBill/edit', query: { type: 'view', id: row.shippingBillId } });
};
/** 修改按钮操作 */
const handleUpdate = async (row?: WmsShippingBillVO) => {
const _shippingBillId = row?.shippingBillId || ids.value[0];
router.push({ path: '/shipping/wmsShippingBill/edit', query: { type: 'update', id: _shippingBillId } });
};
/** 提交按钮 */
const submitForm = () => {
wmsShippingBillFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.shippingBillId) {
await updateWmsShippingBill(form.value).finally(() => (buttonLoading.value = false));
} else {
await addWmsShippingBill(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: WmsShippingBillVO) => {
const _shippingBillIds = row?.shippingBillId || ids.value;
await proxy?.$modal.confirm('是否确认删除发货单编号为"' + _shippingBillIds + '"的数据项?').finally(() => (loading.value = false));
await delWmsShippingBill(_shippingBillIds);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'wms/wmsShippingBill/export',
{
...queryParams.value
},
`wmsShippingBill_${new Date().getTime()}.xlsx`
);
};
onMounted(() => {
getList();
});
</script>

@ -0,0 +1,405 @@
<template>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="100px">
<el-form-item label="发货单ID" prop="shippingBillId">
<el-input v-model="queryParams.shippingBillId" placeholder="请输入发货单ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="ERP物料ID" prop="erpMaterialId">
<el-input v-model="queryParams.erpMaterialId" placeholder="请输入ERP物料ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="WMS物料ID" prop="wmsMaterialId">
<el-input v-model="queryParams.wmsMaterialId" placeholder="请输入WMS物料ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="来源明细ID" prop="sourceDetailId">
<el-input v-model="queryParams.sourceDetailId" placeholder="请输入来源明细ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="仓库ID" prop="warehouseId">
<el-input v-model="queryParams.warehouseId" placeholder="请输入仓库ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="物料ID" prop="materielId">
<el-input v-model="queryParams.materielId" placeholder="请输入物料ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="物料编码" prop="materialCode">
<el-input v-model="queryParams.materialCode" placeholder="请输入物料编码" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="物料名称" prop="materialName">
<el-input v-model="queryParams.materialName" placeholder="请输入物料名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="物料规格" prop="materielSpecification">
<el-input v-model="queryParams.materielSpecification" placeholder="请输入物料规格" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="批次号" prop="batchNumber">
<el-input v-model="queryParams.batchNumber" placeholder="请输入批次号" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="单价" prop="unitPrice">
<el-input v-model="queryParams.unitPrice" placeholder="请输入单价" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="发货数量" prop="shippingStockAmount">
<el-input v-model="queryParams.shippingStockAmount" placeholder="请输入发货数量" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="单位ID" prop="unitId">
<el-input v-model="queryParams.unitId" placeholder="请输入单位ID" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="计量单位名称" prop="unitName">
<el-input v-model="queryParams.unitName" placeholder="请输入计量单位名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="总价" prop="totalPrice">
<el-input v-model="queryParams.totalPrice" placeholder="请输入总价" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery"></el-button>
<el-button icon="Refresh" @click="resetQuery"></el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['wms:wmsShippingDetails:add']"></el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['wms:wmsShippingDetails:edit']"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['wms:wmsShippingDetails:remove']"
>删除</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['wms:wmsShippingDetails:export']"></el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" :columns="columns" :search="true" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="wmsShippingDetailsList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="发货单明细ID" align="center" prop="shippingDetailsId" v-if="columns[0].visible" />
<el-table-column label="发货单ID" align="center" prop="shippingBillId" v-if="columns[2].visible" />
<el-table-column
label="物料来源类型1-ERP物料(base_material_info) 2-WMS物料(仓储物料) 3-手工录入"
align="center"
prop="materialSourceType"
v-if="columns[3].visible"
/>
<el-table-column label="ERP物料ID" align="center" prop="erpMaterialId" v-if="columns[4].visible" />
<el-table-column label="WMS物料ID" align="center" prop="wmsMaterialId" v-if="columns[5].visible" />
<el-table-column
label="来源明细类型如CONTRACT_DETAIL、PURCHASE_DETAIL等"
align="center"
prop="sourceDetailType"
v-if="columns[6].visible"
/>
<el-table-column label="来源明细ID" align="center" prop="sourceDetailId" v-if="columns[7].visible" />
<el-table-column label="仓库ID" align="center" prop="warehouseId" v-if="columns[8].visible" />
<el-table-column label="物料ID" align="center" prop="materielId" v-if="columns[9].visible" />
<el-table-column label="物料编码" align="center" prop="materialCode" v-if="columns[10].visible" />
<el-table-column label="物料名称" align="center" prop="materialName" v-if="columns[11].visible" />
<el-table-column label="物料规格" align="center" prop="materielSpecification" v-if="columns[12].visible" />
<el-table-column label="批次号" align="center" prop="batchNumber" v-if="columns[13].visible" />
<el-table-column label="单价" align="center" prop="unitPrice" v-if="columns[14].visible" />
<el-table-column label="发货数量" align="center" prop="shippingStockAmount" v-if="columns[15].visible" />
<el-table-column label="单位ID" align="center" prop="unitId" v-if="columns[16].visible" />
<el-table-column label="计量单位名称" align="center" prop="unitName" v-if="columns[17].visible" />
<el-table-column label="总价" align="center" prop="totalPrice" v-if="columns[18].visible" />
<el-table-column label="备注" align="center" prop="remark" v-if="columns[19].visible" />
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['wms:wmsShippingDetails:edit']"></el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top">
<el-button
link
type="primary"
icon="Delete"
@click="handleDelete(scope.row)"
v-hasPermi="['wms:wmsShippingDetails:remove']"
></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改发货单明细对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="wmsShippingDetailsFormRef" :model="form" :rules="rules" label-width="120px">
<el-form-item label="发货单ID" prop="shippingBillId">
<el-input v-model="form.shippingBillId" placeholder="请输入发货单ID" />
</el-form-item>
<el-form-item label="ERP物料ID" prop="erpMaterialId">
<el-input v-model="form.erpMaterialId" placeholder="请输入ERP物料ID" />
</el-form-item>
<el-form-item label="WMS物料ID" prop="wmsMaterialId">
<el-input v-model="form.wmsMaterialId" placeholder="请输入WMS物料ID" />
</el-form-item>
<el-form-item label="来源明细ID" prop="sourceDetailId">
<el-input v-model="form.sourceDetailId" placeholder="请输入来源明细ID" />
</el-form-item>
<el-form-item label="仓库ID" prop="warehouseId">
<el-input v-model="form.warehouseId" placeholder="请输入仓库ID" />
</el-form-item>
<el-form-item label="物料ID" prop="materielId">
<el-input v-model="form.materielId" placeholder="请输入物料ID" />
</el-form-item>
<el-form-item label="物料编码" prop="materialCode">
<el-input v-model="form.materialCode" placeholder="请输入物料编码" />
</el-form-item>
<el-form-item label="物料名称" prop="materialName">
<el-input v-model="form.materialName" placeholder="请输入物料名称" />
</el-form-item>
<el-form-item label="物料规格" prop="materielSpecification">
<el-input v-model="form.materielSpecification" placeholder="请输入物料规格" />
</el-form-item>
<el-form-item label="批次号" prop="batchNumber">
<el-input v-model="form.batchNumber" placeholder="请输入批次号" />
</el-form-item>
<el-form-item label="单价" prop="unitPrice">
<el-input v-model="form.unitPrice" placeholder="请输入单价" />
</el-form-item>
<el-form-item label="发货数量" prop="shippingStockAmount">
<el-input v-model="form.shippingStockAmount" placeholder="请输入发货数量" />
</el-form-item>
<el-form-item label="单位ID" prop="unitId">
<el-input v-model="form.unitId" placeholder="请输入单位ID" />
</el-form-item>
<el-form-item label="计量单位名称" prop="unitName">
<el-input v-model="form.unitName" placeholder="请输入计量单位名称" />
</el-form-item>
<el-form-item label="总价" prop="totalPrice">
<el-input v-model="form.totalPrice" placeholder="请输入总价" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="WmsShippingDetails" lang="ts">
import {
addWmsShippingDetails,
delWmsShippingDetails,
getWmsShippingDetails,
listWmsShippingDetails,
updateWmsShippingDetails
} from '@/api/wms/wmsShippingDetails';
import { WmsShippingDetailsForm, WmsShippingDetailsQuery, WmsShippingDetailsVO } from '@/api/wms/wmsShippingDetails/types';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const wmsShippingDetailsList = ref<WmsShippingDetailsVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref<Array<string | number>>([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const wmsShippingDetailsFormRef = ref<ElFormInstance>();
const dialog = reactive<DialogOption>({
visible: false,
title: ''
});
//
const columns = ref<FieldOption[]>([
{ key: 0, label: `发货单明细ID`, visible: true },
{ key: 1, label: `租户编号`, visible: true },
{ key: 2, label: `发货单ID`, visible: true },
{ key: 3, label: `物料来源类型1-ERP物料(base_material_info) 2-WMS物料(仓储物料) 3-手工录入`, visible: true },
{ key: 4, label: `ERP物料ID`, visible: true },
{ key: 5, label: `WMS物料ID`, visible: true },
{ key: 6, label: `来源明细类型如CONTRACT_DETAIL、PURCHASE_DETAIL等`, visible: true },
{ key: 7, label: `来源明细ID`, visible: true },
{ key: 8, label: `仓库ID`, visible: true },
{ key: 9, label: `物料ID`, visible: true },
{ key: 10, label: `物料编码`, visible: true },
{ key: 11, label: `物料名称`, visible: true },
{ key: 12, label: `物料规格`, visible: true },
{ key: 13, label: `批次号`, visible: true },
{ key: 14, label: `单价`, visible: true },
{ key: 15, label: `发货数量`, visible: true },
{ key: 16, label: `单位ID`, visible: true },
{ key: 17, label: `计量单位名称`, visible: true },
{ key: 18, label: `总价`, visible: true },
{ key: 19, label: `备注`, visible: true },
{ key: 20, label: `删除标志`, visible: true },
{ key: 21, label: `创建部门`, visible: true },
{ key: 22, label: `创建人`, visible: true },
{ key: 23, label: `创建时间`, visible: true },
{ key: 24, label: `更新人`, visible: true },
{ key: 25, label: `更新时间`, visible: true }
]);
const initFormData: WmsShippingDetailsForm = {
shippingDetailsId: undefined,
shippingBillId: undefined,
materialSourceType: undefined,
erpMaterialId: undefined,
wmsMaterialId: undefined,
sourceDetailType: undefined,
sourceDetailId: undefined,
warehouseId: undefined,
materielId: undefined,
materialCode: undefined,
materialName: undefined,
materielSpecification: undefined,
batchNumber: undefined,
unitPrice: undefined,
shippingStockAmount: undefined,
unitId: undefined,
unitName: undefined,
totalPrice: undefined,
remark: undefined
};
const data = reactive<PageData<WmsShippingDetailsForm, WmsShippingDetailsQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 10,
shippingBillId: undefined,
materialSourceType: undefined,
erpMaterialId: undefined,
wmsMaterialId: undefined,
sourceDetailType: undefined,
sourceDetailId: undefined,
warehouseId: undefined,
materielId: undefined,
materialCode: undefined,
materialName: undefined,
materielSpecification: undefined,
batchNumber: undefined,
unitPrice: undefined,
shippingStockAmount: undefined,
unitId: undefined,
unitName: undefined,
totalPrice: undefined,
params: {}
},
rules: {
shippingDetailsId: [{ required: true, message: '发货单明细ID不能为空', trigger: 'blur' }]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询发货单明细列表 */
const getList = async () => {
loading.value = true;
const res = await listWmsShippingDetails(queryParams.value);
wmsShippingDetailsList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 取消按钮 */
const cancel = () => {
reset();
dialog.visible = false;
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
wmsShippingDetailsFormRef.value?.resetFields();
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
};
/** 多选框选中数据 */
const handleSelectionChange = (selection: WmsShippingDetailsVO[]) => {
ids.value = selection.map((item) => item.shippingDetailsId);
single.value = selection.length != 1;
multiple.value = !selection.length;
};
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加发货单明细';
};
/** 修改按钮操作 */
const handleUpdate = async (row?: WmsShippingDetailsVO) => {
reset();
const _shippingDetailsId = row?.shippingDetailsId || ids.value[0];
const res = await getWmsShippingDetails(_shippingDetailsId);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改发货单明细';
};
/** 提交按钮 */
const submitForm = () => {
wmsShippingDetailsFormRef.value?.validate(async (valid: boolean) => {
if (valid) {
buttonLoading.value = true;
if (form.value.shippingDetailsId) {
await updateWmsShippingDetails(form.value).finally(() => (buttonLoading.value = false));
} else {
await addWmsShippingDetails(form.value).finally(() => (buttonLoading.value = false));
}
proxy?.$modal.msgSuccess('操作成功');
dialog.visible = false;
await getList();
}
});
};
/** 删除按钮操作 */
const handleDelete = async (row?: WmsShippingDetailsVO) => {
const _shippingDetailsIds = row?.shippingDetailsId || ids.value;
await proxy?.$modal.confirm('是否确认删除发货单明细编号为"' + _shippingDetailsIds + '"的数据项?').finally(() => (loading.value = false));
await delWmsShippingDetails(_shippingDetailsIds);
proxy?.$modal.msgSuccess('删除成功');
await getList();
};
/** 导出按钮操作 */
const handleExport = () => {
proxy?.download(
'wms/wmsShippingDetails/export',
{
...queryParams.value
},
`wmsShippingDetails_${new Date().getTime()}.xlsx`
);
};
onMounted(() => {
getList();
});
</script>
Loading…
Cancel
Save