Files

197 lines
9.8 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Model.Entity.System;
using ORM;
namespace Service.Implement
{
/// <summary>
/// RBAC 数据种子:预定义 4 个系统角色 + 6 个权限 + 默认管理员账号(admin/admin123
/// 幂等:按 Code 查存在性,存在则跳过;可重复执行
/// </summary>
public static class DataSeeder
{
/// <summary>数据范围:1=全部, 2=本实验室</summary>
public const byte DataScopeAll = 1;
public const byte DataScopeLab = 2;
/// <summary>7 个系统权限编码</summary>
public static readonly (string Code, string Name, string Group)[] Permissions =
{
("device:view", "查看设备", "device"),
("device:edit", "编辑设备", "device"),
("device:control", "控制设备", "device"),
("alert:confirm", "确认告警", "alert"),
("inspection:manage", "巡检管理", "inspection"),
("user:manage", "用户管理", "user"),
("system:manage", "系统配置管理", "system")
};
/// <summary>
/// 4 个预定义角色:超级管理员(全部) / 实验室管理员(本实验室) / 设备操作员(本实验室) / 维修工程师(本实验室)
/// 权限矩阵严格按需求文档
/// </summary>
public static readonly (string Code, string Name, byte DataScope, string[] Permissions)[] Roles =
{
("superadmin", "超级管理员", DataScopeAll, new[] { "device:view", "device:edit", "device:control", "alert:confirm", "inspection:manage", "user:manage", "system:manage" }),
("labadmin", "实验室管理员", DataScopeLab, new[] { "device:view", "device:edit", "device:control", "alert:confirm", "inspection:manage", "system:manage" }),
("operator", "设备操作员", DataScopeLab, new[] { "device:view", "inspection:manage" }),
("maintengineer", "维修工程师", DataScopeLab, new[] { "device:view", "device:edit", "device:control", "alert:confirm" })
};
public static void Seed()
{
try
{
var db = SqlSugarContext.DbContext;
var now = DateTime.Now;
// 1. 权限种子
var permIdByCode = new Dictionary<string, long>();
foreach (var (code, name, group) in Permissions)
{
var existing = db.Queryable<PermissionEntity>().Where(x => x.Code == code).First();
if (existing != null) { permIdByCode[code] = existing.Id; continue; }
var perm = new PermissionEntity
{
Code = code, Name = name, Group = group, IsSystem = 1,
Sort = Array.FindIndex(Permissions, p => p.Code == code),
CreateTime = now
};
var id = db.Insertable(perm).ExecuteReturnSnowflakeId();
permIdByCode[code] = id;
}
// 2. 角色种子 + 角色-权限关联
foreach (var (code, name, scope, perms) in Roles)
{
var role = db.Queryable<RoleEntity>().Where(x => x.Code == code).First();
long roleId;
if (role == null)
{
role = new RoleEntity
{
Code = code, Name = name, DataScope = scope, IsSystem = 1,
Sort = Array.FindIndex(Roles, r => r.Code == code),
Remark = "系统预定义角色",
CreateTime = now
};
roleId = db.Insertable(role).ExecuteReturnSnowflakeId();
}
else
{
roleId = role.Id;
}
// 补齐角色-权限关联(只加不删,避免覆盖管理员自定义调整)
foreach (var permCode in perms)
{
if (!permIdByCode.TryGetValue(permCode, out var permId)) continue;
var linkExists = db.Queryable<RolePermissionEntity>()
.Where(x => x.RoleId == roleId && x.PermissionId == permId).Any();
if (!linkExists)
{
db.Insertable(new RolePermissionEntity { RoleId = roleId, PermissionId = permId, CreateTime = now }).ExecuteCommand();
}
}
}
// 3. 默认管理员账号(admin/admin123,挂在超级管理员角色)
var adminExists = db.Queryable<UserEntity>().Where(x => x.UserName == "admin" && x.IsDel == 0).Any();
if (!adminExists)
{
var superAdmin = db.Queryable<RoleEntity>().Where(x => x.Code == "superadmin").First();
var admin = new UserEntity
{
UserName = "admin",
PasswordHash = PasswordHelper.Hash("admin123"),
RealName = "系统管理员",
IsEnabled = 1,
Remark = "系统默认管理员(首次登录后请修改密码)",
CreateTime = now
};
var adminId = db.Insertable(admin).ExecuteReturnSnowflakeId();
if (superAdmin != null)
{
db.Insertable(new UserRoleEntity { UserId = adminId, RoleId = superAdmin.Id, CreateTime = now }).ExecuteCommand();
}
}
// 4. 系统参数种子(一期 4 个内置参数,幂等:按 ParamKey 跳过已存在)
SeedSystemParams(db, now);
// 5. 默认本地文件存储配置(幂等:仅当无任何配置时插入一条默认 Local 通道)
SeedDefaultFileStorage(db, now);
}
catch (Exception)
{
// 种子失败不阻断启动(例如表刚建好并发场景),下次启动会重试
throw;
}
}
private static void SeedDefaultFileStorage(SqlSugar.ISqlSugarClient db, DateTime now)
{
var hasAny = db.Queryable<FileStorageConfigEntity>().Where(x => x.IsDel == 0).Any();
if (hasAny) return;
var entity = new FileStorageConfigEntity
{
Provider = "local",
Name = "本地存储",
Endpoint = "/uploads",
AccessKey = null,
SecretKey = null,
Bucket = null,
Region = null,
BasePath = "wwwroot/uploads",
MaxSizeMB = 10,
AllowedExts = null, // 不限制扩展名;如需限制填 [".jpg",".png",".pdf",".xlsx"]
IsDefault = 1,
Status = 1,
Remark = "系统默认本地存储通道(文件落 wwwroot/uploads,通过 /uploads 静态访问)",
CreateTime = now
};
db.Insertable(entity).ExecuteReturnSnowflakeId();
}
/// <summary>一期 4 个内置系统参数(IsSystem=1,禁止删除,仅允许改 Value/Remark</summary>
/// <remarks>Group 与 ParamType 约定:0=int,1=text,2=enum,3=json</remarks>
private static readonly (string Key, string Name, string? Value, byte Type, string? Options, string? Unit, string Group, int Sort, string? Remark)[] SystemParams =
{
("data_collect_default_frequency", "数据采集默认频率", "5", 0, null, "秒", "数据采集", 1, "设备数据采集的默认间隔(秒),新建设备时作为默认值"),
("alert_notify_method", "告警通知方式", "feishu", 2,
"[{\"value\":\"feishu\",\"label\":\"飞书\"},{\"value\":\"dingtalk\",\"label\":\"钉钉\"},{\"value\":\"wecom\",\"label\":\"企业微信\"},{\"value\":\"email\",\"label\":\"邮件\"}]",
null, "告警", 2, "默认告警通知渠道(多选需在告警规则内单独配置)"),
("work_order_code_rule", "工单编号规则", "WO{yyyyMMddHHmmss}", 1, null, null, "工单", 3,
"工单编号生成模板,支持占位符:{yyyy}年 {MM}月 {dd}日 {HH}时 {mm}分 {ss}秒,序列号用 {seq4} 表示 4 位顺序号"),
("file_upload_limit", "文件上传限制", "10", 2,
"[{\"value\":\"5\",\"label\":\"5MB\"},{\"value\":\"10\",\"label\":\"10MB\"},{\"value\":\"20\",\"label\":\"20MB\"},{\"value\":\"50\",\"label\":\"50MB\"}]",
"MB", "文件", 4, "单个文件上传大小上限(MB)")
};
private static void SeedSystemParams(SqlSugar.ISqlSugarClient db, DateTime now)
{
foreach (var (key, name, value, type, options, unit, group, sort, remark) in SystemParams)
{
var exists = db.Queryable<SystemParamEntity>().Where(x => x.ParamKey == key).Any();
if (exists) continue;
var entity = new SystemParamEntity
{
ParamKey = key,
ParamName = name,
ParamValue = value,
ParamType = type,
ParamOptions = options,
Unit = unit,
Group = group,
Sort = sort,
Remark = remark,
IsSystem = 1,
LastUpdateUser = "system",
LastUpdateTime = now,
CreateTime = now
};
db.Insertable(entity).ExecuteReturnSnowflakeId();
}
}
}
}