Browse Source

fix(s6): disambiguate IPQC source status from workflow status

D-06 语义消歧(纯展示,零逻辑改动):

详情页原「检验状态」绑定的是源单据字段 qms_gcjyd.status,而 S6 工作流推进
刻意不回写该字段,于是页面会同时出现「检验状态=待检验」与流程标签「已通过」,
客户误以为系统状态自相矛盾。

本批只做标签消歧:
- 原「检验状态」→「源单状态」,明确它是上游单据原始字段;
- 详情顶部流程标签补上「流程状态:」前缀,明确它才是当前业务进度;
- 流程状态位于抽屉顶部,信息层级先于基础信息区的源单状态;
- 当前节点规则沿用 Batch 2:进行中显示中文节点名,终态不显示。

字段来源(写入 memory 以免后人再混用):
  源单状态 ← detail.inspectionStatus ← mdp_std_ipqc_inspection.inspection_status
            ← raw_data.$.status ← qms_gcjyd.status
  流程状态 ← flowState.businessStatus / row.businessStatus
            ← ado_s6_ipqc_inspection_flow_state.business_status
  当前节点 ← flowState.currentNodeName ← ApprovalFlowTask.NodeName

未做业务推断:未回写 qms_gcjyd.status、未让 workflow 覆盖源状态、未删除源字段、
未改 DTO / API JSON key / 状态机 / can* / assignee。列表仍只展示流程状态,
不新增第二个状态列。

契约测试扩展至 49 passed(Batch 2 的 43 + 本批 6)。

chore: bump version Web 2.4.371
YY968XX 2 ngày trước cách đây
mục cha
commit
c3da5703fa

+ 1 - 1
Web/package.json

@@ -1,7 +1,7 @@
 {
 	"name": "admin.net",
 	"type": "module",
-	"version": "2.4.370",
+	"version": "2.4.371",
 	"packageManager": "pnpm@10.32.1",
 	"lastBuildTime": "2026.03.15",
 	"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",

+ 8 - 1
Web/src/views/aidop/s6/process-quality/processInspectionList.vue

@@ -97,6 +97,10 @@
 			<div v-loading="detailLoading">
 				<div class="flow-panel" v-loading="flowLoading">
 					<div class="flow-status-line">
+						<!-- 「流程状态」= S6 工作流当前进度(ado_s6_ipqc_inspection_flow_state.business_status)。
+						     与基础信息区的「源单状态」(qms_gcjyd.status) 是两套状态体系,语义不同、不互相覆盖。
+						     客户判断当前业务进度以本字段为准,故置于抽屉顶部、优先于源单状态。 -->
+						<span class="flow-meta">流程状态:</span>
 						<el-tag size="small" :type="flowTagType">{{ flowStatusText }}</el-tag>
 						<span class="flow-msg">{{ flowState.message }}</span>
 						<!-- 当前节点:仅在流程进行中且后端给出中文节点名时展示。
@@ -172,7 +176,10 @@
 					<el-descriptions-item label="生产批号">{{ displayValue(detail.productionBatchNo) }}</el-descriptions-item>
 					<el-descriptions-item label="生产工单">{{ displayValue(detail.productionWorkOrder) }}</el-descriptions-item>
 					<el-descriptions-item label="结果判定">{{ judgementText(detail.resultJudgement) }}</el-descriptions-item>
-					<el-descriptions-item label="检验状态">{{ displayValue(detail.inspectionStatus) }}</el-descriptions-item>
+					<!-- 「源单状态」= 上游检验单 qms_gcjyd.status 原样透出,S6 工作流推进**刻意不回写**该字段,
+					     因此它可能长期停在初始值(如"待检验")而流程已是"已通过/已处置"——这是既定设计,不是数据错误。
+					     原 label「检验状态」会被误读成当前流程进度,故改名消歧;字段/DTO/API key 均未改。 -->
+					<el-descriptions-item label="源单状态">{{ displayValue(detail.inspectionStatus) }}</el-descriptions-item>
 					<el-descriptions-item label="检验人">{{ displayValue(detail.inspector) }}</el-descriptions-item>
 					<el-descriptions-item label="工序编码">{{ displayValue(detail.processCode) }}</el-descriptions-item>
 					<el-descriptions-item label="工序名称">{{ displayValue(detail.processName) }}</el-descriptions-item>

+ 59 - 0
server/Plugins/Admin.NET.Plugin.AiDOP.Tests/S6/Manufacturing/S6IpqcDisplayContractTests.cs

@@ -255,6 +255,65 @@ public class S6IpqcDisplayContractTests
         Assert.Contains("m.tenant_id = @TenantId", s);
     }
 
+    // ───────────────── Batch 3 · D-06 源单状态 / 流程状态 语义消歧 ─────────────────
+
+    /// <summary>
+    /// 误导性 label「检验状态」必须消失——它绑定的是源字段 qms_gcjyd.status,
+    /// 用户会误读成当前流程进度。
+    /// </summary>
+    [Fact]
+    public void Detail_NoLongerUsesMisleadingInspectionStatusLabel()
+    {
+        Assert.DoesNotContain("label=\"检验状态\"", Vue());
+    }
+
+    /// <summary>源字段改标为「源单状态」,但绑定的 DTO 字段不变(API contract 不动)。</summary>
+    [Fact]
+    public void Detail_SourceStatus_RelabelledButBindingUnchanged()
+    {
+        var v = Vue();
+        Assert.Contains("label=\"源单状态\"", v);
+        Assert.Contains("displayValue(detail.inspectionStatus)", v);
+    }
+
+    /// <summary>工作流状态在详情顶部有显式「流程状态:」标注,不再是一个无标签的裸标签。</summary>
+    [Fact]
+    public void Detail_WorkflowStatus_IsExplicitlyLabelled()
+    {
+        var v = Vue();
+        Assert.Contains("流程状态:", v);
+        Assert.Contains("{{ flowStatusText }}", v);
+    }
+
+    /// <summary>
+    /// 信息层级:流程状态(flow-panel)必须出现在源单状态(基础信息区)之前。
+    /// 抽屉先渲染 flow-panel 再渲染 el-descriptions,故以源码位置为序即可断言。
+    /// </summary>
+    [Fact]
+    public void Detail_WorkflowStatus_PrecedesSourceStatus()
+    {
+        var v = Vue();
+        Assert.True(v.IndexOf("流程状态:", StringComparison.Ordinal)
+                  < v.IndexOf("label=\"源单状态\"", StringComparison.Ordinal));
+    }
+
+    /// <summary>列表只展示流程状态,不得再引入第二个状态列造成二次困惑。</summary>
+    [Fact]
+    public void List_ShowsOnlyWorkflowStatus_NoSourceStatusColumn()
+    {
+        var v = Vue();
+        Assert.Contains("prop=\"businessStatus\" label=\"流程状态\"", v);
+        Assert.DoesNotContain("el-table-column prop=\"inspectionStatus\"", v);
+        Assert.DoesNotContain("row.inspectionStatus", v);
+    }
+
+    /// <summary>Batch 2 的终态不显示当前节点逻辑保持不变(防回归)。</summary>
+    [Fact]
+    public void CurrentNode_TerminalSuppression_StillIntact()
+    {
+        Assert.Contains("!flowState.isCompleted && flowState.currentNodeName", Vue());
+    }
+
     private static string FindFile(params string[] parts)
     {
         var dir = new DirectoryInfo(AppContext.BaseDirectory);