Bladeren bron

feat: 对齐PriorityCode并补齐S3工序外协菜单

对齐 PriorityCode 实体到 aidopdev 表结构并同步相关接口与测试,同时修复 S3 供应协同中工序外协订单菜单的启动补插逻辑,避免种子关闭时菜单缺失;前端版本升至 2.4.118、后端版本升至 1.0.85。

Co-authored-by: Cursor <cursoragent@cursor.com>
Pengxy 1 maand geleden
bovenliggende
commit
1b22f9fee8

+ 1 - 1
Web/package.json

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

+ 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.84</AssemblyVersion>
-    <FileVersion>1.0.84</FileVersion>
-    <Version>1.0.84</Version>
+    <AssemblyVersion>1.0.85</AssemblyVersion>
+    <FileVersion>1.0.85</FileVersion>
+    <Version>1.0.85</Version>
   </PropertyGroup>
 
   <ItemGroup>

+ 8 - 9
server/Plugins/Admin.NET.Plugin.AiDOP.Tests/S0/Sales/AdoS0SalesRulesTests.cs

@@ -16,18 +16,17 @@ public class AdoS0SalesRulesTests
         Assert.Equal(expected, AdoS0SalesRules.ForbidStatusFromIsEnabled(isEnabled));
     }
 
-    [Fact]
-    public void PriorityCodeOrderByText_WhenZero_ReturnsDesc()
+    [Theory]
+    [InlineData(false, "倒序")]
+    [InlineData(true, "正序")]
+    public void PriorityCodeOrderByText_WhenBoolValue_ReturnsExpected(bool code, string expected)
     {
-        Assert.Equal("倒序", AdoS0SalesRules.PriorityCodeOrderByText(0));
+        Assert.Equal(expected, AdoS0SalesRules.PriorityCodeOrderByText(code));
     }
 
-    [Theory]
-    [InlineData(1)]
-    [InlineData(-1)]
-    [InlineData(99)]
-    public void PriorityCodeOrderByText_WhenNonZero_ReturnsAsc(int code)
+    [Fact]
+    public void PriorityCodeOrderByText_WhenNull_ReturnsAsc()
     {
-        Assert.Equal("正序", AdoS0SalesRules.PriorityCodeOrderByText(code));
+        Assert.Equal("正序", AdoS0SalesRules.PriorityCodeOrderByText(null));
     }
 }

+ 0 - 1
server/Plugins/Admin.NET.Plugin.AiDOP.Tests/S0/Tenant/S0TenantEntityContractTests.cs

@@ -38,7 +38,6 @@ public class S0TenantEntityContractTests
         yield return [typeof(AdoS0MfgPersonSkillAssignment)];
         yield return [typeof(AdoS0MfgPreprocessElement)];
         yield return [typeof(AdoS0MfgPreprocessElementParam)];
-        yield return [typeof(AdoS0PriorityCode)];
         yield return [typeof(AdoS0ProdLineDetail)];
         yield return [typeof(AdoS0ProductStructureMaster)];
         yield return [typeof(AdoS0ProductStructureOp)];

+ 18 - 32
server/Plugins/Admin.NET.Plugin.AiDOP/Controllers/S0/Sales/AdoS0OrderPriorityRulesController.cs

@@ -26,25 +26,19 @@ public class AdoS0OrderPriorityRulesController : ControllerBase
         (q.Page, q.PageSize) = PagingGuard.Normalize(q.Page, q.PageSize);
 
         var query = _rep.AsQueryable()
-            .WhereIF(q.CompanyRefId.HasValue, x => x.CompanyRefId == q.CompanyRefId.Value)
-            .WhereIF(q.FactoryRefId.HasValue, x => x.FactoryRefId == q.FactoryRefId.Value)
             .WhereIF(!string.IsNullOrWhiteSpace(q.DomainCode), x => x.DomainCode == q.DomainCode)
             .WhereIF(!string.IsNullOrWhiteSpace(q.Descr), x => x.Descr.Contains(q.Descr!))
             .WhereIF(q.Priority.HasValue, x => x.Priority == q.Priority.Value)
+            .WhereIF(q.OrderBy.HasValue, x => x.OrderBy == q.OrderBy.Value)
             .WhereIF(!string.IsNullOrWhiteSpace(q.SourceTable), x => x.SourceTable != null && x.SourceTable.Contains(q.SourceTable!))
             .WhereIF(!string.IsNullOrWhiteSpace(q.SourceColumn), x => x.SourceColumn != null && x.SourceColumn.Contains(q.SourceColumn!))
             .WhereIF(!string.IsNullOrWhiteSpace(q.Value), x => x.Value != null && x.Value.Contains(q.Value!))
