ソースを参照

fix(s0): 工艺路线明细行去组织作用域,放开 scope-zero 编辑保存

行级工艺路线(legacy RoutingOpDetail 复刻)不建模组织作用域,全表 4089/4092 条 company/factory=0,
原前后端硬性要求公司/工厂非空导致这些历史记录编辑保存被必填拦截。

- 前端 RoutingList.vue:隐藏弹窗/筛选区/表格列的公司/工厂,去除其必填规则与失效的 form watch;
  company/factory 仅在写回 DTO 时原样透传,保留既有 scope
- 后端 AdoS0MfgRoutingOpDetailUpsertDto:去掉 CompanyRefId/FactoryRefId 的 [Range(1,..)],放行历史 0/0
- bump Web 2.4.193 / server 1.0.189
YY968XX 20 時間 前
コミット
2cecf0f405

+ 1 - 1
Web/package.json

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

+ 4 - 73
Web/src/views/aidop/s0/manufacturing/RoutingList.vue

@@ -4,16 +4,6 @@
 			<el-form-item label="关键字">
 				<el-input v-model="query.keyword" clearable placeholder="路线/物料/工序/工作中心" style="width: 200px" />
 			</el-form-item>
-			<el-form-item label="公司">
-				<el-select v-model="query.companyRefId" clearable filterable placeholder="全部" style="width: 150px">
-					<el-option v-for="item in companyOptions" :key="item.id" :label="item.name || item.code || `${item.id}`" :value="item.id" />
-				</el-select>
-			</el-form-item>
-			<el-form-item label="工厂">
-				<el-select v-model="query.factoryRefId" clearable filterable placeholder="全部" style="width: 150px">
-					<el-option v-for="item in queryFactories" :key="item.id" :label="item.name || item.code || `${item.id}`" :value="item.id" />
-				</el-select>
-			</el-form-item>
 			<el-form-item label="启用">
 				<el-select v-model="query.isEnabled" clearable placeholder="全部" style="width: 90px">
 					<el-option label="启用" :value="true" />
@@ -28,12 +18,6 @@
 		</el-form>
 
 		<el-table :data="rows" v-loading="loading" border stripe size="small" max-height="calc(100vh - 260px)">
-			<el-table-column label="公司" width="110" show-overflow-tooltip>
-				<template #default="{ row }">{{ companyName(row.companyRefId) }}</template>
-			</el-table-column>
-			<el-table-column label="工厂" width="90" show-overflow-tooltip>
-				<template #default="{ row }">{{ factoryName(row.factoryRefId) }}</template>
-			</el-table-column>
 			<el-table-column prop="routeCode" label="工艺路线编码" width="110" show-overflow-tooltip />
 			<el-table-column prop="routeName" label="工艺路线名称" width="140" show-overflow-tooltip />
 			<el-table-column prop="materialCode" label="物料编码" width="110" show-overflow-tooltip />
@@ -91,20 +75,6 @@
 		<el-dialog v-model="dialogVisible" :title="dialogTitle" width="920px" destroy-on-close @closed="resetForm">
 			<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" class="routing-form">
 				<el-row :gutter="12">
-					<el-col :span="8">
-						<el-form-item label="公司" prop="companyRefId">
-							<el-select v-model="form.companyRefId" filterable style="width: 100%" @change="onFormOrgChange">
-								<el-option v-for="item in companyOptions" :key="item.id" :label="item.name || item.code || `${item.id}`" :value="item.id" />
-							</el-select>
-						</el-form-item>
-					</el-col>
-					<el-col :span="8">
-						<el-form-item label="工厂" prop="factoryRefId">
-							<el-select v-model="form.factoryRefId" filterable style="width: 100%" @change="onFormOrgChange">
-								<el-option v-for="item in formFactories" :key="item.id" :label="item.name || item.code || `${item.id}`" :value="item.id" />
-							</el-select>
-						</el-form-item>
-					</el-col>
 					<el-col :span="8">
 						<el-form-item label="排序" prop="sortNo">
 							<el-input-number v-model="form.sortNo" :min="0" :step="1" style="width: 100%" />
@@ -191,37 +161,21 @@
 </template>
 
 <script setup lang="ts" name="aidopS0MfgRouting">
-import { computed, onMounted, reactive, ref, watch } from 'vue';
+import { computed, onMounted, reactive, ref } from 'vue';
 import { useRoute } from 'vue-router';
 import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
 import AidopDemoShell from '../../components/AidopDemoShell.vue';
-import { useS0MfgOrgScope } from '../composables/useS0MfgOrgScope';
 import { s0MfgRoutingOpDetailsApi, type S0MfgRoutingOpDetailRow, type S0MfgRoutingOpDetailUpsert } from '../api/s0ManufacturingApi';
 
 const route = useRoute();
 const pageTitle = computed(() => (route.meta?.title as string) || '标准工艺路线列表');
 type Row = Record<string, any>;
 
