Explorar o código

feat(s0): align production line code list dictionaries

Update production line menu title to production line code list.

Add S0 dictionary seeds for line type, line category, and main location.

Replace production line type, category, and main location inputs with dictionary-backed selectors.

Add in-page configuration maintenance entry for the three production line dictionaries.
YY968XX hai 2 semanas
pai
achega
5dbbfb5d1e

+ 84 - 4
Web/src/views/aidop/s0/manufacturing/ProductionLineList.vue

@@ -30,6 +30,7 @@
 				<el-button type="primary" @click="loadList">查询</el-button>
 				<el-button @click="resetQuery">重置</el-button>
 				<el-button type="success" @click="openCreate">新增</el-button>
+				<el-button @click="configDialogVisible = true">配置维护</el-button>
 			</el-form-item>
 		</el-form>
 
@@ -95,9 +96,45 @@
 					</el-col>
 					<el-col :span="12"><el-form-item label="生产线" prop="line"><el-input v-model="form.line" maxlength="100" /></el-form-item></el-col>
 					<el-col :span="12"><el-form-item label="描述"><el-input v-model="form.describe" maxlength="255" /></el-form-item></el-col>
-					<el-col :span="12"><el-form-item label="产线类型"><el-input v-model="form.lineType" maxlength="50" clearable /></el-form-item></el-col>
-					<el-col :span="12"><el-form-item label="产线类别"><el-input v-model="form.lineCategory" maxlength="50" clearable /></el-form-item></el-col>
-					<el-col :span="12"><el-form-item label="主库位"><el-input v-model="form.location" maxlength="50" clearable /></el-form-item></el-col>
+					<el-col :span="12">
+						<el-form-item label="产线类型">
+							<el-select v-model="form.lineType" clearable filterable placeholder="请选择产线类型" style="width: 100%">
+								<el-option v-for="item in lineTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
+								<el-option
+									v-if="form.lineType && !lineTypeOptions.some((o) => o.value === form.lineType)"
+									:key="`__compat_${form.lineType}`"
+									:label="form.lineType"
+									:value="form.lineType"
+								/>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="产线类别">
+							<el-select v-model="form.lineCategory" clearable filterable placeholder="请选择产线类别" style="width: 100%">
+								<el-option v-for="item in lineCategoryOptions" :key="item.value" :label="item.label" :value="item.value" />
+								<el-option
+									v-if="form.lineCategory && !lineCategoryOptions.some((o) => o.value === form.lineCategory)"
+									:key="`__compat_${form.lineCategory}`"
+									:label="form.lineCategory"
+									:value="form.lineCategory"
+								/>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="主库位">
+							<el-select v-model="form.location" clearable filterable placeholder="请选择主库位" style="width: 100%">
+								<el-option v-for="item in lineLocationOptions" :key="item.value" :label="item.label" :value="item.value" />
+								<el-option
+									v-if="form.location && !lineLocationOptions.some((o) => o.value === form.location)"
+									:key="`__compat_${form.location}`"
+									:label="form.location"
+									:value="form.location"
+								/>
+							</el-select>
+						</el-form-item>
+					</el-col>
 					<el-col :span="12"><el-form-item label="车间编码"><el-input v-model="form.workshop" maxlength="50" clearable /></el-form-item></el-col>
 					<el-col :span="12"><el-form-item label="虚拟库位"><el-input v-model="form.vLocation" maxlength="50" clearable /></el-form-item></el-col>
 					<el-col :span="12"><el-form-item label="库位2"><el-input v-model="form.location2" maxlength="50" clearable /></el-form-item></el-col>
@@ -112,6 +149,25 @@
 				<el-button type="primary" :loading="saving" @click="submitForm">保存</el-button>
 			</template>
 		</el-dialog>
