// Admin.NET 项目的版æƒã€å•†æ ‡ã€ä¸“利和其他相关æƒåˆ©å‡å—ç›¸åº”æ³•å¾‹æ³•è§„çš„ä¿æŠ¤ã€‚ä½¿ç”¨æœ¬é¡¹ç›®åº”éµå®ˆç›¸å…³æ³•律法规和许å¯è¯çš„è¦æ±‚。 // // 本项目主è¦éµå¾ª MIT 许å¯è¯å’Œ Apache 许å¯è¯ï¼ˆç‰ˆæœ¬ 2.0)进行分å‘和使用。许å¯è¯ä½äºŽæºä»£ç æ ‘æ ¹ç›®å½•ä¸çš„ LICENSE-MIT å’Œ LICENSE-APACHE 文件。 // // ä¸å¾—利用本项目从事å±å®³å›½å®¶å®‰å…¨ã€æ‰°ä¹±ç¤¾ä¼šç§©åºã€ä¾µçŠ¯ä»–äººåˆæ³•æƒç›Šç‰æ³•å¾‹æ³•è§„ç¦æ¢çš„æ´»åЍï¼ä»»ä½•基于本项目二次开å‘è€Œäº§ç”Ÿçš„ä¸€åˆ‡æ³•å¾‹çº çº·å’Œè´£ä»»ï¼Œæˆ‘ä»¬ä¸æ‰¿æ‹…ä»»ä½•è´£ä»»ï¼ namespace Admin.NET.Core.Service; /// <summary> /// ç³»ç»Ÿå‚æ•°é…ç½®æœåŠ¡ 🧩 /// </summary> [ApiDescriptionSettings(Order = 440)] public class SysConfigService : IDynamicApiController, ITransient { private readonly SysCacheService _sysCacheService; private readonly SqlSugarRepository<SysConfig> _sysConfigRep; public SysConfigService(SysCacheService sysCacheService, SqlSugarRepository<SysConfig> sysConfigRep) { _sysCacheService = sysCacheService; _sysConfigRep = sysConfigRep; } /// <summary> /// 获å–傿•°é…置分页列表 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("获å–傿•°é…置分页列表")] public async Task<SqlSugarPagedList<SysConfig>> Page(PageConfigInput input) { return await _sysConfigRep.AsQueryable() .Where(u => u.GroupCode != ConfigConst.SysWebConfigGroup) // 䏿˜¾ç¤º WebConfig 分组 .WhereIF(!string.IsNullOrWhiteSpace(input.Name?.Trim()), u => u.Name.Contains(input.Name)) .WhereIF(!string.IsNullOrWhiteSpace(input.Code?.Trim()), u => u.Code.Contains(input.Code)) .WhereIF(!string.IsNullOrWhiteSpace(input.GroupCode?.Trim()), u => u.GroupCode.Equals(input.GroupCode)) .OrderBuilder(input) .ToPagedListAsync(input.Page, input.PageSize); } /// <summary> /// 获å–傿•°é…置列表 🔖 /// </summary> /// <returns></returns> [DisplayName("获å–傿•°é…置列表")] public async Task<List<SysConfig>> List(PageConfigInput input) { return await _sysConfigRep.AsQueryable() .WhereIF(!string.IsNullOrWhiteSpace(input.GroupCode?.Trim()), u => u.GroupCode.Equals(input.GroupCode)) .ToListAsync(); } /// <summary> /// å¢žåŠ å‚æ•°é…ç½® 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [ApiDescriptionSettings(Name = "Add"), HttpPost] [DisplayName("å¢žåŠ å‚æ•°é…ç½®")] public async Task AddConfig(AddConfigInput input) { var isExist = await _sysConfigRep.IsAnyAsync(u => u.Name == input.Name || u.Code == input.Code); if (isExist) throw Oops.Oh(ErrorCodeEnum.D9000); await _sysConfigRep.InsertAsync(input.Adapt<SysConfig>()); } /// <summary> /// æ›´æ–°å‚æ•°é…ç½® 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [ApiDescriptionSettings(Name = "Update"), HttpPost] [DisplayName("æ›´æ–°å‚æ•°é…ç½®")] public async Task UpdateConfig(UpdateConfigInput input) { var isExist = await _sysConfigRep.IsAnyAsync(u => (u.Name == input.Name || u.Code == input.Code) && u.Id != input.Id); if (isExist) throw Oops.Oh(ErrorCodeEnum.D9000); var config = input.Adapt<SysConfig>(); await _sysConfigRep.AsUpdateable(config).IgnoreColumns(true).ExecuteCommandAsync(); _sysCacheService.Remove($"{CacheConst.KeyConfig}{config.Code}"); } /// <summary> /// åˆ é™¤å‚æ•°é…ç½® 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [ApiDescriptionSettings(Name = "Delete"), HttpPost] [DisplayName("åˆ é™¤å‚æ•°é…ç½®")] public async Task DeleteConfig(DeleteConfigInput input) { var config = await _sysConfigRep.GetFirstAsync(u => u.Id == input.Id); if (config.SysFlag == YesNoEnum.Y) // ç¦æ¢åˆ é™¤ç³»ç»Ÿå‚æ•° throw Oops.Oh(ErrorCodeEnum.D9001); await _sysConfigRep.DeleteAsync(config); _sysCacheService.Remove($"{CacheConst.KeyConfig}{config.Code}"); } /// <summary> /// 批é‡åˆ 除傿•°é…ç½® 🔖 /// </summary> /// <param name="ids"></param> /// <returns></returns> [ApiDescriptionSettings(Name = "BatchDelete"), HttpPost] [DisplayName("批é‡åˆ 除傿•°é…ç½®")] public async Task BatchDeleteConfig(List<long> ids) { foreach (var id in ids) { var config = await _sysConfigRep.GetFirstAsync(u => u.Id == id); if (config.SysFlag == YesNoEnum.Y) // ç¦æ¢åˆ é™¤ç³»ç»Ÿå‚æ•° continue; await _sysConfigRep.DeleteAsync(config); _sysCacheService.Remove($"{CacheConst.KeyConfig}{config.Code}"); } } /// <summary> /// 获å–傿•°é…置详情 🔖 /// </summary> /// <param name="input"></param> /// <returns></returns> [DisplayName("获å–傿•°é…置详情")] public async Task<SysConfig> GetDetail([FromQuery] ConfigInput input) { return await _sysConfigRep.GetFirstAsync(u => u.Id == input.Id); } /// <summary> /// 获å–傿•°é…置值 /// </summary> /// <param name="code"></param> /// <returns></returns> [NonAction] public async Task<T> GetConfigValue<T>(string code) { if (string.IsNullOrWhiteSpace(code)) return default; var value = _sysCacheService.Get<string>($"{CacheConst.KeyConfig}{code}"); if (string.IsNullOrEmpty(value)) { var config = await _sysConfigRep.CopyNew().GetFirstAsync(u => u.Code == code); value = config != null ? config.Value : default; _sysCacheService.Set($"{CacheConst.KeyConfig}{code}", value); } if (string.IsNullOrWhiteSpace(value)) return default; return (T)Convert.ChangeType(value, typeof(T)); } /// <summary> /// æ›´æ–°å‚æ•°é…置值 /// </summary> /// <param name="code"></param> /// <param name="value"></param> /// <returns></returns> [NonAction] public async Task UpdateConfigValue(string code, string value) { var config = await _sysConfigRep.GetFirstAsync(u => u.Code == code); if (config == null) return; config.Value = value; await _sysConfigRep.AsUpdateable(config).ExecuteCommandAsync(); _sysCacheService.Remove($"{CacheConst.KeyConfig}{config.Code}"); } /// <summary> /// 获å–分组列表 🔖 /// </summary> /// <returns></returns> [DisplayName("获å–分组列表")] public async Task<List<string>> GetGroupList() { return await _sysConfigRep.AsQueryable() .Where(u => u.GroupCode != ConfigConst.SysWebConfigGroup) // 䏿˜¾ç¤º WebConfig 分组 .GroupBy(u => u.GroupCode) .Select(u => u.GroupCode).ToListAsync(); } /// <summary> /// èŽ·å– Token 过期时间 /// </summary> /// <returns></returns> [NonAction] public async Task<int> GetTokenExpire() { var tokenExpireStr = await GetConfigValue<string>(ConfigConst.SysTokenExpire); _ = int.TryParse(tokenExpireStr, out var tokenExpire); return tokenExpire == 0 ? 20 : tokenExpire; } /// <summary> /// èŽ·å– RefreshToken 过期时间 /// </summary> /// <returns></returns> [NonAction] public async Task<int> GetRefreshTokenExpire() { var refreshTokenExpireStr = await GetConfigValue<string>(ConfigConst.SysRefreshTokenExpire); _ = int.TryParse(refreshTokenExpireStr, out var refreshTokenExpire); return refreshTokenExpire == 0 ? 40 : refreshTokenExpire; } /// <summary> /// æ‰¹é‡æ›´æ–°å‚æ•°é…置值 /// </summary> /// <param name="input"></param> /// <returns></returns> [ApiDescriptionSettings(Name = "BatchUpdate"), HttpPost] [DisplayName("æ‰¹é‡æ›´æ–°å‚æ•°é…置值")] public async Task BatchUpdateConfig(List<BatchConfigInput> input) { foreach (var Config in input) { await _sysConfigRep.AsUpdateable().SetColumns(u => u.Value == Config.Value).Where(u => u.Code == Config.Code).ExecuteCommandAsync(); _sysCacheService.Remove($"{CacheConst.KeyConfig}{Config.Code}"); } } /// <summary> /// 获å–ç³»ç»Ÿä¿¡æ¯ ðŸ”– /// </summary> /// <returns></returns> [SuppressMonitor] [AllowAnonymous] [DisplayName("获å–系统信æ¯")] public async Task<dynamic> GetSysInfo() { var sysLogo = await GetConfigValue<string>(ConfigConst.SysWebLogo); var sysTitle = await GetConfigValue<string>(ConfigConst.SysWebTitle); var sysViceTitle = await GetConfigValue<string>(ConfigConst.SysWebViceTitle); var sysViceDesc = await GetConfigValue<string>(ConfigConst.SysWebViceDesc); var sysWatermark = await GetConfigValue<string>(ConfigConst.SysWebWatermark); var sysCopyright = await GetConfigValue<string>(ConfigConst.SysWebCopyright); var sysIcp = await GetConfigValue<string>(ConfigConst.SysWebIcp); var sysIcpUrl = await GetConfigValue<string>(ConfigConst.SysWebIcpUrl); var sysSecondVer = await GetConfigValue<bool>(ConfigConst.SysSecondVer); var sysCaptcha = await GetConfigValue<bool>(ConfigConst.SysCaptcha); return new { SysLogo = sysLogo, SysTitle = sysTitle, SysViceTitle = sysViceTitle, SysViceDesc = sysViceDesc, SysWatermark = sysWatermark, SysCopyright = sysCopyright, SysIcp = sysIcp, SysIcpUrl = sysIcpUrl, SysSecondVer = sysSecondVer, SysCaptcha = sysCaptcha }; } /// <summary> /// ä¿å˜ç³»ç»Ÿä¿¡æ¯ 🔖 /// </summary> /// <returns></returns> [UnitOfWork] [DisplayName("ä¿å˜ç³»ç»Ÿä¿¡æ¯")] public async Task SaveSysInfo(InfoSaveInput input) { // logo ä¸ä¸ºç©ºæ‰ä¿å˜ if (!string.IsNullOrEmpty(input.SysLogoBase64)) { // æ—§å›¾æ ‡æ–‡ä»¶ç›¸å¯¹è·¯å¾„ var oldSysLogoRelativeFilePath = await GetConfigValue<string>(ConfigConst.SysWebLogo) ?? ""; var oldSysLogoAbsoluteFilePath = Path.Combine(App.WebHostEnvironment.WebRootPath, oldSysLogoRelativeFilePath.TrimStart('/')); var groups = Regex.Match(input.SysLogoBase64, @"data:image/(?<type>.+?);base64,(?<data>.+)").Groups; //var type = groups["type"].Value; var base64Data = groups["data"].Value; var binData = Convert.FromBase64String(base64Data); // æ ¹æ®æ–‡ä»¶åå–æ‰©å±•å var ext = string.IsNullOrWhiteSpace(input.SysLogoFileName) ? ".png" : Path.GetExtension(input.SysLogoFileName); // æœ¬åœ°å›¾æ ‡ä¿å˜è·¯å¾„ var path = "upload"; var absoluteFilePath = Path.Combine(App.WebHostEnvironment.WebRootPath, path, $"logo{ext}"); // åˆ é™¤å·²å˜åœ¨æ–‡ä»¶ if (File.Exists(oldSysLogoAbsoluteFilePath)) File.Delete(oldSysLogoAbsoluteFilePath); // 创建文件夹 var absoluteFileDir = Path.GetDirectoryName(absoluteFilePath); if (!Directory.Exists(absoluteFileDir)) Directory.CreateDirectory(absoluteFileDir); // ä¿å˜å›¾æ ‡æ–‡ä»¶ await File.WriteAllBytesAsync(absoluteFilePath, binData); // ä¿å˜å›¾æ ‡é…ç½® var relativeUrl = $"/{path}/logo{ext}"; await UpdateConfigValue(ConfigConst.SysWebLogo, relativeUrl); } await UpdateConfigValue(ConfigConst.SysWebTitle, input.SysTitle); await UpdateConfigValue(ConfigConst.SysWebViceTitle, input.SysViceTitle); await UpdateConfigValue(ConfigConst.SysWebViceDesc, input.SysViceDesc); await UpdateConfigValue(ConfigConst.SysWebWatermark, input.SysWatermark); await UpdateConfigValue(ConfigConst.SysWebCopyright, input.SysCopyright); await UpdateConfigValue(ConfigConst.SysWebIcp, input.SysIcp); await UpdateConfigValue(ConfigConst.SysWebIcpUrl, input.SysIcpUrl); await UpdateConfigValue(ConfigConst.SysSecondVer, (input.SysSecondVer ?? false).ToString()); await UpdateConfigValue(ConfigConst.SysCaptcha, (input.SysCaptcha ?? true).ToString()); } }