itfx/src/InterfaceForward.Application/Services/Interface/ServiceProviderInterfaceService.cs
2025-07-17 11:07:39 +08:00

305 lines
11 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.Enum;
using InterfaceForward.Repositories;
using InterfaceForward.Repositories.Interface.Entitys;
using InterfaceForward.Repositories.Interface.Services;
using InterfaceForward.Repositories.Interface.ValueObjects;
using InterfaceForward.Repositories.ServiceProvider.Entitys;
using Microsoft.AspNetCore.Mvc;
namespace InterfaceForward.Application.Services.Interface;
/// <summary>
/// 服务商接口
/// </summary>
[ApiExplorerSettings(GroupName = "接口服务")]
public class ServiceProviderInterfaceService : ApplicationService
{
private ParameterService ParameterService => LazyServiceProvider.GetRequiredService<ParameterService>();
private FormParameterService FormParameterService =>
LazyServiceProvider.GetRequiredService<FormParameterService>();
private IInterfaceRepository InterfaceRepository =>
LazyServiceProvider.GetRequiredService<IInterfaceRepository>();
private IBasicRepository<ServiceProviderEntity> ServiceProviderRepository =>
LazyServiceProvider.GetRequiredService<IBasicRepository<ServiceProviderEntity>>();
private IBasicRepository<InterfaceMapEntity> InterfaceMapRepository =>
LazyServiceProvider.GetRequiredService<IBasicRepository<InterfaceMapEntity>>();
private InterfaceCategoryService InterfaceCategoryService =>
LazyServiceProvider.GetRequiredService<InterfaceCategoryService>();
/// <summary>
/// 服务商接口树形列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/GetServiceProviderInterfaceTreeListAsync")]
public async Task<List<CategoryTreeNode<ServiceProviderInterfaceTreeListOutputValueObject>>>
GetServiceProviderInterfaceTreeListAsync(ServiceProviderInterfaceTreeListInputObjectValue input)
{
var res = await InterfaceRepository.GetServiceProviderInterfaceListAsync(input);
var tree = await InterfaceCategoryService.GetCategoryTree(false, res);
return tree;
}
/// <summary>
/// 服务商接口分页列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("Interface/ServiceProviderInterfacePaginatedList")]
public async Task<PagedResult<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<int> SaveServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
{
switch (input.OptionType)
{
case OptionType.:
return await CreateServiceProviderInterfaceAsync(input);
case OptionType.:
await UpdateServiceProviderInterfaceAsync(input);
break;
case OptionType.:
await BatchDeleteServiceProviderInterfaceByIdsAsync(new List<int> { input.Id ?? 0 });
break;
case OptionType.:
break;
default:
throw new ArgumentOutOfRangeException();
}
return input.Id ?? 0;
}
/// <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 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();
}
}