feat(qc): 新增理化检验相关功能及优化质检流程

1. 新增化学成分明细和物理性能明细的API与管理页面
2. 在钢卷详情页添加检验信息展示模块
3. 优化质保书预览的签章显示逻辑,仅审批通过后显示
4. 重构质保书列表为表格形式,新增审批流程功能
5. 优化质保书选择弹窗的钢卷查询条件
6. 新增批量新增质保书明细时自动填充理化数据功能
This commit is contained in:
2026-05-18 17:54:12 +08:00
parent a705c6a4a9
commit 1bd55b12ec
8 changed files with 1177 additions and 313 deletions

View File

@@ -711,7 +711,7 @@
<div class="section sales-section">
<div class="section-header">
<span class="section-icon">💰</span>
<span class="section-title">销售信息</span>
<span class="section-title">生产合同信息</span>
</div>
<div class="section-body" v-if="salesInfo.orderId">
<el-descriptions :column="3" border size="small">
@@ -734,7 +734,7 @@
<div v-else class="empty-state">
<i class="el-icon-document"></i>
<span>未找到相关销售记录</span>
<span>未找到相关生产合同信息</span>
</div>
</div>
@@ -742,7 +742,7 @@
<!-- 发货单信息 -->
<div class="section-header">
<span class="section-icon">💰</span>
<span class="section-title">发货单对应的合同信息</span>
<span class="section-title">发货合同信息</span>
</div>
<div class="section-body" v-if="deliveryOrderInfo.orderId">
<el-descriptions :column="3" border size="small">
@@ -765,7 +765,7 @@
<div v-else class="empty-state">
<i class="el-icon-document"></i>
<span>未找到相关发货单对应的合同信息记录</span>
<span>未找到相关发货合同信息</span>
</div>
</div>
@@ -807,7 +807,6 @@
</div>
</div>
<div class="section combined-section">
<div class="section-header">
<span class="section-icon">📋</span>
@@ -878,6 +877,79 @@
</div>
</div>
<!-- 检验信息 -->
<div class="section inspection-section">
<div class="section-header">
<span class="section-icon">🔬</span>
<span class="section-title">检验信息</span>
</div>
<div class="section-body">
<el-table :data="inspectionTaskList" v-loading="inspectionLoading" size="small" border stripe style="width: 100%"
@expand-change="handleInspectionExpand" :row-key="row => row.taskId">
<el-table-column type="expand">
<template slot-scope="props">
<div v-loading="inspectionItemLoadingMap[props.row.taskId]" style="padding: 8px;">
<el-table :data="inspectionItemMap[props.row.taskId] || []" size="mini" border stripe style="width: 100%">
<el-table-column label="检验项目名称" align="center" prop="itemName" min-width="120" />
<el-table-column label="标准值" align="center" prop="standardValue" width="80" />
<el-table-column label="上限" align="center" prop="upperLimit" width="80" />
<el-table-column label="下限" align="center" prop="lowerLimit" width="80" />
<el-table-column label="单位" align="center" prop="unit" width="60" />
<el-table-column label="定性/定量" align="center" prop="itemType" width="80" />
<el-table-column label="检验值" align="center" prop="inspectValue" width="100" />
<el-table-column label="是否合格" align="center" prop="isQualified" width="80" />
<el-table-column label="判定结果" align="center" prop="judgeResult" width="100" />
<el-table-column label="检验人" align="center" prop="inspectUser" width="80" />
<el-table-column label="检验时间" align="center" prop="inspectTime" width="160">
<template slot-scope="scope">
<span>{{ parseTime(scope.row.inspectTime, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="100" />
</el-table>
<div v-if="!inspectionItemMap[props.row.taskId] || inspectionItemMap[props.row.taskId].length === 0"
style="text-align:center;padding:16px;color:#999;font-size:13px;">
暂无检验明细
</div>
</div>
</template>
</el-table-column>
<el-table-column label="任务编号" align="center" prop="taskCode" width="160" />
<el-table-column label="任务类型" align="center" prop="taskType" width="100" />
<el-table-column label="所属单位" align="center" prop="belongCompany" width="120" />
<el-table-column label="方案名称" align="center" prop="schemeName" min-width="120" />
<el-table-column label="状态" align="center" prop="status" width="90">
<template slot-scope="scope">
<el-tag v-if="scope.row.status === 0 || scope.row.status === '0'" type="info" size="small">待检验</el-tag>
<el-tag v-else-if="scope.row.status === 1 || scope.row.status === '1'" type="warning" size="small">已检验</el-tag>
<el-tag v-else-if="scope.row.status === 2 || scope.row.status === '2'" type="success" size="small">已审核</el-tag>
<span v-else>{{ scope.row.status }}</span>
</template>
</el-table-column>
<el-table-column label="检验人" align="center" prop="inspectUser" width="80" />
<el-table-column label="审核人" align="center" prop="auditUser" width="80" />
<el-table-column label="最终结果" align="center" prop="result" min-width="100" />
<el-table-column label="关联钢卷" align="center" width="140">
<template slot-scope="scope">
<div v-if="scope.row.coilList && scope.row.coilList.length > 0"
style="display: flex; flex-wrap: wrap; gap: 4px;">
<div v-for="(coil, index) in scope.row.coilList" :key="coil.coilId || index">
<CurrentCoilNo :currentCoilNo="coil.currentCoilNo || coil.coilNo || ''" />
</div>
</div>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" min-width="100" show-overflow-tooltip />
</el-table>
<div v-if="inspectionTaskList.length === 0 && !inspectionLoading"
style="text-align:center;padding:24px 0;color:#999;font-size:14px;">
<i class="el-icon-document" style="font-size:48px;display:block;margin-bottom:8px;color:#ddd;"></i>
未找到相关检验信息
</div>
</div>
</div>
<!-- 生产工艺数据图表 -->
<div v-if="isColdHardCoil" class="section production-section">
<div class="section-header">
@@ -969,6 +1041,9 @@ import { getTimingSegByEncoilId, getTimingPlanDetailByHotcoilId, getTimingRealti
import AbnormalTable from '@/views/wms/coil/components/AbnormalTable.vue';
import FileList from "@/components/FileList";
import CoilTraceResult from '@/views/wms/coil/panels/CoilTraceResult.vue';
import { listInspectionTask } from "@/api/mes/qc/inspectionTask";
import { listInspectionItem } from "@/api/mes/qc/inspectionItem";
import CurrentCoilNo from "@/components/KLPService/Renderer/CurrentCoilNo.vue";
const TREND_GROUPS = [
{
@@ -1087,7 +1162,8 @@ export default {
components: {
AbnormalTable,
FileList,
CoilTraceResult
CoilTraceResult,
CurrentCoilNo
},
data() {
return {
@@ -1131,6 +1207,11 @@ export default {
deliveryOrderInfo: {},
// 销售异议信息
salesObjectionInfo: [],
// 检验信息
inspectionTaskList: [],
inspectionLoading: false,
inspectionItemMap: {},
inspectionItemLoadingMap: {},
}
},
computed: {
@@ -1159,6 +1240,7 @@ export default {
await this.fetchDeliveryOrderInfo();
this.mergeTransferList();
await this.getSalesObjectionList();
await this.getInspectionTasks();
// 如果是冷硬卷,加载生产数据
if (this.isColdHardCoil) {
@@ -1258,6 +1340,33 @@ export default {
});
this.tranferList = list;
},
async getInspectionTasks() {
this.inspectionLoading = true;
try {
const res = await listInspectionTask({ coilIds: this.coilId, pageNum: 1, pageSize: 100 });
this.inspectionTaskList = res.rows || [];
} catch (e) {
console.error('获取检验任务异常:', e);
this.inspectionTaskList = [];
} finally {
this.inspectionLoading = false;
}
},
async handleInspectionExpand(row, expandedRows) {
if (!expandedRows || !expandedRows.includes(row)) return;
const taskId = row.taskId;
if (this.inspectionItemMap[taskId]) return;
this.$set(this.inspectionItemLoadingMap, taskId, true);
try {
const res = await listInspectionItem({ taskId, pageNum: 1, pageSize: 100 });
this.$set(this.inspectionItemMap, taskId, res.rows || []);
} catch (e) {
console.error('获取检验明细异常:', e);
this.$set(this.inspectionItemMap, taskId, []);
} finally {
this.$set(this.inspectionItemLoadingMap, taskId, false);
}
},
formatTime(timeStamp) {
if (!timeStamp) return '-';
const date = new Date(timeStamp);