Просмотр исходного кода

fix(s0): preserve production line organization rehydration

Keep edit-form organization and domain values during record rehydration.

Show historical organization values for invalid company and factory references.

Block saves when production line records are not linked to valid company and factory options.
YY968XX 4 недель назад
Родитель
Сommit
b383e931a1
1 измененных файлов с 48 добавлено и 19 удалено
  1. 48 19
      Web/src/views/aidop/s0/manufacturing/ProductionLineList.vue

+ 48 - 19
Web/src/views/aidop/s0/manufacturing/ProductionLineList.vue

@@ -79,6 +79,12 @@
 						<el-form-item label="公司" prop="companyRefId">
 							<el-select v-model="form.companyRefId" filterable style="width: 100%" @change="onFormCompanyChange">
 								<el-option v-for="item in companyOptions" :key="item.id" :label="item.name || item.code || `${item.id}`" :value="item.id" />
+								<el-option
+									v-if="form.companyRefId != null && form.companyRefId !== '' && !companyOptions.some((o) => o.id === String(form.companyRefId))"
+									:key="`__compat_company_${form.companyRefId}`"
+									:label="`未关联组织(历史值:${form.companyRefId})`"
+									:value="form.companyRefId"
+								/>
 							</el-select>
 						</el-form-item>
 					</el-col>
@@ -86,6 +92,12 @@
 						<el-form-item label="工厂" prop="factoryRefId">
 							<el-select v-model="form.factoryRefId" filterable style="width: 100%" @change="syncDomainFromFactory">
 								<el-option v-for="item in formFactories" :key="item.id" :label="item.name || item.code || `${item.id}`" :value="item.id" />
+								<el-option
+									v-if="form.factoryRefId != null && form.factoryRefId !== '' && !factoryOptions.some((o) => o.id === String(form.factoryRefId))"
+									:key="`__compat_factory_${form.factoryRefId}`"
+									:label="`未关联组织(历史值:${form.factoryRefId})`"
+									:value="form.factoryRefId"
+								/>
 							</el-select>
 						</el-form-item>
 					</el-col>
@@ -172,7 +184,7 @@
 </template>
 
 <script setup lang="ts" name="aidopS0MfgProductionLine">
-import { computed, onMounted, reactive, ref, watch } from 'vue';
+import { computed, nextTick, onMounted, reactive, ref, watch } from 'vue';
 import { useRoute } from 'vue-router';
 import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
 import AidopDemoShell from '../../components/AidopDemoShell.vue';
@@ -184,7 +196,7 @@ import DictDataMaintainPanel from '../sales/components/DictDataMaintainPanel.vue
 const route = useRoute();
 const pageTitle = computed(() => (route.meta?.title as string) || '生产线编码清单');
 
-const { companyOptions, loadOrgs, factoriesForCompany } = useS0MfgOrgScope();
+const { companyOptions, factoryOptions, loadOrgs, factoriesForCompany } = useS0MfgOrgScope();
 const queryFactories = computed(() => factoriesForCompany(query.companyRefId));
 const formFactories = computed(() => factoriesForCompany(form.companyRefId));
 
@@ -214,6 +226,8 @@ const lineLocationOptions = ref<OptionItem[]>([]);
 const configDialogVisible = ref(false);
 const configActiveTab = ref('lineType');
 
+const isRehydrating = ref(false);
+
 async function loadDictOptionsAll() {
 	const [lineType, lineCategory, lineLocation] = await Promise.all([
 		loadDictOptions('s0_line_type'),
@@ -256,6 +270,7 @@ watch(
 watch(
 	() => form.companyRefId,
 	() => {
+		if (isRehydrating.value) return;
 		if (!formFactories.value.some((x) => x.id === form.factoryRefId)) {
 			form.factoryRefId = undefined;
 			form.domain = '';
@@ -347,28 +362,42 @@ async function openEdit(row: S0LineMasterRow) {
 	editingId.value = row.id;
 	dialogTitle.value = `编辑 ${row.line}`;
 	const detail = await s0MfgProductionLinesApi.get(row.id);
-	Object.assign(form, {
-		companyRefId: detail.companyRefId,
-		factoryRefId: detail.factoryRefId,
-		domain: detail.domain || '',
-		line: detail.line || '',
-		describe: (detail as any).describe ?? '',
-		lineType: detail.lineType || '',
-		lineCategory: detail.lineCategory || '',
-		location: detail.location || '',
-		workshop: detail.workshop || '',
-		vLocation: detail.vLocation || '',
-		location2: detail.location2 || '',
-		location3: detail.location3 || '',
-		pickingLocation: detail.pickingLocation || '',
-		midLocation: detail.midLocation || '',
-		isActive: (detail as any).isActive !== false,
-	});
+	isRehydrating.value = true;
+	try {
+		Object.assign(form, {
+			companyRefId: detail.companyRefId,
+			factoryRefId: detail.factoryRefId,
+			domain: detail.domain || '',
+			line: detail.line || '',
+			describe: (detail as any).describe ?? '',
+			lineType: detail.lineType || '',
+			lineCategory: detail.lineCategory || '',
+			location: detail.location || '',
+			workshop: detail.workshop || '',
+			vLocation: detail.vLocation || '',
+			location2: detail.location2 || '',
+			location3: detail.location3 || '',
+			pickingLocation: detail.pickingLocation || '',
+			midLocation: detail.midLocation || '',
+			isActive: (detail as any).isActive !== false,
+		});
+		await nextTick();
+	} finally {
+		isRehydrating.value = false;
+	}
 	dialogVisible.value = true;
 }
 
 async function submitForm() {
 	await formRef.value?.validate();
+
+	const companyHit = companyOptions.value.some((o) => o.id === String(form.companyRefId));
+	const factoryHit = factoryOptions.value.some((o) => o.id === String(form.factoryRefId));
+	if (!companyHit || !factoryHit) {
+		ElMessage.warning('当前记录未关联有效公司/工厂,请先选择公司和工厂后再保存。');
+		return;
+	}
+
 	const payload: S0LineMasterUpsert = {
 		companyRefId: form.companyRefId,
 		factoryRefId: form.factoryRefId,