+
+		<el-dialog
+			v-model="configDialogVisible"
+			title="生产线编码清单配置维护"
+			width="860px"
+			destroy-on-close
+		>
+			<el-tabs v-model="configActiveTab">
+				<el-tab-pane label="产线类型" name="lineType">
+					<DictDataMaintainPanel dict-code="s0_line_type" @changed="onDictChanged" />
+				</el-tab-pane>
+				<el-tab-pane label="产线类别" name="lineCategory">
+					<DictDataMaintainPanel dict-code="s0_line_category" @changed="onDictChanged" />
+				</el-tab-pane>
+				<el-tab-pane label="主库位" name="lineLocation">
+					<DictDataMaintainPanel dict-code="s0_line_location" @changed="onDictChanged" />
+				</el-tab-pane>
+			</el-tabs>
+		</el-dialog>
 	</AidopDemoShell>
 </template>
 
@@ -122,9 +178,11 @@ import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'elem
 import AidopDemoShell from '../../components/AidopDemoShell.vue';
 import { useS0MfgOrgScope } from '../composables/useS0MfgOrgScope';
 import { s0MfgProductionLinesApi, type S0LineMasterRow, type S0LineMasterUpsert } from '../api/s0ManufacturingApi';
+import { loadDictOptions, type OptionItem } from '../api/s0SalesApi';
+import DictDataMaintainPanel from '../sales/components/DictDataMaintainPanel.vue';
 
 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 queryFactories = computed(() => factoriesForCompany(query.companyRefId));
@@ -150,6 +208,27 @@ const editingId = ref<number | null>(null);
 const saving = ref(false);
 const formRef = ref<FormInstance>();
 
+const lineTypeOptions = ref<OptionItem[]>([]);
+const lineCategoryOptions = ref<OptionItem[]>([]);
+const lineLocationOptions = ref<OptionItem[]>([]);
+const configDialogVisible = ref(false);
+const configActiveTab = ref('lineType');
+
+async function loadDictOptionsAll() {
+	const [lineType, lineCategory, lineLocation] = await Promise.all([
+		loadDictOptions('s0_line_type'),
+		loadDictOptions('s0_line_category'),
+		loadDictOptions('s0_line_location'),
+	]);
+	lineTypeOptions.value = lineType;
+	lineCategoryOptions.value = lineCategory;
+	lineLocationOptions.value = lineLocation;
+}
+
+async function onDictChanged() {
+	await loadDictOptionsAll();
+}
+
 const form = reactive({
 	companyRefId: undefined,
 	factoryRefId: undefined,
@@ -346,6 +425,7 @@ function toggleActive(row: S0LineMasterRow) {
 
 onMounted(async () => {
 	await loadOrgs();
+	await loadDictOptionsAll();
 	await loadList();
 });
 </script>

+ 19 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/S0DictDataSeedData.cs

@@ -27,6 +27,9 @@ public class S0DictDataSeedData : ISqlSugarEntitySeedData<SysDictData>
         var orderTypeId            = types[13].Id;
         var dueStatusId            = types[14].Id;
         var ownerApplicationId     = types[15].Id;
+        var lineTypeId             = types[16].Id;
+        var lineCategoryId         = types[17].Id;
+        var lineLocationId         = types[18].Id;
 
         long seq = 1329900100001L;
 
@@ -117,6 +120,22 @@ public class S0DictDataSeedData : ISqlSugarEntitySeedData<SysDictData>
             // ── s0_owner_application ──
             D(seq++, ownerApplicationId, "常规产品", "standard",     100, ct),
             D(seq++, ownerApplicationId, "非标产品", "non_standard", 101, ct),
+
+            // ── s0_line_type ──
+            D(seq++, lineTypeId, "自动线",   "automatic",      100, ct),
+            D(seq++, lineTypeId, "半自动线", "semi_automatic", 101, ct),
+            D(seq++, lineTypeId, "手工线",   "manual",         102, ct),
+
+            // ── s0_line_category ──
+            D(seq++, lineCategoryId, "装配线", "assembly",   100, ct),
+            D(seq++, lineCategoryId, "加工线", "machining",  101, ct),
+            D(seq++, lineCategoryId, "检验线", "inspection", 102, ct),
+
+            // ── s0_line_location ──
+            D(seq++, lineLocationId, "5008", "5008", 100, ct),
+            D(seq++, lineLocationId, "5007", "5007", 101, ct),
+            D(seq++, lineLocationId, "8001", "8001", 102, ct),
+            D(seq++, lineLocationId, "1002", "1002", 103, ct),
         };
     }
 

+ 3 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/S0DictTypeSeedData.cs

@@ -27,6 +27,9 @@ public class S0DictTypeSeedData : ISqlSugarEntitySeedData<SysDictType>
             new SysDictType { Id = 1329900001014L, Name = "S0-订单类型",     Code = "s0_order_type",         SysFlag = YesNoEnum.N, OrderNo = 513, Remark = "S0 订单优先级规则 - 订单类型过滤条件",            Status = StatusEnum.Enable, CreateTime = ct },
             new SysDictType { Id = 1329900001015L, Name = "S0-到期状态",     Code = "s0_due_status",         SysFlag = YesNoEnum.N, OrderNo = 514, Remark = "S0 订单优先级规则 - 到期状态过滤条件",            Status = StatusEnum.Enable, CreateTime = ct },
             new SysDictType { Id = 1329900001016L, Name = "S0-物料属性",     Code = "s0_owner_application",  SysFlag = YesNoEnum.N, OrderNo = 515, Remark = "S0 物料属性(常规/非标)",                       Status = StatusEnum.Enable, CreateTime = ct },
+            new SysDictType { Id = 1329900001017L, Name = "S0-产线类型",     Code = "s0_line_type",          SysFlag = YesNoEnum.N, OrderNo = 516, Remark = "S0 生产线类型(自动/半自动/手工)",              Status = StatusEnum.Enable, CreateTime = ct },
+            new SysDictType { Id = 1329900001018L, Name = "S0-产线类别",     Code = "s0_line_category",      SysFlag = YesNoEnum.N, OrderNo = 517, Remark = "S0 生产线类别(装配/加工/检验)",                Status = StatusEnum.Enable, CreateTime = ct },
+            new SysDictType { Id = 1329900001019L, Name = "S0-主库位",       Code = "s0_line_location",      SysFlag = YesNoEnum.N, OrderNo = 518, Remark = "S0 生产线主库位编码",                            Status = StatusEnum.Enable, CreateTime = ct },
         };
     }
 }