-            .WhereIF(!string.IsNullOrWhiteSpace(q.ScopeCustClass), x => x.ScopeCustClass != null && x.ScopeCustClass.Contains(q.ScopeCustClass!))
-            .WhereIF(!string.IsNullOrWhiteSpace(q.ScopeOrderType), x => x.ScopeOrderType != null && x.ScopeOrderType.Contains(q.ScopeOrderType!))
-            .WhereIF(q.ScopeDueDaysMax.HasValue, x => x.ScopeDueDaysMax == q.ScopeDueDaysMax!.Value)
             .WhereIF(q.IsActive.HasValue, x => x.IsActive == q.IsActive.Value)
             .WhereIF(
                 !string.IsNullOrWhiteSpace(q.Keyword),
                 x => x.Descr.Contains(q.Keyword!) ||
                      (x.SourceTable != null && x.SourceTable.Contains(q.Keyword!)) ||
-                     (x.Value != null && x.Value.Contains(q.Keyword!)) ||
-                     (x.ScopeCustClass != null && x.ScopeCustClass.Contains(q.Keyword!)) ||
-                     (x.ScopeOrderType != null && x.ScopeOrderType.Contains(q.Keyword!)));
+                     (x.Value != null && x.Value.Contains(q.Keyword!)));
 
         var total = await query.CountAsync();
         var list = await query
@@ -54,17 +48,17 @@ public class AdoS0OrderPriorityRulesController : ControllerBase
             .ToListAsync();
 
         foreach (var x in list)
-            x.OrderByText = AdoS0SalesRules.PriorityCodeOrderByText(x.OrderByCode);
+            x.OrderByText = AdoS0SalesRules.PriorityCodeOrderByText(x.OrderBy);
 
         return Ok(new { total, page = q.Page, pageSize = q.PageSize, list });
     }
 
-    [HttpGet("{id:long}")]
-    public async Task<IActionResult> GetAsync(long id)
+    [HttpGet("{id}")]
+    public async Task<IActionResult> GetAsync(string id)
     {
         var item = await _rep.GetByIdAsync(id);
         if (item == null) return NotFound();
-        item.OrderByText = AdoS0SalesRules.PriorityCodeOrderByText(item.OrderByCode);
+        item.OrderByText = AdoS0SalesRules.PriorityCodeOrderByText(item.OrderBy);
         return Ok(item);
     }
 
@@ -74,24 +68,20 @@ public class AdoS0OrderPriorityRulesController : ControllerBase
         var now = DateTime.Now;
         var entity = new AdoS0PriorityCode
         {
-            CompanyRefId = dto.CompanyRefId,
-            FactoryRefId = dto.FactoryRefId,
             DomainCode = dto.DomainCode,
-            Descr = dto.Descr,
+            Descr = dto.Descr ?? string.Empty,
             Value = dto.Value,
             Priority = dto.Priority,
-            OrderByCode = dto.OrderByCode,
+            OrderBy = dto.OrderBy,
             SourceTable = dto.SourceTable,
             SourceColumn = dto.SourceColumn,
             SourceType = dto.SourceType,
             SourceId = dto.SourceId,
             ValueType = dto.ValueType,
             ValueId = dto.ValueId,
-            ScopeCustClass = dto.ScopeCustClass,
-            ScopeOrderType = dto.ScopeOrderType,
-            ScopeDueDaysMax = dto.ScopeDueDaysMax,
             IsActive = dto.IsActive,
             CreateUser = dto.CreateUser,
+            LegacyCreateUser = dto.LegacyCreateUser,
             CreateTime = now,
             UpdateUser = dto.UpdateUser,
             UpdateTime = null
@@ -101,38 +91,34 @@ public class AdoS0OrderPriorityRulesController : ControllerBase
         return Ok(entity);
     }
 
