factor:重构系统/服务商接口

This commit is contained in:
xiaolipro 2025-10-31 16:47:40 +08:00
parent 5ac381f4f1
commit 12ee10692d
22 changed files with 198 additions and 871 deletions

View File

@ -1,6 +1,6 @@
namespace InterfaceForward.Application.Contracts.Dtos.Interface;
public class ServiceProviderInterfaceDropdownListItem
public class InterfaceDropdownListItem
{
///<summary>
/// 接口id

View File

@ -3,14 +3,17 @@ using InterfaceForward.Domain.Shared.Enum;
namespace InterfaceForward.Application.Contracts.Dtos.Interface;
public class ServiceProviderInterfaceInput
public class SaveInterfaceInput
{
/// <summary>
/// 操作类型
/// </summary>
public OptionType OptionType { get; set; }
internal bool IsUpStream { get; set; } = false;
/// <summary>
/// 2025-10-31 重构,前端传入
/// </summary>
public bool IsUpStream { get; set; } = false;
/// <summary>
/// 服务商Id
@ -22,6 +25,16 @@ public class ServiceProviderInterfaceInput
/// </summary>
public int? Id { get; set; }
///<summary>
/// 接口代码
///</summary>
public string Code { get; set; }
///<summary>
/// 接口分组
///</summary>
public int Category { get; set; }
///<summary>
/// 接口名
///</summary>

View File

@ -1,63 +0,0 @@

using InterfaceForward.Domain.Shared.Enum;
namespace InterfaceForward.Application.Contracts.Dtos.Interface
{
/// <summary>
/// 系统接口入参
/// </summary>
public class SystemInterfaceInput
{
/// <summary>
/// 操作类型
/// </summary>
public OptionType OptionType { get; set; }
internal bool IsUpStream { get; set; } = true;
/// <summary>
/// 接口Idid传null则新增反之更新
/// </summary>
public int? Id { get; set; }
///<summary>
/// 接口名
///</summary>
public string Name { get; set; }
///<summary>
/// 接口代码
///</summary>
public string Code { get; set; }
///<summary>
/// 接口描述
///</summary>
public string Description { get; set; }
///<summary>
/// 是否支持批量处理
///</summary>
public bool IsBatch { get; set; }
///<summary>
/// 接口分组
///</summary>
public int Category { get; set; }
///<summary>
/// 是否返回源报文
///</summary>
public bool IsReturnMessage { get; set; }
/// <summary>
/// 入参列表
/// </summary>
public List<ParameterInput> InParameterList { get; set; }
/// <summary>
/// 出参列表
/// </summary>
public List<ParameterInput> OutParameterList { get; set; }
}
}

View File

@ -12,13 +12,10 @@ public class InterfaceProfile : Profile
/// <inheritdoc />
public InterfaceProfile()
{
CreateMap<SystemInterfaceInput, InterfaceEntity>(MemberList.None);
CreateMap<InterfaceEntity, SystemInterfaceOutput>(MemberList.None);
CreateMap<SystemInterfaceInput, InterfaceEntity>(MemberList.None);
CreateMap<InterfaceReturnConfigInput.InterfaceReturnConfigInputItem, InterfaceReturnConfigEntity>(MemberList.None);
CreateMap<ServiceProviderInterfaceInput, InterfaceEntity>(MemberList.None);
CreateMap<SaveInterfaceInput, InterfaceEntity>(MemberList.None);
CreateMap<InterfaceEntity, ServiceProviderInterfaceOutput>(MemberList.None);
CreateMap<InterfaceEntity, InterfaceOutput>(MemberList.None);
CreateMap<InterfaceMapDetail,InterfaceMapDetailEntity>(MemberList.None);
}
}

View File

@ -15,7 +15,6 @@ public class ParameterProfile: Profile
public ParameterProfile()
{
CreateMap<InterfaceParameterOutputValueObject, ParameterInput>(MemberList.None);
CreateMap<InterfaceParameterOutputValueObject, InterfaceParameterOutput>(MemberList.None);
CreateMap<ParameterEntity, MapParameterCascadedItem>(MemberList.None);
CreateMap<ParameterInput, ParameterEntity>(MemberList.None)
.ForMember(dest => dest.Id,

View File

@ -105,6 +105,7 @@ public class InterfaceCategoryService(IBasicRepository<InterfaceCategoryEntity>
}
}
public class CategoryTreeNode<T> where T : HasCategoryId
{
public int Id { get; set; }

View File

@ -16,10 +16,10 @@ using Microsoft.AspNetCore.Mvc;
namespace InterfaceForward.Application.Services.Interface;
/// <summary>
/// 服务商接口
/// 接口服务(包括上下游接口)
/// </summary>
[ApiExplorerSettings(GroupName = "接口服务")]
public class ServiceProviderInterfaceService : ApplicationService
public class InterfaceService : ApplicationService
{
private ParameterService ParameterService => LazyServiceProvider.GetRequiredService<ParameterService>();
@ -40,15 +40,15 @@ public class ServiceProviderInterfaceService : ApplicationService
/// <summary>
/// 服务商接口树形列表
/// 接口树形列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/GetServiceProviderInterfaceTreeListAsync")]
public async Task<List<CategoryTreeNode<ServiceProviderInterfaceTreeListOutputValueObject>>>
GetServiceProviderInterfaceTreeListAsync(ServiceProviderInterfaceTreeListInputObjectValue input)
[HttpPost("Interface/GetInterfaceTreeListAsync")]
public async Task<List<CategoryTreeNode<InterfaceTreeListOutputValueObject>>>
GetInterfaceTreeListAsync(InterfaceTreeListInputObjectValue input)
{
var res = await InterfaceRepository.GetServiceProviderInterfaceListAsync(input);
var res = await InterfaceRepository.GetInterfaceListAsync(input);
var tree = await InterfaceCategoryService.GetCategoryTree(false, res);
@ -56,30 +56,32 @@ public class ServiceProviderInterfaceService : ApplicationService
}
/// <summary>
/// 服务商接口分页列表
/// 接口分页列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/ServiceProviderInterfacePaginatedList")]
public async Task<PagedResult<ServiceProviderInterfacePaginatedOutputValueObject>>
ServiceProviderInterfacePaginatedListAsync(ServiceProviderInterfacePaginatedInputObjectValue input)
[HttpPost("Interface/InterfacePaginatedList")]
public async Task<PagedResult<InterfacePaginatedOutputValueObject>>
InterfacePaginatedListAsync(InterfacePaginatedInputObjectValue input)
{
return await InterfaceRepository.GetServiceProviderInterfacePaginatedListAsync(input);
return await InterfaceRepository.GetInterfacePaginatedListAsync(input);
}
/// <summary>
/// 获取服务商接口下拉列表
/// 获取接口下拉列表
/// </summary>
/// <param name="serviceProviderId">服务商id</param>
/// <param name="isUpstream">是否上游</param>
/// <param name="serviceProviderId">服务商id上游接口传0</param>
/// <returns></returns>
[HttpGet("Interface/GetServiceProviderInterfaceDropdownList")]
public async Task<List<ServiceProviderInterfaceDropdownListItem>> GetServiceProviderInterfaceDropdownListAsync(
[Required] int serviceProviderId)
[HttpGet("Interface/GetInterfaceDropdownList")]
public async Task<List<InterfaceDropdownListItem>> GetInterfaceDropdownListAsync(
[Required] bool isUpstream, [Required] int serviceProviderId)
{
var res = await InterfaceRepository.GetListAsync(x => x.ServiceProviderId == serviceProviderId,
var res = await InterfaceRepository.GetListAsync(x => x.IsUpStream == isUpstream &&
x.ServiceProviderId == serviceProviderId,
x => new { x.Id, x.Code, x.Name });
return res.Select(x => new ServiceProviderInterfaceDropdownListItem
return res.Select(x => new InterfaceDropdownListItem
{
Id = x.Id,
Name = x.Name,
@ -88,21 +90,21 @@ public class ServiceProviderInterfaceService : ApplicationService
}
/// <summary>
/// 获取服务商接口明细
/// 获取接口明细
/// </summary>
/// <param name="id">服务商接口id</param>
/// <param name="id">接口id</param>
/// <returns></returns>
[HttpGet("Interface/GetServiceProviderInterfaceById")]
public async Task<ServiceProviderInterfaceOutput> GetServiceProviderInterfaceByIdAsync([Required] int id)
[HttpGet("Interface/GetInterfaceById")]
public async Task<InterfaceOutput> GetInterfaceByIdAsync([Required] int id)
{
// 接口基本信息
var interfaceEntity = await InterfaceRepository.GetFirstAsync(x => x.Id == id && !x.IsUpStream);
var interfaceEntity = await InterfaceRepository.GetFirstAsync(x => x.Id == id);
if (interfaceEntity == null)
{
throw new BusinessException(message: "服务商接口不存在");
throw new BusinessException(message: "接口不存在");
}
var res = ObjectMapper.Map<InterfaceEntity, ServiceProviderInterfaceOutput>(interfaceEntity);
var res = ObjectMapper.Map<InterfaceEntity, InterfaceOutput>(interfaceEntity);
// 构造参数
var paras = await InterfaceRepository.GetParameterListByIdAsync(id);
@ -119,7 +121,7 @@ public class ServiceProviderInterfaceService : ApplicationService
/// <summary>
/// 保存服务商接口
/// 保存接口
/// </summary>
/// <remarks>
/// 用OptionType来区分操作目的1新增2删除3修改
@ -128,8 +130,8 @@ public class ServiceProviderInterfaceService : ApplicationService
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="BusinessException"></exception>
[HttpPost("Interface/SaveServiceProviderInterface")]
public async Task<int> SaveServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
[HttpPost("Interface/SaveInterface")]
public async Task<int> SaveInterfaceAsync(SaveInterfaceInput input)
{
input.InParameterList.ForEach(x =>
{
@ -145,12 +147,12 @@ public class ServiceProviderInterfaceService : ApplicationService
switch (input.OptionType)
{
case OptionType.:
return await CreateServiceProviderInterfaceAsync(input);
return await CreateInterfaceAsync(input);
case OptionType.:
await UpdateServiceProviderInterfaceAsync(input);
await UpdateInterfaceAsync(input);
break;
case OptionType.:
await BatchDeleteServiceProviderInterfaceByIdsAsync(new List<int> { input.Id ?? 0 });
await BatchDeleteInterfaceByIdsAsync(input.IsUpStream, [input.Id ?? 0]);
break;
case OptionType.:
break;
@ -163,15 +165,30 @@ public class ServiceProviderInterfaceService : ApplicationService
/// <summary>
/// 批量删除服务商接口
/// 批量删除接口
/// </summary>
/// <param name="ids">服务商接口id集合</param>
/// <param name="isUpstream">是否上游</param>
/// <param name="ids">接口id集合</param>
/// <returns></returns>
[HttpPost("Interface/BatchDeleteServiceProviderInterfaceByIds")]
public async Task<bool> BatchDeleteServiceProviderInterfaceByIdsAsync([FromBody] List<int> ids)
[HttpPost("Interface/BatchDeleteInterfaceByIds")]
public async Task<bool> BatchDeleteInterfaceByIdsAsync([FromQuery] bool isUpstream,
[FromBody] List<int> ids)
{
using var tran = TransacationHelper.GetReadCommitted();
if (isUpstream)
{
// 删除接口
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));
}
}
else
{
// 删除接口
await InterfaceRepository.SoftDeleteAsync(x => !x.IsUpStream && ids.Contains(x.Id));
// 删除接口映射
@ -180,13 +197,14 @@ public class ServiceProviderInterfaceService : ApplicationService
{
await InterfaceMapRepository.SoftDeleteAsync(x => mapIds.Contains(x.Id));
}
}
tran.Complete();
return true;
}
internal async Task<int> CreateServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
internal async Task<int> CreateInterfaceAsync(SaveInterfaceInput input)
{
// 校验参数合法性
ParameterService.ValidateParameter(
@ -196,7 +214,6 @@ public class ServiceProviderInterfaceService : ApplicationService
JsonConvert.DeserializeObject<List<ParameterInput>>(
JsonConvert.SerializeObject(input.OutParameterList))!);
/*
* 1.
*
@ -208,53 +225,53 @@ public class ServiceProviderInterfaceService : ApplicationService
#region
if (await InterfaceRepository.IsAnyAsync(x =>
!x.IsUpStream && x.Name.Equals(input.Name) && x.ServiceProviderId == input.ServiceProviderId))
if (input.Code.IsNullOrWhiteSpace())
{
throw new BusinessException(message: $"接口名:{input.Name} 已存在");
input.Code = await GenerateInterfaceCode(input.ServiceProviderId);
}
if (await InterfaceRepository.IsAnyAsync(x =>
x.IsUpStream == input.IsUpStream && (x.Name.Equals(input.Name) || x.Code.Equals(input.Code)) &&
x.ServiceProviderId == input.ServiceProviderId))
{
throw new BusinessException(message: $"接口名或code:{input.Name} 已存在");
}
#endregion
var interfaceEntity = ObjectMapper.Map<ServiceProviderInterfaceInput, InterfaceEntity>(input);
interfaceEntity.IsUpStream = false;
var interfaceEntity = ObjectMapper.Map<SaveInterfaceInput, InterfaceEntity>(input);
// 开启事务
using var ts = TransacationHelper.GetReadCommitted();
// step1、生成接口编码
interfaceEntity.Code = await GenerateServiceProviderInterfaceCode(input.ServiceProviderId);
// step2、持久化接口
// 持久化接口
var interfaceId = await InterfaceRepository.InsertReturnIdentityAsync(interfaceEntity);
// 持久化参数
await ParameterService.CreateParametersAsync(input.InParameterList, interfaceId, true);
await ParameterService.CreateParametersAsync(input.OutParameterList, interfaceId, false);
// 持久化表单参数
await FormParameterService.CreateParametersAsync(input.FormParameterList, interfaceId);
// 接口代码生成时并发兜底方案
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)
private async Task<string> GenerateInterfaceCode(int serviceProviderId)
{
// 系统生成,由服务商代码+3位数字组成0-999按顺序生成
// tips唯一性
var entity = await ServiceProviderRepository.GetFirstAsync(x => x.Id == serviceProviderId);
if (entity == null) throw new BusinessException(message: "服务商不存在");
if (entity == null) throw new BusinessException(message: "服务商不存在系统接口自己定义code谢谢配合");
string res = entity.Code;
@ -267,17 +284,17 @@ public class ServiceProviderInterfaceService : ApplicationService
return res;
}
private async Task UpdateServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
private async Task UpdateInterfaceAsync(SaveInterfaceInput input)
{
#region
if (!await InterfaceRepository.IsAnyAsync(x => x.Id == input.Id))
{
throw new BusinessException(message: "服务商接口不存在");
throw new BusinessException(message: "接口不存在");
}
if (await InterfaceRepository.IsAnyAsync(x =>
x.Name.Equals(input.Name) && x.Id != input.Id && !x.IsUpStream &&
x.Name.Equals(input.Name) && x.Id != input.Id && x.IsUpStream == input.IsUpStream &&
x.ServiceProviderId == input.ServiceProviderId))
{
throw new BusinessException(message: $"接口名:{input.Name} 已存在");
@ -287,7 +304,7 @@ public class ServiceProviderInterfaceService : ApplicationService
Debug.Assert(input.Id != null, $"{input.Id} 不能为空");
var interfaceEntity = ObjectMapper.Map<ServiceProviderInterfaceInput, InterfaceEntity>(input);
var interfaceEntity = ObjectMapper.Map<SaveInterfaceInput, InterfaceEntity>(input);
// 开启事务
using var ts = TransacationHelper.GetReadCommitted();

View File

@ -1,311 +0,0 @@
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using Newtonsoft.Json;
using InterfaceForward.Application.Contracts.Dtos.Interface;
using InterfaceForward.Application.Helpers;
using InterfaceForward.Application.Services.Parameter;
using InterfaceForward.Domain.Shared;
using InterfaceForward.Domain.Shared.Enum;
using InterfaceForward.Repositories;
using InterfaceForward.Repositories.Interface.Entitys;
using InterfaceForward.Repositories.Interface.Services;
using InterfaceForward.Repositories.Interface.ValueObjects;
using InterfaceForward.Repositories.Parameter.VO;
using Microsoft.AspNetCore.Mvc;
namespace InterfaceForward.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;
private readonly InterfaceCategoryService _interfaceCategoryService;
/// <summary>
/// 系统接口下拉列表缓存key
/// </summary>
private const string SystemInterfaceDropdownCacheKey = "SystemInterfaceDropdownCacheKey";
/// <inheritdoc />
public SystemInterfaceService(
IInterfaceRepository interfaceRepository
, ParameterService parameterService
, IBasicRepository<InterfaceMapEntity> interfaceMapRepository
, InterfaceCategoryService interfaceCategoryService)
{
_parameterService = parameterService;
_interfaceMapRepository = interfaceMapRepository;
_interfaceCategoryService = interfaceCategoryService;
_interfaceRepository = interfaceRepository;
}
#endregion
/// <summary>
/// 系统接口分页列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/SystemInterfacePaginatedList")]
public async Task<PagedResult<SystemInterfacePaginatedOutputValueObject>>
SystemInterfacePaginatedListAsync(SystemInterfacePaginatedInputObjectValue input)
{
return await _interfaceRepository.GetSystemInterfacePaginatedListAsync(input);
}
/// <summary>
/// 系统接口树形列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/GetSystemInterfaceTreeListAsync")]
public async Task<List<CategoryTreeNode<SystemInterfaceTreeListValueObject>>>
GetSystemInterfaceTreeListAsync(SystemInterfaceTreeListInputObjectValue input)
{
var res = await _interfaceRepository.GetSystemInterfaceListAsync(input);
var tree = await _interfaceCategoryService.GetCategoryTree(true, res);
return tree;
}
/// <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 =
ObjectMapper.Map<List<InterfaceParameterOutputValueObject>, List<InterfaceParameterOutput>>(
paras.Where(x => x.IsInPara).ToList());
// 出参树形列表
res.OutParameterList =
ObjectMapper.Map<List<InterfaceParameterOutputValueObject>, List<InterfaceParameterOutput>>(
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 SaveSystemInterfaceAsync(SystemInterfaceInput input)
{
input.InParameterList.ForEach(x =>
{
if (x.PId == 0 && x.Type == ParameterType.Array && x.Name == GlobalConst.RootParameterName)
x.Name = string.Empty;
});
input.OutParameterList.ForEach(x =>
{
if (x.PId == 0 && x.Type == ParameterType.Array && x.Name == GlobalConst.RootParameterName)
x.Name = string.Empty;
});
switch (input.OptionType)
{
case OptionType.:
await CreateSystemInterfaceAsync(input);
break;
case OptionType.:
await UpdateSystemInterfaceAsync(input);
break;
case OptionType.:
await BatchDeleteSystemInterfaceByIdsAsync(new List<int> { input.Id ?? 0 });
break;
case OptionType.:
break;
default:
throw new ArgumentOutOfRangeException();
}
// 干掉缓存
await RedisHelper.Client.DelAsync(SystemInterfaceDropdownCacheKey);
}
/// <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 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();
}
private async Task 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();
}
#endregion
}

View File

@ -40,6 +40,7 @@ public class FormParameterService : ApplicationService
/// <param name="interfaceId">接口id</param>
internal async Task CreateParametersAsync(List<FormParameterInput> list, int interfaceId)
{
if (list.Count <= 0) return;
var formEntities = ObjectMapper.Map<List<FormParameterInput>, List<FormParameterEntity>>(list);
formEntities.ForEach(x => x.InterfaceId = interfaceId);
await _formParameterRepository.InsertRangeAsync(formEntities);

View File

@ -328,6 +328,7 @@ public class ParameterService : ApplicationService
/// <exception cref="BusinessException"></exception>
internal async Task CreateParametersAsync(List<ParameterInput> list, int interfaceId, bool isInPara)
{
if (list.Count <= 0) return;
var parameters =
await _parameterRepository.GetListAsync(x => x.InterfaceId == interfaceId && x.IsInPara == isInPara);

View File

@ -13,18 +13,11 @@ namespace InterfaceForward.Repositories.Interface.Services
public interface IInterfaceRepository:IBasicRepository<InterfaceEntity>
{
/// <summary>
/// 获取系统接口列表
/// 获取接口列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<List<SystemInterfaceTreeListValueObject>> GetSystemInterfaceListAsync(SystemInterfaceTreeListInputObjectValue input);
/// <summary>
/// 获取服务商接口列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<List<ServiceProviderInterfaceTreeListOutputValueObject>> GetServiceProviderInterfaceListAsync(ServiceProviderInterfaceTreeListInputObjectValue input);
Task<List<InterfaceTreeListOutputValueObject>> GetInterfaceListAsync(InterfaceTreeListInputObjectValue input);
/// <summary>
/// 获取参数列表
@ -34,12 +27,6 @@ namespace InterfaceForward.Repositories.Interface.Services
/// <returns></returns>
Task<List<InterfaceParameterOutputValueObject>> GetParameterListByIdAsync(int id, bool onlyLeafs = false);
/// <summary>
/// 获取系统接口下拉列表
/// </summary>
/// <returns></returns>
Task<List<SystemInterfaceDropdownValueObject>> GetSystemInterfaceDropdownListAsync();
/// <summary>
/// 获取服务商接口当前用到的code
/// </summary>
@ -47,7 +34,6 @@ namespace InterfaceForward.Repositories.Interface.Services
/// /// <returns></returns>
Task<string> GetCurrentCodeBySpId(int spId);
Task<PagedResult<SystemInterfacePaginatedOutputValueObject>> GetSystemInterfacePaginatedListAsync(SystemInterfacePaginatedInputObjectValue input);
Task<PagedResult<ServiceProviderInterfacePaginatedOutputValueObject>> GetServiceProviderInterfacePaginatedListAsync(ServiceProviderInterfacePaginatedInputObjectValue input);
Task<PagedResult<InterfacePaginatedOutputValueObject>> GetInterfacePaginatedListAsync(InterfacePaginatedInputObjectValue input);
}
}

View File

@ -15,50 +15,35 @@ public class InterfaceRepository : BasicRepository<InterfaceEntity>, IInterfaceR
public string InterfaceGroup => "InterfaceGroup";
/// <inheritdoc />
public async Task<List<SystemInterfaceTreeListValueObject>>
GetSystemInterfaceListAsync(SystemInterfaceTreeListInputObjectValue input)
public async Task<List<InterfaceTreeListOutputValueObject>>
GetInterfaceListAsync(InterfaceTreeListInputObjectValue input)
{
// t_interface驱动t_interface_map数据量上来可以在t_interface_map UpStreamId字段建立索引
var query = AsQueryable()
.Where(a => a.IsUpStream)
;
query
.WhereIF(!string.IsNullOrEmpty(input.Name), a => a.Name.Contains(input.Name!)) // 默认为空,支持模糊搜索
.WhereIF(!string.IsNullOrEmpty(input.Code), a => a.Code.Contains(input.Code!)) // 默认为空,支持模糊搜索
;
return await query
.OrderBy(a => a.CreateTime)
.Select(a => new SystemInterfaceTreeListValueObject
{
Id = a.Id,
CategoryId = a.Category,
Name = a.Name,
Code = a.Code,
RequestProtocol = a.RequestProtocol,
Description = a.Description,
MapCount = SqlFunc.Subqueryable<InterfaceMapEntity>().Where(x => x.UpStreamId == a.Id && !x.IsDeleted)
.DistinctCount(x => x.ServiceProviderId),
UpdateTime = a.UpdateTime,
}).ToListAsync();
}
/// <inheritdoc />
public async Task<List<ServiceProviderInterfaceTreeListOutputValueObject>>
GetServiceProviderInterfaceListAsync(ServiceProviderInterfaceTreeListInputObjectValue input)
{
var query = AsQueryable()
.Where(a => !a.IsUpStream)
.Where(a => a.IsUpStream == input.IsUpstream)
.Where(a => a.ServiceProviderId == input.ServiceProviderId);
query
.WhereIF(!string.IsNullOrEmpty(input.Name), a => a.Name.Contains(input.Name!)) // 默认为空,支持模糊搜索
.WhereIF(!string.IsNullOrEmpty(input.Code), a => a.Code.Contains(input.Code!)) // 默认为空,支持模糊搜索
;
if (input.IsUpstream)
{
return await query
.OrderBy(a => a.CreateTime)
.Select<ServiceProviderInterfaceTreeListOutputValueObject>()
.Select(a => new InterfaceTreeListOutputValueObject
{
Id = a.Id.SelectAll(),
MapCount = SqlFunc.Subqueryable<InterfaceMapEntity>().Where(x => x.UpStreamId == a.Id && !x.IsDeleted)
.DistinctCount(x => x.ServiceProviderId),
})
.ToListAsync();
}
return await query
.OrderBy(a => a.CreateTime)
.Select<InterfaceTreeListOutputValueObject>()
.ToListAsync();
}
@ -82,38 +67,6 @@ public class InterfaceRepository : BasicRepository<InterfaceEntity>, IInterfaceR
return res;
}
/// <inheritdoc />
public async Task<List<SystemInterfaceDropdownValueObject>> GetSystemInterfaceDropdownListAsync()
{
// 获取所有接口分组
// var groups = await Context.Queryable<DictionaryEntity>()
// .Where(x => x.Type == InterfaceGroup)
// .Select(x => new { x.Id, x.Name })
// .ToListAsync();
var groups = new List<string>() { "全部" };
// 获取所有接口
var interfaces = await AsQueryable()
.Where(x => x.IsUpStream)
.Select(x => new { x.Id, x.Name, x.Category })
.ToListAsync();
// 渲染
return groups.Select(x => new SystemInterfaceDropdownValueObject
{
Id = Guid.NewGuid().ToString(),
GroupName = x,
Interfaces = interfaces
//.Where(y => y.Category == x.Id)
.Select(y => new SystemInterfaceItemValueObject
{
Id = y.Id,
Name = y.Name
}).ToList()
}).ToList();
}
/// <inheritdoc />
public async Task<string> GetCurrentCodeBySpId(int spId)
{
@ -128,13 +81,13 @@ public class InterfaceRepository : BasicRepository<InterfaceEntity>, IInterfaceR
}
/// <inheritdoc />
public async Task<PagedResult<SystemInterfacePaginatedOutputValueObject>>
GetSystemInterfacePaginatedListAsync(SystemInterfacePaginatedInputObjectValue input)
public async Task<PagedResult<InterfacePaginatedOutputValueObject>>
GetInterfacePaginatedListAsync(InterfacePaginatedInputObjectValue input)
{
// t_interface驱动t_interface_map数据量上来可以在t_interface_map UpStreamId字段建立索引
var query = AsQueryable()
.Where(a => a.IsUpStream)
;
.Where(a => a.IsUpStream == input.IsUpstream)
.Where(a => a.ServiceProviderId == input.ServiceProviderId);
var keyword = input.NameOrCode?.Trim();
query.WhereIF(input.Category != 0, a => a.Category == input.Category) // 默认“请选择”对应0数据源在数据库字典中配置
@ -142,17 +95,13 @@ public class InterfaceRepository : BasicRepository<InterfaceEntity>, IInterfaceR
|| a.Code.Contains(keyword)) // 默认为空,支持模糊搜索
;
var res = await query.Select(a => new SystemInterfacePaginatedOutputValueObject
if (input.IsUpstream)
{
Id = a.Id,
Category = a.Category,
Name = a.Name,
Code = a.Code,
RequestProtocol = a.RequestProtocol,
Description = a.Description,
var res = await query.Select(a => new InterfacePaginatedOutputValueObject
{
Id = a.Id.SelectAll(),
MapCount = SqlFunc.Subqueryable<InterfaceMapEntity>().Where(x => x.UpStreamId == a.Id && !x.IsDeleted)
.DistinctCount(x => x.ServiceProviderId),
UpdateTime = a.UpdateTime,
})
.OrderByDescending(a => a.UpdateTime)
.ToPagedListAsync(input.PageIndex, input.PageSize);
@ -160,19 +109,7 @@ public class InterfaceRepository : BasicRepository<InterfaceEntity>, IInterfaceR
return res;
}
/// <inheritdoc />
public async Task<PagedResult<ServiceProviderInterfacePaginatedOutputValueObject>>
GetServiceProviderInterfacePaginatedListAsync(ServiceProviderInterfacePaginatedInputObjectValue input)
{
var query = AsQueryable()
.Where(a => !a.IsUpStream)
.Where(a => a.ServiceProviderId == input.ServiceProviderId);
query
.WhereIF(!string.IsNullOrEmpty(input.Name), a => a.Name.Contains(input.Name!)) // 默认为空,支持模糊搜索
.WhereIF(!string.IsNullOrEmpty(input.Code), a => a.Code.Contains(input.Code!)) // 默认为空,支持模糊搜索
;
return await query.Select<ServiceProviderInterfacePaginatedOutputValueObject>()
return await query.Select<InterfacePaginatedOutputValueObject>()
.OrderByDescending(a => a.UpdateTime)
.ToPagedListAsync(input.PageIndex, input.PageSize);
}

View File

@ -7,7 +7,7 @@ namespace InterfaceForward.Repositories.Interface.ValueObjects;
/// <summary>
/// 服务商接口输出模型
/// </summary>
public class ServiceProviderInterfaceOutput
public class InterfaceOutput
{
///<summary>
/// 接口id

View File

@ -3,22 +3,27 @@
namespace InterfaceForward.Repositories.Interface.ValueObjects;
/// <summary>
/// 服务商接口分页
/// 接口分页
/// </summary>
public class ServiceProviderInterfaceTreeListInputObjectValue
public class InterfacePaginatedInputObjectValue : PagedQueryInput
{
/// <summary>
/// 是否上游接口
/// </summary>
public bool IsUpstream { get; set; }
/// <summary>
/// 服务商Id
/// </summary>
public int ServiceProviderId { get; set; }
///<summary>
/// 接口
/// 接口分组默认请选择对应0值
///</summary>
public string? Name { get; set; }
public int Category { get; set; }
///<summary>
/// 接口代码
/// 接口
///</summary>
public string? Code { get; set; }
public string NameOrCode { get; set; }
}

View File

@ -6,13 +6,23 @@ namespace InterfaceForward.Repositories.Interface.ValueObjects;
/// <summary>
///
/// </summary>
public class ServiceProviderInterfacePaginatedOutputValueObject
public class InterfacePaginatedOutputValueObject
{
/// <summary>
/// 接口Id
/// </summary>
public int Id { get; set; }
///<summary>
/// 接口分组
///</summary>
public int Category { get; set; }
///<summary>
/// 接口分组Name
///</summary>
public string CategoryName => "全部";
///<summary>
/// 接口名
///</summary>
@ -53,6 +63,11 @@ public class ServiceProviderInterfacePaginatedOutputValueObject
///</summary>
public string Description { get; set; }
///<summary>
/// 映射数
///</summary>
public int MapCount { get; set; }
/// <summary>
/// 更新时间
/// </summary>

View File

@ -5,8 +5,13 @@ namespace InterfaceForward.Repositories.Interface.ValueObjects;
/// <summary>
/// 服务商接口分页
/// </summary>
public class ServiceProviderInterfacePaginatedInputObjectValue : PagedQueryInput
public class InterfaceTreeListInputObjectValue
{
/// <summary>
/// 是否上游接口
/// </summary>
public bool IsUpstream { get; set; }
/// <summary>
/// 服务商Id
/// </summary>
@ -15,10 +20,10 @@ public class ServiceProviderInterfacePaginatedInputObjectValue : PagedQueryInput
///<summary>
/// 接口名
///</summary>
public string? Name { get; set; }
public string Name { get; set; }
///<summary>
/// 接口代码
///</summary>
public string? Code { get; set; }
public string Code { get; set; }
}

View File

@ -3,10 +3,18 @@ using InterfaceForward.Domain.Shared.Helpers;
namespace InterfaceForward.Repositories.Interface.ValueObjects;
public class HasCategoryId
{
///<summary>
/// 接口分组id
///</summary>
public int CategoryId { get; set; }
}
/// <summary>
///
/// </summary>
public class ServiceProviderInterfaceTreeListOutputValueObject: HasCategoryId
public class InterfaceTreeListOutputValueObject: HasCategoryId
{
/// <summary>
/// 接口Id
@ -53,6 +61,11 @@ public class ServiceProviderInterfaceTreeListOutputValueObject: HasCategoryId
///</summary>
public string Description { get; set; }
///<summary>
/// 映射数
///</summary>
public int MapCount { get; set; }
/// <summary>
/// 更新时间
/// </summary>

View File

@ -1,129 +0,0 @@
using System.Text.Json.Serialization;
using InterfaceForward.Repositories.Parameter.VO;
namespace InterfaceForward.Repositories.Interface.ValueObjects;
/// <summary>
/// 系统接口输出模型
/// </summary>
public class SystemInterfaceOutput
{
///<summary>
/// 接口id
///</summary>
public int Id { get; set; }
///<summary>
/// 接口代码
///</summary>
public string Code { get; set; }
///<summary>
/// 接口名
///</summary>
public string Name { get; set; }
///<summary>
/// 请求地址
///</summary>
public string RequestAddress { get; set; }
///<summary>
/// 接口描述
///</summary>
public string Description { get; set; }
///<summary>
/// 是否支持批量处理
///</summary>
public bool IsBatch { get; set; }
///<summary>
/// 请求协议
///</summary>
public int RequestProtocol { get; set; }
///<summary>
/// 请求方式
///</summary>
public int RequestMethod { get; set; }
///<summary>
/// 接口分组
///</summary>
public int Category { get; set; }
///<summary>
/// 内容类型
///</summary>
public int ContentType { get; set; }
///<summary>
/// 是否返回源报文
///</summary>
public bool IsReturnMessage { get; set; }
/// <summary>
/// 入参列表
/// </summary>
public List<InterfaceParameterOutput> InParameterList { get; set; }
/// <summary>
/// 出参列表
/// </summary>
public List<InterfaceParameterOutput> OutParameterList { get; set; }
}
public class InterfaceParameterOutput
{
/// <summary>
/// Id
/// </summary>
public int Id { get; set; }
/// <summary>
/// 父级Id
/// </summary>
public int PId { get; set; }
/// <summary>
/// 别名
/// </summary>
public string Alias { get; set; }
///<summary>
/// 参数名
///</summary>
public string Name { get; set; }
///<summary>
/// 参数名(中文)
///</summary>
public string CnName { get; set; }
///<summary>
/// 参数类型
///</summary>
public int Type { get; set; }
/// <summary>
/// 是否必填
/// </summary>
public bool IsRequired { get; set; }
///<summary>
/// 参数描述
///</summary>
public string Description { get; set; }
///<summary>
/// 0:返回参数1:请求参数
///</summary>
public bool IsInPara { get; set; }
///<summary>
/// 序列
///</summary>
[JsonIgnore]
public string Sort { get; set; }
}

View File

@ -1,20 +0,0 @@
using InterfaceForward.Domain.Shared.Dtos;
namespace InterfaceForward.Repositories.Interface.ValueObjects
{
/// <summary>
/// 分页查询系统接口
/// </summary>
public class SystemInterfacePaginatedInputObjectValue : PagedQueryInput
{
///<summary>
/// 接口分组默认请选择对应0值
///</summary>
public int Category { get; set; }
///<summary>
/// 接口名
///</summary>
public string? NameOrCode { get; set; }
}
}

View File

@ -1,61 +0,0 @@
using InterfaceForward.Domain.Shared.Enum;
using InterfaceForward.Domain.Shared.Helpers;
namespace InterfaceForward.Repositories.Interface.ValueObjects
{
/// <summary>
///
/// </summary>
public class SystemInterfacePaginatedOutputValueObject
{
/// <summary>
/// 接口Id
/// </summary>
public int Id { get; set; }
///<summary>
/// 接口分组
///</summary>
public int Category { get; set; }
///<summary>
/// 接口分组Name
///</summary>
public string CategoryName => "全部";
///<summary>
/// 接口名
///</summary>
public string Name { get; set; }
///<summary>
/// 接口代码
///</summary>
public string Code { get; set; }
///<summary>
/// 请求协议
///</summary>
public RequestProtocol RequestProtocol { get; set; }
///<summary>
/// 请求协议Name
///</summary>
public string RequestProtocolName => ((RequestProtocol)RequestProtocol).GetDescription();
///<summary>
/// 接口描述
///</summary>
public string Description { get; set; }
///<summary>
/// 映射数
///</summary>
public int MapCount { get; set; }
/// <summary>
/// 更新时间
/// </summary>
public DateTime? UpdateTime { get; set; }
}
}

View File

@ -1,20 +0,0 @@
using InterfaceForward.Domain.Shared.Dtos;
namespace InterfaceForward.Repositories.Interface.ValueObjects
{
/// <summary>
/// 分页查询系统接口
/// </summary>
public class SystemInterfaceTreeListInputObjectValue
{
///<summary>
/// 接口名
///</summary>
public string? Name { get; set; }
///<summary>
/// 接口代码
///</summary>
public string? Code { get; set; }
}
}

View File

@ -1,59 +0,0 @@
using InterfaceForward.Domain.Shared.Enum;
using InterfaceForward.Domain.Shared.Helpers;
namespace InterfaceForward.Repositories.Interface.ValueObjects
{
public class HasCategoryId
{
///<summary>
/// 接口分组id
///</summary>
public int CategoryId { get; set; }
}
/// <summary>
///
/// </summary>
public class SystemInterfaceTreeListValueObject: HasCategoryId
{
/// <summary>
/// 接口Id
/// </summary>
public int Id { get; set; }
///<summary>
/// 接口名
///</summary>
public string Name { get; set; }
///<summary>
/// 接口代码
///</summary>
public string Code { get; set; }
///<summary>
/// 请求协议
///</summary>
public RequestProtocol RequestProtocol { get; set; }
///<summary>
/// 请求协议
///</summary>
public string RequestProtocolName => ((RequestProtocol)RequestProtocol).GetDescription();
///<summary>
/// 接口描述
///</summary>
public string Description { get; set; }
///<summary>
/// 映射数
///</summary>
public int MapCount { get; set; }
/// <summary>
/// 更新时间
/// </summary>
public DateTime? UpdateTime { get; set; }
}
}