using System.ComponentModel.DataAnnotations;
using System.Text;
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 : BaseService
{
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 = "BSI" + 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已存在");
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.UpdateAsync(x => new AppScopeEntity { IsDeleted = true },
x => x.AppId == input.Id);
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
}