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(); } }