This commit is contained in:
Antinew 2024-03-23 09:29:40 +09:00
parent ba53652de6
commit bf8c250e96
5 changed files with 653 additions and 1 deletions

View File

@ -0,0 +1,84 @@
using System.ComponentModel.DataAnnotations;
using Fake;
using Fake.AspNetCore;
using InterfaceForward.Domain.Aggregates.InterfaceAggregate;
using Microsoft.AspNetCore.Mvc;
namespace SJZY.InterfaceRelay.Application.Services.Interface;
/// <summary>
/// 接口返回配置
/// </summary>
[ApiExplorerSettings(GroupName = "接口服务")]
public class InterfaceReturnConfigService : ApplicationService
{
private readonly IInterfaceReturnConfigRepository _interfaceReturnConfigRepository;
private readonly IInterfaceRepository _interfaceRepository;
/// <summary>
///
/// </summary>
public InterfaceReturnConfigService(
IInterfaceReturnConfigRepository interfaceReturnConfigRepository
, IInterfaceRepository interfaceRepository)
{
_interfaceRepository = interfaceRepository;
_interfaceReturnConfigRepository = interfaceReturnConfigRepository;
}
/// <summary>
/// 接口配置列表配置类型传null则全查
/// </summary>
/// <param name="interfaceId">接口ID</param>
/// <returns></returns>
[HttpGet("InterfaceReturnConfig/GetList")]
public async Task<List<InterfaceReturnConfigVO>> GetList([Required] int interfaceId)
{
return await _interfaceReturnConfigRepository.GetListAsync(interfaceId);
}
/// <summary>
/// 更新或新增
/// </summary>
/// <param name="input">入参</param>
/// <returns></returns>
[HttpPost("InterfaceReturnConfig/Save")]
public async Task<bool> SaveAsync(InterfaceReturnConfigInput input)
{
if (!await _interfaceRepository.IsAnyAsync(x => x.Id == input.InterfaceId))
{
throw new BusinessException(message: "接口不存在");
}
// 开启事务
using var ts = TransacationHelper.GetReadCommitted();
foreach (var item in input.Items)
{
var entity =
ObjectMapper
.Map<InterfaceReturnConfigInput.InterfaceReturnConfigInputItem, InterfaceReturnConfigEntity>(item);
entity.InterfaceId = input.InterfaceId;
entity.Value ??= "";
switch (item.OptionType)
{
case OptionType.:
break;
case OptionType.:
await _interfaceReturnConfigRepository.InsertOrUpdateAsync(entity, default);
break;
case OptionType.:
await _interfaceReturnConfigRepository.DeleteConfigByIdAsync(entity.Id);
break;
case OptionType.:
await _interfaceReturnConfigRepository.UpdateAsync(entity, ignoreAllNullColumns:true);
break;
default:
throw new ArgumentOutOfRangeException();
}
}
ts.Complete();
return true;
}
}

View File

