Commit 90f9cc2155cca1e6f48d02e051c100fe6b6f37ac
1 parent
30543ac5
泰鄂版登陆优化;泰鄂版菜单优化
Showing
3 changed files
with
139 additions
and
1 deletions
泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/scripts/seed_host_platform_menus.sql
0 → 100644
| 1 | +-- 泰额版平台级菜单:清空 antis-foodlabeling-host.menu 后按前端路由表重录 | ||
| 2 | +-- 使用稳定 Id(f001*),保证 rolemenu 等引用不失效 | ||
| 3 | +-- MenuSource=0(Ruoyi),平台目录 MenuType=0,页面 MenuType=1 | ||
| 4 | + | ||
| 5 | +SET NAMES utf8mb4; | ||
| 6 | +START TRANSACTION; | ||
| 7 | + | ||
| 8 | +DELETE FROM menu; | ||
| 9 | + | ||
| 10 | +INSERT INTO menu ( | ||
| 11 | + Id, IsDeleted, CreationTime, CreatorId, LastModifierId, LastModificationTime, | ||
| 12 | + OrderNum, State, MenuName, RouterName, MenuType, PermissionCode, ParentId, | ||
| 13 | + MenuIcon, Router, IsLink, IsCache, IsShow, Remark, Component, MenuSource, Query, ConcurrencyStamp | ||
| 14 | +) VALUES | ||
| 15 | +-- 首页概览 | ||
| 16 | +('f0010001-0001-4000-8000-000000000001', 0, NOW(), NULL, NULL, NULL, | ||
| 17 | + -1, 1, '首页概览', 'FoodLabelingDashboard', 1, 'menu.dashboard.analytics', '0', | ||
| 18 | + 'lucide:layout-dashboard', '/analytics', 0, 0, 1, NULL, '/food-labeling/dashboard/index', 0, NULL, ''), | ||
| 19 | + | ||
| 20 | +-- 平台管理 | ||
| 21 | +('f0010002-0001-4000-8000-000000000002', 0, NOW(), NULL, NULL, NULL, | ||
| 22 | + 5, 1, '平台管理', 'FoodLabelingPlatform', 0, 'menu.platform', '0', | ||
| 23 | + 'lucide:cloud-cog', '/platform', 0, 0, 1, NULL, NULL, 0, NULL, ''), | ||
| 24 | +('f0010003-0001-4000-8000-000000000003', 0, NOW(), NULL, NULL, NULL, | ||
| 25 | + 6, 1, 'SAAS 公司', 'FoodLabelingPlatformTenants', 1, 'menu.platform.tenants', 'f0010002-0001-4000-8000-000000000002', | ||
| 26 | + 'lucide:building', '/platform/tenants', 0, 0, 1, NULL, '/food-labeling/platform/tenants/index', 0, NULL, ''), | ||
| 27 | + | ||
| 28 | +-- 标签管理 | ||
| 29 | +('f0010010-0001-4000-8000-000000000010', 0, NOW(), NULL, NULL, NULL, | ||
| 30 | + 10, 1, '标签管理', 'FoodLabelingLabeling', 0, 'menu.labeling', '0', | ||
| 31 | + 'lucide:tags', '/labeling', 0, 0, 1, NULL, NULL, 0, NULL, ''), | ||
| 32 | +('f0010011-0001-4000-8000-000000000011', 0, NOW(), NULL, NULL, NULL, | ||
| 33 | + 11, 1, '标签', 'FoodLabelingLabels', 1, 'menu.labeling.labels', 'f0010010-0001-4000-8000-000000000010', | ||
| 34 | + 'lucide:tag', '/labels', 0, 0, 1, NULL, '/food-labeling/labeling/labels/index', 0, NULL, ''), | ||
| 35 | +('f0010012-0001-4000-8000-000000000012', 0, NOW(), NULL, NULL, NULL, | ||
| 36 | + 12, 1, '标签分类', 'FoodLabelingLabelCategories', 1, 'menu.labeling.categories', 'f0010010-0001-4000-8000-000000000010', | ||
| 37 | + 'lucide:folder-tree', '/label-categories', 0, 0, 1, NULL, '/food-labeling/labeling/label-categories/index', 0, NULL, ''), | ||
| 38 | +('f0010013-0001-4000-8000-000000000013', 0, NOW(), NULL, NULL, NULL, | ||
| 39 | + 13, 1, '标签类型', 'FoodLabelingLabelTypes', 1, 'menu.labeling.types', 'f0010010-0001-4000-8000-000000000010', | ||
| 40 | + 'lucide:layers', '/label-types', 0, 0, 1, NULL, '/food-labeling/labeling/label-types/index', 0, NULL, ''), | ||
| 41 | +('f0010014-0001-4000-8000-000000000014', 0, NOW(), NULL, NULL, NULL, | ||
| 42 | + 14, 1, '标签模板', 'FoodLabelingLabelTemplates', 1, 'menu.labeling.templates', 'f0010010-0001-4000-8000-000000000010', | ||
| 43 | + 'lucide:layout-template', '/label-templates', 0, 0, 1, NULL, '/food-labeling/labeling/label-templates/index', 0, NULL, ''), | ||
| 44 | +('f0010015-0001-4000-8000-000000000015', 0, NOW(), NULL, NULL, NULL, | ||
| 45 | + 15, 1, '多选选项集', 'FoodLabelingMultipleOptions', 1, 'menu.labeling.multiple-options', 'f0010010-0001-4000-8000-000000000010', | ||
| 46 | + 'lucide:list-checks', '/multiple-options', 0, 0, 1, NULL, '/food-labeling/labeling/multiple-options/index', 0, NULL, ''), | ||
| 47 | + | ||
| 48 | +-- 业务模块 | ||
| 49 | +('f0010020-0001-4000-8000-000000000020', 0, NOW(), NULL, NULL, NULL, | ||
| 50 | + 15, 1, '业务模块', 'FoodLabelingModules', 0, 'menu.modules', '0', | ||
| 51 | + 'lucide:boxes', '/modules', 0, 0, 1, NULL, NULL, 0, NULL, ''), | ||
| 52 | +('f0010021-0001-4000-8000-000000000021', 0, NOW(), NULL, NULL, NULL, | ||
| 53 | + 16, 1, '培训', 'FoodLabelingTraining', 1, 'menu.modules.training', 'f0010020-0001-4000-8000-000000000020', | ||
| 54 | + 'lucide:graduation-cap', '/training', 0, 0, 1, NULL, '/food-labeling/modules/training/index', 0, NULL, ''), | ||
| 55 | +('f0010022-0001-4000-8000-000000000022', 0, NOW(), NULL, NULL, NULL, | ||
| 56 | + 17, 1, '告警', 'FoodLabelingAlerts', 1, 'menu.modules.alerts', 'f0010020-0001-4000-8000-000000000020', | ||
| 57 | + 'lucide:bell', '/alerts', 0, 0, 1, NULL, '/food-labeling/modules/alerts/index', 0, NULL, ''), | ||
| 58 | +('f0010023-0001-4000-8000-000000000023', 0, NOW(), NULL, NULL, NULL, | ||
| 59 | + 18, 1, '任务', 'FoodLabelingTasks', 1, 'menu.modules.tasks', 'f0010020-0001-4000-8000-000000000020', | ||
| 60 | + 'lucide:list-todo', '/tasks', 0, 0, 1, NULL, '/food-labeling/modules/tasks/index', 0, NULL, ''), | ||
| 61 | +('f0010024-0001-4000-8000-000000000024', 0, NOW(), NULL, NULL, NULL, | ||
| 62 | + 19, 1, '传感器', 'FoodLabelingSensors', 1, 'menu.modules.sensors', 'f0010020-0001-4000-8000-000000000020', | ||
| 63 | + 'lucide:activity', '/sensors', 0, 0, 1, NULL, '/food-labeling/modules/sensors/index', 0, NULL, ''), | ||
| 64 | +('f0010025-0001-4000-8000-000000000025', 0, NOW(), NULL, NULL, NULL, | ||
| 65 | + 20, 1, '食物浪费', 'FoodLabelingFoodWaste', 1, 'menu.modules.food-waste', 'f0010020-0001-4000-8000-000000000020', | ||
| 66 | + 'lucide:apple', '/food-waste', 0, 0, 1, NULL, '/food-labeling/modules/food-waste/index', 0, NULL, ''), | ||
| 67 | +('f0010026-0001-4000-8000-000000000026', 0, NOW(), NULL, NULL, NULL, | ||
| 68 | + 21, 1, '电子标签', 'FoodLabelingELabelModule', 1, 'menu.modules.e-label', 'f0010020-0001-4000-8000-000000000020', | ||
| 69 | + 'lucide:file-digit', '/e-label-module', 0, 0, 1, NULL, '/food-labeling/modules/e-label/index', 0, NULL, ''), | ||
| 70 | + | ||
| 71 | +-- 管理 | ||
| 72 | +('f0010030-0001-4000-8000-000000000030', 0, NOW(), NULL, NULL, NULL, | ||
| 73 | + 20, 1, '管理', 'FoodLabelingManagement', 0, 'menu.management', '0', | ||
| 74 | + 'lucide:building-2', '/management', 0, 0, 1, NULL, NULL, 0, NULL, ''), | ||
| 75 | +('f0010031-0001-4000-8000-000000000031', 0, NOW(), NULL, NULL, NULL, | ||
| 76 | + 21, 1, '账户管理', 'FoodLabelingAccountManagement', 1, 'menu.management.account', 'f0010030-0001-4000-8000-000000000030', | ||
| 77 | + 'lucide:users', '/account-management', 0, 0, 1, NULL, '/food-labeling/management/account-management/index', 0, NULL, ''), | ||
| 78 | +('f0010032-0001-4000-8000-000000000032', 0, NOW(), NULL, NULL, NULL, | ||
| 79 | + 22, 1, '系统菜单', 'FoodLabelingSystemMenu', 1, 'menu.management.system-menu', 'f0010030-0001-4000-8000-000000000030', | ||
| 80 | + 'lucide:menu-square', '/system-menu', 0, 0, 1, NULL, '/food-labeling/management/system-menu/index', 0, NULL, ''), | ||
| 81 | +('f0010033-0001-4000-8000-000000000033', 0, NOW(), NULL, NULL, NULL, | ||
| 82 | + 23, 1, '菜单管理', 'FoodLabelingMenuManagement', 1, 'menu.management.menu', 'f0010030-0001-4000-8000-000000000030', | ||
| 83 | + 'lucide:utensils', '/menu-management', 0, 0, 1, NULL, '/food-labeling/management/menu-management/index', 0, NULL, ''), | ||
| 84 | +('f0010034-0001-4000-8000-000000000034', 0, NOW(), NULL, NULL, NULL, | ||
| 85 | + 24, 1, '设备', 'FoodLabelingDevices', 1, 'menu.management.devices', 'f0010030-0001-4000-8000-000000000030', | ||
| 86 | + 'lucide:smartphone', '/devices', 0, 0, 1, NULL, '/food-labeling/modules/devices/index', 0, NULL, ''), | ||
| 87 | +('f0010035-0001-4000-8000-000000000035', 0, NOW(), NULL, NULL, NULL, | ||
| 88 | + 25, 1, '报表', 'FoodLabelingReports', 1, 'menu.management.reports', 'f0010030-0001-4000-8000-000000000030', | ||
| 89 | + 'lucide:file-bar-chart', '/reports', 0, 0, 1, NULL, '/food-labeling/management/reports/index', 0, NULL, ''), | ||
| 90 | +('f0010036-0001-4000-8000-000000000036', 0, NOW(), NULL, NULL, NULL, | ||
| 91 | + 26, 1, '发票', 'FoodLabelingInvoices', 1, 'menu.management.invoices', 'f0010030-0001-4000-8000-000000000030', | ||
| 92 | + 'lucide:receipt', '/invoices', 0, 0, 1, NULL, '/food-labeling/modules/invoices/index', 0, NULL, ''), | ||
| 93 | +('f0010037-0001-4000-8000-000000000037', 0, NOW(), NULL, NULL, NULL, | ||
| 94 | + 27, 1, '二维码', 'FoodLabelingQrCodes', 1, 'menu.management.qr-codes', 'f0010030-0001-4000-8000-000000000030', | ||
| 95 | + 'lucide:qr-code', '/qr-codes', 0, 0, 1, NULL, '/food-labeling/modules/qr-codes/index', 0, NULL, ''), | ||
| 96 | +('f0010038-0001-4000-8000-000000000038', 0, NOW(), NULL, NULL, NULL, | ||
| 97 | + 28, 1, '支持', 'FoodLabelingSupport', 1, 'menu.management.support', 'f0010030-0001-4000-8000-000000000030', | ||
| 98 | + 'lucide:life-buoy', '/support', 0, 0, 1, NULL, '/food-labeling/management/support/index', 0, NULL, ''), | ||
| 99 | +('f0010039-0001-4000-8000-000000000039', 0, NOW(), NULL, NULL, NULL, | ||
| 100 | + 29, 1, 'API', 'FoodLabelingApi', 1, 'menu.management.api', 'f0010030-0001-4000-8000-000000000030', | ||
| 101 | + 'lucide:code-2', '/api-settings', 0, 0, 1, NULL, '/food-labeling/modules/api/index', 0, NULL, ''); | ||
| 102 | + | ||
| 103 | +COMMIT; |
泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/MultiTenancy/ThWebPlatformLoginHelper.cs
| @@ -14,6 +14,16 @@ public static class ThWebPlatformLoginHelper | @@ -14,6 +14,16 @@ public static class ThWebPlatformLoginHelper | ||
| 14 | /// <summary>平台登录成功时 th-web-auth 返回的 tenantName(无 TenantId Claim)</summary> | 14 | /// <summary>平台登录成功时 th-web-auth 返回的 tenantName(无 TenantId Claim)</summary> |
| 15 | public const string PlatformTenantDisplayName = "Platform"; | 15 | public const string PlatformTenantDisplayName = "Platform"; |
| 16 | 16 | ||
| 17 | + /// <summary>平台账号误选业务租户时的登录拒绝提示</summary> | ||
| 18 | + public const string PlatformAccountMustUseDefaultMessage = | ||
| 19 | + "登录失败:平台管理员账号请选择 Default 选项登录,不能使用业务租户登录"; | ||
| 20 | + | ||
| 21 | + /// <summary> | ||
| 22 | + /// 是否为业务租户登录(选了具体公司,而非 Default / 空 tenantId) | ||
| 23 | + /// </summary> | ||
| 24 | + public static bool IsBusinessTenantLogin(Guid? tenantId, string? tenantName) | ||
| 25 | + => !ShouldTryPlatformLogin(tenantId, tenantName); | ||
| 26 | + | ||
| 17 | /// <summary> | 27 | /// <summary> |
| 18 | /// 是否应优先尝试主库平台登录(与前端选 Default / 空 tenantId 一致) | 28 | /// 是否应优先尝试主库平台登录(与前端选 Default / 空 tenantId 一致) |
| 19 | /// </summary> | 29 | /// </summary> |
泰额版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling/FoodLabeling.Th.Application/Services/ThWebAuthAppService.cs
| @@ -49,7 +49,8 @@ public class ThWebAuthAppService : ApplicationService, IThWebAuthAppService | @@ -49,7 +49,8 @@ public class ThWebAuthAppService : ApplicationService, IThWebAuthAppService | ||
| 49 | /// 校验租户后在租户独立库验证账号,签发含 TenantId 与 RBAC 权限的 JWT。 | 49 | /// 校验租户后在租户独立库验证账号,签发含 TenantId 与 RBAC 权限的 JWT。 |
| 50 | /// | 50 | /// |
| 51 | /// 泰额 H5 与公司 Web 共用此接口。选 **Default** 或 tenantId 为空时,若邮箱账号存在于主库则走**平台登录**(JWT 无 TenantId); | 51 | /// 泰额 H5 与公司 Web 共用此接口。选 **Default** 或 tenantId 为空时,若邮箱账号存在于主库则走**平台登录**(JWT 无 TenantId); |
| 52 | - /// 选具体公司 tenantId 时在该公司业务库校验。Default 业务库(如 US)仅在主库无该邮箱时作为回落。 | 52 | + /// 选具体公司 tenantId 时在该公司业务库校验;若账号已存在于主库(平台管理员),则拒绝登录并提示改用 Default。 |
| 53 | + /// Default 业务库(如 US)仅在主库无该邮箱时作为回落。 | ||
| 53 | /// | 54 | /// |
| 54 | /// 示例请求(平台,选 Default): | 55 | /// 示例请求(平台,选 Default): |
| 55 | /// ```json | 56 | /// ```json |
| @@ -97,6 +98,10 @@ public class ThWebAuthAppService : ApplicationService, IThWebAuthAppService | @@ -97,6 +98,10 @@ public class ThWebAuthAppService : ApplicationService, IThWebAuthAppService | ||
| 97 | input.TenantId = ThWebPlatformLoginHelper.DefaultTenantId; | 98 | input.TenantId = ThWebPlatformLoginHelper.DefaultTenantId; |
| 98 | } | 99 | } |
| 99 | } | 100 | } |
| 101 | + else | ||
| 102 | + { | ||
| 103 | + await EnsureNotHostPlatformAccountAsync(input.UserName); | ||
| 104 | + } | ||
| 100 | 105 | ||
| 101 | TenantConfiguration tenantConfig; | 106 | TenantConfiguration tenantConfig; |
| 102 | try | 107 | try |
| @@ -157,6 +162,26 @@ public class ThWebAuthAppService : ApplicationService, IThWebAuthAppService | @@ -157,6 +162,26 @@ public class ThWebAuthAppService : ApplicationService, IThWebAuthAppService | ||
| 157 | } | 162 | } |
| 158 | 163 | ||
| 159 | /// <summary> | 164 | /// <summary> |
| 165 | + /// 业务租户登录前校验:主库已存在的账号(平台管理员)不得落入公司业务库。 | ||
| 166 | + /// </summary> | ||
| 167 | + private async Task EnsureNotHostPlatformAccountAsync(string userName) | ||
| 168 | + { | ||
| 169 | + if (string.IsNullOrWhiteSpace(userName)) | ||
| 170 | + { | ||
| 171 | + return; | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + using (CurrentTenant.Change(null)) | ||
| 175 | + { | ||
| 176 | + var hostUser = await FindActiveUserByEmailAsync(userName.Trim()); | ||
| 177 | + if (hostUser != null) | ||
| 178 | + { | ||
| 179 | + throw new UserFriendlyException(ThWebPlatformLoginHelper.PlatformAccountMustUseDefaultMessage); | ||
| 180 | + } | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + /// <summary> | ||
| 160 | /// 主库平台登录:CurrentTenant 为空签发无 TenantId 的 JWT,供 Vue3Router/vben5 使用。 | 185 | /// 主库平台登录:CurrentTenant 为空签发无 TenantId 的 JWT,供 Vue3Router/vben5 使用。 |
| 161 | /// 主库无对应邮箱用户时返回 null,由调用方回落 Default/公司租户库登录。 | 186 | /// 主库无对应邮箱用户时返回 null,由调用方回落 Default/公司租户库登录。 |
| 162 | /// </summary> | 187 | /// </summary> |