Browse Source

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 1 month ago
parent
commit
b383e931a1
1 changed files with 48 additions and 19 deletions
  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-form-item label="公司" prop="companyRefId">
 							<el-select v-model="form.companyRefId" filterable style="width: 100%" @change="onFormCompanyChange">
 							<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-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-select>
 						</el-form-item>
 						</el-form-item>
 					</el-col>
 					</el-col>
@@ -86,6 +92,12 @@
 						<el-form-item label="工厂" prop="factoryRefId">
 						<el-form-item label="工厂" prop="factoryRefId">
 							<el-select v-model="form.factoryRefId" filterable style="width: 100%" @change="syncDomainFromFactory">
 							<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-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-select>
 						</el-form-item>
 						</el-form-item>
 					</el-col>
 					</el-col>
@@ -172,7 +184,7 @@
 </template>
 </template>
 
 
 <script setup lang="ts" name="aidopS0MfgProductionLine">
 <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 { useRoute } from 'vue-router';
 import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
 import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus';
 import AidopDemoShell from '../../components/AidopDemoShell.vue';
 import AidopDemoShell from '../../components/AidopDemoShell.vue';
@@ -184,7 +196,7 @@ import DictDataMaintainPanel from '../sales/components/DictDataMaintainPanel.vue
 const route = useRoute();
 const route = useRoute();
 const pageTitle = computed(() => (route.meta?.title as string) || '生产线编码清单');
 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 queryFactories = computed(() => factoriesForCompany(query.companyRefId));
 const formFactories = computed(() => factoriesForCompany(form.companyRefId));
 const formFactories = computed(() => factoriesForCompany(form.companyRefId));
 
 
@@ -214,6 +226,8 @@ const lineLocationOptions = ref<OptionItem[]>([]);
 const configDialogVisible = ref(false);
 const configDialogVisible = ref(false);
 const configActiveTab = ref('lineType');
 const configActiveTab = ref('lineType');
 
 
+const isRehydrating = ref(false);
+
 async function loadDictOptionsAll() {
 async function loadDictOptionsAll() {
 	const [lineType, lineCategory, lineLocation] = await Promise.all([
 	const [lineType, lineCategory, lineLocation] = await Promise.all([
 		loadDictOptions('s0_line_type'),
 		loadDictOptions('s0_line_type'),
@@ -256,6 +270,7 @@ watch(
 watch(
 watch(
 	() => form.companyRefId,
 	() => form.companyRefId,
 	() => {
 	() => {
+		if (isRehydrating.value) return;
 		if (!formFactories.value.some((x) => x.id === form.factoryRefId)) {
 		if (!formFactories.value.some((x) => x.id === form.factoryRefId)) {
 			form.factoryRefId = undefined;
 			form.factoryRefId = undefined;
 			form.domain = '';
 			form.domain = '';
@@ -347,28 +362,42 @@ async function openEdit(row: S0LineMasterRow) {
 	editingId.value = row.id;
 	editingId.value = row.id;
 	dialogTitle.value = `编辑 ${row.line}`;
 	dialogTitle.value = `编辑 ${row.line}`;
 	const detail = await s0MfgProductionLinesApi.get(row.id);
 	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;
 	dialogVisible.value = true;
 }
 }
 
 
 async function submitForm() {
 async function submitForm() {
 	await formRef.value?.validate();
 	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 = {
 	const payload: S0LineMasterUpsert = {
 		companyRefId: form.companyRefId,
 		companyRefId: form.companyRefId,
 		factoryRefId: form.factoryRefId,
 		factoryRefId: form.factoryRefId,