-    [HttpPut("{id:long}")]
-    public async Task<IActionResult> UpdateAsync(long id, [FromBody] AdoS0PriorityCodeUpsertDto dto)
+    [HttpPut("{id}")]
+    public async Task<IActionResult> UpdateAsync(string id, [FromBody] AdoS0PriorityCodeUpsertDto dto)
     {
         var entity = await _rep.GetByIdAsync(id);
         if (entity == null) return NotFound();
 
-        entity.CompanyRefId = dto.CompanyRefId;
-        entity.FactoryRefId = dto.FactoryRefId;
         entity.DomainCode = dto.DomainCode;
-        entity.Descr = dto.Descr;
+        entity.Descr = dto.Descr ?? string.Empty;
         entity.Value = dto.Value;
         entity.Priority = dto.Priority;
-        entity.OrderByCode = dto.OrderByCode;
+        entity.OrderBy = dto.OrderBy;
         entity.SourceTable = dto.SourceTable;
         entity.SourceColumn = dto.SourceColumn;
         entity.SourceType = dto.SourceType;
         entity.SourceId = dto.SourceId;
         entity.ValueType = dto.ValueType;
         entity.ValueId = dto.ValueId;
-        entity.ScopeCustClass = dto.ScopeCustClass;
-        entity.ScopeOrderType = dto.ScopeOrderType;
-        entity.ScopeDueDaysMax = dto.ScopeDueDaysMax;
         entity.IsActive = dto.IsActive;
         entity.UpdateUser = dto.UpdateUser;
+        entity.LegacyCreateUser = dto.LegacyCreateUser;
         entity.UpdateTime = DateTime.Now;
 
         await _rep.AsUpdateable(entity).ExecuteCommandAsync();
         return Ok(entity);
     }
 
-    [HttpPatch("{id:long}/toggle-enabled")]
-    public async Task<IActionResult> ToggleActiveAsync(long id, [FromBody] AdoS0PriorityCodeToggleActiveDto dto)
+    [HttpPatch("{id}/toggle-enabled")]
+    public async Task<IActionResult> ToggleActiveAsync(string id, [FromBody] AdoS0PriorityCodeToggleActiveDto dto)
     {
         var entity = await _rep.GetByIdAsync(id);
         if (entity == null) return NotFound();
@@ -144,8 +130,8 @@ public class AdoS0OrderPriorityRulesController : ControllerBase
         return Ok(entity);
     }
 
