feat(wms): 优化钢卷库区操作记录吞吐报表统计功能

- 后端新增 statistics 接口聚合图表数据,避免前端遍历计算
- 新增 WmsCoilWarehouseOperationLogStatisticsVo 数据传输对象
- 实现按操作人汇总、按日趋势、汇总指标三个维度的数据查询
- 前端 record 页面集成统计卡片、趋势图、饼图、柱状图展示
- 优化分页逻辑,移除前端全量数据存储和分页计算
- 添加完整的 SQL 统计查询语句支持多维度数据聚合
This commit is contained in:
2026-06-22 17:27:08 +08:00
parent 6436d56ab8
commit b5a269a37a
8 changed files with 254 additions and 111 deletions

View File

@@ -71,4 +71,13 @@ export function getCoilWarehouseOperationLogByCoilId(params) {
method: 'get',
params
})
}
// 吞吐报表统计(后端聚合图表数据)
export function getStatistics(params) {
return request({
url: '/wms/coilWarehouseOperationLog/statistics',
method: 'get',
params
})
}

View File

@@ -177,14 +177,14 @@
</el-table>
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
@pagination="setPageData" />
@pagination="getList" />
</div>
</template>
<script>
import { listCoilWarehouseOperationLog, delCoilWarehouseOperationLog } from "@/api/wms/coilWarehouseOperationLog";
import { listCoilWarehouseOperationLog, delCoilWarehouseOperationLog, getStatistics } from "@/api/wms/coilWarehouseOperationLog";
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
import dayjs from "dayjs";
@@ -219,8 +219,6 @@ export default {
total: 0,
// 钢卷库区操作记录表格数据
coilWarehouseOperationLogList: [],
// 原始数据(用于前端分页)
allData: [],
// 统计指标
stats: {
totalCount: 0,
@@ -248,6 +246,7 @@ export default {
},
created() {
this.getList();
this.getStats();
},
mounted() {
// 初始化图表
@@ -266,7 +265,7 @@ export default {
}
},
methods: {
/** 查询钢卷库区操作记录列表 */
/** 查询钢卷库区操作记录列表(仅表格分页数据) */
getList() {
this.loading = true;
// 处理时间范围
@@ -274,67 +273,50 @@ export default {
this.queryParams.createStartTime = this.queryParams.createTimeRange[0];
this.queryParams.createEndTime = this.queryParams.createTimeRange[1];
}
// 移除分页参数,获取全部数据
const params = { ...this.queryParams, pageNum: 1, pageSize: 10000 };
const params = {
...this.queryParams,
pageNum: this.queryParams.pageNum,
pageSize: this.queryParams.pageSize
};
listCoilWarehouseOperationLog(params).then(response => {
this.allData = response.rows;
this.coilWarehouseOperationLogList = response.rows;
this.total = response.total;
this.calculateStats();
this.setPageData();
this.loading = false;
}).catch(() => {
this.loading = false;
});
},
/** 设置分页数据 */
setPageData() {
const start = (this.queryParams.pageNum - 1) * this.queryParams.pageSize;
const end = start + parseInt(this.queryParams.pageSize);
this.coilWarehouseOperationLogList = this.allData.slice(start, end);
},
/** 计算统计指标 */
calculateStats() {
// 计算操作记录总数
this.stats.totalCount = this.allData.length;
/** 查询吞吐报表统计(图表 + 卡片,后端聚合) */
getStats() {
const params = { ...this.queryParams };
if (params.createTimeRange) {
params.createStartTime = params.createTimeRange[0];
params.createEndTime = params.createTimeRange[1];
}
delete params.pageNum;
delete params.pageSize;
// 计算总重量
this.stats.totalWeight = this.allData.reduce((sum, item) => {
if (item.coil && item.coil.netWeight) {
return sum + parseFloat(item.coil.netWeight);
}
return sum;
}, 0).toFixed(2);
// 计算涉及的库位数量(去重)
const warehouseIds = new Set();
this.allData.forEach(item => {
if (item.warehouse && item.warehouse.actualWarehouseId) {
warehouseIds.add(item.warehouse.actualWarehouseId);
}
getStatistics(params).then(response => {
const data = response.data;
this.stats.totalCount = Number(data.totalCount) || 0;
this.stats.totalWeight = Number(data.totalWeight || 0).toFixed(2);
this.stats.warehouseCount = Number(data.warehouseCount) || 0;
this.userSummaryData = (data.userSummary || []).map(item => ({
createBy: item.createBy,
coilCount: Number(item.coilCount) || 0,
totalWeight: Number(item.totalWeight || 0)
}));
// 更新图表
this.updateTrendChart((data.trendData || []).map(item => ({
date: item.date,
count: Number(item.count) || 0
})));
this.updatePieChart(this.userSummaryData);
this.updateBarChart(this.userSummaryData);
}).catch(err => {
console.error('获取统计失败:', err);
});
this.stats.warehouseCount = warehouseIds.size;
// 按操作人汇总数据
const userMap = {};
this.allData.forEach(item => {
const user = item.createBy || '未知';
if (!userMap[user]) {
userMap[user] = {
createBy: user,
coilCount: 0,
totalWeight: 0
};
}
userMap[user].coilCount++;
if (item.coil && item.coil.netWeight) {
userMap[user].totalWeight += parseFloat(item.coil.netWeight);
}
});
// 转换为数组并按操作卷数降序排序
this.userSummaryData = Object.values(userMap).sort((a, b) => b.coilCount - a.coilCount);
// 更新图表数据
this.updateCharts();
},
/** 初始化图表 */
initCharts() {
@@ -345,29 +327,12 @@ export default {
// 柱状图
this.barChart = echarts.init(document.getElementById('barChart'));
},
/** 更新图表数据 */
updateCharts() {
this.updateTrendChart();
this.updatePieChart();
this.updateBarChart();
},
/** 更新趋势图 */
updateTrendChart() {
updateTrendChart(trendData) {
if (!this.trendChart) return;
// 按日期分组数据
const dateMap = {};
this.allData.forEach(item => {
const date = item.createTime.substring(0, 10);
if (!dateMap[date]) {
dateMap[date] = 0;
}
dateMap[date]++;
});
// 转换为数组并排序
const dateArr = Object.keys(dateMap).sort();
const dataArr = dateArr.map(date => dateMap[date]);
const dateArr = (trendData || []).map(item => item.date);
const dataArr = (trendData || []).map(item => item.count);
const option = {
tooltip: {
@@ -390,26 +355,13 @@ export default {
this.trendChart.setOption(option);
},
/** 更新饼图 */
updatePieChart() {
updatePieChart(userSummaryData) {
if (!this.pieChart) return;
// 按操作人分组数据
const userMap = {};
this.allData.forEach(item => {
const user = item.createBy || '未知';
if (!userMap[user]) {
userMap[user] = 0;
}
userMap[user]++;
});
// 转换为数组并按操作次数从大到小排序
const data = Object.entries(userMap)
.sort((a, b) => b[1] - a[1])
.map(([user, value]) => ({
name: user,
value: value
}));
const data = (userSummaryData || []).map(item => ({
name: item.createBy,
value: item.coilCount
}));
const option = {
tooltip: {
@@ -425,23 +377,11 @@ export default {
this.pieChart.setOption(option);
},
/** 更新柱状图 */
updateBarChart() {
updateBarChart(userSummaryData) {
if (!this.barChart) return;
// 按操作人分组数据
const userMap = {};
this.allData.forEach(item => {
const user = item.createBy || '未知';
if (!userMap[user]) {
userMap[user] = 0;
}
userMap[user]++;
});
// 转换为数组并按操作次数从大到小排序
const sortedEntries = Object.entries(userMap).sort((a, b) => b[1] - a[1]);
const users = sortedEntries.map(([user]) => user);
const counts = sortedEntries.map(([, count]) => count);
const users = (userSummaryData || []).map(item => item.createBy);
const counts = (userSummaryData || []).map(item => item.coilCount);
const option = {
tooltip: {
@@ -470,6 +410,7 @@ export default {
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
this.getStats();
},
/** 重置按钮操作 */
resetQuery() {