feat:物料档案增加安全库存上限, 新增仓库数量汇总报表页

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
caoqianming 2026-07-14 15:21:32 +08:00
parent 94859d431d
commit cc69fa8cca
3 changed files with 174 additions and 2 deletions

View File

@ -0,0 +1,155 @@
<!--
物料保障车间-仓库数量汇总表
数据来源: BI 数据集 code=wh_material_summary (POST api/bi/dataset/{code}/exec)
返回 res.data2.ds0~ds3, 分组维度为 material.model(型号)
菜单/路由由后端下发, component bi/material_wh_summary
-->
<template>
<el-container>
<el-header style="display: flex; align-items: center;">
<span style="font-weight: 600; margin-right: 12px;">周区间</span>
<el-date-picker
v-model="dateRange"
type="daterange"
value-format="YYYY-MM-DD"
range-separator="至"
start-placeholder="开始时间(当周周一)"
end-placeholder="截止时间(当周周末)"
:clearable="false"
style="margin-right: 12px;"
/>
<el-button type="primary" icon="el-icon-search" @click="fetchData" :loading="loading">查询</el-button>
</el-header>
<el-main v-loading="loading">
<!-- ds0: 库存量 + 安全库存上下限 -->
<el-card shadow="never" class="rpt-card">
<template #header>库存量 安全库存上下限(个人设定)</template>
<el-table :data="ds0" border stripe size="small" :span-method="ds0Span">
<el-table-column label="区块" prop="区块" width="90" />
<el-table-column label="型号" prop="型号" width="120" />
<el-table-column label="库存量" prop="库存量" align="right" />
<el-table-column label="安全库存下限" prop="安全库存下限" align="right" />
<el-table-column label="安全库存上限" prop="安全库存上限" align="right" />
</el-table>
</el-card>
<!-- ds1: 成品库周数据 -->
<el-card shadow="never" class="rpt-card">
<template #header>成品库周数据(入库=生产入库 / 出库=销售发货)</template>
<el-table :data="ds1" border stripe size="small">
<el-table-column label="型号" prop="型号" width="120" />
<el-table-column label="入库数据" prop="入库数据" align="right" />
<el-table-column label="出库数据" prop="出库数据" align="right" />
<el-table-column label="现有库存" prop="现有库存" align="right" />
</el-table>
</el-card>
<!-- ds2: 原料库(棒料)周数据 -->
<el-card shadow="never" class="rpt-card">
<template #header>原料库(棒料)周数据</template>
<el-table :data="ds2" border stripe size="small">
<el-table-column label="型号" prop="型号" width="120" />
<el-table-column label="入库数据" prop="入库数据" align="right" />
<el-table-column label="外协出库" prop="外协出库" align="right" />
<el-table-column label="光芯出库" prop="光芯出库" align="right" />
<el-table-column label="现有库存" prop="现有库存" align="right" />
</el-table>
</el-card>
<!-- ds3: 白玻 / 黑玻 周数据 -->
<el-card shadow="never" class="rpt-card">
<template #header>白玻 / 黑玻 周数据(外协以"外协%"工段判定)</template>
<el-table :data="ds3" border stripe size="small" :span-method="ds3Span">
<el-table-column label="区块" prop="区块" width="90" />
<el-table-column label="型号" prop="型号" width="120" />
<el-table-column label="外协外发数量" prop="外协外发数量" align="right" />
<el-table-column label="外协来料数量" prop="外协来料数量" align="right" />
<el-table-column label="现有库存" prop="现有库存" align="right" />
</el-table>
</el-card>
</el-main>
</el-container>
</template>
<script>
export default {
name: "materialWhSummary",
data() {
return {
loading: false,
dateRange: [],
ds0: [],
ds1: [],
ds2: [],
ds3: [],
};
},
created() {
this.dateRange = this.currentWeekRange();
this.fetchData();
},
methods: {
// ~
currentWeekRange() {
const now = new Date();
const day = now.getDay() || 7; // 7
const monday = new Date(now);
monday.setDate(now.getDate() - day + 1);
const sunday = new Date(monday);
sunday.setDate(monday.getDate() + 6);
return [this.fmt(monday), this.fmt(sunday)];
},
fmt(d) {
const p = (n) => (n < 10 ? "0" + n : "" + n);
return d.getFullYear() + "-" + p(d.getMonth() + 1) + "-" + p(d.getDate());
},
fetchData() {
const [start_date, end_date] = this.dateRange || [];
if (!start_date || !end_date) {
this.$message.warning("请选择周区间");
return;
}
this.loading = true;
this.$API.bi.dataset.exec
.req("wh_material_summary", { query: { start_date, end_date } })
.then((res) => {
const d = res.data2 || {};
this.ds0 = d.ds0 || [];
this.ds1 = d.ds1 || [];
this.ds2 = d.ds2 || [];
this.ds3 = d.ds3 || [];
})
.finally(() => {
this.loading = false;
});
},
// ""
mergeFirstCol(rows, key, rowIndex, columnIndex) {
if (columnIndex !== 0) return;
const cur = rows[rowIndex] && rows[rowIndex][key];
const prev = rows[rowIndex - 1] && rows[rowIndex - 1][key];
if (rowIndex > 0 && cur === prev) {
return { rowspan: 0, colspan: 0 };
}
let span = 1;
for (let i = rowIndex + 1; i < rows.length; i++) {
if (rows[i][key] === cur) span++;
else break;
}
return { rowspan: span, colspan: 1 };
},
ds0Span({ rowIndex, columnIndex }) {
return this.mergeFirstCol(this.ds0, "区块", rowIndex, columnIndex);
},
ds3Span({ rowIndex, columnIndex }) {
return this.mergeFirstCol(this.ds3, "区块", rowIndex, columnIndex);
},
},
};
</script>
<style scoped>
.rpt-card {
margin-bottom: 16px;
}
</style>

View File

@ -133,13 +133,21 @@
</el-form-item>
</el-col>
<el-col :md="12" :sm="24">
<el-form-item label="安全库存" prop="count_safe">
<el-form-item label="安全库存下限" prop="count_safe">
<el-input-number
v-model="form.count_safe"
:min="0"
/>
</el-form-item>
</el-col>
<el-col :md="12" :sm="24">
<el-form-item label="安全库存上限" prop="count_safe_upper">
<el-input-number
v-model="form.count_safe_upper"
:min="0"
/>
</el-form-item>
</el-col>
<el-col :md="12" :sm="24">
<el-form-item label="组合件" prop="is_assemb">
<el-switch v-model="form.is_assemb" />

View File

@ -122,13 +122,21 @@
</el-form-item>
</el-col>
<el-col :md="12" :sm="24">
<el-form-item label="安全库存" prop="count_safe">
<el-form-item label="安全库存下限" prop="count_safe">
<el-input-number
v-model="form.count_safe"
:min="0"
/>
</el-form-item>
</el-col>
<el-col :md="12" :sm="24">
<el-form-item label="安全库存上限" prop="count_safe_upper">
<el-input-number
v-model="form.count_safe_upper"
:min="0"
/>
</el-form-item>
</el-col>
<!-- 光芯 -->
<el-col :md="12" :sm="24" v-if="form.type == 40">
<el-form-item label="仓库位号">
@ -346,6 +354,7 @@ export default {
that.form.process = data.process;
that.form.tracking = data.tracking;
that.form.count_safe = data.count_safe;
that.form.count_safe_upper = data.count_safe_upper;
that.form.is_hidden = data.is_hidden;
that.form.unit_price = data.unit_price;
that.form.photo = data.photo;