Files
klp-oa/klp-ui/src/views/wms/delivery/plan/index.vue
砂糖 eba5f69fac feat(wms): 新增库存统计模块并优化钢卷选择器逻辑
新增库存统计相关组件,包括物料汇总、仓库统计和树形统计视图,提供可视化数据展示和钻取功能。优化钢卷选择器显示逻辑,移除审核状态判断。调整钻取表格组件,支持实际仓库ID参数传递。

- 新增itemSummary.vue、warehouseBox.vue和warehouseTree.vue组件
- 移除钢卷选择器的审核状态条件判断
- 扩展钻取表格组件支持实际仓库ID参数
- 添加数据汇总展示和图表可视化功能
2025-12-09 15:35:10 +08:00

460 lines
15 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-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="计划名称" prop="planName">
<el-input v-model="queryParams.planName" placeholder="请输入发货计划名称" clearable @keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="计划日期" prop="planDate">
<el-date-picker clearable v-model="queryParams.planDate" type="date" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择计划日期">
</el-date-picker>
</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-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single"
@click="handleUpdate">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple"
@click="handleDelete">删除</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport">导出</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-row :gutter="10">
<el-col :span="8">
<el-row :gutter="20" v-loading="loading">
<el-col :span="12" v-for="(row, index) in deliveryPlanList" :key="row.planId">
<el-card shadow="hover" class="delivery-plan-card" @click.native="handleCardClick(row)">
<div class="card-header">
<el-checkbox v-model="row.selected" @change="handleCardSelectionChange(row)"></el-checkbox>
<div class="card-title">{{ row.planName }}</div>
</div>
<div class="card-content">
<div class="content-item">
<span>{{ parseTime(row.planDate, '{y}-{m}-{d}') }}</span>
<span>
<el-tag type="success" v-if="row.auditStatus == 1">已审批</el-tag>
<el-tag type="primary" v-else>待审批</el-tag>
</span>
</div>
<div class="content-item">
<span>{{ row.createBy }}({{ parseTime(row.updateTime, '{y}-{m}-{d}') }})</span>
</div>
<div class="content-item">
<span class="label">备注</span>
<span>{{ row.remark || '-' }}</span>
</div>
</div>
<div class="card-actions">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleApprove(row)" v-if="row.auditStatus != 1">审批</el-button>
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(row)">删除</el-button>
</div>
</el-card>
</el-col>
</el-row>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize" @pagination="getList" />
</el-col>
<!-- 钢卷列表 -->
<el-col :span="16" v-loading="rightLoading">
<!-- 选中的钢卷表格为空时的提示 -->
<div v-if="!currentPlan.planId" class="empty-tip">
<el-empty description="请先选择发货计划" />
</div>
<div v-else>
<coil-selector ref="coilSelector" placeholder="请选择钢卷添加至计划" @change="handleCoilChange"></coil-selector>
<div v-if="selectedCoilList.length > 0 && currentPlan.planId">
<el-table :data="selectedCoilList" highlight-current-row height="400px" style="width: 100%">
<el-table-column type="index" width="50" align="center" label="序号" />
<el-table-column label="卷号" align="center" prop="currentCoilNo" :show-overflow-tooltip="true" />
<el-table-column label="存储位置" align="center" prop="actualWarehouseName" width="120"
:show-overflow-tooltip="true" />
<el-table-column label="物料" align="center" prop="itemName" width="100" />
<el-table-column label="规格" align="center" prop="specification" width="100" />
<el-table-column label="材质" align="center" prop="material" />
<el-table-column label="厂家" align="center" prop="manufacturer" />
<el-table-column label="重量(t)" align="center" prop="netWeight" width="100" />
<el-table-column label="库区" align="center" prop="warehouseName" :show-overflow-tooltip="true" />
<el-table-column label="操作" align="center" width="100" fixed="right" v-if="currentPlan.auditStatus != 1">
<template slot-scope="scope">
<el-button type="danger" size="small" @click.stop="handleDeleteCoil(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div v-else class="empty-tip">
<el-empty description="暂无数据" />
</div>
</div>
</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="planName">
<el-input v-model="form.planName" placeholder="请输入发货计划名称" />
</el-form-item>
<el-form-item label="计划日期" prop="planDate">
<el-date-picker clearable v-model="form.planDate" type="datetime" value-format="yyyy-MM-dd HH:mm:ss"
placeholder="请选择计划日期">
</el-date-picker>
</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>
</div>
</template>
<script>
import { listDeliveryPlan, getDeliveryPlan, delDeliveryPlan, addDeliveryPlan, updateDeliveryPlan } from "@/api/wms/deliveryPlan";
import { listCoilByIds, getMaterialCoil } from "@/api/wms/coil";
import coilSelector from "@/components/CoilSelector";
export default {
name: "DeliveryPlan",
components: {
coilSelector,
},
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 发货计划表格数据
deliveryPlanList: [],
rightLoading: false,
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
planName: undefined,
planDate: undefined,
planType: 0,
},
// 表单参数
form: {
planName: '',
planDate: '',
},
// 表单校验
rules: {},
// 选中的钢卷列表
selectedCoilList: [],
currentPlan: {},
// 防抖定时器
debounceTimer: null,
};
},
created() {
this.getList();
},
methods: {
/** 查询发货计划列表 */
getList() {
this.loading = true;
listDeliveryPlan(this.queryParams).then(response => {
this.deliveryPlanList = response.rows.map(item => ({
...item,
selected: false
}));
this.total = response.total;
this.loading = false;
// 重置选择状态
this.ids = [];
this.single = true;
this.multiple = true;
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
handleApprove(row) {
// 二次确认
this.$confirm('确定审批通过该发货计划吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.loading = true;
this.buttonLoading = true;
const auditTime = this.parseTime(new Date(), '{y}-{m}-{d} {h}:{i}:{s}');
updateDeliveryPlan({
planId: row.planId,
auditStatus: 1,
auditBy: this.$store.getters.name,
auditTime: auditTime,
}).then(res => {
this.loading = false;
this.buttonLoading = false;
this.$message({
message: '审批成功',
type: 'success'
});
this.getList();
})
})
},
handleCardClick(row) {
// 防抖处理,防止频繁点击
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
}
this.debounceTimer = setTimeout(() => {
this.currentPlan = row;
if (!row.coil) {
this.selectedCoilList = [];
return;
}
this.rightLoading = true;
listCoilByIds(row.coil).then(response => {
this.selectedCoilList = response.rows || [];
this.rightLoading = false;
});
}, 300); // 300ms防抖时间
},
handleCoilChange(coilId) {
const ids = this.selectedCoilList.map(item => item.coilId);
if (coilId) {
// 检查是否已存在
if (!ids.includes(coilId)) {
ids.push(coilId);
// 从后端查询详细信息
this.rightLoading = true;
updateDeliveryPlan({
planId: this.currentPlan.planId,
coil: ids.join(',')
}).then(_ => {
this.getList();
})
getMaterialCoil(coilId).then(res => {
this.selectedCoilList.push(res.data);
this.rightLoading = false;
this.$message({
message: '添加成功',
type: 'success'
});
})
} else {
this.$message({
message: '钢卷已存在',
type: 'warning'
});
}
}
},
// 处理删除选中钢卷
handleDeleteCoil(row) {
// 从选中的钢卷列表中删除选中的行
this.selectedCoilList = this.selectedCoilList.filter(item => item !== row);
// 更新发货计划
this.rightLoading = true;
updateDeliveryPlan({
planId: this.currentPlan.planId,
coil: this.selectedCoilList.map(item => item.coilId).join(',')
}).then(res => {
this.rightLoading = false;
this.$message({
message: '删除成功',
type: 'success'
});
this.getList();
})
},
// 表单重置
reset() {
this.form = {
planId: undefined,
planName: undefined,
planDate: undefined,
planType: 0,
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");
this.handleQuery();
},
// 卡片选择处理
handleCardSelectionChange(row) {
// 重新计算选中的ID数组
this.ids = this.deliveryPlanList.filter(item => item.selected).map(item => item.planId);
this.single = this.ids.length !== 1;
this.multiple = !this.ids.length;
},
/** 新增按钮操作 */
handleAdd() {
// this.reset();
// 默认选中今天的日期和时间, 格式化未yyyy-MM-dd HH:mm:ss
this.form.planDate = new Date().toLocaleString().replace('T', ' ').replace().replace(/\//g, '-')
// 发货计划名称格式为年-月-日命名
this.form.planName = new Date().toLocaleDateString().replace(/\//g, '-') + '发货计划'
// 计划类型为发货计划
this.form.planType = 0
this.open = true;
this.title = "添加发货计划";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const planId = row.planId || this.ids
getDeliveryPlan(planId).then(response => {
this.loading = false;
this.form = response.data;
this.open = true;
this.title = "修改发货计划";
});
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.planId != null) {
updateDeliveryPlan(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addDeliveryPlan(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const planIds = row.planId || this.ids;
this.$modal.confirm('是否确认删除发货计划编号为"' + planIds + '"的数据项?').then(() => {
this.loading = true;
return delDeliveryPlan(planIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/deliveryPlan/export', {
...this.queryParams
}, `deliveryPlan_${new Date().getTime()}.xlsx`)
}
}
};
</script>
<style scoped>
.delivery-plan-card {
margin-bottom: 20px;
height: 100%;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.card-title {
font-size: 16px;
font-weight: bold;
color: #333;
}
.card-content {
margin-bottom: 20px;
}
.content-item {
margin-bottom: 10px;
display: flex;
gap: 10px;
align-items: center;
}
.content-item:last-child {
margin-bottom: 0;
}
.label {
width: 80px;
font-weight: 500;
color: #606266;
margin-right: 10px;
}
.card-actions {
display: flex;
justify-content: center;
gap: 5px;
}
</style>