feat(wms): 新增钢卷表面处理字段及相关功能

在钢卷相关实体类、前端页面和查询逻辑中新增钢卷表面处理字段,包括:
1. 在WmsMaterialCoil、WmsMaterialCoilVo、WmsMaterialCoilBo中新增coilSurfaceTreatment字段
2. 在前端多个页面中新增钢卷表面处理的展示和编辑功能
3. 在查询逻辑中新增对钢卷表面处理的过滤条件
4. 新增仓库操作记录页面及相关统计图表功能
This commit is contained in:
砂糖
2026-04-01 14:50:56 +08:00
parent f959f97099
commit 579bf3796f
19 changed files with 677 additions and 47 deletions

View File

@@ -433,6 +433,7 @@ export default {
};
</script>
<style scoped>
.app-container {
overflow: hidden;

View File

@@ -137,6 +137,10 @@
<span class="param-label">镀层种类</span>
<span class="param-value">{{ item.coatingType }}</span>
</div>
<div class="param-row" v-if="item.coilSurfaceTreatment">
<span class="param-label">钢卷表面处理</span>
<span class="param-value">{{ item.coilSurfaceTreatment }}</span>
</div>
<div class="param-row" v-if="item.team">
<span class="param-label">班组</span>
<span class="param-value">{{ item.team }}</span>
@@ -349,6 +353,9 @@
<el-form-item label="镀层种类" prop="coatingType">
<MemoInput storageKey="coatingType" v-model="form.coatingType" placeholder="请输入镀层种类" />
</el-form-item>
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="form.coilSurfaceTreatment" placeholder="请输入钢卷表面处理" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>

View File

@@ -128,6 +128,10 @@
<span class="param-label">镀层种类</span>
<span class="param-value">{{ item.coatingType }}</span>
</div>
<div class="param-row" v-if="item.coilSurfaceTreatment">
<span class="param-label">钢卷表面处理</span>
<span class="param-value">{{ item.coilSurfaceTreatment }}</span>
</div>
<div class="param-row" v-if="item.team">
<span class="param-label">班组</span>
<span class="param-value">{{ item.team }}</span>
@@ -423,6 +427,9 @@
<el-form-item label="镀层种类" prop="coatingType">
<MemoInput storageKey="coatingType" v-model="form.coatingType" placeholder="请输入镀层种类" />
</el-form-item>
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="form.coilSurfaceTreatment" placeholder="请输入钢卷表面处理" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>

View File

@@ -222,13 +222,20 @@
</el-form-item>
</div>
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment" class="form-item-half">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="targetCoil.coilSurfaceTreatment"
placeholder="请输入钢卷表面处理" />
</el-form-item>
<!-- <div class="form-row"> -->
<el-form-item label="生产开始时间" prop="productionStartTime" class="form-item-half">
<TimeInput v-model="targetCoil.productionStartTime" @input="calculateProductionDuration" :disabled="readonly" />
</el-form-item>
<el-form-item label="生产结束时间" prop="productionEndTime" class="form-item-half">
<TimeInput v-model="targetCoil.productionEndTime" @input="calculateProductionDuration" :disabled="readonly" :show-now-button="true" />
</el-form-item>
<el-form-item label="生产开始时间" prop="productionStartTime" class="form-item-half">
<TimeInput v-model="targetCoil.productionStartTime" @input="calculateProductionDuration"
:disabled="readonly" />
</el-form-item>
<el-form-item label="生产结束时间" prop="productionEndTime" class="form-item-half">
<TimeInput v-model="targetCoil.productionEndTime" @input="calculateProductionDuration"
:disabled="readonly" :show-now-button="true" />
</el-form-item>
<!-- </div> -->
<div class="form-row">
@@ -240,30 +247,18 @@
<div class="form-row">
<el-form-item label="异常信息" class="form-item-full">
<div class="abnormal-container">
<div
v-for="(abnormal, index) in abnormals"
:key="index"
class="abnormal-item"
@click="editAbnormal(index)"
>
<div v-for="(abnormal, index) in abnormals" :key="index" class="abnormal-item"
@click="editAbnormal(index)">
<div class="abnormal-content">
<div class="abnormal-info">
<div class="abnormal-position">{{ getAbnormalPositionText(abnormal.position) }}</div>
<div class="abnormal-code">{{ getAbnormalCodeText(abnormal.defectCode) }}</div>
</div>
<el-button
type="danger"
size="mini"
icon="el-icon-close"
class="abnormal-delete"
@click.stop="deleteAbnormal(index)"
></el-button>
<el-button type="danger" size="mini" icon="el-icon-close" class="abnormal-delete"
@click.stop="deleteAbnormal(index)"></el-button>
</div>
</div>
<div
class="abnormal-add"
@click="addAbnormal"
>
<div class="abnormal-add" @click="addAbnormal">
<i class="el-icon-plus"></i>
</div>
</div>
@@ -276,16 +271,9 @@
</div>
<!-- 异常表单弹窗 -->
<el-dialog
:title="currentAbnormalIndex === -1 ? '新增异常' : '编辑异常'"
:visible.sync="abnormalDialogVisible"
width="600px"
>
<abnormal-form
ref="abnormalForm"
v-model="abnormalForm"
:show-coil-selector="false"
></abnormal-form>
<el-dialog :title="currentAbnormalIndex === -1 ? '新增异常' : '编辑异常'" :visible.sync="abnormalDialogVisible"
width="600px">
<abnormal-form ref="abnormalForm" v-model="abnormalForm" :show-coil-selector="false"></abnormal-form>
<div slot="footer" class="dialog-footer">
<el-button @click="abnormalDialogVisible = false"> </el-button>
<el-button type="primary" @click="saveAbnormal"> </el-button>
@@ -858,20 +846,20 @@ export default {
// 格式化毫秒值为xx天xx小时xx分钟
formatDuration(milliseconds) {
if (!milliseconds || milliseconds < 0) return '';
const seconds = Math.floor(milliseconds / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
const remainingHours = hours % 24;
const remainingMinutes = minutes % 60;
let result = '';
if (days > 0) result += `${days}`;
if (remainingHours > 0) result += `${remainingHours}小时`;
if (remainingMinutes > 0) result += `${remainingMinutes}分钟`;
return result || '0分钟';
},
// 计算生产耗时
@@ -902,7 +890,7 @@ export default {
closePage() {
this.$router.back();
},
// 新增异常
addAbnormal() {
this.currentAbnormalIndex = -1;
@@ -918,21 +906,21 @@ export default {
};
this.abnormalDialogVisible = true;
},
// 编辑异常
editAbnormal(index) {
this.currentAbnormalIndex = index;
this.abnormalForm = { ...this.abnormals[index] };
this.abnormalDialogVisible = true;
},
// 保存异常
saveAbnormal() {
this.$refs.abnormalForm.validate(valid => {
if (valid) {
// 计算缺陷长度
this.abnormalForm.length = this.abnormalForm.endPosition - this.abnormalForm.startPosition;
if (this.currentAbnormalIndex === -1) {
// 新增异常
this.abnormals.push({ ...this.abnormalForm });
@@ -940,12 +928,12 @@ export default {
// 编辑异常
this.abnormals[this.currentAbnormalIndex] = { ...this.abnormalForm };
}
this.abnormalDialogVisible = false;
}
});
},
// 删除异常
deleteAbnormal(index) {
this.$confirm('确定要删除这个异常信息吗?', '提示', {
@@ -956,7 +944,7 @@ export default {
this.abnormals.splice(index, 1);
});
},
// 获取异常位置文本
getAbnormalPositionText(position) {
if (!position) return '';
@@ -965,7 +953,7 @@ export default {
const item = dict.find(item => item.value === position);
return item ? item.label : position;
},
// 获取异常代码文本
getAbnormalCodeText(code) {
if (!code) return '';

View File

@@ -394,6 +394,9 @@
<el-form-item label="镀层种类" prop="coatingType">
<MemoInput storageKey="coatingType" v-model="form.coatingType" placeholder="请输入镀层种类" />
</el-form-item>
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="form.coilSurfaceTreatment" placeholder="请输入钢卷表面处理" />
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" placeholder="请输入备注" />
</el-form-item>
@@ -796,6 +799,8 @@ export default {
{ label: '镀层种类', prop: 'coatingType' },
{ label: '实测长度(m)', prop: 'actualLength' },
{ label: '实测宽度(m)', prop: 'actualWidth' },
{ label: '实测厚度(m)', prop: 'actualThickness' },
{ label: '钢卷表面处理', prop: 'coilSurfaceTreatment' },
],
title: '详细信息'
},

View File

@@ -123,6 +123,10 @@
<span class="param-label">镀层种类</span>
<span class="param-value">{{ item.coatingType }}</span>
</div>
<div class="param-row" v-if="item.coilSurfaceTreatment">
<span class="param-label">钢卷表面处理</span>
<span class="param-value">{{ item.coilSurfaceTreatment }}</span>
</div>
<div class="param-row" v-if="item.team">
<span class="param-label">班组</span>
<span class="param-value">{{ item.team }}</span>

View File

@@ -34,6 +34,10 @@
<el-descriptions-item label="规格">{{ coilInfo.specification || '-' }}</el-descriptions-item>
<el-descriptions-item label="材质">{{ coilInfo.material || '-' }}</el-descriptions-item>
<el-descriptions-item label="原料材质">{{ coilInfo.packingStatus || '-' }}</el-descriptions-item>
<el-descriptions-item label="实测长度(m)">{{ coilInfo.actualLength || '-' }}</el-descriptions-item>
<el-descriptions-item label="实测宽度(m)">{{ coilInfo.actualWidth || '-' }}</el-descriptions-item>
<el-descriptions-item label="实测厚度(m)">{{ coilInfo.actualThickness || '-' }}</el-descriptions-item>
<el-descriptions-item label="钢卷表面处理">{{ coilInfo.coilSurfaceTreatment || '-' }}</el-descriptions-item>
<el-descriptions-item label="净重">{{ coilInfo.netWeight || '-' }} T</el-descriptions-item>
</el-descriptions>
<!-- 已分条钢卷列表 -->
@@ -175,6 +179,9 @@
<el-form-item label="镀层种类" prop="coatingType">
<MemoInput storageKey="coatingType" v-model="splitForm.coatingType" placeholder="请输入镀层种类" />
</el-form-item>
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="splitForm.coilSurfaceTreatment" placeholder="请输入钢卷表面处理" />
</el-form-item>
<el-form-item label="生产开始时间" prop="productionStartTime">
<TimeInput v-model="splitForm.productionStartTime" @input="calculateProductionDuration" />
</el-form-item>
@@ -257,6 +264,7 @@
<el-descriptions-item label="调制度">{{ selectedSplitItem.temperGrade || '-' }}</el-descriptions-item>
<el-descriptions-item label="镀层种类">{{ selectedSplitItem.coatingType || '-' }}</el-descriptions-item>
<el-descriptions-item label="钢卷表面处理">{{ selectedSplitItem.coilSurfaceTreatment || '-' }}</el-descriptions-item>
<el-descriptions-item label="生产开始时间">{{ selectedSplitItem.productionStartTime || '-'
}}</el-descriptions-item>
<el-descriptions-item label="生产结束时间">{{ selectedSplitItem.productionEndTime || '-'

View File

@@ -61,6 +61,10 @@
<span class="label">镀层种类</span>
<span class="value">{{ motherCoil.coatingType || '—' }}</span>
</div>
<div class="coil-info-row">
<span class="label">钢卷表面处理</span>
<span class="value">{{ motherCoil.coilSurfaceTreatment || '—' }}</span>
</div>
<div class="coil-info-row" v-if="motherCoil.materialName || motherCoil.productName">
<span class="label">物料名称</span>
<span class="value">{{ motherCoil.materialName || motherCoil.productName || '—' }}</span>
@@ -217,6 +221,9 @@
<el-form-item label="镀层种类" prop="coatingType">
<MemoInput storageKey="coatingType" v-model="item.coatingType" placeholder="请输入镀层种类" />
</el-form-item>
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="item.coilSurfaceTreatment" placeholder="请输入钢卷表面处理" />
</el-form-item>
<el-form-item label="逻辑库区" required>
<WarehouseSelect v-model="item.warehouseId" placeholder="请选择逻辑库区" :disabled="readonly" />
</el-form-item>

View File

@@ -60,6 +60,10 @@
<span class="info-label">原料材质</span>
<span class="info-value">{{ currentInfo.packingStatus || '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">钢卷表面处理</span>
<span class="info-value">{{ currentInfo.coilSurfaceTreatment || '—' }}</span>
</div>
<div class="info-row">
<span class="info-label">厂家</span>
<span class="info-value">{{ currentInfo.manufacturer || '—' }}</span>
@@ -211,6 +215,10 @@
<MemoInput storageKey="coatingType" v-model="updateForm.coatingType" placeholder="请输入镀层种类" />
</el-form-item>
<el-form-item label="钢卷表面处理" prop="coilSurfaceTreatment">
<MemoInput storageKey="surfaceTreatmentDesc" v-model="updateForm.coilSurfaceTreatment" placeholder="请输入钢卷表面处理" />
</el-form-item>
<el-form-item label="逻辑库区" prop="warehouseId">
<WarehouseSelect v-model="updateForm.warehouseId" placeholder="请选择逻辑库区" />
</el-form-item>

View File

@@ -63,7 +63,7 @@
</el-table-column>
<el-table-column prop="coil.specification" label="规格" width="220">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.coil.itemType == 'product'" :product="scope.row.coil.product" />
<ProductInfo v-if="scope.row.coil.itemType == 'product'" :product="scope.row.coil" />
<RawMaterialInfo v-else-if="scope.row.coil.itemType === 'raw_material'"
:material="scope.row.coil" />
</template>

View File

@@ -0,0 +1,514 @@
<template>
<div class="app-container" v-loading="loading">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="操作时间" prop="createTimeRange">
<el-date-picker clearable v-model="queryParams.createTimeRange" type="datetimerange"
value-format="yyyy-MM-dd HH:mm:ss" range-separator="" start-placeholder="开始日期" end-placeholder="结束日期">
</el-date-picker>
</el-form-item>
<el-form-item label="创建人" prop="createBy">
<el-input v-model="queryParams.createBy" 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-form-item>
</el-form>
<!-- 统计指标卡 -->
<el-row :gutter="10" class="mb10">
<el-col :span="8">
<el-card shadow="hover" :body-style="{ padding: '10px' }">
<div class="stat-card">
<div class="stat-icon stat-icon-primary">
<i class="el-icon-document"></i>
</div>
<div class="stat-content">
<div class="stat-title">操作记录总数</div>
<div class="stat-value">{{ stats.totalCount }}</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" :body-style="{ padding: '10px' }">
<div class="stat-card">
<div class="stat-icon stat-icon-success">
<i class="el-icon-s-finance"></i>
</div>
<div class="stat-content">
<div class="stat-title">总重量</div>
<div class="stat-value">{{ stats.totalWeight }} kg</div>
</div>
</div>
</el-card>
</el-col>
<el-col :span="8">
<el-card shadow="hover" :body-style="{ padding: '10px' }">
<div class="stat-card">
<div class="stat-icon stat-icon-warning">
<i class="el-icon-location"></i>
</div>
<div class="stat-content">
<div class="stat-title">涉及库位</div>
<div class="stat-value">{{ stats.warehouseCount }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- 图表区域 -->
<el-row :gutter="10" class="mb10">
<el-col :span="12">
<el-card shadow="hover" :body-style="{ padding: '10px' }">
<div slot="header" class="clearfix" style="padding-bottom: 5px;">
<span>操作记录趋势</span>
</div>
<div id="trendChart" style="height: 250px;"></div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover" :body-style="{ padding: '10px' }">
<div slot="header" class="clearfix" style="padding-bottom: 5px;">
<span>操作人分布饼图</span>
</div>
<div id="pieChart" style="height: 250px;"></div>
</el-card>
</el-col>
<el-col :span="6">
<el-card shadow="hover" :body-style="{ padding: '10px' }">
<div slot="header" class="clearfix" style="padding-bottom: 5px;">
<span>操作人分布柱状图</span>
</div>
<div id="barChart" style="height: 250px;"></div>
</el-card>
</el-col>
</el-row>
<el-table height="calc(100vh - 400px)" :data="coilWarehouseOperationLogList"
@selection-change="handleSelectionChange">
<el-table-column prop="createTime" label="操作时间" width="180">
<template slot-scope="scope">
{{ scope.row.createTime }}
</template>
</el-table-column>
<el-table-column prop="createBy" label="操作人" width="180">
<template slot-scope="scope">
{{ scope.row.createBy }}
</template>
</el-table-column>
<el-table-column prop="operationType" label="操作类型" width="100">
<template slot-scope="scope">
<span v-if="scope.row.operationType === 1">收货</span>
<span v-else-if="scope.row.operationType === 2">加工</span>
<span v-else-if="scope.row.operationType === 3">调拨</span>
<span v-else-if="scope.row.operationType === 4">发货</span>
<!-- {{ scope.row.operationType === 1 ? '入库' : '出库' }} -->
</template>
</el-table-column>
<el-table-column prop="inOutType" label="出入库类型" width="100">
<template slot-scope="scope">
{{ scope.row.inOutType === 1 ? '入库' : '出库' }}
</template>
</el-table-column>
<el-table-column prop="coil.enterCoilNo" label="入场卷号" width="150">
<template slot-scope="scope">
{{ scope.row.coil && scope.row.coil.enterCoilNo ? scope.row.coil.enterCoilNo : '-' }}
</template>
</el-table-column>
<el-table-column prop="coil.currentCoilNo" label="当前卷号" width="150">
<template slot-scope="scope">
{{ scope.row.coil && scope.row.coil.currentCoilNo ? scope.row.coil.currentCoilNo : '-' }}
</template>
</el-table-column>
<el-table-column prop="coil.weight" label="重量">
<template slot-scope="scope">
{{ scope.row.coil && scope.row.coil.netWeight ? scope.row.coil.netWeight : '-' }}
</template>
</el-table-column>
<el-table-column prop="coil.specification" label="规格" width="180">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.coil.itemType == 'product'" :product="scope.row.coil" />
<RawMaterialInfo v-else-if="scope.row.coil.itemType === 'raw_material'" :material="scope.row.coil" />
</template>
</el-table-column>
<el-table-column prop="warehouse.actualWarehouseName" label="库位">
<template slot-scope="scope">
{{ scope.row.warehouse && scope.row.warehouse.actualWarehouseName ? scope.row.warehouse.actualWarehouseName :
'-' }}
</template>
</el-table-column>
<el-table-column label="操作" width="100">
<template slot-scope="scope">
<el-button :loading="buttonLoading" type="danger" size="mini" icon="el-icon-delete"
@click="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="setPageData" />
</div>
</template>
<script>
import { listCoilWarehouseOperationLog, delCoilWarehouseOperationLog } from "@/api/wms/coilWarehouseOperationLog";
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
import dayjs from "dayjs";
import * as echarts from "echarts";
export default {
name: "CoilWarehouseOperationLog",
components: {
ProductInfo,
RawMaterialInfo,
},
data() {
// 筛选时间设置为本月时间
const createTimeRange = [
dayjs().startOf('month').format('YYYY-MM-DD HH:mm:ss'),
dayjs().endOf('month').format('YYYY-MM-DD HH:mm:ss')
];
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 钢卷库区操作记录表格数据
coilWarehouseOperationLogList: [],
// 原始数据(用于前端分页)
allData: [],
// 统计指标
stats: {
totalCount: 0,
totalWeight: 0,
warehouseCount: 0
},
// 图表实例
trendChart: null,
pieChart: null,
barChart: null,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 50,
actualWarehouseId: undefined,
createTimeRange: createTimeRange,
operationType: undefined,
inOutType: undefined,
createTime: undefined,
createBy: undefined,
}
};
},
created() {
this.getList();
},
mounted() {
// 初始化图表
this.initCharts();
},
beforeDestroy() {
// 销毁图表实例
if (this.trendChart) {
this.trendChart.dispose();
}
if (this.pieChart) {
this.pieChart.dispose();
}
if (this.barChart) {
this.barChart.dispose();
}
},
methods: {
/** 查询钢卷库区操作记录列表 */
getList() {
this.loading = true;
// 处理时间范围
if (this.queryParams.createTimeRange) {
this.queryParams.createStartTime = this.queryParams.createTimeRange[0];
this.queryParams.createEndTime = this.queryParams.createTimeRange[1];
}
// 移除分页参数,获取全部数据
const params = { ...this.queryParams, pageNum:1, pageSize: 10000 };
listCoilWarehouseOperationLog(params).then(response => {
this.allData = response.rows;
this.total = response.total;
this.calculateStats();
this.setPageData();
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;
// 计算总重量
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);
}
});
this.stats.warehouseCount = warehouseIds.size;
// 更新图表数据
this.updateCharts();
},
/** 初始化图表 */
initCharts() {
// 趋势图
this.trendChart = echarts.init(document.getElementById('trendChart'));
// 饼图
this.pieChart = echarts.init(document.getElementById('pieChart'));
// 柱状图
this.barChart = echarts.init(document.getElementById('barChart'));
},
/** 更新图表数据 */
updateCharts() {
this.updateTrendChart();
this.updatePieChart();
this.updateBarChart();
},
/** 更新趋势图 */
updateTrendChart() {
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 option = {
tooltip: {
trigger: 'axis'
},
xAxis: {
type: 'category',
data: dateArr
},
yAxis: {
type: 'value'
},
series: [{
data: dataArr,
type: 'line',
smooth: true
}]
};
this.trendChart.setOption(option);
},
/** 更新饼图 */
updatePieChart() {
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 option = {
tooltip: {
trigger: 'item'
},
series: [{
type: 'pie',
data: data,
radius: '50%'
}]
};
this.pieChart.setOption(option);
},
/** 更新柱状图 */
updateBarChart() {
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 option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
xAxis: {
type: 'category',
data: users
},
yAxis: {
type: 'value'
},
series: [{
data: counts,
type: 'bar'
}]
};
this.barChart.setOption(option);
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.logId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 删除按钮操作 */
handleDelete(row) {
const logIds = row.logId || this.ids;
this.$modal.confirm('是否确认删除钢卷库区操作记录编号为"' + logIds + '"的数据项?').then(() => {
this.loading = true;
return delCoilWarehouseOperationLog(logIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/coilWarehouseOperationLog/export', {
...this.queryParams
}, `coilWarehouseOperationLog_${new Date().getTime()}.xlsx`)
}
}
};
</script>
<style scoped>
.stat-card {
display: flex;
align-items: center;
padding: 5px 0;
}
.stat-icon {
width: 50px;
height: 50px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 15px;
font-size: 20px;
color: #fff;
}
.stat-icon-primary {
background-color: #409eff;
}
.stat-icon-success {
background-color: #67c23a;
}
.stat-icon-warning {
background-color: #e6a23c;
}
.stat-content {
flex: 1;
}
.stat-title {
font-size: 12px;
color: #606266;
margin-bottom: 3px;
}
.stat-value {
font-size: 20px;
font-weight: bold;
color: #303133;
}
.mb10 {
margin-bottom: 10px;
}
.mb20 {
margin-bottom: 20px;
}
</style>