340 lines
12 KiB
C#
340 lines
12 KiB
C#
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;
|
|
|
|
/// <summary>
|
|
/// 应用服务
|
|
/// </summary>
|
|
[Route("App")]
|
|
[ApiExplorerSettings(GroupName = "应用服务")]
|
|
public class AppsService : BaseService
|
|
{
|
|
private readonly IAppRepository _appRepository;
|
|
private readonly IAppScopeRepository _appScopeRepository;
|
|
private readonly IBasicRepository<InterfaceEntity> _interfaceRepository;
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public AppsService(
|
|
IAppRepository appRepository
|
|
, IAppScopeRepository appScopeRepository
|
|
, IBasicRepository<InterfaceEntity> interfaceRepository)
|
|
{
|
|
_appRepository = appRepository;
|
|
_appScopeRepository = appScopeRepository;
|
|
_interfaceRepository = interfaceRepository;
|
|
}
|
|
|
|
#region Get
|
|
|
|
/// <summary>
|
|
/// 应用列表
|
|
/// </summary>
|
|
/// <param name="input">入参</param>
|
|
/// <returns></returns>
|
|
[HttpGet("GetList")]
|
|
public async Task<PagedListDto<AppListOutput>> 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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 应用下拉列表
|
|
/// </summary>
|
|
/// <param name="keyword">应用名称</param>
|
|
/// <returns></returns>
|
|
[HttpGet("GetDropDownList")]
|
|
public async Task<List<AppDropDownItem>> 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
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成Key 和 Secret
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
[HttpGet("GetKeyAndSecret")]
|
|
public async Task<dynamic> 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() };
|
|
}
|
|
|
|
/// <summary>
|
|
/// 详情
|
|
/// </summary>
|
|
/// <param name="id">主键</param>
|
|
/// <returns></returns>
|
|
[HttpGet("GetInfo")]
|
|
public async Task<AppOutput> 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
|
|
|
|
/// <summary>
|
|
/// 创建
|
|
/// </summary>
|
|
/// <param name="input">入参</param>
|
|
/// <returns></returns>
|
|
[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<CreateAppInput, AppEntity>(input);
|
|
var appScopeEntitys = ObjectMapper.Map<List<CreateAppScopeInput>, List<AppScopeEntity>>(input.AppScopeList);
|
|
List<int> 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();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新
|
|
/// </summary>
|
|
/// <param name="input">入参</param>
|
|
/// <returns></returns>
|
|
[HttpPost("Update")]
|
|
public async Task<bool> 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<UpdateAppInput, AppEntity>(input);
|
|
var appScopeEntitys = ObjectMapper.Map<List<CreateAppScopeInput>, List<AppScopeEntity>>(input.AppScopeList);
|
|
List<int> 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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 删除
|
|
/// </summary>
|
|
/// <param name="ids">主键</param>
|
|
/// <returns></returns>
|
|
[HttpDelete("Delete")]
|
|
public async Task<bool> 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;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 更新是否上线
|
|
/// </summary>
|
|
/// <param name="id">主键</param>
|
|
/// <param name="isOnline">是否上线</param>
|
|
/// <returns></returns>
|
|
[HttpPut("UpdateOnline")]
|
|
public async Task<bool> UpdateOnline(int id, bool isOnline)
|
|
{
|
|
return await _appRepository.AsUpdateable().SetColumns(x => x.IsOnline == isOnline).Where(x => x.Id == id)
|
|
.ExecuteCommandHasChangeAsync();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 检查应用接口是否可用
|
|
/// </summary>
|
|
/// <param name="input">入参</param>
|
|
/// <returns></returns>
|
|
/// <exception cref="BusinessException"></exception>
|
|
[HttpPost("CheckApp")]
|
|
public async Task<bool> 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
|
|
|
|
/// <summary>
|
|
/// 生成单个随机数字
|
|
/// </summary>
|
|
private int CreateNum()
|
|
{
|
|
Random random = new Random();
|
|
int num = random.Next(10);
|
|
return num;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成单个大写随机字母
|
|
/// </summary>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 生成单个小写随机字母
|
|
/// </summary>
|
|
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
|
|
} |