Merge remote-tracking branch 'origin/0.8.X' into 0.8.X

This commit is contained in:
2026-02-28 10:16:48 +08:00
25 changed files with 1422 additions and 851 deletions

View File

@@ -1,7 +1,6 @@
package com.klp.pocket.acid.service;
import com.klp.pocket.acid.domain.vo.AcidTypingPrefillVo;
import org.w3c.dom.stylesheets.LinkStyle;
import java.util.List;

View File

@@ -14,10 +14,10 @@
@close="handleClose">
<!-- 搜索区域 -->
<el-form :inline="true" :model="queryParams" class="search-form" size="small">
<el-form-item label="产品编号">
<!-- <el-form-item label="产品编号">
<el-input v-model="queryParams.productCode" placeholder="请输入产品编号" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
</el-form-item> -->
<el-form-item label="产品名称">
<MemoInput storageKey="productName" v-model="queryParams.productName" placeholder="请输入产品名称" clearable
@keyup.enter.native="handleQuery" />
@@ -45,6 +45,7 @@
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" plain icon="el-icon-plus" @click="handleAdd" title="添加产品">新增</el-button>
</el-form-item>
</el-form>
@@ -67,10 +68,9 @@
<div class="card-content">
<div class="card-title">
<span class="name">{{ item.productName }}</span>
<span class="code">[{{ item.productCode }}]</span>
<span class="code">[{{ item.specification || '-' }}]</span>
</div>
<div class="card-info">
<div class="info-item">规格<span>{{ item.specification || '-' }}</span></div>
<div class="info-item">材质<span>{{ item.material || '-' }}</span></div>
<div class="info-item">厂家<span>{{ item.manufacturer || '-' }}</span></div>
<div class="info-item">表面处理<span>{{ item.surfaceTreatmentDesc || '-' }}</span></div>
@@ -81,7 +81,8 @@
<!-- 空数据提示 -->
<div class="empty-tip" v-if="productList.length === 0 && !loading">
暂无匹配的产品数据
暂无匹配的产品数据,
<span @click="handleAdd" style="cursor: pointer; color: #409eff;">点击快速新增产品</span>
</div>
</div>
@@ -92,12 +93,58 @@
<div slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
</div>
</el-dialog>
<!-- 添加或修改产品对话框 -->
<el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<!-- <el-form-item label="产品编号" prop="productCode">
<el-input v-model="form.productCode" placeholder="请输入产品编号" />
</el-form-item> -->
<el-form-item label="产品名称" prop="productName">
<el-input v-model="form.productName" placeholder="请输入产品名称" />
</el-form-item>
<!-- <el-form-item label="负责人" prop="owner">
<el-input v-model="form.owner" :multiple="false" placeholder="请填写负责人" />
</el-form-item> -->
<el-form-item label="计量单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入计量单位" />
</el-form-item>
<el-form-item label="规格" prop="specification">
<el-input v-model="form.specification" placeholder="请输入规格" />
</el-form-item>
<el-form-item label="材质" prop="material">
<el-input v-model="form.material" placeholder="请输入材质" />
</el-form-item>
<el-form-item label="厂家" prop="manufacturer">
<el-input v-model="form.manufacturer" placeholder="请输入厂家" />
</el-form-item>
<el-form-item label="表面处理" prop="surfaceTreatmentDesc">
<el-input v-model="form.surfaceTreatmentDesc" placeholder="请输入表面处理" />
</el-form-item>
<el-form-item label="镀层质量" prop="zincLayer">
<el-input v-model="form.zincLayer" 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 { listProduct, getProduct } from '@/api/wms/product';
import { listProduct, getProduct, addProduct } from '@/api/wms/product';
import MemoInput from '@/components/MemoInput/index.vue';
export default {
@@ -124,6 +171,21 @@ export default {
dialogVisible: false,
loading: false,
productList: [],
open: false,
form: {},
rules: {
productName: [
{ required: true, message: "产品名称不能为空", trigger: "blur" }
],
unit: [
{ required: true, message: "计量单位不能为空", trigger: "blur" }
],
specification: [
{ required: true, message: "规格不能为空", trigger: "blur" }
],
},
buttonLoading: false,
title: '新增产品',
total: 0,
queryParams: {
pageNum: 1,
@@ -270,7 +332,81 @@ export default {
handleClose() {
this.selectedId = this.value || '';
this.dialogVisible = false;
}
},
/** 新增按钮操作 */
handleAdd() {
// this.reset();
this.form = { ...this.queryParams };
this.open = true;
this.title = "添加产品";
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.productId != null) {
updateProduct(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addProduct({
...this.form,
productCode: this.form.material || '' + (this.form.zincLayer || '') + new Date().getTime(),
}).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
productId: undefined,
productCode: undefined,
productName: undefined,
owner: undefined,
baseMaterialId: undefined,
surfaceTreatmentId: undefined,
customerReqId: undefined,
packagingId: undefined,
thickness: undefined,
width: undefined,
innerDiameter: undefined,
isEnabled: undefined,
unit: '卷',
delFlag: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined,
type: undefined,
specification: undefined,
material: undefined,
manufacturer: undefined,
surfaceTreatmentDesc: undefined,
zincLayer: undefined,
};
this.resetForm("form");
},
},
mounted() {
this.listRecentlySelected();
@@ -365,9 +501,9 @@ export default {
}
.card-info {
display: flex;
flex-direction: column;
gap: 10px;
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
font-size: 14px;
color: #606266;
}

View File

@@ -14,10 +14,6 @@
@close="handleClose" append-to-body>
<!-- 搜索区域 -->
<el-form :inline="true" :model="queryParams" class="search-form" size="small">
<el-form-item label="编号">
<el-input v-model="queryParams.rawMaterialCode" placeholder="请输入原材料编号" clearable
@keyup.enter.native="handleQuery" />
</el-form-item>
<el-form-item label="名称">
<MemoInput storageKey="productName" v-model="queryParams.rawMaterialName" placeholder="请输入原材料名称" clearable
@keyup.enter.native="handleQuery" />
@@ -45,6 +41,7 @@
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
<el-button type="primary" plain icon="el-icon-plus" @click="handleAdd">新增</el-button>
</el-form-item>
</el-form>
@@ -67,10 +64,9 @@
<div class="card-content">
<div class="card-title">
<span class="name">{{ item.rawMaterialName }}</span>
<span class="code">[{{ item.rawMaterialCode }}]</span>
<span class="code">[{{ item.specification || '-' }}]</span>
</div>
<div class="card-info">
<div class="info-item">规格<span>{{ item.specification || '-' }}</span></div>
<div class="info-item">材质<span>{{ item.material || '-' }}</span></div>
<div class="info-item">厂家<span>{{ item.manufacturer || '-' }}</span></div>
<div class="info-item">表面处理<span>{{ item.surfaceTreatmentDesc || '-' }}</span></div>
@@ -81,7 +77,8 @@
<!-- 空数据提示 -->
<div class="empty-tip" v-if="rawMaterialList.length === 0 && !loading">
暂无匹配的原材料数据
暂无匹配的原材料数据,
<span @click="handleAdd" style="cursor: pointer; color: #409eff;">点击快速新增原材料</span>
</div>
</div>
@@ -93,11 +90,48 @@
<el-button @click="dialogVisible = false">取消</el-button>
</div>
</el-dialog>
<!-- 添加或修改原材料对话框 -->
<el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="120px">
<!-- <el-form-item label="原材料编号" prop="rawMaterialCode">
<el-input v-model="form.rawMaterialCode" placeholder="请输入原材料编号" />
</el-form-item> -->
<el-form-item label="原材料名称" prop="rawMaterialName">
<el-input v-model="form.rawMaterialName" placeholder="请输入原材料名称" />
</el-form-item>
<el-form-item label="规格" prop="specification">
<el-input v-model="form.specification" placeholder="请输入规格" />
</el-form-item>
<el-form-item label="计量单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入计量单位" />
</el-form-item>
<el-form-item label="材质" prop="material">
<el-input v-model="form.material" placeholder="请输入材质" />
</el-form-item>
<el-form-item label="厂家" prop="manufacturer">
<el-input v-model="form.manufacturer" placeholder="请输入厂家" />
</el-form-item>
<el-form-item label="表面处理" prop="surfaceTreatmentDesc">
<el-input v-model="form.surfaceTreatmentDesc" placeholder="请输入表面处理" />
</el-form-item>
<el-form-item label="镀层质量" prop="zincLayer">
<el-input v-model="form.zincLayer" 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 { listRawMaterial, getRawMaterial } from '@/api/wms/rawMaterial';
import { listRawMaterial, getRawMaterial, updateRawMaterial, addRawMaterial } from '@/api/wms/rawMaterial';
import MemoInput from '@/components/MemoInput/index.vue'
export default {
@@ -143,7 +177,30 @@ export default {
},
// ✅ 单选核心变量选中的ID和单条数据对象
selectedId: '',
selectedRow: {}
selectedRow: {},
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 表单参数
form: {},
// 表单校验
rules: {
// rawMaterialCode: [
// { required: true, message: "原材料编号不能为空", trigger: "blur" }
// ],
rawMaterialName: [
{ required: true, message: "原材料名称不能为空", trigger: "blur" }
],
unit: [
{ required: true, message: "计量单位不能为空", trigger: "blur" }
],
specification: [
{ required: true, message: "规格不能为空", trigger: "blur" }
],
},
// 提交按钮加载状态
buttonLoading: false,
};
},
computed: {
@@ -187,6 +244,91 @@ export default {
return this.selectedId === rawMaterialId;
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
rawMaterialId: undefined,
rawMaterialCode: undefined,
rawMaterialName: undefined,
steelGrade: undefined,
targetColdGrade: undefined,
baseMaterialId: undefined,
surfaceTreatmentId: undefined,
thickness: undefined,
thicknessDeviation: undefined,
width: undefined,
targetColdWidth: undefined,
targetColdThickness: undefined,
crown: undefined,
coilWeight: undefined,
surfaceQuality: undefined,
hardnessHv5: undefined,
hardnessDiff: undefined,
compositionMn: undefined,
compositionP: undefined,
grainSize: undefined,
headTailCutFlag: undefined,
inspectionResult: undefined,
isEnabled: undefined,
delFlag: undefined,
remark: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined,
specification: undefined,
unit: '卷',
material: undefined,
manufacturer: undefined,
surfaceTreatmentDesc: undefined,
zincLayer: undefined,
};
this.resetForm("form");
},
/** 新增按钮操作 */
handleAdd() {
// this.reset();
this.form = { ...this.queryParams };
this.open = true;
this.title = "添加原材料";
},
/** 提交按钮 */
submitForm() {
this.$refs["form"].validate(valid => {
if (valid) {
this.buttonLoading = true;
if (this.form.rawMaterialId != null) {
updateRawMaterial({
...this.form,
}).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
this.$store.dispatch('category/getRawMaterialMap');
}).finally(() => {
this.buttonLoading = false;
});
} else {
addRawMaterial({
...this.form,
rawMaterialCode: this.form.material || '' + (this.form.zincLayer || '') + new Date().getTime(),
}).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
this.$store.dispatch('category/getRawMaterialMap');
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
// 获取最近选择的原材料数据
async listRecentlySelected() {
try {

View File

@@ -28,11 +28,11 @@
</div>
</div>
<el-tag type="info" size="small" slot="reference">{{ coilNo }}</el-tag>
<el-tag type="info" size="small" slot="reference">{{ currentCoilNo }}</el-tag>
</el-popover>
<!-- 无coilId时仅显示标签 -->
<el-tag v-else type="info" size="small">{{ coilNo }}</el-tag>
<el-tag v-else type="info" size="small">{{ currentCoilNo }}</el-tag>
</div>
</template>
@@ -71,6 +71,9 @@ export default {
manufacturer() {
return this.coilInfo.product?.manufacturer || this.coilInfo.rawMaterial?.manufacturer || '-'
},
currentCoilNo() {
return this.coilNo || this.coilInfo?.currentCoilNo || '-'
}
},
methods: {
getCoilInfo() {

View File

@@ -13,9 +13,9 @@
<el-descriptions-item label="产品名称">
{{ productFull.productName || '--' }}
</el-descriptions-item>
<el-descriptions-item label="产品编码">
<!-- <el-descriptions-item label="产品编码">
{{ productFull.productCode || '--' }}
</el-descriptions-item>
</el-descriptions-item> -->
<el-descriptions-item label="规格">
{{ productFull.specification || '--' }}
</el-descriptions-item>

View File

@@ -12,7 +12,7 @@
<!-- popover 内容两列布局的描述列表 -->
<el-descriptions :column="2" class="popover-content">
<el-descriptions-item label="原材料名称">{{ materialFull.rawMaterialName || '--' }}</el-descriptions-item>
<el-descriptions-item label="原材料编码">{{ materialFull.rawMaterialCode || '--' }}</el-descriptions-item>
<!-- <el-descriptions-item label="原材料编码">{{ materialFull.rawMaterialCode || '--' }}</el-descriptions-item> -->
<el-descriptions-item label="规格">{{ materialFull.specification || '--' }}</el-descriptions-item>
<el-descriptions-item label="材质">{{ materialFull.material || '--' }}</el-descriptions-item>
<el-descriptions-item label="表面处理">{{ materialFull.surfaceTreatment || '--' }}</el-descriptions-item>

View File

@@ -0,0 +1,402 @@
<template>
<div class="app-container">
<el-row :gutter="10">
<el-col :span="6" v-loading="coilLoading">
<div>
<div style="display: flex; align-items: center; gap: 8px;">
<el-input v-model="coilQuery.currentCoilNo" placeholder="请输入钢卷号" @change="getCoilList"></el-input>
<el-button @click="handleAdd" icon="el-icon-plus"></el-button>
</div>
<div>
<CoilList :coilList="coilList" @click="handleCoilClick" />
</div>
<pagination v-show="coilTotal > 0" :total="coilTotal" :page.sync="coilQuery.pageNum"
:limit.sync="coilQuery.pageSize" @pagination="getCoilList" />
</div>
<!-- 左侧为有异常的钢卷列表 -->
<!-- <el-table :data="coilList" border stripe @row-click="handleCoilClick">
<el-table-column label="入场卷号" prop="entryCoilNo" />
<el-table-column label="钢卷号" prop="currentCoilNo" />
<el-table-column label="逻辑库区" prop="warehouseName" />
</el-table> -->
</el-col>
<el-col :span="18" v-if="currentCoilId">
<!-- 右侧为钢卷异常明细 -->
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch"
label-width="68px">
<el-form-item label="位置" prop="position">
<el-select v-model="queryParams.position" placeholder="请选择位置" clearable>
<el-option v-for="dict in dict.type.coil_abnormal_position" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="缺陷代码" prop="defectCode">
<el-select v-model="queryParams.defectCode" placeholder="请选择缺陷代码" clearable>
<el-option v-for="dict in dict.type.coil_abnormal_code" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</el-form-item>
<el-form-item label="程度" prop="degree">
<el-select v-model="queryParams.degree" placeholder="请选择程度" clearable>
<el-option v-for="dict in dict.type.coil_abnormal_degree" :key="dict.value" :label="dict.label"
:value="dict.value" />
</el-select>
</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="handleAddWithCoil">新增</el-button>
</el-form-item>
</el-form>
<el-table v-loading="loading" :data="coilAbnormalList" @selection-change="handleSelectionChange">
<!-- <el-table-column type="selection" width="55" align="center" /> -->
<el-table-column label="主键ID" align="center" prop="abnormalId" v-if="false" />
<!-- <el-table-column label="异常钢卷" align="center" prop="coilId">
<template slot-scope="scope">
<coil-no :coilId="scope.row.coilId">
{{ scope.row.coilNo }}
</coil-no>
</template>
</el-table-column> -->
<el-table-column label="位置" align="center" prop="position">
<template slot-scope="scope">
<dict-tag :options="dict.type.coil_abnormal_position" :value="scope.row.position" />
</template>
</el-table-column>
<el-table-column label="长度坐标" align="center" prop="lengthCoord" />
<el-table-column label="缺陷代码" align="center" prop="defectCode">
<template slot-scope="scope">
<dict-tag :options="dict.type.coil_abnormal_code" :value="scope.row.defectCode" />
</template>
</el-table-column>
<el-table-column label="程度" align="center" prop="degree">
<template slot-scope="scope">
<dict-tag :options="dict.type.coil_abnormal_degree" :value="scope.row.degree" />
</template>
</el-table-column>
<!-- <el-table-column label="判级" align="center" prop="judgeLevel">
<template slot-scope="scope">
<dict-tag :options="dict.type.coil_abnormal_level" :value="scope.row.judgeLevel" />
</template>
</el-table-column>
<el-table-column label="判级人" align="center" prop="judgeBy" />
<el-table-column label="判级时间" align="center" prop="judgeTime" width="180">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.judgeTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column> -->
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
<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-check" @click="handleJudge(scope.row)">判级</el-button> -->
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" 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="getList" />
</el-col>
<el-col :span="18" v-else>
<el-empty description="请选择钢卷后查看异常明细" />
</el-col>
</el-row>
<!-- 添加或修改钢卷异常信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="钢卷ID" prop="coilId" v-if="!form.abnormalId && showCoilSelector">
<coil-selector v-model="form.coilId"></coil-selector>
</el-form-item>
<el-form-item label="位置" prop="position">
<el-radio-group v-model="form.position">
<el-radio-button v-for="dict in dict.type.coil_abnormal_position" :key="dict.value" :label="dict.value">{{
dict.label }}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="长度坐标" prop="lengthCoord">
<el-input v-model="form.lengthCoord" placeholder="请输入长度坐标" />
</el-form-item>
<el-form-item label="缺陷代码" prop="defectCode">
<el-radio-group v-model="form.defectCode">
<el-radio-button v-for="dict in dict.type.coil_abnormal_code" :key="dict.value" :label="dict.value">{{
dict.label }}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="程度" prop="degree">
<el-radio-group v-model="form.degree">
<el-radio-button v-for="dict in dict.type.coil_abnormal_degree" :key="dict.value" :label="dict.value">{{
dict.label }}</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input type="textarea" v-model="form.remark" 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="title" :visible.sync="judgeOpen" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="判级" prop="judgeLevel">
<el-radio-group v-model="form.judgeLevel">
<el-radio-button v-for="dict in dict.type.coil_abnormal_level" :key="dict.value" :label="dict.value">{{
dict.label }}</el-radio-button>
</el-radio-group>
</el-form-item>
</el-form>
<div slot="footer" class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitJudge"> </el-button>
<el-button @click="judgeOpen = false"> </el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { listCoilAbnormal, getCoilAbnormal, delCoilAbnormal, addCoilAbnormal, updateCoilAbnormal, judgeAbnormalLevel } from "@/api/wms/coilAbnormal";
import { listMaterialCoil } from "@/api/wms/coil";
import CoilSelector from '@/components/CoilSelector'
import CoilNo from '@/components/KLPService/Renderer/CoilNo'
import CoilList from "./components/CoilList.vue";
export default {
name: "CoilAbnormal",
dicts: ['coil_abnormal_code', 'coil_abnormal_position', 'coil_abnormal_degree', 'coil_abnormal_level'],
components: {
CoilSelector,
CoilNo,
CoilList
},
data() {
return {
coilList: [],
currentCoil: {},
showCoilSelector: true,
coilQuery: {
dataType: 1,
// 筛选异常数量大于等于1的
minAbnormalCount: 1,
pageNum: 1,
pageSize: 10,
currentCoilNo: undefined,
},
coilTotal: 0,
coilLoading: false,
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 钢卷异常信息表格数据
coilAbnormalList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 10,
coilId: undefined,
position: undefined,
lengthCoord: undefined,
defectCode: undefined,
degree: undefined,
judgeLevel: undefined,
judgeBy: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
},
judgeOpen: false,
};
},
computed: {
currentCoilId() {
return this.currentCoil?.coilId || undefined
}
},
mounted() {
this.getCoilList();
},
methods: {
/** 查询钢卷异常信息列表 */
getList() {
this.loading = true;
listCoilAbnormal(this.queryParams).then(response => {
this.coilAbnormalList = response.rows;
this.total = response.total;
this.loading = false;
});
},
/** 查询钢卷列表 */
getCoilList() {
this.coilLoading = true;
listMaterialCoil(this.coilQuery).then(response => {
this.coilList = response.rows;
this.coilTotal = response.total;
this.coilLoading = false;
});
},
/** 点击钢卷列表行 */
handleCoilClick(row) {
this.currentCoil = row;
this.queryParams.coilId = row.coilId;
this.handleQuery();
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
abnormalId: undefined,
coilId: this.$route.query.coilId,
position: undefined,
lengthCoord: undefined,
defectCode: undefined,
degree: undefined,
judgeLevel: undefined,
judgeBy: undefined,
judgeTime: 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");
this.handleQuery();
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.abnormalId)
this.single = selection.length !== 1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.showCoilSelector = true;
this.title = "添加钢卷异常信息";
},
handleAddWithCoil() {
this.reset();
this.open = true;
this.form.coilId = this.currentCoilId;
this.showCoilSelector = false;
this.title = "添加钢卷异常信息";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const abnormalId = row.abnormalId || this.ids
getCoilAbnormal(abnormalId).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.abnormalId != null) {
updateCoilAbnormal(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
} else {
addCoilAbnormal(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const abnormalIds = row.abnormalId || this.ids;
this.$modal.confirm('是否确认删除钢卷异常信息编号为"' + abnormalIds + '"的数据项?').then(() => {
this.loading = true;
return delCoilAbnormal(abnormalIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/coilAbnormal/export', {
...this.queryParams
}, `coilAbnormal_${new Date().getTime()}.xlsx`)
},
/** 异常判级按钮操作 */
handleJudge(row) {
this.reset();
this.form = row
this.judgeOpen = true;
this.title = "异常判级";
},
/** 提交异常判级按钮操作 */
submitJudge() {
this.buttonLoading = true;
judgeAbnormalLevel(this.form).then(response => {
this.$modal.msgSuccess("判级成功");
this.judgeOpen = false;
this.getList();
}).finally(() => {
this.buttonLoading = false;
});
}
}
};
</script>

View File

@@ -46,6 +46,13 @@
<el-table v-loading="loading" :data="coilAbnormalList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="abnormalId" v-if="false" />
<el-table-column label="异常钢卷" align="center" prop="coilId">
<template slot-scope="scope">
<coil-no :coilId="scope.row.coilId">
{{ scope.row.coilNo }}
</coil-no>
</template>
</el-table-column>
<el-table-column label="位置" align="center" prop="position">
<template slot-scope="scope">
<dict-tag :options="dict.type.coil_abnormal_position" :value="scope.row.position" />
@@ -62,7 +69,7 @@
<dict-tag :options="dict.type.coil_abnormal_degree" :value="scope.row.degree" />
</template>
</el-table-column>
<el-table-column label="判级" align="center" prop="judgeLevel">
<!-- <el-table-column label="判级" align="center" prop="judgeLevel">
<template slot-scope="scope">
<dict-tag :options="dict.type.coil_abnormal_level" :value="scope.row.judgeLevel" />
</template>
@@ -72,10 +79,12 @@
<template slot-scope="scope">
<span>{{ parseTime(scope.row.judgeTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
<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-check" @click="handleJudge(scope.row)">判级</el-button>
<!-- <el-button size="mini" type="text" icon="el-icon-check" @click="handleJudge(scope.row)">判级</el-button> -->
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)">删除</el-button>
</template>
@@ -88,7 +97,7 @@
<!-- 添加或修改钢卷异常信息对话框 -->
<el-dialog :title="title" :visible.sync="open" width="600px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
<el-form-item label="钢卷ID" prop="coilId">
<el-form-item label="钢卷ID" prop="coilId" v-if="!form.abnormalId">
<coil-selector v-model="form.coilId"></coil-selector>
</el-form-item>
<el-form-item label="位置" prop="position">
@@ -143,12 +152,14 @@
<script>
import { listCoilAbnormal, getCoilAbnormal, delCoilAbnormal, addCoilAbnormal, updateCoilAbnormal, judgeAbnormalLevel } from "@/api/wms/coilAbnormal";
import CoilSelector from '@/components/CoilSelector'
import CoilNo from '@/components/KLPService/Renderer/CoilNo'
export default {
name: "CoilAbnormal",
dicts: ['coil_abnormal_code', 'coil_abnormal_position', 'coil_abnormal_degree', 'coil_abnormal_level'],
components: {
CoilSelector
CoilSelector,
CoilNo
},
data() {
return {
@@ -225,7 +236,7 @@ export default {
reset() {
this.form = {
abnormalId: undefined,
coilId: undefined,
coilId: this.$route.query.coilId,
position: undefined,
lengthCoord: undefined,
defectCode: undefined,

View File

@@ -0,0 +1,196 @@
<template>
<div class="coil-list-container">
<!-- 列表空状态提示 -->
<div v-if="coilList.length === 0" class="empty-tip">暂无钢卷数据</div>
<!-- 钢卷列表 -->
<div
v-else
class="coil-list"
>
<!-- v-for 循环渲染列表项 -->
<div
v-for="(coil, index) in coilList"
:key="index"
:class="['coil-item', { 'coil-item--active': currentCoil.coilId === coil.coilId }]"
@click="handleCoilClick(coil)"
>
<!-- 主信息区域 - 突出展示核心字段 -->
<div class="main-info">
<div class="coil-no-wrapper">
<span class="label">钢卷号</span>
<span class="value primary">{{ coil.currentCoilNo || '未知' }}</span>
</div>
<div class="entry-no-wrapper">
<span class="label">入场卷号</span>
<span class="value">{{ coil.enterCoilNo || '未知' }}</span>
</div>
</div>
<!-- 次信息区域 - 次要字段 -->
<div class="secondary-info">
<div class="warehouse-wrapper">
<span class="label">逻辑库区</span>
<span class="value">{{ coil.warehouseName || '未知' }}</span>
</div>
<!-- 钢卷信息 - 动态渲染组件 -->
<div class="coil-detail-wrapper">
<span class="label">钢卷信息</span>
<div class="detail-content">
<ProductInfo
v-if="coil.itemType == 'product'"
:product="coil.product"
/>
<RawMaterialInfo
v-else-if="coil.itemType === 'raw_material'"
:material="coil.rawMaterial"
/>
<span v-else class="empty-text">暂无钢卷信息</span>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import ProductInfo from "@/components/KLPService/Renderer/ProductInfo";
import RawMaterialInfo from "@/components/KLPService/Renderer/RawMaterialInfo";
export default {
name: "CoilList",
props: {
coilList: {
type: Array,
default: () => []
}
},
components: {
ProductInfo,
RawMaterialInfo
},
data() {
return {
currentCoil: {}
};
},
methods: {
handleCoilClick(coil) {
this.currentCoil = coil;
this.$emit('click', coil);
}
}
};
</script>
<style scoped>
/* 容器样式 */
.coil-list-container {
width: 100%;
padding: 6px;
box-sizing: border-box;
/* background-color: #f9fafb; */
border-radius: 8px;
}
/* 空状态提示 */
.empty-tip {
text-align: center;
padding: 40px 0;
color: #999;
font-size: 14px;
}
/* 列表容器 */
.coil-list {
display: flex;
flex-direction: column;
gap: 12px;
}
/* 列表项样式 */
.coil-item {
background-color: #fff;
border-radius: 6px;
padding: 16px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
cursor: pointer;
transition: all 0.2s ease;
/* 默认上边框(透明),保证布局一致 */
border-top: 3px solid transparent;
}
/* 核心新增:选中状态的样式 */
.coil-item--active {
/* 特殊上边框 - 可自定义颜色/样式 */
border-top: 3px solid #1989fa;
/* 可选:增加背景色/阴影强化选中效果 */
background-color: #f0f7ff;
box-shadow: 0 1px 5px rgba(25, 137, 250, 0.15);
}
/* 列表项 hover 效果 */
.coil-item:hover {
transform: translateY(-2px);
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}
/* 主信息区域 - 突出展示 */
.main-info {
display: flex;
align-items: center;
gap: 24px;
padding-bottom: 12px;
margin-bottom: 12px;
border-bottom: 1px solid #f0f0f0;
}
.main-info .coil-no-wrapper .value.primary {
font-size: 18px;
font-weight: 600;
color: #1989fa; /* 主色调突出钢卷号 */
}
/* 次信息区域 */
.secondary-info {
display: flex;
flex-direction: column;
gap: 8px;
}
/* 通用标签样式 */
.label {
font-size: 14px;
color: #666;
margin-right: 4px;
}
/* 通用值样式 */
.value {
font-size: 14px;
color: #333;
}
/* 钢卷信息内容容器 */
.detail-content {
display: inline-block;
vertical-align: middle;
}
/* 空文本样式 */
.empty-text {
color: #999;
font-size: 13px;
}
/* 响应式适配 */
@media (max-width: 768px) {
.main-info {
flex-direction: column;
gap: 8px;
align-items: flex-start;
}
}
</style>

View File

@@ -0,0 +1,44 @@
<template>
<el-tabs class="app-container" v-model="activeTab">
<el-tab-pane label="待收卷" name="second">
<BasePage :qrcode="qrcode" :querys="querys2" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
:hideType="hideType" />
</el-tab-pane>
<el-tab-pane label="已收卷" name="first">
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
:hideType="hideType" />
</el-tab-pane>
</el-tabs>
</template>
<script>
import BasePage from '../panels/base.vue';
export default {
components: {
BasePage
},
data() {
return {
qrcode: false,
activeTab: 'second',
querys: {
dataType: 1,
status: 0,
warehouseId: '2027272748164853762', // 其他内部仓
// materialType: '废品'
},
querys2: {
dataType: 1,
status: 0,
nextWarehouseId: '2027272748164853762', // 其他内部仓
// materialType: '废品'
},
hideWarehouseQuery: true,
showAbnormal: true,
labelType: '2',
hideType: false,
}
}
}
</script>

View File

@@ -0,0 +1,44 @@
<template>
<el-tabs class="app-container" v-model="activeTab">
<el-tab-pane label="待收卷" name="second">
<BasePage :qrcode="qrcode" :querys="querys2" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
:hideType="hideType" />
</el-tab-pane>
<el-tab-pane label="已收卷" name="first">
<BasePage :qrcode="qrcode" :querys="querys" :labelType="labelType" :hideWarehouseQuery="hideWarehouseQuery"
:hideType="hideType" />
</el-tab-pane>
</el-tabs>
</template>
<script>
import BasePage from '../panels/base.vue';
export default {
components: {
BasePage
},
data() {
return {
qrcode: false,
activeTab: 'second',
querys: {
dataType: 1,
status: 0,
warehouseId: "2027272581575487489", // 包装用内部仓
// materialType: '废品'
},
querys2: {
dataType: 1,
status: 0,
nextWarehouseId: "2027272581575487489", // 包装用内部仓
// materialType: '废品'
},
hideWarehouseQuery: true,
showAbnormal: true,
labelType: '2',
hideType: false,
}
}
}
</script>

View File

@@ -5,8 +5,11 @@
<PlanList ref="planList" @select="handlePlanSelect"/>
</el-col>
<el-col :span="19">
<el-card>
<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">
@@ -25,6 +28,12 @@
<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
@@ -199,6 +208,16 @@ export default {
created() {
this.getList();
},
computed: {
/** 计算已发货数量 */
deliveryCountFinished() {
return this.deliveryWaybillList.filter(row => row.status === 1 || row.status === 2).length;
},
/** 计算总数量 */
deliveryCountTotal() {
return this.deliveryWaybillList.length;
}
},
methods: {
/** 查询发货单列表 */
getList() {

View File

@@ -1,411 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
<el-form-item label="半成品编号" prop="productCode">
<el-input
v-model="queryParams.productCode"
placeholder="请输入半成品编号"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="半成品名称" prop="productName">
<el-input
v-model="queryParams.productName"
placeholder="请输入半成品名称"
clearable
@keyup.enter.native="handleQuery"
/>
</el-form-item>
<el-form-item label="负责人" prop="salesManager">
<el-input v-model="queryParams.owner" :multiple="false" placeholder="请填写负责人" />
</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>
<KLPTable v-loading="loading" :data="productList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="半成品类型编号" align="center" prop="productCode" />
<el-table-column label="半成品类型名称" align="center" prop="productName" />
<el-table-column label="负责人" align="center" prop="owner" />
<!-- <el-table-column label="基础材质" align="center">
<template slot-scope="scope">
<CategoryRenderer :category-id="scope.row.baseMaterialId" />
</template>
</el-table-column>
<el-table-column label="表面处理" align="center">
<template slot-scope="scope">
<CategoryRenderer :category-id="scope.row.surfaceTreatmentId" />
</template>
</el-table-column>
<el-table-column label="客户需求" align="center">
<template slot-scope="scope">
<CategoryRenderer :category-id="scope.row.customerReqId" />
</template>
</el-table-column>
<el-table-column label="包装方式" align="center">
<template slot-scope="scope">
<CategoryRenderer :category-id="scope.row.packagingId" />
</template>
</el-table-column>
<el-table-column label="厚度" align="center" prop="thickness" />
<el-table-column label="宽度" align="center" prop="width" />
<el-table-column label="内径" align="center" prop="innerDiameter" /> -->
<el-table-column label="计量单位" align="center" prop="unit" />
<!-- <el-table-column label="是否启用" align="center" prop="isEnabled">
<template slot-scope="scope">
<dict-tag :options="dict.type.common_swicth" :value="scope.row.isEnabled"/>
</template>
</el-table-column> -->
<el-table-column label="参数" align="center">
<template slot-scope="scope">
<BomInfoMini :bomId="scope.row.bomId" />
</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-edit"
@click="handleUpdate(scope.row)"
>修改</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-delete"
@click="handleDelete(scope.row)"
>删除</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-document"
@click="goLedger(scope.row)"
>台账</el-button>
<el-button
size="mini"
type="text"
icon="el-icon-data-analysis"
@click="handleBom(scope.row)"
>参数</el-button>
</template>
</el-table-column>
</KLPTable>
<pagination
v-show="total>0"
:total="total"
:page.sync="queryParams.pageNum"
:limit.sync="queryParams.pageSize"
@pagination="getList"
/>
<!-- 添加或修改半成品对话框 -->
<el-dialog :title="title" :visible.sync="open" width="400px" append-to-body>
<el-form ref="form" :model="form" :rules="rules" label-width="100px">
<!-- <el-divider>基础信息</el-divider> -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="半成品编号" prop="productCode">
<el-input v-model="form.productCode" placeholder="请输入半成品编号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="半成品名称" prop="productName">
<el-input v-model="form.productName" placeholder="请输入半成品名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="负责人" prop="owner">
<el-input v-model="form.owner" :multiple="false" placeholder="请填写负责人" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计量单位" prop="unit">
<el-input v-model="form.unit" placeholder="请输入计量单位" />
</el-form-item>
</el-col>
</el-row>
</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="参数" @close="bomDialogVisible = false" :visible.sync="bomDialogVisible" width="600px" append-to-body>
<BomPanel :id="bomId" type="product" @addBom="handleAddBom" :itemId="itemId" />
</el-dialog> -->
</div>
</template>
<script>
import { listProduct, getProduct, delProduct, addProduct, updateProduct } from "@/api/wms/product";
import CategoryRenderer from '@/components/KLPService/Renderer/CategoryRenderer.vue';
import UserSelect from '@/components/KLPService/UserSelect';
// import BomPanel from '../bom/components/BomPanel.vue';
import BomInfoMini from '@/components/KLPService/Renderer/BomInfoMini.vue';
export default {
name: "Product",
components: {
CategoryRenderer,
UserSelect,
// BomPanel,
BomInfoMini
},
dicts: ['common_swicth'],
data() {
return {
// 按钮loading
buttonLoading: false,
// 遮罩层
loading: true,
// 选中数组
ids: [],
// 非单个禁用
single: true,
// 非多个禁用
multiple: true,
// 显示搜索条件
showSearch: true,
// 总条数
total: 0,
// 半成品表格数据
productList: [],
// 弹出层标题
title: "",
// 是否显示弹出层
open: false,
// 查询参数
queryParams: {
pageNum: 1,
pageSize: 20,
type: 'semi',
productCode: undefined,
productName: undefined,
owner: undefined,
baseMaterialId: undefined,
surfaceTreatmentId: undefined,
customerReqId: undefined,
packagingId: undefined,
thickness: undefined,
width: undefined,
innerDiameter: undefined,
isEnabled: undefined,
},
// 表单参数
form: {},
// 表单校验
rules: {
productCode: [
{ required: true, message: "半成品编号不能为空", trigger: "blur" }
],
productName: [
{ required: true, message: "半成品名称不能为空", trigger: "blur" }
],
owner: [
{ required: true, message: "负责人不能为空", trigger: "blur" }
],
},
bomDialogVisible: false,
bomId: undefined,
itemId: undefined,
};
},
created() {
this.getList();
},
methods: {
/** 查询半成品列表 */
getList() {
this.loading = true;
listProduct(this.queryParams).then(response => {
this.productList = response.rows;
this.total = response.total;
this.loading = false;
});
},
handleAddBom(bom) {
this.bomId = bom.bomId;
this.getList();
},
// 取消按钮
cancel() {
this.open = false;
this.reset();
},
// 表单重置
reset() {
this.form = {
productId: undefined,
productCode: undefined,
productName: undefined,
owner: undefined,
baseMaterialId: undefined,
surfaceTreatmentId: undefined,
customerReqId: undefined,
packagingId: undefined,
thickness: undefined,
width: undefined,
innerDiameter: undefined,
isEnabled: undefined,
unit: '卷',
delFlag: undefined,
createTime: undefined,
createBy: undefined,
updateTime: undefined,
updateBy: undefined,
type: 'semi'
};
this.resetForm("form");
},
/** 搜索按钮操作 */
handleQuery() {
this.queryParams.pageNum = 1;
this.getList();
},
/** 重置按钮操作 */
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
goLedger(row) {
this.$router.push({
path: '/wms/ledger',
query: {
itemId: row.productId,
itemType: 'product'
}
})
},
handleBom(row) {
this.bomDialogVisible = true;
this.bomId = row.bomId;
this.itemId = row.productId;
},
// 多选框选中数据
handleSelectionChange(selection) {
this.ids = selection.map(item => item.productId)
this.single = selection.length!==1
this.multiple = !selection.length
},
/** 新增按钮操作 */
handleAdd() {
this.reset();
this.open = true;
this.title = "添加半成品";
},
/** 修改按钮操作 */
handleUpdate(row) {
this.loading = true;
this.reset();
const productId = row.productId || this.ids
getProduct(productId).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.productId != null) {
updateProduct(this.form).then(response => {
this.$modal.msgSuccess("修改成功");
this.open = false;
this.getList();
this.$store.dispatch('category/getProductMap');
}).finally(() => {
this.buttonLoading = false;
});
} else {
addProduct(this.form).then(response => {
this.$modal.msgSuccess("新增成功");
this.open = false;
this.getList();
this.$store.dispatch('category/getProductMap');
}).finally(() => {
this.buttonLoading = false;
});
}
}
});
},
/** 删除按钮操作 */
handleDelete(row) {
const productIds = row.productId || this.ids;
this.$modal.confirm('是否确认删除半成品编号为"' + productIds + '"的数据项?').then(() => {
this.loading = true;
return delProduct(productIds);
}).then(() => {
this.loading = false;
this.getList();
this.$modal.msgSuccess("删除成功");
this.$store.dispatch('category/getProductMap');
}).catch(() => {
}).finally(() => {
this.loading = false;
});
},
/** 导出按钮操作 */
handleExport() {
this.download('wms/product/export', {
...this.queryParams
}, `product_${new Date().getTime()}.xlsx`)
}
}
};
</script>

View File

@@ -0,0 +1,117 @@
const calcSummary = (list, lossList) => {
// 总钢卷数量、总重、均重
const outCount = list.length
const outTotalWeight = list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = lossList.length
const lossTotalWeight = lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 成品比率
const passRate = outCount > 0 ? (outTotalWeight / lossTotalWeight) : 0
// 损失比率
const lossRate = totalCount > 0 ? (1 - passRate) : 0
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = totalCount != 0 ? list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount : 0
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: (passRate * 100)?.toFixed(2) + '%',
lossRate: (lossRate * 100)?.toFixed(2) + '%',
abRate: (abRate * 100)?.toFixed(2) || 0,
}
}
const calcAbSummary = (list) => {
// 异常统计,统计四个异常库中的各自的数量和总重
let o = {
jishuCount: 0,
jishuWeight: 0,
miniCount: 0,
miniWeight: 0,
rubbishCount: 0,
rubbishWeight: 0,
returnCount: 0,
returnWeight: 0,
}
for (let i = 0; i < list.length; i++) {
// { label: '技术部', value: '2019583656787259393' },
// { label: '小钢卷库', value: '2019583325311414274' },
// { label: '废品库', value: '2019583429955104769' },
// { label: '退货库', value: '2019583137616310273' },
// 技术部
const coil = list[i];
// 技术部
if (coil.warehouseId == '2019583656787259393') {
o['jishuCount'] = o['jishuCount'] + 1
o['jishuWeight'] = o['jishuWeight'] + parseFloat(coil.netWeight) || 0
}
// 小刚卷库
if (coil.warehouseId == '2019583325311414274') {
o['miniCount'] = o['miniCount'] + 1
o['miniWeight'] = o['miniWeight'] + parseFloat(coil.netWeight) || 0
}
// 废品库
if (coil.warehouseId == '2019583429955104769') {
o['rubbishCount'] = o['rubbishCount'] + 1
o['rubbishWeight'] = o['rubbishWeight'] + parseFloat(coil.netWeight) || 0
}
// 退货库
if (coil.warehouseId == '2019583137616310273') {
o['returnCount'] = o['returnCount'] + 1
o['returnWeight'] = o['returnWeight'] + parseFloat(coil.netWeight) || 0
}
}
return [
{ label: '技术部钢卷数', value: o['jishuCount'] },
{ label: '技术部钢卷重量', value: o['jishuWeight'] },
{ label: '小钢卷库钢卷数', value: o['miniCount'] },
{ label: '小钢卷库钢卷重量', value: o['miniWeight'] },
{ label: '废品库钢卷数', value: o['rubbishCount'] },
{ label: '废品库钢卷重量', value: o['rubbishWeight'] },
{ label: '退货库钢卷数', value: o['returnCount'] },
{ label: '退货库钢卷重量', value: o['returnWeight'] },
]
}
const calcTeamSummary = (list) => {
// 按照班组汇总信息
const teamSummary = {}
for (let i = 0; i < list.length; i++) {
const coil = list[i];
if (!teamSummary[coil.team]) {
teamSummary[coil.team] = {
count: 0,
weight: 0,
}
}
teamSummary[coil.team].count = teamSummary[coil.team].count + 1
teamSummary[coil.team].weight = teamSummary[coil.team].weight + parseFloat(coil.netWeight) || 0
}
return teamSummary
}
export {
calcSummary,
calcAbSummary,
calcTeamSummary,
}

View File

@@ -197,10 +197,10 @@ export default {
createBy: 'suanzhakuguan',
warehouseId: '2019583656787259393'
},
'20195833325311414274': {
'2019583325311414274': {
selectType: 'product',
createBy: 'suanzhakuguan',
warehouseId: '20195833325311414274'
warehouseId: '2019583325311414274'
},
'2019583429955104769': {
selectType: 'product',

View File

@@ -63,10 +63,15 @@
<el-descriptions-item label="异常率">{{ summary.abRate }}</el-descriptions-item>
</el-descriptions>
<!-- 异常统计 -->
<el-descriptions title="异常统计" :column="4" border>
<el-descriptions-item v-for="item in abSummary" :key="item.label" :label="item.label">{{ item.value }}</el-descriptions-item>
</el-descriptions>
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -144,6 +149,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary } from "@/views/wms/report/js/calc";
export default {
components: {
@@ -180,7 +186,7 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 9999,
date: currentDate, // 绑定日期选择器的默认值(当天)
// date: currentDate, // 绑定日期选择器的默认值(当天)
byCreateTimeStart: start, // 默认当天0点
byCreateTimeEnd: end, // 默认当天23:59:59
selectType: 'product',
@@ -260,47 +266,10 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return calcSummary(this.list, this.lossList)
},
abSummary() {
return calcAbSummary(this.list)
}
},
methods: {
@@ -360,7 +329,7 @@ export default {
message: '暂无数据',
type: 'warning',
})
this.list = []
this.lossList = []
this.loading = false
return
}

View File

@@ -66,7 +66,7 @@
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -144,6 +144,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary } from "@/views/wms/report/js/calc";
export default {
components: {
@@ -161,7 +162,7 @@ export default {
// 获取当前日期(默认选中当天)
const now = new Date()
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}}`
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}`
/**
* 生成指定日期/月份的时间范围字符串
@@ -290,47 +291,7 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return calcSummary(this.list, this.lossList)
}
},
methods: {
@@ -390,7 +351,7 @@ export default {
message: '暂无数据',
type: 'warning',
})
this.list = []
this.lossList = []
this.loading = false
return
}

View File

@@ -2,9 +2,13 @@
<div class="app-container" v-loading="loading">
<el-row>
<el-form label-width="80px" inline>
<el-form-item label="日期" prop="date">
<el-date-picker style="width: 200px;" v-model="queryParams.date" type="date" value-format="yyyy-MM-dd"
placeholder="选择日期" @change="handleDateChange"></el-date-picker>
<el-form-item label="开始日期" prop="date">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeStart" type="date"
value-format="yyyy-MM-dd" placeholder="选择日期"></el-date-picker>
</el-form-item>
<el-form-item label="结束日期" prop="date">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeEnd" type="date"
value-format="yyyy-MM-dd" placeholder="选择日期"></el-date-picker>
</el-form-item>
<el-form-item label="班组" prop="team">
<el-select v-model="queryParams.team" placeholder="请选择班组" style="width: 200px;">
@@ -54,25 +58,36 @@
<el-descriptions-item label="产出总重">{{ summary.outTotalWeight }}t</el-descriptions-item>
<el-descriptions-item label="产出均重">{{ summary.outAvgWeight }}t</el-descriptions-item>
<el-descriptions-item label="消耗数量">{{ summary.lossCount }}</el-descriptions-item>
<!-- <el-descriptions-item label="消耗数量">{{ summary.lossCount }}</el-descriptions-item>
<el-descriptions-item label="消耗总重">{{ summary.lossTotalWeight }}t</el-descriptions-item>
<el-descriptions-item label="消耗均重">{{ summary.lossAvgWeight }}t</el-descriptions-item>
<el-descriptions-item label="合计数量">{{ summary.totalCount }}</el-descriptions-item>
<el-descriptions-item label="合计总重">{{ summary.totalWeight }}t</el-descriptions-item>
<el-descriptions-item label="合计均重">{{ summary.totalAvgWeight }}t</el-descriptions-item>
<el-descriptions-item label="合计均重">{{ summary.totalAvgWeight }}t</el-descriptions-item> -->
<!-- 成品率 -->
<el-descriptions-item label="成品率">{{ summary.passRate }}</el-descriptions-item>
<el-descriptions-item label="损耗率">{{ summary.lossRate }}</el-descriptions-item>
<!-- <el-descriptions-item label="成品率">{{ summary.passRate }}</el-descriptions-item> -->
<!-- <el-descriptions-item label="损耗率">{{ summary.lossRate }}</el-descriptions-item> -->
<!-- 异常率 -->
<el-descriptions-item label="异常率">{{ summary.abRate }}</el-descriptions-item>
<!-- <el-descriptions-item label="异常率">{{ summary.abRate }}</el-descriptions-item> -->
</el-descriptions>
<el-descriptions title="班组统计信息" :column="3" border>
</el-descriptions>
<el-table :data="teamSummary" border>
<el-table-column label="班组" align="center" prop="team" />
<el-table-column label="产出数量" align="center" prop="outCount" />
<el-table-column label="产出总重" align="center" prop="outWeight" />
<!-- <el-table-column label="消耗数量" align="center" prop="lossCount" />
<el-table-column label="消耗总重" align="center" prop="lossWeight" />
<el-table-column label="成品率" align="center" prop="passRate" /> -->
</el-table>
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<!-- <el-tabs v-model="activeTab">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -86,7 +101,6 @@
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" />
<el-table-column label="逻辑库位" align="center" prop="warehouseName" />
<!-- <el-table-column label="实际库区" align="center" prop="actualWarehouseName" /> -->
<el-table-column label="产品类型" align="center" width="250">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.itemType == 'product'" :product="scope.row.product" />
@@ -99,8 +113,8 @@
<el-table-column label="更新人" align="center" prop="updateByName" />
<el-table-column label="更新时间" align="center" prop="updateTime" />
</el-table>
</el-tab-pane>
<el-tab-pane label="产出钢卷" name="output">
</el-tab-pane> -->
<!-- <el-tab-pane label="产出钢卷" name="output"> -->
<el-table :data="list" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -134,8 +148,8 @@
<el-table-column label="更新人" align="center" prop="updateByName" />
<el-table-column label="更新时间" align="center" prop="updateTime" />
</el-table>
</el-tab-pane>
</el-tabs>
<!-- </el-tab-pane> -->
<!-- </el-tabs> -->
</div>
</template>
@@ -151,6 +165,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary, calcTeamSummary } from "@/views/wms/report/js/calc";
export default {
components: {
@@ -168,15 +183,45 @@ export default {
// 获取当前日期(默认选中当天)
const now = new Date()
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}-${addZero(now.getDate())}`
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}`
// 生成指定日期的 00:00:00 和 23:59:59 时间字符串
/**
* 生成指定日期/月份的时间范围字符串
* @param {string} dateStr - 支持格式yyyy-MM月份 或 yyyy-MM-dd具体日期
* @returns {object} 包含start开始时间和end结束时间的对象
*/
const getDayTimeRange = (dateStr) => {
return {
start: `${dateStr} 00:00:00`,
end: `${dateStr} 23:59:59`
// 先校验输入格式是否合法
const monthPattern = /^\d{4}-\d{2}$/; // yyyy-MM 正则
const dayPattern = /^\d{4}-\d{2}-\d{2}$/; // yyyy-MM-dd 正则
if (!monthPattern.test(dateStr) && !dayPattern.test(dateStr)) {
throw new Error('输入格式错误,请传入 yyyy-MM 或 yyyy-MM-dd 格式的字符串');
}
}
let startDate, endDate;
if (monthPattern.test(dateStr)) {
// 处理 yyyy-MM 格式:获取本月第一天和最后一天
const [year, month] = dateStr.split('-').map(Number);
// 月份是0基的0=1月1=2月...所以要减1
// 第一天yyyy-MM-01
startDate = `${dateStr}-01`;
// 最后一天:通过 new Date(year, month, 0) 计算month是原始月份比如2代表2月传2则取3月0日=2月最后一天
const lastDayOfMonth = new Date(year, month, 0).getDate();
endDate = `${dateStr}-${lastDayOfMonth.toString().padStart(2, '0')}`;
} else {
// 处理 yyyy-MM-dd 格式:直接使用传入的日期
startDate = dateStr;
endDate = dateStr;
}
// 拼接时间部分
return {
start: `${startDate} 00:00:00`,
end: `${endDate} 23:59:59`
};
};
const { start, end } = getDayTimeRange(currentDate)
@@ -267,47 +312,41 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
return calcSummary(this.list, this.lossList)
},
// 合并两个汇总结果并转换为目标数组的方法
teamSummary() {
const teamOutSummary = calcTeamSummary(this.list);
// const teamLossSummary = calcTeamSummary(this.lossList);
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
const allTeams = [...new Set([
...Object.keys(teamOutSummary),
// ...Object.keys(teamLossSummary)
])];
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
const result = allTeams.map(team => {
const outData = teamOutSummary[team] || { count: 0, weight: 0 };
// const lossData = teamLossSummary[team] || { count: 0, weight: 0 };
// 核心修复:先确保是有效数字,再保留两位小数
const formatWeight = (weight) => {
// 步骤1转数字非数字则置为0步骤2保留两位小数
return Number(weight || 0).toFixed(2);
// 如果需要返回数字类型(而非字符串),用这行:
// return Number(Number(weight || 0).toFixed(2));
};
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return {
team: team,
outCount: outData.count,
outWeight: formatWeight(outData.weight), // 格式化出库重量
// lossCount: lossData.count,
// lossWeight: formatWeight(lossData.weight), // 格式化损耗重量
// passRate: (outData.weight / lossData.weight * 100).toFixed(2) + '%' , // 计算成品率
};
});
return result;
}
},
methods: {
@@ -344,7 +383,7 @@ export default {
(a, b) => new Date(b.createTime) - new Date(a.createTime)
)
this.loading = false
this.getLossList()
// this.getLossList()
}).catch(err => { // 增加错误处理
console.error('查询失败:', err)
this.loading = false

View File

@@ -66,7 +66,7 @@
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -144,6 +144,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary } from "@/views/wms/report/js/calc";
export default {
components: {
@@ -161,7 +162,7 @@ export default {
// 获取当前日期(默认选中当天)
const now = new Date()
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}-${addZero(now.getDate())}`
const currentDate = `${now.getFullYear()}`
/**
* 生成指定年份的时间范围字符串
@@ -183,6 +184,8 @@ export default {
};
};
console.log(currentDate)
const { start, end } = getDayTimeRange(currentDate)
return {
@@ -272,47 +275,7 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return calcSummary(this.list, this.lossList)
}
},
methods: {
@@ -359,7 +322,7 @@ export default {
this.loading = true
listPendingAction({
actionType: 11, // 酸轧工序
pageSize: 999,
pageSize: 9999,
pageNum: 1,
startTime: this.queryParams.byCreateTimeStart,
endTime: this.queryParams.byCreateTimeEnd,
@@ -372,7 +335,7 @@ export default {
message: '暂无数据',
type: 'warning',
})
this.list = []
this.lossList = []
this.loading = false
return
}

View File

@@ -183,10 +183,10 @@ export default {
// createBy: 'suanzhakuguan',
warehouseId: '2019583656787259393'
},
'20195833325311414274': {
'2019583325311414274': {
selectType: 'product',
// createBy: 'suanzhakuguan',
warehouseId: '20195833325311414274'
warehouseId: '2019583325311414274'
},
'2019583429955104769': {
selectType: 'product',

View File

@@ -63,10 +63,15 @@
<el-descriptions-item label="异常率">{{ summary.abRate }}</el-descriptions-item>
</el-descriptions>
<!-- 异常统计 -->
<el-descriptions title="异常统计" :column="4" border>
<el-descriptions-item v-for="item in abSummary" :key="item.label" :label="item.label">{{ item.value }}</el-descriptions-item>
</el-descriptions>
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -144,6 +149,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary } from "@/views/wms/report/js/calc";
export default {
components: {
@@ -180,7 +186,7 @@ export default {
queryParams: {
pageNum: 1,
pageSize: 9999,
date: currentDate, // 绑定日期选择器的默认值(当天)
// date: currentDate, // 绑定日期选择器的默认值(当天)
byCreateTimeStart: start, // 默认当天0点
byCreateTimeEnd: end, // 默认当天23:59:59
selectType: 'product',
@@ -212,32 +218,32 @@ export default {
warehouseQueryMap: {
'1988150323162836993': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '1988150323162836993'
},
'1988150487185289217': {
selectType: 'raw_material',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '1988150487185289217'
},
'2019583656787259393': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '2019583656787259393'
},
'20195833325311414274': {
'2019583325311414274': {
selectType: 'product',
// createBy: 'suanzhakuguan',
warehouseId: '20195833325311414274'
createBy: 'suanzhakuguan',
warehouseId: '2019583325311414274'
},
'2019583429955104769': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '2019583429955104769'
},
'2019583137616310273': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '2019583137616310273'
},
},
@@ -246,47 +252,10 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return calcSummary(this.list, this.lossList)
},
abSummary() {
return calcAbSummary(this.list)
}
},
methods: {

View File

@@ -66,7 +66,7 @@
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -144,6 +144,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary } from "@/views/wms/report/js/calc";
export default {
components: {
@@ -161,7 +162,7 @@ export default {
// 获取当前日期(默认选中当天)
const now = new Date()
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}}`
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}`
/**
* 生成指定日期/月份的时间范围字符串
@@ -255,10 +256,10 @@ export default {
// createBy: 'suanzhakuguan',
warehouseId: '2019583656787259393'
},
'20195833325311414274': {
'2019583325311414274': {
selectType: 'product',
// createBy: 'suanzhakuguan',
warehouseId: '20195833325311414274'
warehouseId: '2019583325311414274'
},
'2019583429955104769': {
selectType: 'product',
@@ -276,47 +277,7 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return calcSummary(this.list, this.lossList)
}
},
methods: {
@@ -376,7 +337,7 @@ export default {
message: '暂无数据',
type: 'warning',
})
this.list = []
this.lossList = []
this.loading = false
return
}

View File

@@ -2,9 +2,13 @@
<div class="app-container" v-loading="loading">
<el-row>
<el-form label-width="80px" inline>
<el-form-item label="日期" prop="date">
<el-date-picker style="width: 200px;" v-model="queryParams.date" type="date" value-format="yyyy-MM-dd"
placeholder="选择日期" @change="handleDateChange"></el-date-picker>
<el-form-item label="开始日期" prop="date">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeStart" type="date"
value-format="yyyy-MM-dd" placeholder="选择日期"></el-date-picker>
</el-form-item>
<el-form-item label="结束日期" prop="date">
<el-date-picker style="width: 200px;" v-model="queryParams.byCreateTimeEnd" type="date"
value-format="yyyy-MM-dd" placeholder="选择日期"></el-date-picker>
</el-form-item>
<el-form-item label="入场钢卷号" prop="enterCoilNo">
<el-input style="width: 200px; display: inline-block;" v-model="queryParams.enterCoilNo"
@@ -54,25 +58,37 @@
<el-descriptions-item label="产出总重">{{ summary.outTotalWeight }}t</el-descriptions-item>
<el-descriptions-item label="产出均重">{{ summary.outAvgWeight }}t</el-descriptions-item>
<el-descriptions-item label="消耗数量">{{ summary.lossCount }}</el-descriptions-item>
<!-- <el-descriptions-item label="消耗数量">{{ summary.lossCount }}</el-descriptions-item>
<el-descriptions-item label="消耗总重">{{ summary.lossTotalWeight }}t</el-descriptions-item>
<el-descriptions-item label="消耗均重">{{ summary.lossAvgWeight }}t</el-descriptions-item>
<el-descriptions-item label="合计数量">{{ summary.totalCount }}</el-descriptions-item>
<el-descriptions-item label="合计总重">{{ summary.totalWeight }}t</el-descriptions-item>
<el-descriptions-item label="合计均重">{{ summary.totalAvgWeight }}t</el-descriptions-item>
<el-descriptions-item label="合计均重">{{ summary.totalAvgWeight }}t</el-descriptions-item> -->
<!-- 成品率 -->
<el-descriptions-item label="成品率">{{ summary.passRate }}</el-descriptions-item>
<el-descriptions-item label="损耗率">{{ summary.lossRate }}</el-descriptions-item>
<!-- <el-descriptions-item label="成品率">{{ summary.passRate }}</el-descriptions-item>
<el-descriptions-item label="损耗率">{{ summary.lossRate }}</el-descriptions-item> -->
<!-- 异常率 -->
<el-descriptions-item label="异常率">{{ summary.abRate }}</el-descriptions-item>
<!-- <el-descriptions-item label="异常率">{{ summary.abRate }}</el-descriptions-item> -->
</el-descriptions>
<el-descriptions title="班组统计信息" :column="3" border>
</el-descriptions>
<el-table :data="teamSummary" border>
<el-table-column label="班组" align="center" prop="team" />
<el-table-column label="产出数量" align="center" prop="outCount" />
<el-table-column label="产出总重" align="center" prop="outWeight" />
<!-- <el-table-column label="消耗数量" align="center" prop="lossCount" />
<el-table-column label="消耗总重" align="center" prop="lossWeight" />
<el-table-column label="成品率" align="center" prop="passRate" /> -->
</el-table>
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<!-- <el-tabs v-model="activeTab">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -86,7 +102,6 @@
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" />
<el-table-column label="逻辑库位" align="center" prop="warehouseName" />
<!-- <el-table-column label="实际库区" align="center" prop="actualWarehouseName" /> -->
<el-table-column label="产品类型" align="center" width="250">
<template slot-scope="scope">
<ProductInfo v-if="scope.row.itemType == 'product'" :product="scope.row.product" />
@@ -99,8 +114,8 @@
<el-table-column label="更新人" align="center" prop="updateByName" />
<el-table-column label="更新时间" align="center" prop="updateTime" />
</el-table>
</el-tab-pane>
<el-tab-pane label="产出钢卷" name="output">
</el-tab-pane> -->
<!-- <el-tab-pane label="产出钢卷" name="output"> -->
<el-table :data="list" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -134,8 +149,8 @@
<el-table-column label="更新人" align="center" prop="updateByName" />
<el-table-column label="更新时间" align="center" prop="updateTime" />
</el-table>
</el-tab-pane>
</el-tabs>
<!-- </el-tab-pane> -->
<!-- </el-tabs> -->
</div>
</template>
@@ -151,6 +166,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary, calcTeamSummary } from "@/views/wms/report/js/calc.js";
export default {
components: {
@@ -168,15 +184,45 @@ export default {
// 获取当前日期(默认选中当天)
const now = new Date()
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}-${addZero(now.getDate())}`
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}`
// 生成指定日期的 00:00:00 和 23:59:59 时间字符串
/**
* 生成指定日期/月份的时间范围字符串
* @param {string} dateStr - 支持格式yyyy-MM月份 或 yyyy-MM-dd具体日期
* @returns {object} 包含start开始时间和end结束时间的对象
*/
const getDayTimeRange = (dateStr) => {
return {
start: `${dateStr} 00:00:00`,
end: `${dateStr} 23:59:59`
// 先校验输入格式是否合法
const monthPattern = /^\d{4}-\d{2}$/; // yyyy-MM 正则
const dayPattern = /^\d{4}-\d{2}-\d{2}$/; // yyyy-MM-dd 正则
if (!monthPattern.test(dateStr) && !dayPattern.test(dateStr)) {
throw new Error('输入格式错误,请传入 yyyy-MM 或 yyyy-MM-dd 格式的字符串');
}
}
let startDate, endDate;
if (monthPattern.test(dateStr)) {
// 处理 yyyy-MM 格式:获取本月第一天和最后一天
const [year, month] = dateStr.split('-').map(Number);
// 月份是0基的0=1月1=2月...所以要减1
// 第一天yyyy-MM-01
startDate = `${dateStr}-01`;
// 最后一天:通过 new Date(year, month, 0) 计算month是原始月份比如2代表2月传2则取3月0日=2月最后一天
const lastDayOfMonth = new Date(year, month, 0).getDate();
endDate = `${dateStr}-${lastDayOfMonth.toString().padStart(2, '0')}`;
} else {
// 处理 yyyy-MM-dd 格式:直接使用传入的日期
startDate = dateStr;
endDate = dateStr;
}
// 拼接时间部分
return {
start: `${startDate} 00:00:00`,
end: `${endDate} 23:59:59`
};
};
const { start, end } = getDayTimeRange(currentDate)
@@ -232,10 +278,10 @@ export default {
// createBy: 'suanzhakuguan',
warehouseId: '2019583656787259393'
},
'20195833325311414274': {
'2019583325311414274': {
selectType: 'product',
// createBy: 'suanzhakuguan',
warehouseId: '20195833325311414274'
warehouseId: '2019583325311414274'
},
'2019583429955104769': {
selectType: 'product',
@@ -253,47 +299,41 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
return calcSummary(this.list, this.lossList)
},
// 合并两个汇总结果并转换为目标数组的方法
teamSummary() {
const teamOutSummary = calcTeamSummary(this.list);
// const teamLossSummary = calcTeamSummary(this.lossList);
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
const allTeams = [...new Set([
...Object.keys(teamOutSummary),
// ...Object.keys(teamLossSummary)
])];
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
const result = allTeams.map(team => {
const outData = teamOutSummary[team] || { count: 0, weight: 0 };
// const lossData = teamLossSummary[team] || { count: 0, weight: 0 };
// 核心修复:先确保是有效数字,再保留两位小数
const formatWeight = (weight) => {
// 步骤1转数字非数字则置为0步骤2保留两位小数
return Number(weight || 0).toFixed(2);
// 如果需要返回数字类型(而非字符串),用这行:
// return Number(Number(weight || 0).toFixed(2));
};
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return {
team: team,
outCount: outData.count,
outWeight: formatWeight(outData.weight), // 格式化出库重量
// lossCount: lossData.count,
// lossWeight: formatWeight(lossData.weight),
// passRate: (outData.weight / lossData.weight * 100).toFixed(2) + '%', // 计算成品率
};
});
return result;
}
},
methods: {
@@ -330,7 +370,7 @@ export default {
(a, b) => new Date(b.createTime) - new Date(a.createTime)
)
this.loading = false
this.getLossList()
// this.getLossList()
}).catch(err => { // 增加错误处理
console.error('查询失败:', err)
this.loading = false

View File

@@ -66,7 +66,7 @@
<el-descriptions title="明细信息" :column="3" border>
</el-descriptions>
<el-tabs v-model="activeTab">
<el-tab-pane label="损耗钢卷" name="loss">
<el-tab-pane label="投入钢卷" name="loss">
<el-table :data="lossList" border height="calc(100vh - 320px)">
<el-table-column label="入场钢卷号" align="center" prop="enterCoilNo">
<template slot-scope="scope">
@@ -144,6 +144,7 @@ import CoilNo from "@/components/KLPService/Renderer/CoilNo.vue";
import MemoInput from "@/components/MemoInput";
import MutiSelect from "@/components/MutiSelect";
import WarehouseSelect from "@/components/KLPService/WarehouseSelect";
import { calcSummary, calcAbSummary } from "@/views/wms/report/js/calc";
export default {
components: {
@@ -161,7 +162,7 @@ export default {
// 获取当前日期(默认选中当天)
const now = new Date()
const currentDate = `${now.getFullYear()}-${addZero(now.getMonth() + 1)}-${addZero(now.getDate())}`
const currentDate = `${now.getFullYear()}`
/**
* 生成指定年份的时间范围字符串
@@ -224,32 +225,32 @@ export default {
warehouseQueryMap: {
'1988150323162836993': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '1988150323162836993'
},
'1988150487185289217': {
selectType: 'raw_material',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '1988150487185289217'
},
'2019583656787259393': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '2019583656787259393'
},
'20195833325311414274': {
'2019583325311414274': {
selectType: 'product',
// createBy: 'suanzhakuguan',
warehouseId: '20195833325311414274'
createBy: 'suanzhakuguan',
warehouseId: '2019583325311414274'
},
'2019583429955104769': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '2019583429955104769'
},
'2019583137616310273': {
selectType: 'product',
// createBy: 'suanzhakuguan',
createBy: 'suanzhakuguan',
warehouseId: '2019583137616310273'
},
},
@@ -258,47 +259,7 @@ export default {
},
computed: {
summary() {
// 总钢卷数量、总重、均重
const outCount = this.list.length
const outTotalWeight = this.list.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const outAvgWeight = outCount > 0 ? (outTotalWeight / outCount)?.toFixed(2) : 0
// 损失钢卷数量、总重、均重
const lossCount = this.lossList.length
const lossTotalWeight = this.lossList.reduce((acc, cur) => acc + (parseFloat(cur.netWeight) || 0), 0) // 增加容错
const lossAvgWeight = lossCount > 0 ? (lossTotalWeight / lossCount)?.toFixed(2) : 0
// 合计数量、总重、均重
const totalCount = outCount + lossCount
const totalWeight = parseFloat((outTotalWeight + lossTotalWeight).toFixed(2))
const totalAvgWeight = totalCount > 0 ? (totalWeight / totalCount)?.toFixed(2) : 0
// 成品比率
const passRate = outCount > 0 ? (outCount / lossCount) : 0
// 损失比率
const lossRate = 1 - passRate
// 异常率,成品在warehouseId在'2019583656787259393',
// '2019583325311414274',
// '2019583429955104769',
// '2019583137616310273',这四个库中的占比
const abRate = this.list.filter(item => {
return item.warehouseId == '2019583656787259393' || item.warehouseId == '2019583325311414274' || item.warehouseId == '2019583429955104769' || item.warehouseId == '2019583137616310273'
}).length / totalCount
return {
outCount,
outTotalWeight: outTotalWeight.toFixed(2),
outAvgWeight,
lossCount,
lossTotalWeight: lossTotalWeight.toFixed(2),
lossAvgWeight,
totalCount,
totalWeight: totalWeight.toFixed(2),
totalAvgWeight,
passRate: passRate?.toFixed(2) * 100 + '%',
lossRate: lossRate?.toFixed(2) * 100 + '%',
abRate: (abRate?.toFixed(2) * 100) || 0 + '%',
}
return calcSummary(this.list, this.lossList)
}
},
methods: {
@@ -345,7 +306,7 @@ export default {
this.loading = true
listPendingAction({
actionType: 501, // 镀锌工序
pageSize: 999,
pageSize: 9999,
pageNum: 1,
startTime: this.queryParams.byCreateTimeStart,
endTime: this.queryParams.byCreateTimeEnd,
@@ -358,7 +319,7 @@ export default {
message: '暂无数据',
type: 'warning',
})
this.list = []
this.lossList = []
this.loading = false
return
}

6
package-lock.json generated Normal file
View File

@@ -0,0 +1,6 @@
{
"name": "klp-oa",
"lockfileVersion": 2,
"requires": true,
"packages": {}
}