-    [HttpDelete("{id:long}")]
-    public async Task<IActionResult> DeleteAsync(long id)
+    [HttpDelete("{id}")]
+    public async Task<IActionResult> DeleteAsync(string id)
     {
         var item = await _rep.GetByIdAsync(id);
         if (item == null) return NotFound();

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

@@ -227,19 +227,15 @@ public class AdoS0PriorityCodeToggleActiveDto
 
 public class AdoS0PriorityCodeQueryDto
 {
-    public long? CompanyRefId { get; set; }
-    public long? FactoryRefId { get; set; }
     public string? DomainCode { get; set; }
     /// <summary>匹配名称、来源表、工单字段 value</summary>
     public string? Keyword { get; set; }
     public string? Descr { get; set; }
     public int? Priority { get; set; }
+    public bool? OrderBy { get; set; }
     public string? SourceTable { get; set; }
     public string? SourceColumn { get; set; }
     public string? Value { get; set; }
-    public string? ScopeCustClass { get; set; }
-    public string? ScopeOrderType { get; set; }
-    public int? ScopeDueDaysMax { get; set; }
     public bool? IsActive { get; set; }
     public int Page { get; set; } = 1;
     public int PageSize { get; set; } = 20;
@@ -247,32 +243,22 @@ public class AdoS0PriorityCodeQueryDto
 
 public class AdoS0PriorityCodeUpsertDto
 {
-    [Range(1, long.MaxValue, ErrorMessage = "公司不能为空")]
-    public long CompanyRefId { get; set; }
-
-    [Range(1, long.MaxValue, ErrorMessage = "工厂不能为空")]
-    public long FactoryRefId { get; set; }
-
     public string? DomainCode { get; set; }
 
-    [Required(ErrorMessage = "名称不能为空")]
-    public string Descr { get; set; } = string.Empty;
+    public string? Descr { get; set; }
 
     public string? Value { get; set; }
     public int Priority { get; set; }
-    /// <summary>0=倒序,非0=正序</summary>
-    public int OrderByCode { get; set; } = 1;
+    public bool? OrderBy { get; set; }
     public string? SourceTable { get; set; }
     public string? SourceColumn { get; set; }
     public string? SourceType { get; set; }
     public string? SourceId { get; set; }
     public string? ValueType { get; set; }
     public string? ValueId { get; set; }
-    public string? ScopeCustClass { get; set; }
-    public string? ScopeOrderType { get; set; }
-    public int? ScopeDueDaysMax { get; set; }
     public bool IsActive { get; set; } = true;
     public string? CreateUser { get; set; }
+    public string? LegacyCreateUser { get; set; }
     public string? UpdateUser { get; set; }
 }
 

+ 19 - 34
server/Plugins/Admin.NET.Plugin.AiDOP/Entity/S0/Sales/AdoS0PriorityCode.cs

@@ -4,70 +4,57 @@ namespace Admin.NET.Plugin.AiDOP.Entity.S0.Sales;
 /// 订单优先级配置(复刻 PriorityCode)
 /// </summary>
 [SugarTable("PriorityCode", "订单优先级配置(复刻 PriorityCode)")]
-public class AdoS0PriorityCode : ITenantIdFilter
+public class AdoS0PriorityCode
 {
-    [SugarColumn(ColumnName = "RecID", ColumnDescription = "主键", IsPrimaryKey = true, IsIdentity = true, ColumnDataType = "bigint")]
-    public long Id { get; set; }
+    [SugarColumn(ColumnName = "RecID", ColumnDescription = "主键", IsPrimaryKey = true, Length = 36)]
+    public string Id { get; set; } = string.Empty;
 
-    [SugarColumn(ColumnName = "company_ref_id", ColumnDescription = "关联公司 ID", ColumnDataType = "bigint")]
-    public long CompanyRefId { get; set; }
-
-    [SugarColumn(ColumnName = "factory_ref_id", ColumnDescription = "关联工厂 ID", ColumnDataType = "bigint")]
-    public long FactoryRefId { get; set; }
-
-    [SugarColumn(ColumnName = "Domain", ColumnDescription = "工厂域编码", Length = 50, IsNullable = true)]
+    [SugarColumn(ColumnName = "Domain", ColumnDescription = "工厂域编码", Length = 255, IsNullable = true)]
     public string? DomainCode { get; set; }
 
-    [SugarColumn(ColumnName = "Descr", ColumnDescription = "名称", Length = 200)]
+    [SugarColumn(ColumnName = "Descr", ColumnDescription = "名称", Length = 255, IsNullable = true)]
     public string Descr { get; set; } = string.Empty;
 
-    [SugarColumn(ColumnName = "Value", ColumnDescription = "工单表字段", Length = 200, IsNullable = true)]
+    [SugarColumn(ColumnName = "Value", ColumnDescription = "工单表字段", Length = 255, IsNullable = true)]
     public string? Value { get; set; }
 
     [SugarColumn(ColumnName = "Priority", ColumnDescription = "优先级")]
     public int Priority { get; set; }
 
-    /// <summary>源系统 OrderBy:0=倒序,非0=正序</summary>
-    [SugarColumn(ColumnName = "order_by_code", ColumnDescription = "排序方式编码")]
-    public int OrderByCode { get; set; } = 1;
+    [SugarColumn(ColumnName = "OrderBy", ColumnDescription = "排序方式", ColumnDataType = "bit(1)", IsNullable = true)]
+    public bool? OrderBy { get; set; }
 
-    [SugarColumn(ColumnName = "SourceTable", ColumnDescription = "来源表", Length = 200, IsNullable = true)]
+    [SugarColumn(ColumnName = "SourceTable", ColumnDescription = "来源表", Length = 255, IsNullable = true)]
     public string? SourceTable { get; set; }
 
-    [SugarColumn(ColumnName = "SourceColumn", ColumnDescription = "来源表字段", Length = 200, IsNullable = true)]
+    [SugarColumn(ColumnName = "SourceColumn", ColumnDescription = "来源表字段", Length = 255, IsNullable = true)]
     public string? SourceColumn { get; set; }
 
-    [SugarColumn(ColumnName = "SourceType", ColumnDescription = "来源表字段类型", Length = 100, IsNullable = true)]
+    [SugarColumn(ColumnName = "SourceType", ColumnDescription = "来源表字段类型", Length = 255, IsNullable = true)]
     public string? SourceType { get; set; }
 
-    [SugarColumn(ColumnName = "SourceID", ColumnDescription = "来源表关联字段", Length = 200, IsNullable = true)]
+    [SugarColumn(ColumnName = "SourceID", ColumnDescription = "来源表关联字段", Length = 255, IsNullable = true)]
     public string? SourceId { get; set; }
 
-    [SugarColumn(ColumnName = "ValueType", ColumnDescription = "工单表字段类型", Length = 100, IsNullable = true)]
+    [SugarColumn(ColumnName = "ValueType", ColumnDescription = "工单表字段类型", Length = 255, IsNullable = true)]
     public string? ValueType { get; set; }
 
-    [SugarColumn(ColumnName = "ValueID", ColumnDescription = "工单表关联字段", Length = 200, IsNullable = true)]
+    [SugarColumn(ColumnName = "ValueID", ColumnDescription = "工单表关联字段", Length = 255, IsNullable = true)]
     public string? ValueId { get; set; }
 
-    [SugarColumn(ColumnName = "ScopeCustClass", ColumnDescription = "业务维度:客户类型/级别", Length = 100, IsNullable = true)]
-    public string? ScopeCustClass { get; set; }
-
-    [SugarColumn(ColumnName = "ScopeOrderType", ColumnDescription = "业务维度:订单类型", Length = 100, IsNullable = true)]
-    public string? ScopeOrderType { get; set; }
-
-    [SugarColumn(ColumnName = "ScopeDueDaysMax", ColumnDescription = "业务维度:承诺交期上限天数", IsNullable = true)]
-    public int? ScopeDueDaysMax { get; set; }
-
     [SugarColumn(ColumnName = "IsActive", ColumnDescription = "是否生效", ColumnDataType = "boolean")]
     public bool IsActive { get; set; } = true;
 
-    [SugarColumn(ColumnName = "CreateUser", ColumnDescription = "创建人", Length = 100, IsNullable = true)]
+    [SugarColumn(ColumnName = "CreateUser", ColumnDescription = "创建人", Length = 24, IsNullable = true)]
     public string? CreateUser { get; set; }
 
+    [SugarColumn(ColumnName = "create_user", ColumnDescription = "创建人(历史列)", Length = 100, IsNullable = true)]
+    public string? LegacyCreateUser { get; set; }
+
     [SugarColumn(ColumnName = "CreateTime", ColumnDescription = "创建时间")]
     public DateTime CreateTime { get; set; } = DateTime.Now;
 
-    [SugarColumn(ColumnName = "UpdateUser", ColumnDescription = "更新人", Length = 100, IsNullable = true)]
+    [SugarColumn(ColumnName = "UpdateUser", ColumnDescription = "更新人", Length = 24, IsNullable = true)]
     public string? UpdateUser { get; set; }
 
     [SugarColumn(ColumnName = "UpdateTime", ColumnDescription = "更新时间", IsNullable = true)]
@@ -77,6 +64,4 @@ public class AdoS0PriorityCode : ITenantIdFilter
     [SugarColumn(IsIgnore = true)]
     public string? OrderByText { get; set; }
 
-    [SugarColumn(ColumnName = "tenant_id", IsNullable = true)]
-    public long? TenantId { get; set; }
 }

+ 3 - 3
server/Plugins/Admin.NET.Plugin.AiDOP/Infrastructure/AdoS0SalesRules.cs

@@ -9,8 +9,8 @@ public static class AdoS0SalesRules
         isEnabled ? "normal" : "forbidden";
 
     /// <summary>
-    /// PriorityCode.OrderBy 源值:0 为倒序,否则为正序(与源平台列表 SQL 一致)
+    /// PriorityCode.OrderBy(bit)源值:false=倒序,true=正序;null 按正序展示
     /// </summary>
-    public static string PriorityCodeOrderByText(int orderByCode) =>
-        orderByCode == 0 ? "倒序" : "正序";
+    public static string PriorityCodeOrderByText(bool? orderBy) =>
+        orderBy == false ? "倒序" : "正序";
 }

+ 5 - 0
server/Plugins/Admin.NET.Plugin.AiDOP/Infrastructure/AidopMenuLinkSync.cs

@@ -607,6 +607,11 @@ public static class AidopMenuLinkSync
             "/aidop/s3/procurement/outsource-order", "aidopS3OutsourceOrder",
             "/aidop/s3/supply/outsourceOrderList", "ele-List", 30, "S3 委外加工订单(PurOrdMaster/PW)");
 
+        EnsureS3LeafMenu(
+            db, ct, 1329003100014L, procurementDirId, "工序外协订单",
+            "/aidop/s3/procurement/process-outsource-order", "aidopS3ProcessOutsourceOrder",
+            "/aidop/s3/supply/processOutsourceOrderList", "ele-List", 40, "S3 工序外协订单(PurOrdMaster/PW)");
+
         EnsureS3DirMenu(
             db, ct, 1329003100010L, s3RootId, "供应协同看板",
             "/aidop/s3/supply-kanban", "aidopS3SupplyKanbanDir",