using Fake;
using InterfaceForward.Domain.Shared.Dtos;
using InterfaceForward.Domain.Shared.Enum;
using InterfaceForward.Domain.Shared.Helpers;
using InterfaceForward.Repositories.App.Entitys;
using InterfaceForward.Repositories.App.ValueObjects;
using InterfaceForward.Repositories.Dictionary.Entitys;
using InterfaceForward.Repositories.Interface.Entitys;
using InterfaceForward.Repositories.Parameter.Entities;
using InterfaceForward.Repositories.ServiceProvider.Entitys;
namespace InterfaceForward.Repositories;
///
///
///
public class InterfaceForwardQuery : BasicRepository, IScopedDependency
{
///
/// 通过服务商id和主体id查找账户id,如果账户不存在则返回null
///
/// 服务商id
/// 应用id
///
public async Task GetAccountIdAsync(int serviceProviderId, int appId)
{
return await Context.Queryable()
.Where(x => x.ServiceProviderId == serviceProviderId && x.AppId == appId)
.Select(x => x.Id)
.FirstAsync();
}
///
/// 通过服务商code获取服务商
///
/// 服务商code
///
public async Task GetServiceProviderByCodeAsync(string serviceProviderCode)
{
return await Context.Queryable()
.Where(x => x.Code == serviceProviderCode).Select()
.FirstAsync();
}
///
/// 通过服务商Id获取服务商
///
/// 服务商Id
///
public async Task GetServiceProviderByIdAsync(int serviceProviderId)
{
return await Context.Queryable()
.Where(x => x.Id == serviceProviderId).Select()
.FirstAsync();
}
///
/// 通过账户id获取账户字段列表
///
/// 账户id
///
public async Task> GetAccountFieldListAsync(int accountId)
{
if (accountId == default) return new List();
var query = Context.Queryable()
.LeftJoin((a, b) => a.Id == b.AccountFieldId);
return await query.Where((a, b) => b.AccountId == accountId)
.Select((a, b) => new ServiceProviderAccountFieldWithValueDto
{
FieldName = a.FieldName,
FieldValue = b.FieldValue
})
.ToListAsync();
}
///
/// 查找app
///
///
///
///
public async Task FindAppAsync(string appKey, string appSecret)
{
return await Context.Queryable()
.Where(x => x.AppKey == appKey && x.AppSecret == appSecret)
.Select()
.FirstAsync();
}
///
/// 获取接口QPS
///
///
///
///
public async Task GetQpsAsync(int appId, string interfaceCode)
{
return await Context.Queryable()
.Where(x =>
x.AppId == appId && x.InterfaceCode == interfaceCode)
.Select(x => x.QPS)
.FirstAsync();
}
///
/// 获取参数映射列表
///
/// 映射id集合
/// 是入参映射
///
public async Task> GetParameterMapListAsync(List mapIds,
bool isInParaMap)
{
// tips:这里要拿所有节点,而非仅叶子,因为要构建参数树
/*
SELECT `b`.`Id` AS `Id` , `b`.`PId` AS `PId` , b.InterfaceId, `b`.`Name` AS `Name` ,b.Sort, `b`.`Type` AS `Type` , `b`.`Alias` AS `Alias` , CONCAT(d.Code, '.', c.Alias) AS `MapAlias` , `b`.`IsRequired` AS `IsRequired`
from t_interface_map t
LEFT JOIN `t_parameter` `b` ON ( `t`.`DownStreamId` = `b`.`InterfaceId` ) and b.IsInPara and `b`.`IsDeleted` = 0 -- AND ( `b`.`Type` <> 12 ) AND ( `b`.`Type` <> 10 )
Left JOIN `t_interface_map_detail` `a` ON ( `t`.`Id` = `a`.`InterfaceMapId` ) and b.id = a.ParaId and a.IsDeleted = 0
Left JOIN `t_parameter` `c` ON ( `a`.`MappedParaId` = `c`.`Id` ) AND ( `c`.`IsDeleted` = 0 )
Left JOIN t_interface d on c.interfaceid = d.id
WHERE t.id in (403) and t.IsDeleted = 0
ORDER BY `b`.`Sort` ASC
*/
var ids = mapIds.JoinAsString(",");
var isMultiMap = mapIds.Count > 1;
// 因为入参映射有多个 出参映射只有一个(挂在第一个映射)
return await Context.SqlQueryable(@$"
select `b`.`Id` AS `Id` , `b`.`PId` AS `PId` , b.InterfaceId, `b`.`Name` AS `Name` ,b.Sort, `b`.`Type` AS `Type` , `b`.`Alias` AS `Alias` , {(isMultiMap ? "CONCAT(d.Code, '.', c.Alias)" : "c.Alias")} AS `MapAlias` , `b`.`IsRequired` AS `IsRequired`
from t_interface_map t
LEFT JOIN `t_parameter` `b` ON {(isInParaMap ? "t.DownStreamId" : "t.UpStreamId")} = `b`.`InterfaceId` and b.IsInPara = {isInParaMap} AND ( `b`.`IsDeleted` = 0 )
Left JOIN `t_interface_map_detail` `a` ON ( `t`.`Id` = `a`.`InterfaceMapId` ) and b.id = a.ParaId and a.IsDeleted = 0
Left JOIN `t_parameter` `c` ON ( `a`.`MappedParaId` = `c`.`Id` ) AND ( `c`.`IsDeleted` = 0 )
Left JOIN t_interface d on c.interfaceid = d.id
WHERE {(isInParaMap ? $"t.id in ({ids})" : $"t.id = {mapIds.First()}")} and t.IsDeleted = 0
ORDER BY `b`.`Sort` ASC").ToListAsync();
}
///
/// 获取接口根据接口code
///
///
///
public async Task GetInterfaceByCodeAsync(string interfaceCode)
{
var res = await GetInterfaceByCodesAsync(interfaceCode);
return res.FirstOrDefault();
}
///
/// 构建转发核心上下文
///
///
///
///
///
public async Task BuildForwardCoreContext(InterfaceDto systemInterface,
ServiceProviderDto serviceProvider)
{
var maps = await Context.Queryable()
.Where(x => x.UpStreamCode == systemInterface.Code && x.ServiceProviderId == serviceProvider.Id)
.Select(x => new { x.Id, x.DownStreamCode, x.PrefixScript, x.PostfixScript })
.ToArrayAsync();
if (maps == null || maps.Length == 0) throw new BusinessException(message: "映射不存在");
var downStreamIds = maps.Select(x => x.DownStreamCode).ToArray();
var targetInterfaceList = await GetInterfaceByCodesAsync(downStreamIds);
if (targetInterfaceList == null || targetInterfaceList.Count != downStreamIds.Length)
throw new BusinessException(message: "服务商一个或多个接口不存在");
var mapIds = maps.Select(x => x.Id).ToList();
var context = new ForwardCoreContextCache
{
OriginalInterface = systemInterface,
TargetServiceProvider = serviceProvider,
ServiceProviderAuthConfigs = await Context.Queryable()
.LeftJoin((a, b) => a.ParameterId == b.Id)
.Where(a => a.ServiceProviderId == serviceProvider.Id)
.Select((a, b) => new ServiceProviderAuthConfigDto
{
Flag = a.Flag,
ParameterAlias = b.Alias,
Value1 = a.Value1,
Value2 = a.Value2,
Value3 = a.Value3
})
.ToListAsync(),
OutParamTreeList = JsonHelper.BuildTreeList(
await GetParameterMapListAsync(mapIds, false)
) // 构建系统返参数树形结构
};
if (serviceProvider.AuthInterfaceCode != null)
{
var authInterface = await GetInterfaceByCodeAsync(serviceProvider.AuthInterfaceCode);
if (authInterface == null)
{
throw new BusinessException($"授权接口{serviceProvider.AuthInterfaceCode}不存在");
}
context.ServiceProviderAuthInterface = new TargetInterfaceSummary
{
TargetInterface = authInterface,
FixedFieldList = await GetAllFixedFieldListAsync(serviceProvider.Id, authInterface.Id),
ReturnConfigList = await GetInterfaceReturnConfigListAsync(authInterface.Id),
FormFieldList = await GetFormFieldListAsync(authInterface.Id),
};
}
var inParaMaps = await GetParameterMapListAsync(mapIds, true);
foreach (var map in maps)
{
var targetInterface = targetInterfaceList.First(x => map.DownStreamCode == x.Code);
var items = inParaMaps.Where(x => x.InterfaceId == targetInterface.Id).ToList();
var fixedFieldList = await GetAllFixedFieldListAsync(serviceProvider.Id, targetInterface.Id);
if (targetInterface.MappedParamType == ParameterType.Array)
{
var rootLen = items.First(x => x.PId == 0).Alias.Length;
foreach (var item in fixedFieldList.Where(x => x.FieldPosition == FieldPosition.Body))
{
// 去除固定参数[*]前面的路径
item.FieldName = item.FieldName[rootLen..];
}
}
context.TargetInterfaces.Add(new TargetInterfaceSummary
{
TargetInterface = targetInterface,
InParamTreeList = JsonHelper.BuildTreeList(items), // 构建目标接口入参树形结构
FixedFieldList = fixedFieldList,
ReturnConfigList = await GetInterfaceReturnConfigListAsync(targetInterface.Id),
PrefixScript = map.PrefixScript,
PostfixScript = map.PostfixScript,
FormFieldList = await GetFormFieldListAsync(targetInterface.Id),
});
}
return context;
}
private async Task> GetFormFieldListAsync(int interfaceId)
{
return await Context.Queryable()
.Where(x => x.InterfaceId == interfaceId)
.Select()
.ToListAsync();
}
///
/// 获取所有固定字段(服务商+接口)
///
/// 服务商id
/// 接口id
///
private async Task> GetAllFixedFieldListAsync(int serviceProviderId,
int interfaceId)
{
var fixedFieldList = await Context.Queryable()
.Where(a => a.ServiceProviderId == serviceProviderId || a.InterfaceId == interfaceId)
.Select(x => new
{
x.ServiceProviderId,
x.InterfaceId,
x.FieldName,
x.FieldValue,
x.FieldPositions,
x.Description
})
.ToListAsync();
// 接口字段
var list1 = from interfaceField in fixedFieldList.Where(x => x.InterfaceId == interfaceId)
from position in interfaceField.FieldPositions.Split(",").Select(Enum.Parse)
select new FixedFieldWithValueDto
{
FieldOwner = FieldOwner.Interface, FieldName = interfaceField.FieldName,
FieldValue = interfaceField.FieldValue, Description = interfaceField.Description,
FieldPosition = position,
};
// 接口不曾拥有的服务商参数
var list2 = from serviceProviderField in fixedFieldList.Where(x => x.ServiceProviderId == serviceProviderId)
from position in serviceProviderField.FieldPositions.Split(",")
.Select(Enum.Parse)
where !list1.Any(it => it.FieldName.Equals(serviceProviderField.FieldName) && it.FieldPosition == position)
select new FixedFieldWithValueDto
{
FieldOwner = FieldOwner.ServiceProvider, FieldName = serviceProviderField.FieldName,
FieldValue = serviceProviderField.FieldValue, Description = serviceProviderField.Description,
FieldPosition = position,
};
return list1.Concat(list2).ToList();
}
///
/// 获取接口返回配置集合
///
/// 接口id
///
private async Task> GetInterfaceReturnConfigListAsync(int interfaceId)
{
return await Context.Queryable()
.LeftJoin((a, b) => a.ParameterId == b.Id)
.Where(a => a.InterfaceId == interfaceId)
.Select((a, b) => new InterfaceReturnConfigDto
{
InterfaceId = a.InterfaceId,
ConfigType = a.ConfigType,
Path = b.Alias,
Value = a.Value,
}).ToListAsync();
}
///
/// 获取接口根据接口code
///
///
///
private async Task> GetInterfaceByCodesAsync(params string[] interfaceCodes)
{
var query = Context.Queryable(
(a, d) => new JoinQueryInfos(
JoinType.Left, a.RequestMethod == d.Id
))
.Where(a => interfaceCodes.Contains(a.Code) && a.IsDeleted == false)
.Filter(null, true)
.Select((a, d) =>
new InterfaceDto
{
Id = a.Id,
Name = a.Name,
ServiceProviderId = a.ServiceProviderId,
Code = a.Code,
RequestAddress = a.RequestAddress,
RequestProtocol = a.RequestProtocol,
ContentType = a.ContentType,
ResponseContentType = a.ResponseContentType,
RequestMethod = d.Name,
IsBatch = a.IsBatch,
Limit = a.Limit,
Qps = a.Qps,
FlowCode = a.FlowCode,
IsDisableAuth = a.IsDisableAuth,
MappedParamType = a.MappedParamType
});
return await query.ToListAsync();
}
}