Bladeren bron

fix(s0): support customer and order type in priority code

YY968XX 1 dag geleden
bovenliggende
commit
c3dc799ea8

+ 1 - 1
Web/package.json

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

+ 4 - 0
Web/src/views/aidop/s0/api/s0SalesApi.ts

@@ -228,6 +228,8 @@ export interface S0PriorityCodeRow {
 	sourceId?: string | null;
 	valueType?: string | null;
 	valueId?: string | null;
+	customerTypeCode?: string | null;
+	orderTypeCode?: string | null;
 	isActive: boolean;
 	createUser?: string | null;
 	createTime?: string;
@@ -247,6 +249,8 @@ export interface S0PriorityCodeUpsert {
 	sourceId?: string;
 	valueType?: string;
 	valueId?: string;
+	customerTypeCode?: string;
+	orderTypeCode?: string;
 	isActive: boolean;
 	createUser?: string;
 	updateUser?: string;

+ 117 - 12
Web/src/views/aidop/s0/sales/OrderPriorityRuleList.vue

@@ -15,36 +15,43 @@
 				<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>
 
 		<!-- ── 主列表 ── -->
 		<el-table :data="rows" v-loading="loading" border stripe style="width: 100%" max-height="calc(100vh - 260px)">
-			<el-table-column prop="descr" label="名称" min-width="150" show-overflow-tooltip>
+			<el-table-column prop="descr" label="名称" width="200" class-name="wrap-cell">
 				<template #default="{ row }">{{ row.descr || '—' }}</template>
 			</el-table-column>
-			<el-table-column prop="value" label="工单字段" width="130" show-overflow-tooltip>
+			<el-table-column label="客户类型" width="140" class-name="wrap-cell">
+				<template #default="{ row }">{{ customerTypeLabel(row.customerTypeCode) }}</template>
+			</el-table-column>
+			<el-table-column label="订单类型" width="140" class-name="wrap-cell">
+				<template #default="{ row }">{{ orderTypeLabel(row.orderTypeCode) }}</template>
+			</el-table-column>
+			<el-table-column prop="value" label="工单字段" width="130" class-name="wrap-cell">
 				<template #default="{ row }">{{ row.value || '—' }}</template>
 			</el-table-column>
-			<el-table-column prop="priority" label="优先级" width="80" align="center" />
-			<el-table-column prop="sourceTable" label="来源表" width="140" show-overflow-tooltip>
+			<el-table-column prop="priority" label="优先级" width="90" align="center" />
+			<el-table-column prop="sourceTable" label="来源表" width="160" class-name="wrap-cell">
 				<template #default="{ row }">{{ row.sourceTable || '—' }}</template>
 			</el-table-column>
-			<el-table-column prop="sourceColumn" label="来源字段" width="130" show-overflow-tooltip>
+			<el-table-column prop="sourceColumn" label="来源字段" width="150" class-name="wrap-cell">
 				<template #default="{ row }">{{ row.sourceColumn || '—' }}</template>
 			</el-table-column>
-			<el-table-column label="排序" width="80" align="center">
+			<el-table-column label="排序" width="90" align="center">
 				<template #default="{ row }">{{ orderByDisplay(row) }}</template>
 			</el-table-column>
-			<el-table-column label="是否生效" width="88" align="center">
+			<el-table-column label="是否生效" width="100" align="center">
 				<template #default="{ row }">
 					<el-tag :type="row.isActive ? 'success' : 'info'" size="small">{{ row.isActive ? '是' : '否' }}</el-tag>
 				</template>
 			</el-table-column>
-			<el-table-column prop="domainCode" label="工厂域" width="100" show-overflow-tooltip>
+			<el-table-column prop="domainCode" label="工厂域" width="100" class-name="wrap-cell">
 				<template #default="{ row }">{{ row.domainCode || '—' }}</template>
 			</el-table-column>
-			<el-table-column label="操作" width="200" fixed="right" align="center">
+			<el-table-column label="操作" width="180" fixed="right" align="center">
 				<template #default="{ row }">
 					<el-button link type="primary" @click="openEdit(row)">编辑</el-button>
 					<el-button link :type="row.isActive ? 'warning' : 'success'" @click="toggleActive(row)">
@@ -87,6 +94,30 @@
 							<el-input v-model="form.value" placeholder="工单表字段(Value)" />
 						</el-form-item>
 					</el-col>
+					<el-col :span="12">
+						<el-form-item label="客户类型">
+							<el-select v-model="form.customerTypeCode" clearable placeholder="不限" style="width: 100%">
+								<el-option
+									v-for="opt in dictOptions.customerType"
+									:key="opt.value"
+									:label="opt.label"
+									:value="String(opt.value)"
+								/>
+							</el-select>
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="订单类型">
+							<el-select v-model="form.orderTypeCode" clearable placeholder="不限" style="width: 100%">
+								<el-option
+									v-for="opt in dictOptions.orderType"
+									:key="opt.value"
+									:label="opt.label"
+									:value="String(opt.value)"
+								/>
+							</el-select>
+						</el-form-item>
+					</el-col>
 					<el-col :span="12">
 						<el-form-item label="优先级" prop="priority">
 							<el-input-number v-model="form.priority" :min="0" style="width: 100%" controls-position="right" />
@@ -147,6 +178,24 @@
 				<el-button type="primary" :loading="saving" @click="submitForm">保存</el-button>
 			</template>
 		</el-dialog>
+
+		<!-- ── 配置维护弹窗(仅客户类型 / 订单类型)── -->
+		<el-dialog v-model="configDialogVisible" title="订单优先级配置维护" width="820px" destroy-on-close>
+			<el-tabs v-model="configActiveTab">
+				<el-tab-pane label="客户类型" name="customerType">
+					<DictDataMaintainPanel
+						dict-code="s0_order_priority_customer_type"
+						@changed="loadDictSelects"
+					/>
+				</el-tab-pane>
+				<el-tab-pane label="订单类型" name="orderType">
+					<DictDataMaintainPanel
+						dict-code="s0_order_type"
+						@changed="loadDictSelects"
+					/>
+				</el-tab-pane>
+			</el-tabs>
+		</el-dialog>
 	</AidopDemoShell>
 </template>
 
@@ -159,7 +208,10 @@ import {
 	s0OrderPriorityRulesApi,
 	type S0PriorityCodeRow,
 	type S0PriorityCodeUpsert,
+	loadDictOptions,
+	type OptionItem,
 } from '../api/s0SalesApi';
+import DictDataMaintainPanel from './components/DictDataMaintainPanel.vue';
 
 const route = useRoute();
 const pageTitle = computed(() => (route.meta?.title as string) || '订单优先级配置');
@@ -206,6 +258,38 @@ function resetQuery() {
 	void loadList();
 }
 
+// ── 字典选项(客户类型 / 订单类型)─────────────────────────────────────────
+const dictOptions = reactive({
+	customerType: [] as OptionItem[],
+	orderType: [] as OptionItem[],
+});
+
+const customerTypeMap = computed(
+	() => new Map(dictOptions.customerType.map((o) => [String(o.value), o.label])),
+);
+const orderTypeMap = computed(
+	() => new Map(dictOptions.orderType.map((o) => [String(o.value), o.label])),
+);
+
+/** code → label;空值显示 —;字典缺 label 时回退显示 code,不编造文案。 */
+function customerTypeLabel(code?: string | null): string {
+	if (!code) return '—';
+	return customerTypeMap.value.get(code) ?? code;
+}
+function orderTypeLabel(code?: string | null): string {
+	if (!code) return '—';
+	return orderTypeMap.value.get(code) ?? code;
+}
+
+async function loadDictSelects() {
+	const [ct, ot] = await Promise.all([
+		loadDictOptions('s0_order_priority_customer_type'),
+		loadDictOptions('s0_order_type'),
+	]);
+	dictOptions.customerType = ct;
+	dictOptions.orderType = ot;
+}
+
 // ── 配置表单 ──────────────────────────────────────────────────────────────
 const formDialogVisible = ref(false);
 const formDialogTitle = ref('新增配置');
@@ -216,6 +300,8 @@ const formRef = ref<FormInstance>();
 interface PriorityCodeForm {
 	descr: string;
 	value: string;
+	customerTypeCode: string;
+	orderTypeCode: string;
 	priority: number;
 	orderBy: boolean | null;
 	sourceTable: string;
@@ -232,6 +318,8 @@ function emptyForm(): PriorityCodeForm {
 	return {
 		descr: '',
 		value: '',
+		customerTypeCode: '',
+		orderTypeCode: '',
 		priority: 1,
 		orderBy: null,
 		sourceTable: '',
@@ -271,6 +359,8 @@ function openEdit(row: S0PriorityCodeRow) {
 	Object.assign(form, {
 		descr: row.descr ?? '',
 		value: row.value ?? '',
+		customerTypeCode: row.customerTypeCode ?? '',
+		orderTypeCode: row.orderTypeCode ?? '',
 		priority: row.priority,
 		orderBy: row.orderBy ?? null,
 		sourceTable: row.sourceTable ?? '',
@@ -285,8 +375,10 @@ function openEdit(row: S0PriorityCodeRow) {
 	formDialogVisible.value = true;
 }
 
-/** 空字符串归一为 undefined,避免把空值写库。 */
-function blankToUndefined(v: string): string | undefined {
+/** 空串 / undefined / null 统一归一为 undefined,避免把空值写库;
+ *  el-select 清空后 v-model 变为 undefined,必须容忍。 */
+function blankToUndefined(v: string | null | undefined): string | undefined {
+	if (v === null || v === undefined) return undefined;
 	return v.trim() === '' ? undefined : v;
 }
 
@@ -297,6 +389,8 @@ async function submitForm() {
 		const payload: S0PriorityCodeUpsert = {
 			descr: form.descr,
 			value: blankToUndefined(form.value),
+			customerTypeCode: blankToUndefined(form.customerTypeCode),
+			orderTypeCode: blankToUndefined(form.orderTypeCode),
 			priority: form.priority,
 			orderBy: form.orderBy,
 			sourceTable: blankToUndefined(form.sourceTable),
@@ -346,8 +440,12 @@ function toggleActive(row: S0PriorityCodeRow) {
 		.catch(() => {});
 }
 
+// ── 配置维护弹窗 ──────────────────────────────────────────────────────────
+const configDialogVisible = ref(false);
+const configActiveTab = ref('customerType');
+
 onMounted(async () => {
-	await loadList();
+	await Promise.all([loadList(), loadDictSelects()]);
 });
 </script>
 
@@ -363,4 +461,11 @@ onMounted(async () => {
 	display: flex;
 	justify-content: flex-end;
 }
+
+// 长文本列自动换行(替代 tooltip 截断),仅作用于本页表格
+:deep(.wrap-cell .cell) {
+	white-space: normal;
+	word-break: break-word;
+	line-height: 1.4;
+}
 </style>

+ 6 - 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.153</AssemblyVersion>
-    <FileVersion>1.0.153</FileVersion>
-    <Version>1.0.153</Version>
+    <AssemblyVersion>1.0.154</AssemblyVersion>
+    <FileVersion>1.0.154</FileVersion>
+    <Version>1.0.154</Version>
   </PropertyGroup>
 
   <ItemGroup>
@@ -106,6 +106,9 @@
     <None Update="UpdateScripts\1.0.153.sql">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </None>
+    <None Update="UpdateScripts\1.0.154.sql">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </None>
   </ItemGroup>
 
   <ItemGroup>

+ 25 - 0
server/Admin.NET.Web.Entry/UpdateScripts/1.0.154.sql

@@ -0,0 +1,25 @@
+-- S0-PRIORITYCODE-CUSTOMER-ORDER-TYPE-CONFIG-1
+-- 为 PriorityCode 表增加 客户类型/订单类型 两个可空编码列(字典 Value)。
+-- 幂等:用 information_schema 守卫,列已存在则跳过;不更新现有数据、不写默认值、不做破坏性操作。
+
+SET @ddl_customer := (SELECT IF(
+    EXISTS(SELECT 1 FROM information_schema.COLUMNS
+           WHERE TABLE_SCHEMA = DATABASE()
+             AND TABLE_NAME = 'PriorityCode'
+             AND COLUMN_NAME = 'CustomerTypeCode'),
+    'SELECT 1',
+    'ALTER TABLE `PriorityCode` ADD COLUMN `CustomerTypeCode` varchar(50) NULL COMMENT ''客户类型编码(字典 s0_order_priority_customer_type 的 Value)'''));
+PREPARE stmt_customer FROM @ddl_customer;
+EXECUTE stmt_customer;
+DEALLOCATE PREPARE stmt_customer;
+
+SET @ddl_order := (SELECT IF(
+    EXISTS(SELECT 1 FROM information_schema.COLUMNS
+           WHERE TABLE_SCHEMA = DATABASE()
+             AND TABLE_NAME = 'PriorityCode'
+             AND COLUMN_NAME = 'OrderTypeCode'),
+    'SELECT 1',
+    'ALTER TABLE `PriorityCode` ADD COLUMN `OrderTypeCode` varchar(50) NULL COMMENT ''订单类型编码(字典 s0_order_type 的 Value)'''));
+PREPARE stmt_order FROM @ddl_order;
+EXECUTE stmt_order;
+DEALLOCATE PREPARE stmt_order;

+ 4 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/S0/Sales/AdoS0OrderPriorityRulesController.cs

@@ -80,6 +80,8 @@ public class AdoS0OrderPriorityRulesController : ControllerBase
             SourceId = dto.SourceId,
             ValueType = dto.ValueType,
             ValueId = dto.ValueId,
+            CustomerTypeCode = dto.CustomerTypeCode,
+            OrderTypeCode = dto.OrderTypeCode,
             IsActive = dto.IsActive,
             CreateUser = dto.CreateUser,
             LegacyCreateUser = dto.LegacyCreateUser,
@@ -109,6 +111,8 @@ public class AdoS0OrderPriorityRulesController : ControllerBase
         entity.SourceId = dto.SourceId;
         entity.ValueType = dto.ValueType;
         entity.ValueId = dto.ValueId;
+        entity.CustomerTypeCode = dto.CustomerTypeCode;
+        entity.OrderTypeCode = dto.OrderTypeCode;
         entity.IsActive = dto.IsActive;
         entity.UpdateUser = dto.UpdateUser;
         entity.LegacyCreateUser = dto.LegacyCreateUser;

+ 4 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Dto/S0/Sales/AdoS0SalesDtos.cs

@@ -259,6 +259,10 @@ public class AdoS0PriorityCodeUpsertDto
     public string? SourceId { get; set; }
     public string? ValueType { get; set; }
     public string? ValueId { get; set; }
+    /// <summary>客户类型编码(字典 s0_order_priority_customer_type 的 Value),可空</summary>
+    public string? CustomerTypeCode { get; set; }
+    /// <summary>订单类型编码(字典 s0_order_type 的 Value),可空</summary>
+    public string? OrderTypeCode { get; set; }
     public bool IsActive { get; set; } = true;
     public string? CreateUser { get; set; }
     public string? LegacyCreateUser { get; set; }

+ 6 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S0/Sales/AdoS0PriorityCode.cs

@@ -42,6 +42,12 @@ public class AdoS0PriorityCode
     [SugarColumn(ColumnName = "ValueID", ColumnDescription = "工单表关联字段", Length = 255, IsNullable = true)]
     public string? ValueId { get; set; }
 
+    [SugarColumn(ColumnName = "CustomerTypeCode", ColumnDescription = "客户类型编码(字典 s0_order_priority_customer_type 的 Value)", Length = 50, IsNullable = true)]
+    public string? CustomerTypeCode { get; set; }
+
+    [SugarColumn(ColumnName = "OrderTypeCode", ColumnDescription = "订单类型编码(字典 s0_order_type 的 Value)", Length = 50, IsNullable = true)]
+    public string? OrderTypeCode { get; set; }
+
     [SugarColumn(ColumnName = "IsActive", ColumnDescription = "是否生效", ColumnDataType = "boolean")]
     public bool IsActive { get; set; } = true;