|
|
@@ -16,11 +16,42 @@ public class S8RoleConfigService : ITransient
|
|
|
_sysRoleRep = sysRoleRep;
|
|
|
}
|
|
|
|
|
|
- public async Task<List<AdoS8RolePermissionConfig>> ListAsync(long tenantId, long factoryId) =>
|
|
|
- await _rep.AsQueryable()
|
|
|
- .Where(x => x.TenantId == tenantId && x.FactoryId == factoryId)
|
|
|
+ /// <summary>
|
|
|
+ /// S8-STEP6B-CFG-ROLES-CLOSURE-1:改为「平台默认 (0,0) + 当前工厂覆盖」合并读取,
|
|
|
+ /// 与 S8ExceptionTypeService / S8DashboardCellConfigService / S8MonitoringService 的
|
|
|
+ /// S8-CONFIG-GLOBAL-ROW-SEMANTICS-AND-KPI-TARGET-1 范式一致(同 role_code 取工厂覆盖优先的唯一有效行)。
|
|
|
+ ///
|
|
|
+ /// 原实现只精确匹配 (tenantId, factoryId),而 S8RolePermissionSeedData 的 7 个业务角色种在 (0,0)
|
|
|
+ /// 且其类注释自述「tenant_id=0 / factory_id=0 表示全局默认」「作为异常类型配置的责任角色来源」——
|
|
|
+ /// 两者口径相反,导致任何真实租户下本接口恒返回 0 行。
|
|
|
+ /// 实测后果(UAT 租户 838257186181189):异常类型配置页把本接口当作「责任角色 / 升级角色」下拉词表
|
|
|
+ /// (S8ExceptionTypeConfigPage.vue:159),下拉恒为空;而同页 53 条异常类型中已有 48 条带 owner_role_code,
|
|
|
+ /// 即「值显示得出来、编辑时选不到」。
|
|
|
+ /// </summary>
|
|
|
+ public async Task<List<AdoS8RolePermissionConfig>> ListAsync(long tenantId, long factoryId)
|
|
|
+ {
|
|
|
+ var all = await _rep.AsQueryable()
|
|
|
+ .Where(x => (x.TenantId == S8ConfigScope.GlobalTenantId && x.FactoryId == S8ConfigScope.GlobalFactoryId)
|
|
|
+ || (x.TenantId == tenantId && x.FactoryId == factoryId))
|
|
|
.ToListAsync();
|
|
|
|
|
|
+ var globalCodes = all
|
|
|
+ .Where(x => S8ConfigScope.IsGlobal(x.TenantId, x.FactoryId))
|
|
|
+ .Select(x => x.RoleCode)
|
|
|
+ .ToHashSet();
|
|
|
+
|
|
|
+ var effective = all
|
|
|
+ .GroupBy(x => x.RoleCode)
|
|
|
+ .Select(g => g.OrderByDescending(x => x.FactoryId).First())
|
|
|
+ .OrderBy(x => x.RoleCode)
|
|
|
+ .ToList();
|
|
|
+
|
|
|
+ foreach (var row in effective)
|
|
|
+ row.HasGlobalDefault = globalCodes.Contains(row.RoleCode);
|
|
|
+
|
|
|
+ return effective;
|
|
|
+ }
|
|
|
+
|
|
|
// S8-TENANT-FACTORY-P0-CLOSURE-1:归属一律由服务端可信作用域盖章,忽略 body.TenantId / body.FactoryId。
|
|
|
public async Task<AdoS8RolePermissionConfig> CreateAsync(AdoS8RolePermissionConfig body, S8TrustedScope scope)
|
|
|
{
|
|
|
@@ -32,7 +63,10 @@ public class S8RoleConfigService : ITransient
|
|
|
if (exists) throw new S8BizException("角色编码已存在");
|
|
|
body.Id = 0;
|
|
|
body.CreatedAt = DateTime.Now;
|
|
|
- await _rep.InsertAsync(body);
|
|
|
+ // S8-STEP6B-CFG-ROLES-CLOSURE-1:回填自增主键(与 CFG_DATASRC D-3 同源缺陷)。
|
|
|
+ // 原 InsertAsync 只返回 bool,body.Id 保持 0,调用方随后 GET/PUT/DELETE 一律 404。
|
|
|
+ // 采用仓内既有写法(同 S8ExceptionTypeService / S8DataSourceService)。
|
|
|
+ body.Id = await _rep.AsInsertable(body).ExecuteReturnBigIdentityAsync();
|
|
|
return body;
|
|
|
}
|
|
|
|