@ -0,0 +1,287 @@
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using Newtonsoft.Json;
using SJZY.Expand.ABP.Common.Enums;
using SJZY.InterfaceRelay.Application.Dtos.Interface;
using SJZY.InterfaceRelay.Application.Services.Parameter;
using SJZY.InterfaceRelay.Repository.Interface.Entitys;
using SJZY.InterfaceRelay.Repository.Interface.Services;
using SJZY.InterfaceRelay.Repository.Interface.ValueObjects;
using SJZY.InterfaceRelay.Repository.ServiceProvider.Entitys;
namespace SJZY.InterfaceRelay.Application.Services.Interface;
/// <summary>
/// 服务商接口
/// </summary>
[ApiExplorerSettings(GroupName = "接口服务")]
public class ServiceProviderInterfaceService : ApplicationService
{
private ParameterService ParameterService => LazyServiceProvider.LazyGetRequiredService<ParameterService>();
private FormParameterService FormParameterService =>
LazyServiceProvider.LazyGetRequiredService<FormParameterService>();
private IInterfaceRepository InterfaceRepository =>
LazyServiceProvider.LazyGetRequiredService<IInterfaceRepository>();
private IBasicRepository<ServiceProviderEntity> ServiceProviderRepository =>
LazyServiceProvider.LazyGetRequiredService<IBasicRepository<ServiceProviderEntity>>();
private IBasicRepository<InterfaceMapEntity> InterfaceMapRepository =>
LazyServiceProvider.LazyGetRequiredService<IBasicRepository<InterfaceMapEntity>>();
/// <summary>
/// 服务商接口分页列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/ServiceProviderInterfacePaginatedList")]
public async Task<UnifyPageResultDto<ServiceProviderInterfacePaginatedOutputValueObject>>
ServiceProviderInterfacePaginatedListAsync(ServiceProviderInterfacePaginatedInputObjectValue input)
{
return await InterfaceRepository.GetServiceProviderInterfacePaginatedListAsync(input);
}
/// <summary>
/// 获取服务商接口下拉列表
/// </summary>
/// <param name="serviceProviderId">服务商id</param>
/// <returns></returns>
[HttpGet("Interface/GetServiceProviderInterfaceDropdownList")]
public async Task<List<ServiceProviderInterfaceDropdownListItem>> GetServiceProviderInterfaceDropdownListAsync(
[Required] int serviceProviderId)
{
var res = await InterfaceRepository.GetListAsync(x => x.ServiceProviderId == serviceProviderId,
x => new { x.Id, x.Code, x.Name });
return res.Select(x => new ServiceProviderInterfaceDropdownListItem
{
Id = x.Id,
Name = x.Name,
Code = x.Code
}).ToList();
}
/// <summary>
/// 获取服务商接口明细
/// </summary>
/// <param name="id">服务商接口id</param>
/// <returns></returns>
[HttpGet("Interface/GetServiceProviderInterfaceById")]
public async Task<ServiceProviderInterfaceOutput> GetServiceProviderInterfaceByIdAsync([Required] int id)
{
// 接口基本信息
var interfaceEntity = await InterfaceRepository.GetFirstAsync(x => x.Id == id && !x.IsUpStream);
if (interfaceEntity == null)
{
throw new BusinessException(message: "服务商接口不存在");
}
var res = ObjectMapper.Map<InterfaceEntity, ServiceProviderInterfaceOutput>(interfaceEntity);
// 构造参数
var paras = await InterfaceRepository.GetParameterListByIdAsync(id);
// 入参树形列表
res.InParameterList = paras.Where(x => x.IsInPara).ToList();
// 出参树形列表
res.OutParameterList = paras.Where(x => !x.IsInPara).ToList();
// 表单列表
res.FormParameterList = await FormParameterService.GetParameterListAsync(id);
return res;
}
/// <summary>
/// 保存服务商接口
/// </summary>
/// <remarks>
/// 用OptionType来区分操作目的1新增2删除3修改
///<para>tips新增时参数id由调用者伪造以表现层级关系不能小于1你必须真实的表达id和pid的关系</para>
/// </remarks>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Interface/SaveServiceProviderInterface")]
public async Task<IdBaseDto> SaveServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
{
var res = new IdBaseDto();
switch (input.OptionType)
{
case OptionType.:
res.Id = await CreateServiceProviderInterfaceAsync(input);
break;
case OptionType.:
res.Id = await UpdateServiceProviderInterfaceAsync(input);
break;
case OptionType.:
await BatchDeleteServiceProviderInterfaceByIdsAsync(new List<int> { input.Id ?? 0 });
break;
default:
res.Id = res.Id;
break;
}
return res;
}
/// <summary>
/// 批量删除服务商接口
/// </summary>
/// <param name="ids">服务商接口id集合</param>
/// <returns></returns>
[HttpPost("Interface/BatchDeleteServiceProviderInterfaceByIds")]
public async Task<bool> BatchDeleteServiceProviderInterfaceByIdsAsync([FromBody] List<int> ids)
{
using var tran = TransacationHelper.GetReadCommitted();
// 删除接口
await InterfaceRepository.SoftDeleteAsync(x => !x.IsUpStream && ids.Contains(x.Id));
// 删除接口映射
var mapIds = await InterfaceMapRepository.GetListAsync(x => ids.Contains(x.DownStreamId), x => x.Id);
if (mapIds.Count > 0)
{
await InterfaceMapRepository.SoftDeleteAsync(x => mapIds.Contains(x.Id));
}
tran.Complete();
return true;
}
internal async Task<int> CreateServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
{
// 校验参数合法性
ParameterService.ValidateParameter(
JsonConvert.DeserializeObject<List<ParameterInput>>(
JsonConvert.SerializeObject(input.InParameterList)));
ParameterService.ValidateParameter(
JsonConvert.DeserializeObject<List<ParameterInput>>(
JsonConvert.SerializeObject(input.OutParameterList)));
/*
* 1.
*
* 2.
* bfs
* 3.
*
*/
#region
if (await InterfaceRepository.IsAnyAsync(x =>
!x.IsUpStream && x.Name.Equals(input.Name) && x.ServiceProviderId == input.ServiceProviderId))
{
throw new BusinessException(message: $"接口名:{input.Name} 已存在");
}
#endregion
var interfaceEntity = ObjectMapper.Map<ServiceProviderInterfaceInput, InterfaceEntity>(input);
interfaceEntity.IsUpStream = false;
// 开启事务
using var ts = TransacationHelper.GetReadCommitted();
// step1、生成接口编码
interfaceEntity.Code = await GenerateServiceProviderInterfaceCode(input.ServiceProviderId);
// step2、持久化接口
var interfaceId = await InterfaceRepository.InsertReturnIdentityAsync(interfaceEntity);
// 接口代码生成时并发兜底方案
if (await InterfaceRepository.CountAsync(x => x.Code.Equals(interfaceEntity.Code)) > 1)
{
throw new BusinessException(message: "接口代码生成异常,请稍后重试");
}
// step3、持久化参数
await ParameterService.CreateParametersAsync(input.InParameterList, interfaceId, true);
await ParameterService.CreateParametersAsync(input.OutParameterList, interfaceId, false);
// step4、持久化表单参数
if (input.FormParameterList.Count > 0)
{
await FormParameterService.CreateParametersAsync(input.FormParameterList, interfaceId);
}
// 提交事务
ts.Complete();
return interfaceId;
}
private async Task<string> GenerateServiceProviderInterfaceCode(int serviceProviderId)
{
// 系统生成,由服务商代码+3位数字组成0-999按顺序生成
// tips唯一性
var entity = await ServiceProviderRepository.GetFirstAsync(x => x.Id == serviceProviderId);
if (entity == null) throw new BusinessException(message: "服务商不存在");
string res = entity.Code;
// tips要考虑并发
var code = await InterfaceRepository.GetCurrentCodeBySpId(serviceProviderId);
int count = 0;
if (!string.IsNullOrEmpty(code)) count = int.Parse(code.Substring(code.Length - 3, 3));
res += (count + 1).ToString().PadLeft(3, '0');
return res;
}
private async Task<int> UpdateServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
{
#region
if (!await InterfaceRepository.IsAnyAsync(x => x.Id == input.Id))
{
throw new BusinessException(message: "服务商接口不存在");
}
if (await InterfaceRepository.IsAnyAsync(x =>
x.Name.Equals(input.Name) && x.Id != input.Id && !x.IsUpStream &&
x.ServiceProviderId == input.ServiceProviderId))
{
throw new BusinessException(message: $"接口名:{input.Name} 已存在");
}
#endregion
Debug.Assert(input.Id != null, $"{input.Id} 不能为空");
var interfaceEntity = ObjectMapper.Map<ServiceProviderInterfaceInput, InterfaceEntity>(input);
// 开启事务
using var ts = TransacationHelper.GetReadCommitted();
// step1、更新接口
await InterfaceRepository.UpdateAsync(interfaceEntity, x => new
{
x.Code,
x.IsUpStream,
x.ServiceProviderId,
x.CreateTime,
x.CreateUserId,
x.IsDeleted
});
// step2、维护参数增删改
await ParameterService.MaintainParametersAsync(input.InParameterList, (int)input.Id, true);
await ParameterService.MaintainParametersAsync(input.OutParameterList, (int)input.Id, false);
// step3、更新表单参数
await FormParameterService.MaintainParametersAsync(input.FormParameterList, interfaceEntity.Id);
// 提交事务
ts.Complete();
return (int)input.Id;
}
}

