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;
///
/// 服务商接口
///
[ApiExplorerSettings(GroupName = "接口服务")]
public class ServiceProviderInterfaceService : ApplicationService
{
private ParameterService ParameterService => LazyServiceProvider.GetRequiredService();
private FormParameterService FormParameterService =>
LazyServiceProvider.GetRequiredService();
private IInterfaceRepository InterfaceRepository =>
LazyServiceProvider.GetRequiredService();
private IBasicRepository ServiceProviderRepository =>
LazyServiceProvider.GetRequiredService>();
private IBasicRepository InterfaceMapRepository =>
LazyServiceProvider.GetRequiredService>();
private InterfaceCategoryService InterfaceCategoryService =>
LazyServiceProvider.GetRequiredService();
///
/// 服务商接口树形列表
///
///
///
[HttpPost("Interface/GetServiceProviderInterfaceTreeListAsync")]
public async Task>>
GetServiceProviderInterfaceTreeListAsync(ServiceProviderInterfaceTreeListInputObjectValue input)
{
var res = await InterfaceRepository.GetServiceProviderInterfaceListAsync(input);
var tree = await InterfaceCategoryService.GetCategoryTree(false, res);
return tree;
}
///
/// 服务商接口分页列表
///
///
///
[HttpPost("Interface/ServiceProviderInterfacePaginatedList")]
public async Task>
ServiceProviderInterfacePaginatedListAsync(ServiceProviderInterfacePaginatedInputObjectValue input)
{
return await InterfaceRepository.GetServiceProviderInterfacePaginatedListAsync(input);
}
///
/// 获取服务商接口下拉列表
///
/// 服务商id
///
[HttpGet("Interface/GetServiceProviderInterfaceDropdownList")]
public async Task> 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();
}
///
/// 获取服务商接口明细
///
/// 服务商接口id
///
[HttpGet("Interface/GetServiceProviderInterfaceById")]
public async Task 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);
// 构造参数
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;
}
///
/// 保存服务商接口
///
///
/// 用OptionType来区分操作目的,1:新增,2:删除,3:修改
///tips:新增时,参数id由调用者伪造,以表现层级关系,不能小于1,你必须真实的表达id和pid的关系
///
///
///
///
[HttpPost("Interface/SaveServiceProviderInterface")]
public async Task SaveServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
{
switch (input.OptionType)
{
case OptionType.新增:
return await CreateServiceProviderInterfaceAsync(input);
case OptionType.修改:
await UpdateServiceProviderInterfaceAsync(input);
break;
case OptionType.删除:
await BatchDeleteServiceProviderInterfaceByIdsAsync(new List { input.Id ?? 0 });
break;
case OptionType.无:
break;
default:
throw new ArgumentOutOfRangeException();
}
return input.Id ?? 0;
}
///
/// 批量删除服务商接口
///
/// 服务商接口id集合
///
[HttpPost("Interface/BatchDeleteServiceProviderInterfaceByIds")]
public async Task BatchDeleteServiceProviderInterfaceByIdsAsync([FromBody] List 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 CreateServiceProviderInterfaceAsync(ServiceProviderInterfaceInput input)
{
// 校验参数合法性
ParameterService.ValidateParameter(
JsonConvert.DeserializeObject>(
JsonConvert.SerializeObject(input.InParameterList))!);
ParameterService.ValidateParameter(
JsonConvert.DeserializeObject>(
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(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 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(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();
}
}