Files
klp-oa/klp-ui/src/views/wms/delivery/waybill/index.vue
砂糖 730148e966 feat(wms): 新增导出功能并优化发货单显示
- 在base.vue中新增导出按钮和按库区排序选项
- 添加exportCoilWithAll API接口用于批量导出
- 在waybill.vue中新增showNewExport属性控制导出按钮显示
- 优化发货单页面显示,增加订单编号和备注显示
- 新增delivery/canuse页面用于展示可用钢卷
- 修复发货单修改时订单编号显示问题
2026-03-10 13:33:30 +08:00

497 lines
19 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="app-container">
<el-row :gutter="10">
<el-col :span="5">
<PlanList ref="planList" @select="handlePlanSelect"/>
</el-col>
<el-col :span="19" style="height: calc(100vh - 124px); overflow-y: scroll;">
<el-card v-if="!selectedPlan">
<el-empty description="请先选择发货计划" />
</el-card>
<el-card v-else>
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
label-width="68px">
<el-form-item label="发货单名称" prop="waybillName">
<el-input v-model="queryParams.waybillName" placeholder="请输入发货单名称" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="收货单位" prop="consigneeUnit">
<el-input v-model="queryParams.consigneeUnit" placeholder="请输入收货单位" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
:disabled="!selectedPlan" title="请先选择发货计划">新增</el-button>
<el-button type="success" plain icon="el-icon-refresh" size="mini" @click="handleQuery">刷新</el-button>
<!-- <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button> -->
</el-form-item>
<el-form-item>
<el-descriptions :column="2" :data="queryParams" border>
<el-descriptions-item label="单据总数">{{ deliveryCountTotal }}</el-descriptions-item>
<el-descriptions-item label="已发数量">{{ deliveryCountFinished }}</el-descriptions-item>
</el-descriptions>
</el-form-item>
</el-form>
<el-table v-loading="loading" border :data="deliveryWaybillList" highlight-current-row
@row-click="handleRowClick">
<el-table-column label="发货单唯一ID" align="center" prop="waybillId" v-if="false" />
<el-table-column label="发货单名称" align="center" prop="waybillName" />
<el-table-column label="车牌" align="center" prop="licensePlate" width="100" />
<el-table-column label="收货单位" align="center" prop="consigneeUnit" />
<!-- <el-table-column label="发货单位" align="center" prop="senderUnit" /> -->
<el-table-column label="订单编号" align="center" prop="orderNo">
<template slot-scope="scope">
<span v-if="scope.row.orderId">{{ scope.row.orderCode }}</span>
<span v-else>{{ scope.row.principalPhone }}</span>
</template>
</el-table-column>
<el-table-column label="发货时间" align="center" prop="deliveryTime" width="100">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.deliveryTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="负责人" align="center" prop="principal" width="60" />
<el-table-column label="备注" align="center" prop="remark" width="100" show-overflow-tooltip/>
<!-- <el-table-column label="负责人电话" align="center" prop="principalPhone" width="100" /> -->
<el-table-column label="完成状态" align="center" prop="status" width="120">
<template slot-scope="scope">
<el-select v-model="scope.row.status" placeholder="请选择完成状态" @change="handleStatusChange(scope.row)">
<el-option label="已发货" :value="1" />
<el-option label="未发货" :value="0" />
<el-option label="已打印" :value="2" />
<el-option label="未打印" :value="3" />
</el-select>
</template>
</el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-view"
@click.stop="handlePrint(scope.row)">打印发货单</el-button>
<el-button size="mini" type="text" icon="el-icon-copy"
@click.stop="handleCopy(scope.row)">复制新增</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" :disabled="scope.row.status === 1"
title="已发货的发货单不能修改" @click.stop="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" :disabled="scope.row.status === 1"
title="已发货的发货单不能删除" @click.stop="handleDelete(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
<el-divider style="margin: 20px 0;" />
<DeliveryWaybillDetail v-if="canEdit" ref="detailTable" :waybillId="waybillId" :coilList="coilList" />
<el-empty v-else description="已发货,不可修改,点击打印查看详情" />
</el-card>
</el-col>
</el-row>
<!-- 添加或修改发货单对话框 -->
<el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="发货单名称" prop="waybillName">
<el-input v-model="form.waybillName" placeholder="请输入发货单名称" />
</el-form-item>
<el-form-item label="车牌" prop="licensePlate">
<MemoInput v-model="form.licensePlate" storageKey="licensePlate" placeholder="请输入车牌" />
</el-form-item>
<el-form-item label="收货单位" prop="consigneeUnit">
<el-input v-model="form.consigneeUnit" placeholder="请输入收货单位" />
</el-form-item>
<el-form-item label="发货单位" prop="senderUnit">
<el-input v-model="form.senderUnit" placeholder="请输入发货单位" />
</el-form-item>
<el-form-item label="发货时间" prop="deliveryTime">
<el-date-picker clearable v-model="form.deliveryTime" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择发货时间">
</el-date-picker>
</el-form-item>
<el-form-item label="负责人" prop="principal">
<el-input v-model="form.principal" placeholder="请输入负责人" />
</el-form-item>
<el-form-item label="订单编号" prop="principalPhone" v-if="!form.orderId">
<el-input v-model="form.principalPhone" placeholder="请输入订单编号"/>
</el-form-item>
<el-form-item label="订单编号" prop="principalPhone" v-else title="当前发货单已绑定订单">
<el-input v-model="form.orderCode" placeholder="请输入订单编号" readonly disabled/>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</el-dialog>
<!-- 打印发货单对话框 -->
<el-dialog title="打印发货单" :visible.sync="printDialogVisible" width="1000px" append-to-body center>
<WayBill :waybill="currentWaybill" :waybillDetails="currentWaybillDetails" />
</el-dialog>
</div>
</template>
<script>
import { listDeliveryWaybill, getDeliveryWaybill, delDeliveryWaybill, addDeliveryWaybill, updateDeliveryWaybill, updateDeliveryWaybillStatus } from "@/api/wms/deliveryWaybill";
import { listSelectableCoils } from "@/api/wms/deliveryPlan"; // 导入发货计划API
import { listCoilByIds } from "@/api/wms/coil";
import { listDeliveryWaybillDetail } from "@/api/wms/deliveryWaybillDetail";
import MemoInput from "@/components/MemoInput";
import DeliveryWaybillDetail from "../components/detailTable.vue";
import WayBill from "../components/wayBill.vue";
import PlanList from "../components/planList.vue";
export default {
name: "DeliveryWaybill",
components: {
MemoInput,
DeliveryWaybillDetail,
WayBill,
PlanList
},
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 发货单表格数据
deliveryWaybillList: [],
waybillId: null,
// 打印相关数据
printDialogVisible: false,
currentWaybill: {},
currentWaybillDetails: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
waybillNo: undefined,
waybillName: undefined,
licensePlate: undefined,
consigneeUnit: undefined,
senderUnit: undefined,
deliveryTime: undefined,
weighbridge: undefined,
salesPerson: undefined,
principal: undefined,
principalPhone: undefined,
status: undefined,
planId: undefined
},
// 表单参数
form: {},
// 表单校验
rules: {},
selectedPlan: null,
planQueryParams: {
pageNum: 1,
pageSize: 20, // 增大分页大小以确保树形结构显示足够数据
planName: undefined,
planType: 0,
// auditStatus: 1,
},
coilList: [],
canEdit: true,
};
},
created() {
this.getList();
},
computed: {
/** 计算已发货数量 */
deliveryCountFinished() {
return this.deliveryWaybillList.filter(row => row.status === 1 || row.status === 2).length;
},
/** 计算总数量 */
deliveryCountTotal() {
return this.deliveryWaybillList.length;
}
},
methods: {
/** 查询发货单列表 */
getList() {
this.loading = true;
// 确保查询参数包含planId
const params = {
...this.queryParams,
// 如果选中了计划传递planId否则不传递该参数
planId: this.selectedPlan ? this.selectedPlan.planId : undefined
};
listDeliveryWaybill(params).then(response => {
this.deliveryWaybillList = response.rows;
this.total = response.total;
this.loading = false;
});
},
refreshCoilList() {
if (this.selectedPlan && this.selectedPlan.planId) {
listSelectableCoils(this.selectedPlan.planId).then(response => {
this.coilList = response.data;
});
}
},
/** 完成状态改变时的处理 */
handleStatusChange(row) {
// 确保在更新状态时包含waybillId
updateDeliveryWaybillStatus({
waybillId: row.waybillId,
status: row.status
}).then(() => {
this.$modal.msgSuccess("状态更新成功");
this.getList(); // 刷新列表
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
waybillId: undefined,
waybillNo: new Date().getTime(),
waybillName: undefined,
planId: undefined,
licensePlate: undefined,
consigneeUnit: undefined,
senderUnit: '科伦普',
deliveryTime: undefined,
weighbridge: undefined,
salesPerson: undefined,
principal: undefined,
principalPhone: undefined,
status: undefined,
remark: undefined,
delFlag: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
// 重置查询时保留planId
if (this.selectedPlan) {
this.queryParams.planId = this.selectedPlan.planId;
}
this.handleQuery();
},
handlePlanSelect(row) {
this.selectedPlan = row;
// this.refreshCoilList();
// 更新查询参数根据选中的planId筛选发货单
this.queryParams.planId = row.planId;
this.waybillId = null;
this.getList();
},
handleRowClick(row) {
if (row.status === 1) {
this.canEdit = false;
this.waybillId = row.waybillId;
// this.$modal.msgWarning("已发货的发货单不能操作");
return;
}
this.canEdit = true;
this.waybillId = row.waybillId;
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
// 自动填入选中的planId
if (this.selectedPlan) {
this.form.planId = this.selectedPlan.planId;
// 可以根据需要填充其他相关字段
if (this.selectedPlan.planName) {
this.form.waybillName = `发货单_${this.selectedPlan.planName}`;
}
}
this.open = true;
this.title = "添加发货单";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const waybillId = row.waybillId || this.ids
getDeliveryWaybill(waybillId).then(response => {
this.loading = false;
this.form = {
...response.data,
orderCode: row.orderCode
};
this.open = true;
this.title = "修改发货单";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.waybillId != null) {
updateDeliveryWaybill(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addDeliveryWaybill(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const waybillIds = row.waybillId || this.ids;
this.$modal.confirm('是否确认删除发货单编号为"' + waybillIds + '"的数据项?会同时删除该发货单的所有明细记录且无法恢复。').then(() => {
this.loading = true;
return delDeliveryWaybill(waybillIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
handleCopy(row) {
this.form = {
waybillNo: new Date().getTime(),
waybillName: row.waybillName,
planId: row.planId,
consigneeUnit: row.consigneeUnit,
senderUnit: row.senderUnit,
deliveryTime: row.deliveryTime,
weighbridge: row.weighbridge,
salesPerson: row.salesPerson,
principal: row.principal,
principalPhone: row.principalPhone,
remark: row.remark
};
this.open = true;
this.title = "复制新增发货单";
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/deliveryWaybill/export', {
...this.queryParams
}, `deliveryWaybill_${new Date().getTime()}.xlsx`)
},
/** 打印发货单 */
handlePrint(row) {
this.loading = true;
// 获取发货单明细
listDeliveryWaybillDetail({
waybillId: row.waybillId,
pageNum: 1,
pageSize: 1000 // 获取所有明细
}).then(response => {
// 处理字段映射确保与wayBill组件使用的字段名一致
this.currentWaybillDetails = response.rows.map(item => ({
coilId: item.coilId,
productName: item.productName,
edgeType: item.edgeType,
packageType: item.packaging, // 映射packaging到packageType
settlementType: item.settlementType,
rawMaterialFactory: item.rawMaterialFactory,
coilNumber: item.coilNo, // 映射coilNo到coilNumber
specification: item.specification,
material: item.material,
quantity: item.quantity,
weight: item.weight,
unitPrice: item.unitPrice || '',
// 单价为空时,显示为空字符串
remark: item.remark
}));
const coils = this.currentWaybillDetails.map(item => item.coilId).join(',');
if (coils) {
listCoilByIds(coils).then(response => {
// 取前三位, 然后去抽后用;连接
// 设置当前发货单
const actualWahouseNames = [...new Set(response.rows.filter(item => Boolean(item.actualWarehouseName)).map(item => item.actualWarehouseName.slice(0, 3)))].join(';');
this.currentWaybill = {
...row,
pickupLocation: actualWahouseNames || '',
};
this.currentWaybillDetails = this.currentWaybillDetails.map(item => {
const actualWarehouseName = response.rows.find(detail => detail.coilId === item.coilId)?.actualWarehouseName || '';
return {
...item,
actualWarehouseName: actualWarehouseName,
};
});
});
}
this.currentWaybill = {
...row,
};
this.printDialogVisible = true;
this.loading = false;
}).catch(error => {
console.error('获取发货单明细失败:', error);
this.$modal.msgError('获取发货单明细失败');
this.loading = false;
});
}
}
};
</script>
<style scoped>
.plan-container {
padding: 10px;
height: 100%;
border-right: 1px solid #ebeef5;
}
.plan-container h3 {
margin: 0 0 10px 0;
padding: 0;
font-size: 16px;
font-weight: 500;
}
</style>