View File

@ -0,0 +1,279 @@
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using Newtonsoft.Json;
using SJZY.Expand.ABP.Common.Enums;
using SJZY.Expand.ABP.Core;
using SJZY.Expand.ABP.Core.PublicMethords;
using SJZY.InterfaceRelay.Application.Dtos.Interface;
using SJZY.InterfaceRelay.Application.Services.Parameter;
using SJZY.InterfaceRelay.Repository.Interface.Entitys;
using SJZY.InterfaceRelay.Repository.Interface.Services;
using SJZY.InterfaceRelay.Repository.Interface.ValueObjects;
namespace SJZY.InterfaceRelay.Application.Services.Interface;
/// <summary>
/// 系统接口
/// </summary>
[ApiExplorerSettings(GroupName = "接口服务")]
public class SystemInterfaceService : ApplicationService
{
#region ctor
private readonly ParameterService _parameterService;
private readonly IInterfaceRepository _interfaceRepository;
private readonly IBasicRepository<InterfaceMapEntity> _interfaceMapRepository;
/// <summary>
/// 系统接口下拉列表缓存key
/// </summary>
private const string SystemInterfaceDropdownCacheKey = "SystemInterfaceDropdownCacheKey";
/// <inheritdoc />
public SystemInterfaceService(
IInterfaceRepository interfaceRepository
, ParameterService parameterService
, IBasicRepository<InterfaceMapEntity> interfaceMapRepository)
{
_parameterService = parameterService;
_interfaceMapRepository = interfaceMapRepository;
_interfaceRepository = interfaceRepository;
}
#endregion
/// <summary>
/// 系统接口分页列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/SystemInterfacePaginatedList")]
public async Task<UnifyPageResultDto<SystemInterfacePaginatedOutputValueObject>>
SystemInterfacePaginatedListAsync(SystemInterfacePaginatedInputObjectValue input)
{
return await _interfaceRepository.GetSystemInterfacePaginatedListAsync(input);
}
/// <summary>
/// 获取系统接口明细
/// </summary>
/// <param name="id">系统接口id</param>
/// <returns></returns>
[HttpGet("Interface/GetSystemInterfaceById")]
public async Task<SystemInterfaceOutput> GetSystemInterfaceByIdAsync([Required] int id)
{
// 接口基本信息
var interfaceEntity = await _interfaceRepository.GetFirstAsync(x => x.Id == id && x.IsUpStream);
if (interfaceEntity == null)
{
throw new BusinessException(message: "系统接口不存在");
}
var res = ObjectMapper.Map<InterfaceEntity, SystemInterfaceOutput>(interfaceEntity);
// 构造参数
var paras = await _interfaceRepository.GetParameterListByIdAsync(id);
// 入参树形列表
res.InParameterList = paras.Where(x => x.IsInPara).ToList();
// 出参树形列表
res.OutParameterList = paras.Where(x => !x.IsInPara).ToList();
return res;
}
/// <summary>
/// 获取系统接口下拉列表
/// </summary>
/// <returns></returns>
[HttpGet("Interface/GetSystemInterfaceDropdownList")]
public async Task<List<SystemInterfaceDropdownValueObject>> GetSystemInterfaceDropdownListAsync()
{
var res =
(await RedisHelper.Client.GetAsync<string>(SystemInterfaceDropdownCacheKey))
.ToObject<List<SystemInterfaceDropdownValueObject>>();
if (res == null)
{
res = await _interfaceRepository.GetSystemInterfaceDropdownListAsync();
await RedisHelper.Client.SetAsync(SystemInterfaceDropdownCacheKey, res.ToJson(), 2 * 60 * 60);
}
return res;
}
/// <summary>
/// 保存系统接口
/// </summary>
/// <remarks>
/// 用OptionType来区分操作目的1新增2删除3修改
///<para>注意新增时参数id由调用者伪造以表现层级关系不能小于1你必须真实的表达id和pid的关系</para>
/// </remarks>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Interface/SaveSystemInterface")]
public async Task<IdBaseDto> SaveSystemInterfaceAsync(SystemInterfaceInput input)
{
var res = new IdBaseDto();
switch (input.OptionType)
{
case OptionType.:
res.Id = await CreateSystemInterfaceAsync(input);
break;
case OptionType.:
res.Id = await UpdateSystemInterfaceAsync(input);
break;
case OptionType.:
await BatchDeleteSystemInterfaceByIdsAsync(new List<int> { input.Id ?? 0 });
break;
default:
res.Id = res.Id;
break;
}
// 干掉缓存
await RedisHelper.Client.DelAsync(SystemInterfaceDropdownCacheKey);
return res;
}
/// <summary>
/// 批量删除系统接口
/// </summary>
/// <param name="ids">系统接口id集合</param>
/// <returns></returns>
[HttpPost("Interface/BatchDeleteSystemInterfaceByIds")]
public async Task<bool> BatchDeleteSystemInterfaceByIdsAsync([FromBody] List<int> ids)
{
using var tran = TransacationHelper.GetReadCommitted();
// 删除接口
await _interfaceRepository.SoftDeleteAsync(x => x.IsUpStream && ids.Contains(x.Id));
// 删除接口映射
var mapIds = await _interfaceMapRepository.GetListAsync(x => ids.Contains(x.UpStreamId), x => x.Id);
if (mapIds.Count > 0)
{
await _interfaceMapRepository.SoftDeleteAsync(x => mapIds.Contains(x.Id));
}
// 删缓存
await RedisHelper.Client.DelAsync(SystemInterfaceDropdownCacheKey);
tran.Complete();
return true;
}
#region private
/// <summary>
/// 更新系统接口
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private async Task<int> UpdateSystemInterfaceAsync(SystemInterfaceInput input)
{
#region
var entity = await _interfaceRepository.GetFirstAsync(x => x.Id == input.Id && x.IsUpStream);
if (entity == null)
{
throw new BusinessException(message: "系统接口不存在");
}
if (await _interfaceRepository.IsAnyAsync(x =>
x.Id != input.Id && x.IsUpStream && x.Name.Equals(input.Name)))
{
throw new BusinessException(message: $"接口名:{input.Name} 已存在");
}
if (await _interfaceRepository.IsAnyAsync(
x => x.Id != input.Id && x.IsUpStream && x.Code.Equals(input.Code)))
{
throw new BusinessException(message: "接口code已存在");
}
#endregion
Debug.Assert(input.Id != null, $"{input.Id} 不能为空");
var interfaceEntity = ObjectMapper.Map<SystemInterfaceInput, InterfaceEntity>(input);
// 开启事务
using var ts = TransacationHelper.GetReadCommitted();
// step1、更新接口
await _interfaceRepository.UpdateAsync(interfaceEntity, x => new
{
x.IsUpStream,
x.ServiceProviderId,
x.CreateTime,
x.CreateUserId,
x.IsDeleted
});
// step2、维护参数增删改
await _parameterService.MaintainParametersAsync(input.InParameterList, (int)input.Id, true);
await _parameterService.MaintainParametersAsync(input.OutParameterList, (int)input.Id, false);
// 这里再做参数校验,回滚代价是不是有点大了。。
// 提交事务
ts.Complete();
return (int)input.Id;
}
private async Task<int> CreateSystemInterfaceAsync(SystemInterfaceInput input)
{
// 校验参数合法性
_parameterService.ValidateParameter(
JsonConvert.DeserializeObject<List<ParameterInput>>(
JsonConvert.SerializeObject(input.InParameterList)));
_parameterService.ValidateParameter(
JsonConvert.DeserializeObject<List<ParameterInput>>(
JsonConvert.SerializeObject(input.OutParameterList)));
/*
* 1.
*
* 2.
* bfs
* 3.
*
*/
#region
if (await _interfaceRepository.IsAnyAsync(x => x.IsUpStream && x.Name.Equals(input.Name)))
{
throw new BusinessException(message: $"接口名:{input.Name} 已存在");
}
if (await _interfaceRepository.IsAnyAsync(x => x.IsUpStream && x.Code.Equals(input.Code)))
{
throw new BusinessException(message: "接口code已存在");
}
#endregion
var interfaceEntity = ObjectMapper.Map<SystemInterfaceInput, InterfaceEntity>(input);
interfaceEntity.IsUpStream = true;
// 开启事务
using var ts = TransacationHelper.GetReadCommitted();
// step1、持久化接口
var interfaceId = await _interfaceRepository.InsertReturnIdentityAsync(interfaceEntity);
// step2、持久化参数
await _parameterService.CreateParametersAsync(input.InParameterList, interfaceId, true);
await _parameterService.CreateParametersAsync(input.OutParameterList, interfaceId, false);
// 提交事务
ts.Complete();
return interfaceId;
}
#endregion
}

View File

@ -1,5 +1,6 @@
using Fake.AspNetCore;
using Fake.Authorization;
using Fake.Helpers;
using Fake.Modularity;
using InterfaceForward.Api.Contract;
using InterfaceForward.Api.Filters;

View File

@ -1,8 +1,9 @@
using System;
using Fake.Modularity;
namespace InterfaceForward.Domain
{
public class InterfaceForwardDomainModule
public class InterfaceForwardDomainModule : FakeModule
{
}
}