using System.ComponentModel.DataAnnotations; using System.Text; using Fake.UnitOfWork; using InterfaceForward.Application.Contracts.Dtos.App; using InterfaceForward.Application.Helpers; using InterfaceForward.Application.OSS; using InterfaceForward.Domain.Shared.Dtos; using InterfaceForward.Repositories; using InterfaceForward.Repositories.App.Entitys; using InterfaceForward.Repositories.App.Services; using InterfaceForward.Repositories.Interface.Entitys; using Microsoft.AspNetCore.Mvc; using SqlSugar; using SqlSugar.Extensions; namespace InterfaceForward.Application.Services.App; /// /// 应用服务 /// [Route("App")] [ApiExplorerSettings(GroupName = "应用服务")] public class AppsService : ApplicationService { private readonly IAppRepository _appRepository; private readonly IAppScopeRepository _appScopeRepository; private readonly IBasicRepository _interfaceRepository; /// /// /// public AppsService( IAppRepository appRepository , IAppScopeRepository appScopeRepository , IBasicRepository interfaceRepository) { _appRepository = appRepository; _appScopeRepository = appScopeRepository; _interfaceRepository = interfaceRepository; } #region Get /// /// 应用列表 /// /// 入参 /// [HttpGet("GetList")] public async Task> GetList([FromQuery] PagedQueryInput input) { var res = await _appRepository.AsQueryable() .Select(x => new AppListOutput { Id = x.Id.SelectAll() }) .OrderByDescending(a => a.UpdateTime) .ToPagedListAsync(input.PageIndex, input.PageSize); // var logoKeys = res.Items // .Where(x => !x.LogoKey.IsNullOrWhiteSpace()) // .Select(x => x.LogoKey).ToArray(); // var urlDic = OSSHelper.GetUrlByKeys(logoKeys); // foreach (var url in urlDic) // res.Items.First(x => x.LogoKey == url.Key).LogoUrl = url.Value; return res; } /// /// 应用下拉列表 /// /// 应用名称 /// [HttpGet("GetDropDownList")] public async Task> GetDropDownList(string keyword) { bool flag = keyword.IsNullOrWhiteSpace(); return await _appRepository .GetListAsync(x => flag || x.Name.Contains(keyword), x => new AppDropDownItem { Key = x.Id, Value = x.Name }); } /// /// 生成Key 和 Secret /// /// [HttpGet("GetKeyAndSecret")] public async Task GetKeyAndSecret() { var date = DateTime.Now.ToString("yyMM"); var redisKey = nameof(GetKeyAndSecret) + "_" + date; var num = await RedisHelper.Client.IncrByAsync(redisKey, 1); if (num > 999) throw new BusinessException("超过每月设计的数量"); var key = "W" + date + num.ToString().PadLeft(3, '0'); //创建一个StringBuilder对象存储密码 StringBuilder secret = new StringBuilder(); //使用for循环把单个字符填充进StringBuilder对象里面变成14位密码字符串 for (int i = 0; i < 32; i++) { Random random = new Random(); //随机选择里面其中的一种字符生成 switch (random.Next(3)) { case 0: //调用生成生成随机数字的方法 secret.Append(CreateNum()); break; case 1: //调用生成生成随机小写字母的方法 secret.Append(CreateSmallAbc()); break; case 2: //调用生成生成随机大写字母的方法 secret.Append(CreateBigAbc()); break; } } return new { Key = key, Secret = secret.ToString() }; } /// /// 详情 /// /// 主键 /// [HttpGet("GetInfo")] public async Task GetInfo([Required] int id) { var res = await _appRepository.AsQueryable() .Select(x => new AppOutput { Id = x.Id.SelectAll() }) .SingleAsync(x => x.Id == id); _ = res ?? throw new BusinessException(message: "在指定的编号下找不到数据"); // if (res.LogoKey != null) res.LogoUrl = OSSHelper.GetUrlByKey(res.LogoKey); res.AppScope = await _appScopeRepository.AsQueryable() .Where(x => x.AppId == id) .Select(x => new AppScopeOutput { Id = x.Id.SelectAll() }) .ToListAsync(); return res; } #endregion #region Post /// /// 创建 /// /// 入参 /// [HttpPost("Create")] public async Task Create(CreateAppInput input) { if (await _appRepository.IsAnyAsync(x => x.Name == input.Name)) throw new BusinessException(message: "应用名称已存在"); if (await _appRepository.IsAnyAsync(x => x.AppKey == input.AppKey)) throw new BusinessException(message: "appkey已存在"); input.LogoKey = String.Empty; if (await _appRepository.IsAnyAsync(x => x.AppSecret == input.AppSecret)) throw new BusinessException(message: "appsecret已存在"); var entity = ObjectMapper.Map(input); var appScopeEntitys = ObjectMapper.Map, List>(input.AppScopeList); List interfaceIds = input.AppScopeList.Select(x => x.InterfaceId).ToList(); var interfaceDic = (await _interfaceRepository.GetListAsync(x => interfaceIds.Contains(x.Id), x => new { x.Id, x.Code })) .ToDictionary(x => x.Id, x => x.Code); using (var ts = TransacationHelper.GetReadCommitted()) { var id = await _appRepository.InsertReturnIdentityAsync(entity); appScopeEntitys.ForEach(item => { item.AppId = id; item.InterfaceCode = interfaceDic[item.InterfaceId]; }); await _appScopeRepository.InsertRangeAsync(appScopeEntitys); ts.Complete(); } } /// /// 更新 /// /// 入参 /// [HttpPost("Update")] public async Task Update(UpdateAppInput input) { if (await _appRepository.IsAnyAsync(x => x.Name == input.Name && x.Id != input.Id)) throw new BusinessException(message: "应用名称已存在"); if (await _appRepository.IsAnyAsync(x => x.AppKey == input.AppKey && x.Id != input.Id)) throw new BusinessException(message: "appkey已存在"); if (await _appRepository.IsAnyAsync(x => x.AppSecret == input.AppSecret && x.Id != input.Id)) throw new BusinessException(message: "appsecret已存在"); var entity = ObjectMapper.Map(input); var appScopeEntitys = ObjectMapper.Map, List>(input.AppScopeList); List interfaceIds = input.AppScopeList.Select(x => x.InterfaceId).ToList(); var interfaceDic = (await _interfaceRepository.GetListAsync(x => interfaceIds.Contains(x.Id), x => new { x.Id, x.Code })) .ToDictionary(x => x.Id, x => x.Code); using (var ts = TransacationHelper.GetReadCommitted()) { await _appRepository.AsUpdateable(entity).IgnoreColumns(x => x.IsOnline) .IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandHasChangeAsync(); appScopeEntitys.ForEach(item => { item.AppId = input.Id; item.InterfaceCode = interfaceDic[item.InterfaceId]; }); await _appScopeRepository.AsUpdateable().SetColumns(x => x.IsDeleted == true) .Where(x => x.AppId == input.Id).ExecuteCommandAsync(); await _appScopeRepository.InsertRangeAsync(appScopeEntitys); ts.Complete(); return true; } } /// /// 删除 /// /// 主键 /// [HttpDelete("Delete")] public async Task Delete([FromBody] int[] ids) { using (var ts = TransacationHelper.GetReadCommitted()) { await _appRepository.AsUpdateable().SetColumns(x => x.IsDeleted == true).Where(x => ids.Contains(x.Id)) .ExecuteCommandAsync(); await _appScopeRepository.AsUpdateable().SetColumns(x => x.IsDeleted == true) .Where(x => ids.Contains(x.AppId)).ExecuteCommandAsync(); ts.Complete(); return true; } } /// /// 更新是否上线 /// /// 主键 /// 是否上线 /// [HttpPut("UpdateOnline")] public async Task UpdateOnline(int id, bool isOnline) { return await _appRepository.AsUpdateable().SetColumns(x => x.IsOnline == isOnline).Where(x => x.Id == id) .ExecuteCommandHasChangeAsync(); } /// /// 检查应用接口是否可用 /// /// 入参 /// /// [HttpPost("CheckApp")] public async Task CheckApp(CheckAppInput input) { var appEntity = await _appRepository.GetFirstAsync(x => x.AppKey == input.AppKey && x.AppSecret == input.AppSecret && x.IsOnline == true); if (appEntity is null) throw new BusinessException(message: "在指定的编号下找不到数据"); var appScopeEntity = await _appScopeRepository.GetAppScopeAsync(appEntity.Id, input.InterfaceCode); if (appScopeEntity is null) throw new BusinessException(message: "应用不可访问该接口"); string redisKey = input.AppKey + input.InterfaceCode; if (await RedisHelper.Client.ExistsAsync(redisKey)) { int num = (await RedisHelper.Client.GetAsync(redisKey)).ObjToInt(); if (num < appScopeEntity.QPS) await RedisHelper.Client.IncrByAsync(redisKey, 1); else throw new BusinessException(message: "超过流量限制"); } else await RedisHelper.Client.SetAsync(redisKey, 1, 1); return true; } #endregion #region Private /// /// 生成单个随机数字 /// private int CreateNum() { Random random = new Random(); int num = random.Next(10); return num; } /// /// 生成单个大写随机字母 /// private string CreateBigAbc() { //A-Z的 ASCII值为65-90 Random random = new Random(); int num = random.Next(65, 91); string abc = Convert.ToChar(num).ToString(); return abc; } /// /// 生成单个小写随机字母 /// private string CreateSmallAbc() { //a-z的 ASCII值为97-122 Random random = new Random(); int num = random.Next(97, 123); string abc = Convert.ToChar(num).ToString(); return abc; } #endregion }