-const { companyOptions, factoryOptions, loadOrgs, factoriesForCompany } = useS0MfgOrgScope();
-
-function companyName(refId?: string | number | null): string {
-	if (refId == null || refId === '') return '';
-	const hit = companyOptions.value.find((o) => o.id === String(refId));
-	return hit ? (hit.name || hit.code || String(hit.id)) : `未关联组织(历史值:${refId})`;
-}
-
-function factoryName(refId?: string | number | null): string {
-	if (refId == null || refId === '') return '';
-	const hit = factoryOptions.value.find((o) => o.id === String(refId));
-	return hit ? (hit.name || hit.code || String(hit.id)) : `未关联组织(历史值:${refId})`;
-}
-const queryFactories = computed(() => factoriesForCompany(query.companyRefId));
-const formFactories = computed(() => factoriesForCompany(form.companyRefId));
+// 行级工艺路线(legacy RoutingOpDetail 复刻)不建模组织作用域:全表 company/factory 多为 0,
+// 故页面不展示公司/工厂筛选与列;company/factory 仅在写回 DTO 时原样透传,保留既有 scope。
 
 const query = reactive({
 	keyword: '',
-	companyRefId: undefined as string | undefined,
-	factoryRefId: undefined as string | undefined,
 	isEnabled: undefined as boolean | undefined,
 	page: 1,
 	pageSize: 20,
@@ -274,32 +228,13 @@ function emptyForm() {
 
 const form = reactive(emptyForm());
 
-watch(
-	() => query.companyRefId,
-	() => {
-		if (!queryFactories.value.some((x) => x.id === query.factoryRefId)) query.factoryRefId = undefined;
-	},
-);
-watch(
-	() => form.companyRefId,
-	() => {
-		if (!formFactories.value.some((x) => x.id === form.factoryRefId)) form.factoryRefId = undefined;
-	},
-);
-
 const rules: FormRules = {
-	companyRefId: [{ required: true, message: '请选择公司', trigger: 'change' }],
-	factoryRefId: [{ required: true, message: '请选择工厂', trigger: 'change' }],
 	routeCode: [{ required: true, message: '请填写路线编码', trigger: 'blur' }],
 	routeName: [{ required: true, message: '请填写路线名称', trigger: 'blur' }],
 	materialCode: [{ required: true, message: '请填写物料编码', trigger: 'blur' }],
 	operationCode: [{ required: true, message: '请填写工序编码', trigger: 'blur' }],
 };
 
-function onFormOrgChange() {
-	/* 行级页无远程物料搜索 */
-}
-
 async function loadList() {
 	loading.value = true;
 	try {
@@ -307,8 +242,6 @@ async function loadList() {
 			page: query.page,
 			pageSize: query.pageSize,
 			keyword: query.keyword || undefined,
-			companyRefId: query.companyRefId,
-			factoryRefId: query.factoryRefId,
 			isEnabled: query.isEnabled,
 		});
 		rows.value = data.list as Row[];
@@ -323,8 +256,6 @@ async function loadList() {
 
 function resetQuery() {
 	query.keyword = '';
-	query.companyRefId = undefined;
-	query.factoryRefId = undefined;
 	query.isEnabled = undefined;
 	query.page = 1;
 	void loadList();
@@ -337,6 +268,7 @@ function resetForm() {
 }
 
 function rowToForm(row: S0MfgRoutingOpDetailRow) {
+	// company/factory 不在 UI 展示,仅原样回填以便写回时透传,保留既有 scope。
 	Object.assign(form, {
 		companyRefId: row.companyRefId,
 		factoryRefId: row.factoryRefId,
@@ -469,7 +401,6 @@ function toggleEnabled(row: Row) {
 }
 
 onMounted(async () => {
-	await loadOrgs();
 	await loadList();
 });
 </script>

+ 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.188</AssemblyVersion>
-    <FileVersion>1.0.188</FileVersion>
-    <Version>1.0.188</Version>
+    <AssemblyVersion>1.0.189</AssemblyVersion>
+    <FileVersion>1.0.189</FileVersion>
+    <Version>1.0.189</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 2 - 2
server/Plugins/Admin.NET.Plugin.AiDOP/Dto/S0/Manufacturing/AdoS0ManufacturingDtos.cs

@@ -793,10 +793,10 @@ public class AdoS0ProductStructureUpsertDto
 /// <summary>标准工艺路线明细行(RoutingOpDetail 复刻)Upsert。</summary>
 public class AdoS0MfgRoutingOpDetailUpsertDto
 {
-    [Range(1, long.MaxValue, ErrorMessage = "公司不能为空")]
+    // 行级工艺路线(legacy RoutingOpDetail 复刻)不建模组织作用域:全表 company/factory 多为 0,
+    // 前端已不展示公司/工厂,故此处放行 0,按原值透传,不强制非零。
     public long CompanyRefId { get; set; }
 
-    [Range(1, long.MaxValue, ErrorMessage = "工厂不能为空")]
     public long FactoryRefId { get; set; }
 
     [Required(ErrorMessage = "工艺路线编码不能为空")]