Explorar o código

feat(s7): FQC录入检验加检验负责人门(三层),仅本人可进入/保存

要求:录入检验须检验负责人(jyfzr)==当前账号才能进入。三层(镜像生成检验单认领门):
- ①前端按钮门 fqcInspectionTaskList.vue openInspection:row.ownerId!=当前userInfos.id
  → 弹「检验负责人与当前账号不一致,无法进入录入检验」+不跳转
- ②后端进入门 FqcInspectionService.Detail:head.OwnerId(jyfzr)!=当前UserId→抛错,
  非负责人打不开录入页(查看走FQC检验结果列表只读详情,不受此限)
- ③后端保存门 FqcInspectionService.SaveDetail:JOIN qms_fqcbj 取jyfzr!=当前UserId→拒
  (防绕过UI直连接口)

jyfzr在录入阶段为认领/调配写的数字userId,按数字比对。DDL-free。

chore: bump version Web 2.4.308 / server 1.0.374
YY968XX hai 2 días
pai
achega
20af75dba5

+ 1 - 1
Web/package.json

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

+ 7 - 0
Web/src/views/aidop/s7/fqc/fqcInspectionTaskList.vue

@@ -154,6 +154,7 @@ import { computed, onActivated, onMounted, reactive, ref } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import { ElMessage } from 'element-plus';
 import AidopDemoShell from '/@/views/aidop/components/AidopDemoShell.vue';
+import { useUserInfo } from '/@/stores/userInfo';
 import FqcInspBillDetailDrawer from './components/FqcInspBillDetailDrawer.vue';
 import FqcInspectorPickerDialog from './components/FqcInspectorPickerDialog.vue';
 import { fetchFqcResultList, fetchFqcDetail, type FqcResultRow, type FqcDetail } from '../api/fqcInspBill';
@@ -303,6 +304,12 @@ async function onGenerate(row: FqcTaskEntryRow) {
 }
 function openInspection(row: FqcTaskEntryRow) {
 	if (!row.inspBillId) return;
+	// 检验负责人门:仅本人(jyfzr==当前账号)可进入录入检验
+	const uid = useUserInfo().userInfos?.id;
+	if (uid == null || String(row.ownerId ?? '') !== String(uid)) {
+		ElMessage.error('检验负责人与当前账号不一致,无法进入录入检验');
+		return;
+	}
 	router.push({ path: '/aidop/s7/fqc/insp-detail', query: { id: String(row.inspBillId) } });
 }
 

+ 3 - 3
server/Admin.NET.Web.Entry/Admin.NET.Web.Entry.csproj

@@ -11,9 +11,9 @@
     <GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
     <Copyright>Admin.NET</Copyright>
     <Description>Admin.NET 通用权限开发平台</Description>
-    <AssemblyVersion>1.0.373</AssemblyVersion>
-    <FileVersion>1.0.373</FileVersion>
-    <Version>1.0.373</Version>
+    <AssemblyVersion>1.0.374</AssemblyVersion>
+    <FileVersion>1.0.374</FileVersion>
+    <Version>1.0.374</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 13 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/FinishedWarehouse/FqcInspectionService.cs

@@ -52,6 +52,10 @@ public class FqcInspectionService : IDynamicApiController, ITransient
             new SugarParameter("@id", inspBillId), new SugarParameter("@t", tenantId))).FirstOrDefault();
         if (head == null) return null;
 
+        // 检验负责人门:仅本人(jyfzr==当前账号)可进入录入检验(查看走 FQC检验结果列表的只读详情,不受此限)
+        if (!string.Equals((head.OwnerId ?? "").Trim(), _userManager.UserId.ToString(), StringComparison.Ordinal))
+            throw Oops.Oh("检验负责人与当前账号不一致,无法进入录入检验");
+
         // 检验负责人 jyfzr 双语义:认领/调配写 SysUser id(数字,可能跨租户),检验流程提交写姓名字符串。
         // 数字 → ClearFilter 反解姓名(解不到回落原值);非数字 → 本就是姓名,直接展示。
         if (!string.IsNullOrWhiteSpace(head.OwnerId))
@@ -107,6 +111,15 @@ public class FqcInspectionService : IDynamicApiController, ITransient
             new SugarParameter("@id", input.InspBillId), new SugarParameter("@t", tenantId));
         if (owns == 0) throw Oops.Oh("检验单不存在或不属于当前租户");
 
+        // 检验负责人门:仅本人(jyfzr==当前账号)可保存录入(防绕过 UI 直接调接口)
+        var saveOwner = await _db.Ado.SqlQuerySingleAsync<string>(
+            @"SELECT q.jyfzr FROM qms_qcpp_inspbill i
+              JOIN qms_fqcbj q ON q.FBILLNO=i.lydjbh AND q.id=i.hid AND q.tenant_id=i.tenant_id
+              WHERE i.id=@id AND i.tenant_id=@t LIMIT 1",
+            new SugarParameter("@id", input.InspBillId), new SugarParameter("@t", tenantId));
+        if (!string.Equals((saveOwner ?? "").Trim(), _userManager.UserId.ToString(), StringComparison.Ordinal))
+            throw Oops.Oh("检验负责人与当前账号不一致,无法录入");
+
         var tran = await _db.Ado.UseTranAsync(async () =>
         {
             foreach (var ln in input.Lines)