+ 1 - 1
server/Plugins/Admin.NET.Plugin.AiDOP/SeedData/SysMenuSeedData.cs

@@ -659,7 +659,7 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
         {
             (1, "/aidop/s0/manufacturing/standard-bom", "aidopS0MfgStandardBom", "标准 BOM", "/aidop/s0/manufacturing/StandardBomManagement", 10),
             (2, "/aidop/s0/manufacturing/standard-operation", "aidopS0MfgStandardOperation", "标准工序", "/aidop/s0/manufacturing/StandardProcessList", 20),
-            (3, "/aidop/s0/manufacturing/production-line", "aidopS0MfgProductionLine", "产线", "/aidop/s0/manufacturing/ProductionLineList", 30),
+            (3, "/aidop/s0/manufacturing/production-line", "aidopS0MfgProductionLine", "产线编码清单", "/aidop/s0/manufacturing/ProductionLineList", 30),
             (4, "/aidop/s0/manufacturing/routing", "aidopS0MfgRouting", "工艺路线", "/aidop/s0/manufacturing/RoutingList", 40),
             (5, "/aidop/s0/manufacturing/material-substitution", "aidopS0MfgMaterialSubstitution", "物料替代", "/aidop/s0/manufacturing/MaterialSubstitutionList", 50),
             (6, "/aidop/s0/manufacturing/work-order-control", "aidopS0MfgWorkOrderControl", "工单控制参数", "/aidop/s0/manufacturing/WorkOrderControlParams", 60),