后端服务A远程调用服务B传递List<String>参数

本文介绍了服务A如何通过POST请求调用服务B的/user/count接口,获取教研室根据corpIdList查询的成员数量。展示了JSON数据封装和HTTP请求的实现细节。

服务B的接收接口

   @ApiOperation("根据教研室corpIdList查询教研室的成员数量")
    @PostMapping("/user/count")
    public AjaxResult getRoomUserCount(@RequestBody List<String> corpIdList) {
        List<JxClassroomUserCountVo> voList = classroomService.getRoomUserCount(corpIdList);
        return AjaxResult.success(voList);
    }

服务A调用方

List<String> corpIdList = jxClassroomList.stream().map(JxClassroom::getCorpId).collect(Collectors.toList());
String jsonString = JSONObject.toJSONString(corpIdList);
String info = HttpUtil.sendPost(DataUrl + "/room/user/count", jsonString);

这个是封装好的发送post请求方法

/**
     * 发送HttpPost请求,参数为json字符串
     *
     * @param url     请求地址
     * @param jsonStr json字符串
     * @return
     */
    public static String sendPost(String url, String jsonStr) {
        CloseableHttpClient httpclient = getBuilder().build();
        HttpPost httpPost = new HttpPost(url);
        String result = null;
        try {
            StringEntity stringEntity = new StringEntity(jsonStr, Consts.UTF_8);
            stringEntity.setContentType("application/json");
            httpPost.setEntity(stringEntity);
            CloseableHttpResponse httpResponse = httpclient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            result = EntityUtils.toString(httpEntity);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;

    }
using Mds.Contracts.Customization; using Mds.Customization.Entities; using Mds.Customization.Repositories; using Mds.Enums.Customization; using Mds.Extention; using Mds.Master.Customer; using Mds.Master.Entities; using Mds.Som.ChargePriceAdjust; using Mds.Som.ChargePriceAdjustItem; using Mds.Som.Entities; using Mds.Toolkit; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Minio.DataModel.Notification; using Modern.Toolkits.Dtos; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Net.Http; using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; using Volo.Abp; using Volo.Abp.Application.Dtos; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Repositories; namespace Mds.Customization { //[Authorize] public class CustSearchAppService : MdsCustCrudAppService <SearchEntity, SearchDto, Dictionary<string, object>, Guid, PagedAndFilterResultRequestDto, CreateOrUpdateSearchDto, CreateOrUpdateSearchDto>, ICustSearchAppService { private readonly ILogger<CustSearchAppService> _logger; private readonly ISearchRepository _searchRepository; private readonly IRecordTypeRepository _recordTypeRepository; private readonly ICustRecordTypeFieldAppService _recordTypeFieldAppService; private readonly IRecordTypeFieldFilterSourceListRepository _recordFieldFilterSourceListRepository; private readonly ISearchAvailableFilterRepository _searchAvailableFilterRepository; private readonly ISearchCriteriaRepository _searchCriteriaRepository; private readonly ISearchResultRepository _searchResultRepository; private readonly IRecordTypeFieldRepository _recordTypeFieldRepository; public CustSearchAppService( IHttpClientFactory httpClientFactory, IRepository<SearchEntity, Guid> repository, ILogger<CustSearchAppService> logger, IHttpContextAccessor httpContextAccessor, ISearchRepository searchRepository, ISearchCriteriaRepository searchCriteriaRepository, ISearchAvailableFilterRepository searchAvailableFilterRepository, IRecordTypeRepository recordTypeRepository, IRecordTypeFieldRepository recordFieldRepository, IFieldRepository fieldRepository, ICustFieldAppService fieldAppService, ICustRecordTypeFieldAppService recordTypeFieldAppService, IRecordTypeFieldFilterSourceListRepository recordTypeFieldFilterSourceListRepository , ISearchResultRepository searchResultRepository, IRecordTypeFieldRepository recordTypeFieldRepository) : base(repository) { _logger = logger; _searchRepository = searchRepository; _recordTypeRepository = recordTypeRepository; _recordTypeFieldAppService = recordTypeFieldAppService; _recordFieldFilterSourceListRepository = recordTypeFieldFilterSourceListRepository; _searchAvailableFilterRepository = searchAvailableFilterRepository; _searchCriteriaRepository = searchCriteriaRepository; _searchResultRepository = searchResultRepository; _recordTypeFieldRepository = recordTypeFieldRepository; } public async override Task<SearchDto> GetAsync(Guid id) { var entity = await _searchRepository.FindAsync(id); //.GetAsync(id); if (entity == null) { var recordType = await _recordTypeRepository.GetAsync(id); entity = ObjectMapper.Map<RecordTypeEntity, SearchEntity>(recordType); } var dto = ObjectMapper.Map<SearchEntity, SearchDto>(entity); var fields = await _GetFieldDtosAsync(entity); foreach (var item in dto.SearchResults) { var field = fields.FirstOrDefault(x => x.Id == item.FieldId); item.FieldCustomId = field.CustomId; item.FieldName = field.Name; item.field = field; if (item.LinkFieldId.HasValue && item.LinkFieldId != Guid.Empty) { var linkField = fields.FirstOrDefault(x => x.Id == item.LinkFieldId); item.FieldCustomId = field.CustomId + "." + linkField.CustomId; item.FieldName = linkField.Name; item.field = Newtonsoft.Json.JsonConvert.DeserializeObject<RecordTypeFieldDto>(Newtonsoft.Json.JsonConvert.SerializeObject(linkField)); item.field.FieldCustomId = item.FieldCustomId; item.field.Name = item.FieldName; } item.RecordTypeId = entity.RecordTypeId; } var searchAvailableFilterDtos = await _GetSearchAvailableFilterDtos(fields, entity); dto.SearchAvailableFilters = searchAvailableFilterDtos; foreach (var item in dto.SearchAvailableFilters) { item.RecordTypeId = entity.RecordTypeId; } foreach (var item in dto.SearchCriterias) { item.RecordTypeId = entity.RecordTypeId; Guid filter = new Guid(); if (Guid.TryParse(item.Filter, out filter)) { var fieldInfo = fields.FirstOrDefault(o => o.Id == Guid.Parse(item.Filter)); item.FilterOptionLabelFields = fieldInfo.OptionLabelFields; item.FilterFieldListOrRecordTypeId = fieldInfo.FieldListOrRecordTypeId; } } return dto; } public async Task<object> GetSearchResultsAsync(Guid id, FilterSearchResultRequestDto input) { var search = await _searchRepository.FindAsync(id); RecordTypeEntity recordType = null; if (search == null) { recordType = await _recordTypeRepository.GetAsync(id); search = ObjectMapper.Map<RecordTypeEntity, SearchEntity>(recordType); } if (recordType == null) recordType = await _recordTypeRepository.GetAsync(search.RecordTypeId); var fieldDtos = await _GetFieldDtosAsync(search); var searchResultDtos = await _GetSearchResultDto(fieldDtos, search); var methdorNameUri = ReplaceMethodNamePlaceholders(recordType.MethodName, input); input.Filter = await _GetFilterAsync(input, search, recordType, searchResultDtos); var result = await _fetchRemoteDataAsync(recordType, input, methdorNameUri); List<dynamic> resultItems = result.Items; // CamelCaseHelper.ToCamelCaseList(result.Items); if (recordType.IsList) { List<ListLineDto> dyList = new List<ListLineDto>(); foreach (var item in resultItems) { JObject jObject = JObject.FromObject(item); var dto = jObject.ToObject<ListLineDto>(); dyList.Add(dto); } var pageResult = new PagedResultDto<ListLineDto>() { TotalCount = result.TotalCount, Items = dyList }; return pageResult; } ProvideAdditionalInfo(resultItems, searchResultDtos, 0); if (recordType.CustomId == "history") await RepalceHistoryValueAsync(resultItems, input.RecordTypeId.Value); if (recordType.CustomId == "record-type-field-filter-source-list") await ProvidefilterSourceListInfoAsync(resultItems,searchResultDtos); List<object> list = new List<object>(); // 1. 构建对象 var propertyTypes = GetPropertyTypes(searchResultDtos); var dyResult = ReflectionHelper.CreateDynamicType("dyResult", propertyTypes); foreach (var item in resultItems) { var newdy = Activator.CreateInstance(dyResult); var properties = dyResult.GetProperties(); foreach (var property in properties) { var val = item[property.Name] ?? item[ToPascalCase(property.Name)]; ReflectionHelper.SetPropertyValue(newdy, property.Name, val); } list.Add(newdy); } result.Items = list; return new PagedResultDto<dynamic>() { TotalCount = result.TotalCount, Items = result.Items }; } private static string ToPascalCase(string camelCase) { if (string.IsNullOrEmpty(camelCase)) return camelCase; return char.ToUpper(camelCase[0]) + camelCase.Substring(1); } public async Task<List<object>> ComplementAdditionalInfo(Guid id, List<dynamic> items) { var search = await _searchRepository.FindAsync(id); if (search == null) { var recordType = await _recordTypeRepository.GetAsync(id); search = ObjectMapper.Map<RecordTypeEntity, SearchEntity>(recordType); } var fieldDtos = await _GetFieldDtosAsync(search); var searchResultDtos = await _GetSearchResultDto(fieldDtos, search); ProvideAdditionalInfo(items, searchResultDtos, 0); List<object> list = new List<object>(); // 1. 构建对象 var propertyTypes = GetPropertyTypes(searchResultDtos); var dyResult = ReflectionHelper.CreateDynamicType("dyResult", propertyTypes); foreach (var item in items) { var newdy = Activator.CreateInstance(dyResult); var properties = dyResult.GetProperties(); foreach (var property in properties) { var val = item[property.Name]; ReflectionHelper.SetPropertyValue(newdy, property.Name, val); } list.Add(newdy); } return list; } public async Task<SearchDto> GetSearchResultsByCustomIdAsync(string customId) { //根据customId先取recordType var entity = await _recordTypeRepository.GetAsync(p => p.CustomId == customId); if (entity == null) { throw new UserFriendlyException(string.Format("未找到对应的RecodType")); } var result = await GetAsync(entity.Id); return result; } #region 私有方法 protected async override Task DeleteBeforeCheckAsync(Guid id) { var entity = await _searchRepository.GetAsync(id); if (entity.IsStandard) throw new BusinessException(MdsDomainErrorCodes.IsStandardDataNotCanDelete); } private async Task<AllResultDto<dynamic>> _fetchRemoteDataAsync(RecordTypeEntity recordType, FilterSearchResultRequestDto input, string methodName) // Search search, { var pageResult = new AllResultDto<dynamic>(); SetDefaultSorting(input, recordType); string serviceModule = recordType.ServiceModule; string recordTypeServiceName = recordType.ServiceName; //.EntityName; int maxResultCount = input.MaxResultCount == 1 ? 1000 : input.MaxResultCount; string strParams = string.Format("?Sorting={0}&SkipCount={1}&MaxResultCount={2}&IsInActive={3}&Filter={4}", input.Sorting, input.SkipCount, maxResultCount, input.IsInActive, input.Filter); var result = await GetDaprInvokeResultAsync<PagedResultDto<dynamic>>(HttpMethod.Get, recordType.DaprAppId, serviceModule, recordTypeServiceName, methodName, strParams); pageResult.TotalCount = result.TotalCount; pageResult.Items = result.Items.ToList(); if (input.MaxResultCount == 1) { var pageCount = Math.Ceiling((double)pageResult.TotalCount / maxResultCount); for (int i = 1; i < pageCount; i++) { int skipCount = 1000 * i; string strParams1 = string.Format("?Sorting={0}&SkipCount={1}&MaxResultCount={2}&IsInActive={3}&Filter={4}", input.Sorting, skipCount, maxResultCount, input.IsInActive, input.Filter); var result1 = await GetDaprInvokeResultAsync<PagedResultDto<dynamic>>(HttpMethod.Get, recordType.DaprAppId, serviceModule, recordType.ServiceName, methodName, strParams1); // .EntityName pageResult.Items.AddRange(result1.Items); } } return pageResult; } private static void SetDefaultSorting(FilterSearchResultRequestDto input, RecordTypeEntity recordType) { var hasInputSort = !string.IsNullOrWhiteSpace(input.Sorting) && recordType.RecordTypeFields.Any(f => f.FieldCustomId == input.Sorting.Split(" ")[0]); if (hasInputSort) return; if (recordType.IsList) { input.Sorting = "sort"; return; } var hasSort = recordType.RecordTypeFields.Any(f => f.FieldCustomId == "sort"); input.Sorting = hasSort ? "sort" : "id"; } private async Task RepalceHistoryValueAsync(List<dynamic> items, Guid recordTypeId) { var recordType = await _recordTypeRepository.GetAsync(recordTypeId); items.ForEach(item => { string propertyName = Convert.ToString(item["propertyName"]); var field = recordType.RecordTypeFields.Find(p => p.FieldCustomId.ToLower() == propertyName.ToLower()); if (field != null) { item["propertyName"] = field.Name; } }); } private async Task ProvidefilterSourceListInfoAsync(List<dynamic> items, List<SearchResultDto> dicSearchResult) { List<Guid> filterUsingFieldIds = new List<Guid>(); items.ForEach(item => { string filterUsing = Convert.ToString(item["filterUsingId"]); var id = filterUsing.Split('.').LastOrDefault(); if (id != null) filterUsingFieldIds.Add(Guid.Parse(id)); }); var fieldDtos = await _recordTypeFieldAppService.GetListByIdsAsync(filterUsingFieldIds.Distinct().ToList()); var listOrRecordTypeFieldDtos = fieldDtos.Where(p => p.FieldViewType == FieldViewType._13_ListOrRecordType).ToList(); foreach (var item in items) { string filterUsing = Convert.ToString(item["filterUsingId"]); var id = filterUsing.Split('.').LastOrDefault(); if (id == null) return; var fieldDto = listOrRecordTypeFieldDtos.FirstOrDefault(p => p.Id.ToString() == id); if (fieldDto == null) { item["value1_text"] = item["value1"]; item["value2_text"] = item["value2"]; } else if (!string.IsNullOrWhiteSpace(Convert.ToString(item["value1"]))) { string v1 = Convert.ToString(item["value1"]); string v2 = Convert.ToString(item["value2"]); var ids = new List<object> { v1, v2 }; var entities = await _GetEntitiesByIdsAsync(ids, fieldDto); var entityV1 = entities.FirstOrDefault(p => p.id == v1 || p.value == v1); if (entityV1 != null) { item["value1_text"] = GetFieldCustomIdText(entityV1, "[\"name\"]"); // "name" } var entityV2 = entities.FirstOrDefault(p => p.id == v2 || p.value == v2); if (entityV2 != null) { item["value2_text"] = GetFieldCustomIdText(entityV2, "[\"name\"]"); } } } } private static string ReplaceMethodNamePlaceholders(string methodName, FilterSearchResultRequestDto input) { if (string.IsNullOrWhiteSpace(methodName)) return null; Dictionary<string, string> placeholders = new Dictionary<string, string>(); if (!string.IsNullOrWhiteSpace(input.Filter) && input.Filter != "{}" && input.Filter != "[]") { var inputFilter = Newtonsoft.Json.Linq.JObject.Parse(input.Filter); foreach (var property in inputFilter.Properties()) { string propertyName = property.Name; string propertyValue = property.Value.ToString(); placeholders[propertyName] = propertyValue; } } // 使用正则表达式查找所有被大括号包围的占位符 var newMethodName = Regex.Replace(methodName, @"\{([^}]+)\}", match => { // 获取大括号内的内容(占位符) string placeholder = match.Groups[1].Value; // 尝试从字典中获取替换值 // 如果字典中存在该占位符,则返回替换值 // 如果不存在,则返回原始匹配(即保留大括号和占位符内容) if (placeholders.ContainsKey(placeholder)) { var val = placeholders[placeholder]; placeholders.Remove(placeholder); return val; } return match.Value; }); // 检查替换后的字符串中是否还有剩余的占位符 var matches = Regex.Matches(newMethodName, @"\{([^}]+)\}"); var remainingPlaceholders = matches.Cast<Match>().Select(m => m.Groups[1].Value).ToList(); if (remainingPlaceholders.Any()) throw new UserFriendlyException(string.Format("方法{0}中,缺少参数{1}", methodName, string.Join(",", remainingPlaceholders))); input.Filter = Newtonsoft.Json.JsonConvert.SerializeObject(placeholders); return newMethodName; } private async Task<string> _GetFilterAsync(FilterSearchResultRequestDto input, SearchEntity search, RecordTypeEntity recordType, List<SearchResultDto> searchResultDtos) { List<FilterModel> filters = new List<FilterModel>(); if (!string.IsNullOrWhiteSpace(input.Filter) && input.Filter != "{}" && input.Filter != "[]") { var inputFilter = Newtonsoft.Json.Linq.JObject.Parse(input.Filter); // 遍历对象的所有属性 // 1. 添加动态数据过滤 // 1.1 当属性里有Filter_RecordTypeFieldId(特定字段,根据id查找RecordTypeFieldFilterSourceListDto 列表)构建过滤条件; // 1.2 comparedField 使用参数传过来的值,替换RecordTypeFieldFilterSourceListDto中CompareField的值; // 1.3 构建过滤条件,并合并其他用户动态传递过来的参数 var hasFilterField = inputFilter.Properties().Any(p => p.Name == "filter_RecordTypeFieldId"); if (hasFilterField) { var recordTypeFieldId = inputFilter["filter_RecordTypeFieldId"].ToString(); var filterSourceList = await _recordFieldFilterSourceListRepository.GetListAsync(p => p.RecordTypeFieldId == Guid.Parse(recordTypeFieldId)); var filterSourceListDtos = ObjectMapper.Map<List<RecordTypeFieldFilterSourceListEntity>, List<RecordTypeFieldFilterSourceListDto>>(filterSourceList); filterSourceListDtos = filterSourceListDtos.OrderBy(p => p.Line).ToList(); filterSourceListDtos.ForEach(line => { if (line.CompareToField.HasValue) { var compareValue = inputFilter["filter_" + line.FilterUsing].ToString(); line.Value1 = compareValue.StartsWith("opt_") ? compareValue.Substring(compareValue.Split(" ")[0].Length + 1) : compareValue; if (line.Value1 == "undefined" || line.Value1 == "null") line.Value1 = Guid.Empty.ToString(); inputFilter.Remove("filter_" + line.FilterUsing); } }); var filterList1 = ObjectMapper.Map<List<RecordTypeFieldFilterSourceListDto>, List<FilterModel>>(filterSourceListDtos); filterList1[filterList1.Count - 1].LogicalOperator = LogicalOperator.And; filters = filterList1; inputFilter.Remove("filter_RecordTypeFieldId"); } foreach (var property in inputFilter.Properties()) { string propertyName = property.Name; // object propertyValue = property.Value; string propertyValue = property.Value.ToString(); if (string.IsNullOrWhiteSpace(propertyValue)) continue; int optType = propertyValue.StartsWith("opt_") ? Convert.ToInt32(propertyValue.Substring(4, propertyValue.Split(" ")[0].Length - 4)) : (int)OperatorType.Equal; propertyValue = propertyValue.StartsWith("opt_") ? propertyValue.Substring(propertyValue.Split(" ")[0].Length + 1) : propertyValue; string propertyValue2 = string.Empty; OperatorType operatorType = (OperatorType)optType; if (operatorType == OperatorType.Between) { var values = JsonSerializer.Deserialize<List<string>>(propertyValue); propertyValue = values[0]; propertyValue2 = values[1]; if (!string.IsNullOrWhiteSpace(propertyValue) && !string.IsNullOrWhiteSpace(propertyValue2)) { FilterModel filter1 = new FilterModel(); filter1.Not = false; filter1.OpenParens = 1; filter1.FilterUsing = propertyName; filter1.OperatorType = OperatorType.GreaterThanOrEqual; filter1.Value1 = propertyValue.ToString(); filter1.Value2 = string.Empty; filter1.CloseParens = 0; filter1.LogicalOperator = LogicalOperator.And; filter1.Line = -1; filters.Add(filter1); FilterModel filter2 = new FilterModel(); filter2.Not = false; filter2.OpenParens = 1; filter2.FilterUsing = propertyName; filter2.OperatorType = OperatorType.LessThanOrEqual; filter2.Value1 = propertyValue2.ToString(); filter2.Value2 = string.Empty; filter2.CloseParens = 0; filter2.LogicalOperator = LogicalOperator.And; filter2.Line = -1; filters.Add(filter2); } else if (string.IsNullOrWhiteSpace(propertyValue) && !string.IsNullOrWhiteSpace(propertyValue2)) { FilterModel filter2 = new FilterModel(); filter2.Not = false; filter2.OpenParens = 0; filter2.FilterUsing = propertyName; filter2.OperatorType = OperatorType.LessThanOrEqual; filter2.Value1 = propertyValue2.ToString(); filter2.Value2 = string.Empty; filter2.CloseParens = 0; filter2.LogicalOperator = LogicalOperator.And; filter2.Line = -1; filters.Add(filter2); } else if (!string.IsNullOrWhiteSpace(propertyValue) && string.IsNullOrWhiteSpace(propertyValue2)) { FilterModel filter1 = new FilterModel(); filter1.Not = false; filter1.OpenParens = 0; filter1.FilterUsing = propertyName; filter1.OperatorType = OperatorType.GreaterThanOrEqual; filter1.Value1 = propertyValue.ToString(); filter1.Value2 = string.Empty; filter1.CloseParens = 0; filter1.LogicalOperator = LogicalOperator.And; filter1.Line = -1; filters.Add(filter1); } } else if (propertyName.ToLower() == "keywords") { if (string.IsNullOrWhiteSpace(propertyValue) || propertyValue == "null") continue; var kvFilters = GetKeyWordsFilterModels(propertyValue, searchResultDtos); filters.AddRange(kvFilters); } else { FilterModel filter = new FilterModel(); filter.Not = false; filter.OpenParens = 0; filter.FilterUsing = propertyName; filter.OperatorType = (OperatorType)optType; // OperatorType.Equal; filter.Value1 = propertyValue.ToString(); filter.Value2 = propertyValue2; filter.LogicalOperator = LogicalOperator.And; filter.CloseParens = 0; filter.Line = -1; filters.Add(filter); } } } if (recordType.IsList) { FilterModel filter = new FilterModel(); filter.Not = false; filter.OpenParens = 0; filter.FilterUsing = "RecordTypeId"; filter.OperatorType = OperatorType.Equal; filter.Value1 = recordType.Id.ToString(); filter.Value2 = string.Empty; filter.LogicalOperator = LogicalOperator.And; filter.CloseParens = 0; filter.Line = -1; filters.Add(filter); } if (search.SearchCriterias != null && search.SearchCriterias.Count > 0) { // 子查询处理 foreach (var item in search.SearchCriterias) { FilterModel filterModel = new FilterModel(); filterModel.Not = item.Not; filterModel.OpenParens = item.OpenParens; filterModel.FilterUsing = item.Filter; filterModel.OperatorType = item.OperatorType; filterModel.Value1 = item.Value1; filterModel.Value2 = item.Value2; filterModel.LogicalOperator = item.LogicalOperator; filterModel.CloseParens = item.CloseParens; filterModel.Line = item.Line; filters.Add(filterModel); } await _ResetSubScopeFilterAsync(recordType, filters); } for (int i = 0; i < filters.Count; i++) { filters[i].Line = i; } var strFilter = filters.Count > 0 ? JsonSerializer.Serialize(filters) : string.Empty; return strFilter; } public async Task ProvideAdditionalInfo(List<dynamic> items, List<SearchResultDto> dicSearchResult, int level) { if (level > 5 || items.Count == 0) return; List<string> containCustomIdTexts = new List<string>(); var textSearchResult = dicSearchResult.Where(p => !string.IsNullOrWhiteSpace(p.FieldCustomId) && p.FieldCustomId.Contains("_text")).ToList(); if (textSearchResult.Count > 0) { containCustomIdTexts = textSearchResult.Select(p => p.FieldCustomId).ToList(); } var searchResultDtos = dicSearchResult.Where(p => (p.field.FieldViewType == FieldViewType._13_ListOrRecordType || p.field.FieldViewType == FieldViewType._23_Dynamic) && !containCustomIdTexts.Contains(p.FieldCustomId + "_text")).ToList(); if (searchResultDtos.Count == 0) return; foreach (var searchResultDto in searchResultDtos) { var fieldDto = searchResultDto.field; if (fieldDto.FieldViewType == FieldViewType._23_Dynamic) // 动态字段类型,其text文本,由服务传递,不在这里聚合 { bool flag = dicSearchResult.Any(p => p.FieldCustomId == searchResultDto.FieldCustomId + "_text"); if (!flag) { var searchResultDtoText = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchResultDto>(Newtonsoft.Json.JsonConvert.SerializeObject(searchResultDto)); searchResultDtoText!.FieldCustomId = searchResultDto.FieldCustomId + "_text"; searchResultDtoText.field.FieldViewType = FieldViewType._7_FreeFormText; dicSearchResult.Add(searchResultDtoText); } continue; } if (fieldDto.FieldViewType != FieldViewType._13_ListOrRecordType) continue; //if (fieldDto.CustomId.ToLower() == "filterUsing".ToLower()) //{ // foreach (var item in items) // { // item[searchResultDto.FieldCustomId + "_text"] = GetFieldCustomIdText(item, searchResultDto.FieldCustomId); // item[searchResultDto.FieldCustomId]; // bool flag = dicSearchResult.Any(p => p.FieldCustomId == searchResultDto.FieldCustomId + "_text"); // if (!flag) // { // var searchResultDtoText = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchResultDto>(Newtonsoft.Json.JsonConvert.SerializeObject(searchResultDto)); // searchResultDtoText.FieldCustomId = searchResultDto.FieldCustomId + "_text"; // searchResultDtoText.field.FieldViewType = FieldViewType._7_FreeFormText; // dicSearchResult.Add(searchResultDtoText); // } // } // continue; //} var ids = items.Select(p => p[searchResultDto.FieldCustomId]).Distinct().ToList(); ids.RemoveAll(p => p == null); if (ids.Count == 0) { continue; } var groupedLists = ids .Select((value, index) => new { Index = index, Value = value }) .GroupBy(x => x.Index / 10) .Select(g => g.Select(x => x.Value).ToList()) .ToList(); List<dynamic> resultItemlist = new List<dynamic>(); #region 并行 Task<List<dynamic>>[] taskArray = new Task<List<dynamic>>[groupedLists.Count]; for (var i = 0; i < groupedLists.Count; i++) { var groupIds = groupedLists[i]; taskArray[i] = _GetEntitiesByIdsAsync(groupIds, fieldDto); } // 等待所有任务完成 Task.WaitAll(taskArray); foreach (var task in taskArray) { var resultItems = task.Result; if (resultItems != null) resultItemlist.AddRange(resultItems); } #endregion foreach (var item in items) { string itemid = item[searchResultDto.FieldCustomId]; if (string.IsNullOrWhiteSpace(itemid)) continue; var resultItem = fieldDto.FieldListOrRecordTypeIsList ? resultItemlist.FirstOrDefault(p => p.value == itemid && p.recordTypeId == fieldDto.FieldListOrRecordTypeId) : resultItemlist.FirstOrDefault(p => string.Equals(Convert.ToString(p.id), itemid, StringComparison.OrdinalIgnoreCase)); if (string.IsNullOrWhiteSpace(item[searchResultDto.FieldCustomId + "_text"] as string)) { item[searchResultDto.FieldCustomId + "_text"] = resultItem == null ? "" : GetFieldCustomIdText(resultItem, searchResultDto.field.LabelFields); // resultItem.name; } //item[searchResultDto.FieldCustomId + "_text"] = resultItem == null ? "" : GetFieldCustomIdText(resultItem, searchResultDto.field.LabelFields); // resultItem.name; bool flag = dicSearchResult.Any(p => p.FieldCustomId == searchResultDto.FieldCustomId + "_text"); if (!flag) { var searchResultDtoText = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchResultDto>(Newtonsoft.Json.JsonConvert.SerializeObject(searchResultDto)); searchResultDtoText.FieldCustomId = searchResultDto.FieldCustomId + "_text"; searchResultDtoText.field.FieldViewType = FieldViewType._7_FreeFormText; dicSearchResult.Add(searchResultDtoText); } var searchResults = dicSearchResult.FindAll(p => p.FieldId == fieldDto.Id && p.LinkFieldId != null && p.LinkFieldId != Guid.Empty); foreach (var searchResult in searchResults) { var linkField = searchResult.field; item[searchResult.FieldCustomId] = resultItem[linkField.CustomId]; } } } level++; ProvideAdditionalInfo(items, dicSearchResult, level); } private static string GetFieldCustomIdText(dynamic item, string? fieldName) { if (!string.IsNullOrEmpty(fieldName)) { var array = JArray.Parse(fieldName); fieldName = array[0].ToString(); } else { fieldName = "name"; } if (item is JToken jToken) { JObject? jObject = jToken as JObject; if (jObject == null) { return string.Empty; } foreach (var property in jObject) { if ( (property.Key== fieldName) && property.Value != null && property.Value.Type != JTokenType.Null) { return property.Value.ToString(); } } } return string.Empty; } private static List<FilterModel> GetKeyWordsFilterModels(string propertyValue, List<SearchResultDto> searchResultDtos) { List<FilterModel> filters = new List<FilterModel>(); List<string> keywordFields = new List<string>() { "name", "no", "code", "customId" }; List<string> keywordSearchResultDtos = searchResultDtos.Where(p => p.FieldCustomId.ToLower().EndsWith("name") || p.FieldCustomId.ToLower().EndsWith("no") || p.FieldCustomId.ToLower().EndsWith("code")).Select(p => p.FieldCustomId).ToList(); keywordFields = new HashSet<string>(keywordFields.Concat(keywordSearchResultDtos), StringComparer.OrdinalIgnoreCase).ToList(); for (int i = 0; i < keywordFields.Count; i++) { var item = keywordFields[i]; FilterModel filter = new FilterModel(); filter.Not = false; filter.OpenParens = 0; filter.FilterUsing = item; filter.OperatorType = OperatorType.Contains; filter.Value1 = propertyValue; filter.Value2 = string.Empty; filter.CloseParens = 0; filter.LogicalOperator = LogicalOperator.Or; filter.Line = -1; if (i == 0) filter.OpenParens = 1; if (i == keywordFields.Count - 1) { filter.LogicalOperator = LogicalOperator.And; filter.CloseParens = 1; } filters.Add(filter); } return filters; } private async Task<List<SearchResultDto>> _GetSearchResultDto(List<RecordTypeFieldDto> fieldDtos, SearchEntity search) { var recordType = await _recordTypeRepository.GetAsync(search.RecordTypeId); List<SearchResultDto> dicSearchResult = new List<SearchResultDto>(); foreach (var searchResult in search.SearchResults) { var searchResultDto = ObjectMapper.Map<SearchResultEntity, SearchResultDto>(searchResult); var fieldDto = fieldDtos.Find(p => p.Id == searchResult.FieldId); searchResultDto.FieldCustomId = fieldDto.CustomId; searchResultDto.field = fieldDto; if (fieldDto.FieldViewType != FieldViewType._13_ListOrRecordType) { dicSearchResult.Add(searchResultDto); continue; } if (searchResult.LinkFieldId == null) { var newFieldDto = await _UpdateFieldDtoAsync(recordType, fieldDto); searchResultDto.FieldCustomId = newFieldDto.CustomId; searchResultDto.field = newFieldDto; dicSearchResult.Add(searchResultDto); } else { var linkFieldDto = fieldDtos.Find(p => p.Id == searchResult.LinkFieldId); var newRecordType = await _recordTypeRepository.GetAsync(searchResultDto.field.FieldListOrRecordTypeId.Value); var newFieldDto = await _UpdateFieldDtoAsync(newRecordType, linkFieldDto); searchResultDto.FieldCustomId = string.Format("{0}.{1}", fieldDto.CustomId, newFieldDto.CustomId); searchResultDto.field = newFieldDto; dicSearchResult.Add(searchResultDto); var linkFieldSearchResultDto = dicSearchResult.Any(p => p.FieldId == searchResult.FieldId && (p.LinkFieldId == null || p.LinkFieldId == Guid.Empty)); var linkFieldSearchResult = search.SearchResults.Any(p => p.FieldId.Equals(searchResult.FieldId) && (p.LinkFieldId == null || p.LinkFieldId == Guid.Empty)); if (!linkFieldSearchResultDto && !linkFieldSearchResult) { var linkFieldSearchResultDto1 = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchResultDto>(Newtonsoft.Json.JsonConvert.SerializeObject(searchResultDto)); var fieldDto1 = fieldDtos.Find(p => p.Id == linkFieldSearchResultDto1.FieldId); var newFieldDto1 = await _UpdateFieldDtoAsync(recordType, fieldDto1); linkFieldSearchResultDto1.FieldCustomId = newFieldDto1.CustomId; linkFieldSearchResultDto1.field = newFieldDto1; linkFieldSearchResultDto1.LinkFieldId = null; dicSearchResult.Add(linkFieldSearchResultDto1); } } } return dicSearchResult; } private async Task<List<SearchAvailableFilterDto>> _GetSearchAvailableFilterDtos(List<RecordTypeFieldDto> fieldDtos, SearchEntity search) { var recordType = await _recordTypeRepository.GetAsync(search.RecordTypeId); List<SearchAvailableFilterDto> dicSearchResult = new List<SearchAvailableFilterDto>(); // Dictionary<string, FieldDto>(); foreach (var searchAvailableFilter in search.SearchAvailableFilters) { var searchResultDto = ObjectMapper.Map<SearchAvailableFilterEntity, SearchAvailableFilterDto>(searchAvailableFilter); var fieldDto = fieldDtos.Find(p => p.Id == searchAvailableFilter.FieldId); if (fieldDto == null) continue; searchResultDto.FieldCustomId = fieldDto.CustomId; searchResultDto.Field = fieldDto; if (fieldDto.FieldViewType != FieldViewType._13_ListOrRecordType) { dicSearchResult.Add(searchResultDto); continue; } if (searchAvailableFilter.LinkFieldId == null) { var newFieldDto = await _UpdateFieldDtoAsync(recordType, fieldDto); searchResultDto.FieldCustomId = newFieldDto.CustomId; searchResultDto.Field = newFieldDto; dicSearchResult.Add(searchResultDto); } else { var linkFieldDto = fieldDtos.Find(p => p.Id == searchAvailableFilter.LinkFieldId); var newRecordType = await _recordTypeRepository.GetAsync(searchResultDto.Field.FieldListOrRecordTypeId.Value); var newFieldDto = await _UpdateFieldDtoAsync(newRecordType, linkFieldDto); searchResultDto.FieldCustomId = string.Format("{0}.{1}", fieldDto.CustomId, newFieldDto.CustomId); searchResultDto.Field = newFieldDto; dicSearchResult.Add(searchResultDto); var linkFieldSearchResultDto = dicSearchResult.Any(p => p.FieldId == searchAvailableFilter.FieldId && (p.LinkFieldId == null || p.LinkFieldId == Guid.Empty)); var linkFieldSearchResult = search.SearchResults.Any(p => p.FieldId.Equals(searchAvailableFilter.FieldId) && (p.LinkFieldId == null || p.LinkFieldId == Guid.Empty)); if (!linkFieldSearchResultDto && !linkFieldSearchResult) { var linkFieldSearchResultDto1 = Newtonsoft.Json.JsonConvert.DeserializeObject<SearchAvailableFilterDto>(Newtonsoft.Json.JsonConvert.SerializeObject(searchResultDto)); var fieldDto1 = fieldDtos.Find(p => p.Id == linkFieldSearchResultDto1.FieldId); var newFieldDto1 = await _UpdateFieldDtoAsync(recordType, fieldDto1); linkFieldSearchResultDto1.FieldCustomId = newFieldDto1.CustomId; linkFieldSearchResultDto1.Field = newFieldDto1; linkFieldSearchResultDto1.LinkFieldId = null; dicSearchResult.Add(linkFieldSearchResultDto1); } } } return dicSearchResult; } private async Task<RecordTypeFieldDto> _UpdateFieldDtoAsync(RecordTypeEntity recordType, RecordTypeFieldDto fieldDto) { var copyFieldDto = Newtonsoft.Json.JsonConvert.DeserializeObject<RecordTypeFieldDto>(Newtonsoft.Json.JsonConvert.SerializeObject(fieldDto)); if (copyFieldDto.FieldViewType != FieldViewType._13_ListOrRecordType) return copyFieldDto; var recordField = recordType.RecordTypeFields.Find(p => p.FieldId == fieldDto.Id); if (recordField != null && recordField.FieldListOrRecordTypeId.HasValue) { var fieldRecordType = await _recordTypeRepository.GetAsync(recordField.FieldListOrRecordTypeId.Value, false); copyFieldDto.RecordTypeId = recordField.FieldListOrRecordTypeId.Value; copyFieldDto.FieldListOrRecordTypeCustomId = fieldRecordType.CustomId; copyFieldDto.FieldListOrRecordTypeServiceName = fieldRecordType.ServiceName; copyFieldDto.FieldListOrRecordTypeEntityName = fieldRecordType.EntityName; copyFieldDto.FieldListOrRecordTypeIsList = fieldRecordType.IsList; copyFieldDto.FieldListOrRecordTypeName = fieldRecordType.Name; copyFieldDto.FieldListOrRecordTypeServiceModule = fieldRecordType.ServiceModule; } return copyFieldDto; } private async Task<List<dynamic>> _GetEntitiesByIdsAsync(List<object> ids, RecordTypeFieldDto fieldDto) { if (fieldDto.FieldViewType != FieldViewType._13_ListOrRecordType) return null; List<FilterModel> filters = new List<FilterModel>(); int line = 1; foreach (var id in ids) { if (fieldDto.FieldListOrRecordTypeIsList) { FilterModel filter = new FilterModel(); filter.Not = false; filter.OpenParens = 1; filter.FilterUsing = fieldDto.FieldListOrRecordTypeIsList ? "value" : "Id"; filter.OperatorType = OperatorType.Equal; filter.Value1 = id.ToString(); filter.Value2 = string.Empty; filter.LogicalOperator = LogicalOperator.And; filter.CloseParens = 0; filter.Line = line; filters.Add(filter); FilterModel filter1 = new FilterModel(); filter1.Not = false; filter1.OpenParens = 0; filter1.FilterUsing = "RecordTypeId"; filter1.OperatorType = OperatorType.Equal; filter1.Value1 = fieldDto.FieldListOrRecordTypeId.ToString(); filter1.Value2 = string.Empty; filter1.LogicalOperator = LogicalOperator.Or; filter1.CloseParens = 1; filter1.Line = line + 1; filters.Add(filter1); line = line + 2; } else { FilterModel filter = new FilterModel(); filter.Not = false; filter.OpenParens = 0; filter.FilterUsing = fieldDto.OptionValue; // fieldDto.FieldListOrRecordTypeIsList ? "value" : "Id"; filter.OperatorType = OperatorType.Equal; filter.Value1 = id.ToString(); filter.Value2 = string.Empty; filter.LogicalOperator = LogicalOperator.Or; filter.CloseParens = 0; filter.Line = line; filters.Add(filter); line = line + 1; } } var strFilter = filters.Count > 0 ? JsonSerializer.Serialize(filters) : string.Empty; //string recordTypeEntityName = fieldDto.FieldListOrRecordTypeEntityName; string recordTypeServiceName = fieldDto.FieldListOrRecordTypeServiceName ?? string.Empty; string strParams = string.Format("?SkipCount={0}&MaxResultCount=1000&Filter={1}", 0, strFilter); string methodName = fieldDto.FieldListOrRecordTypeMethodName ?? string.Empty; var result = await GetDaprInvokeResultAsync<PagedResultDto<dynamic>>(HttpMethod.Get, fieldDto.FieldListOrRecordTypeDaprAppId, fieldDto.FieldListOrRecordTypeServiceModule, recordTypeServiceName, methodName, strParams); // Todo: 暂不支持自定义MethodName的recordType return (List<dynamic>)result.Items; } private async Task<List<RecordTypeFieldDto>> _GetFieldDtosAsync(SearchEntity search) { var originFieldIds = search.SearchResults.Select(p => p.FieldId).Distinct().ToList(); var linkFieldIds = search.SearchResults.Where(p => p.LinkFieldId.HasValue).Select(p => p.LinkFieldId.Value).ToList(); var availableFilter = search.SearchAvailableFilters.Select(p => p.FieldId).Distinct().ToList(); var avaiLinkFieldIds = search.SearchAvailableFilters.Where(p => p.LinkFieldId.HasValue).Select(p => p.LinkFieldId.Value).ToList(); var filterFieldIds = search.SearchCriterias.Where(p => !string.IsNullOrEmpty(p.Filter)).Select(p => p.Filter).ToList(); List<Guid> fieldIds = new List<Guid>(); fieldIds.AddRange(originFieldIds); fieldIds.AddRange(linkFieldIds); fieldIds.AddRange(availableFilter); fieldIds.AddRange(avaiLinkFieldIds); foreach (var item in filterFieldIds) { Guid filter = new Guid() ; if (Guid.TryParse(item,out filter)) { fieldIds.Add(filter); } } fieldIds = fieldIds.Distinct().ToList(); var dtos = await _recordTypeFieldAppService.GetListByIdsAsync(fieldIds); return dtos; } private Dictionary<string, Type> GetPropertyTypes(List<SearchResultDto> searchResultDtos) { Dictionary<string, Type> propertyTypes = new Dictionary<string, Type>(); foreach (var searchResultDto in searchResultDtos) { if (propertyTypes.ContainsKey(searchResultDto.FieldCustomId)) continue; if (searchResultDto.field.FieldViewType == FieldViewType._13_ListOrRecordType) { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(string)); } else if (searchResultDto.field.FieldViewType == FieldViewType._12_IntegerNumber) { if (searchResultDto.field.Mandatory) { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(int)); } else { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(int?)); } } else if (searchResultDto.field.FieldViewType == FieldViewType._1_Currency || searchResultDto.field.FieldViewType == FieldViewType._4_DecimalNumber || searchResultDto.field.FieldViewType == FieldViewType._16_Percent) { if(searchResultDto.field.Mandatory) { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(decimal)); } else { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(decimal?)); } } else if (searchResultDto.field.FieldViewType == FieldViewType._0_CheckBox) { if(searchResultDto.field.Mandatory) { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(bool)); } else { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(bool?)); } } else { propertyTypes.Add(searchResultDto.FieldCustomId, typeof(string)); } } return propertyTypes; } protected override void MapToEntity(CreateOrUpdateSearchDto updateInput, SearchEntity entity) { base.MapToEntity(updateInput, entity); //固定条件映射 var cearchCriteriaIds = updateInput.SearchCriterias.Select(p => p.Id).ToList(); entity.SearchCriterias.RemoveAll(u => !cearchCriteriaIds.Contains(u.Id)); foreach (var item in updateInput.SearchCriterias) { var oldEntity = entity.SearchCriterias.Find(p => p.Id == item.Id); if (oldEntity == null) { entity.SearchCriterias.Add(ObjectMapper.Map<CreateOrUpdateSearchCriteriaDto, SearchCriteriaEntity>(item)); } else { ObjectMapper.Map(item, oldEntity); } } //可选条件映射 var searchAvailableFiltersIds = updateInput.SearchAvailableFilters.Select(p => p.Id).ToList(); entity.SearchAvailableFilters.RemoveAll(u => !searchAvailableFiltersIds.Contains(u.Id)); foreach (var item in updateInput.SearchAvailableFilters) { var oldEntity = entity.SearchAvailableFilters.Find(p => p.Id == item.Id); if (oldEntity == null) { entity.SearchAvailableFilters.Add(ObjectMapper.Map<CreateOrUpdateSearchAvailableFilterDto, SearchAvailableFilterEntity>(item)); } else { ObjectMapper.Map(item, oldEntity); } } //结果集映射 var searchResultIds = updateInput.SearchResults.Select(p => p.Id).ToList(); entity.SearchResults.RemoveAll(u => !searchResultIds.Contains(u.Id)); foreach (var item in updateInput.SearchResults) { var oldEntity = entity.SearchResults.Find(p => p.Id == item.Id); if (oldEntity == null) { entity.SearchResults.Add(ObjectMapper.Map<CreateOrUpdateSearchResultDto, SearchResultEntity>(item)); } else { ObjectMapper.Map(item, oldEntity); } } //SetIdForGuids(entity); } protected override void SetIdForGuids(SearchEntity entity) { base.SetIdForGuids(entity); foreach (var item in entity.SearchAvailableFilters) { if (item.Id == Guid.Empty) EntityHelper.TrySetId(item, () => GuidGenerator.Create(), true); } foreach (var item in entity.SearchCriterias) { if (item.Id == Guid.Empty) EntityHelper.TrySetId(item, () => GuidGenerator.Create(), true); } foreach (var item in entity.SearchResults) { if (item.Id == Guid.Empty) EntityHelper.TrySetId(item, () => GuidGenerator.Create(), true); } } // 处理子(join表)查询 private async Task _ResetSubScopeFilterAsync(RecordTypeEntity recordType, List<FilterModel> filters) { var tasks = new List<Task>(); foreach (var filter in filters) { //var currFilter = filters[i]; var filterUsings = filter.FilterUsing.Split("."); if (filterUsings.Count() > 5) throw new UserFriendlyException("最多只能5级关联查询"); if (filterUsings.Count() == 1) continue; tasks.Add(_ResetSubScopeFilterAsync1(recordType.Id, filter)); } await Task.WhenAll(tasks); } private async Task _ResetSubScopeFilterAsync1(Guid recordTypeId, FilterModel currFilter) { var filterUsings = currFilter.FilterUsing.Split("."); Guid currRecordTypeId = recordTypeId; Stack<RecordTypeFieldDto> recordTypeFieldDtoStack = new Stack<RecordTypeFieldDto>(); for (int j = 0; j < filterUsings.Count(); j++) { var filter = filterUsings[j]; var recordTypeFieldDto = await _recordTypeFieldAppService.GetByCustomIdAsync(currRecordTypeId, filter); currRecordTypeId = recordTypeFieldDto.FieldListOrRecordTypeId.Value; recordTypeFieldDtoStack.Push(recordTypeFieldDto); } FilterSearchResultRequestDto filterSearchResultRequestDto = new FilterSearchResultRequestDto() { MaxResultCount = 1, SkipCount = 0, Sorting = "sort", Filter = "" }; var subFilter = Newtonsoft.Json.JsonConvert.DeserializeObject<FilterModel>(Newtonsoft.Json.JsonConvert.SerializeObject(currFilter)); var recordTypeFieldDtoS = recordTypeFieldDtoStack.Pop(); subFilter.FilterUsing = recordTypeFieldDtoS.CustomId; List<FilterModel> filterModels = new List<FilterModel>() { subFilter }; var strFilter = filterModels.Count > 0 ? JsonSerializer.Serialize(filterModels) : string.Empty; for (int j = 1; j < filterUsings.Count(); j++) { var recordType1 = await _recordTypeRepository.GetAsync(recordTypeFieldDtoS.RecordTypeId); // 查询远程数据列表 filterSearchResultRequestDto.Filter = strFilter; //string methodName = string.Format("api/{0}/{1}/{2}", recordType1.ServiceModule, recordType1.EntityName, strParams); var result = await _fetchRemoteDataAsync(recordType1, filterSearchResultRequestDto, null); // Todo: 暂不支持自定义MethodName的recordtype 作为子记录 List<Guid> ids = new List<Guid>(); foreach (var item in result.Items) { ids.Add(item.id); } recordTypeFieldDtoS = recordTypeFieldDtoStack.Pop(); subFilter.FilterUsing = recordTypeFieldDtoS.CustomId; subFilter.OperatorType = OperatorType.AnyOf; subFilter.Value1 = Newtonsoft.Json.JsonConvert.SerializeObject(ids); } currFilter.FilterUsing = recordTypeFieldDtoS.CustomId; currFilter.OperatorType = OperatorType.AnyOf; currFilter.Value1 = subFilter.Value1; } #endregion /// <summary> /// 根据recordTypeId查询视图列表,及明细 /// </summary> /// <param name="recordTypeId"></param> /// <returns></returns> public async Task<List<SearchDto>> GetListDetailsAsync(Guid recordTypeId) { List<SearchDto> result = []; var list = await _searchRepository.GetListAsync(o => o.RecordTypeId == recordTypeId); if (list.Any()) { var searchIds = list.Select(o => o.Id).ToList(); var searchAvailableFilters = await _searchAvailableFilterRepository.GetListAsync(o => searchIds.Contains(o.SearchId)); var searchResults = await _searchResultRepository.GetListAsync(o => searchIds.Contains(o.SearchId)); var searchCriterias = await _searchCriteriaRepository.GetListAsync(o => searchIds.Contains(o.SearchId)); //需要查询字段集合 var havingSelfileIds = new List<Guid>(); havingSelfileIds.AddRange(searchAvailableFilters.Select(o => o.FieldId).Distinct().ToList()); havingSelfileIds.AddRange(searchResults.Select(o => o.FieldId).Distinct().ToList()); havingSelfileIds.AddRange(searchAvailableFilters.Where(o => o.LinkFieldId.HasValue).Select(o => o.LinkFieldId.Value).Distinct().ToList()); havingSelfileIds = havingSelfileIds.Distinct().ToList(); var fieldDtos = await _recordTypeFieldAppService.GetListByIdsAsync(havingSelfileIds); foreach (var item in list) { item.SearchResults = searchResults.Where(o => o.SearchId == item.Id).OrderBy(o => o.Sort).ToList(); item.SearchAvailableFilters = searchAvailableFilters.Where(o => o.SearchId == item.Id).OrderBy(o => o.Sort).ToList(); item.SearchCriterias = searchCriterias.Where(o => o.SearchId == item.Id).OrderBy(o => o.Sort).ToList(); } result = ObjectMapper.Map<List<SearchEntity>, List<SearchDto>>(list); foreach (var item in result) { //可选条件字段信息赋值 if (item.SearchAvailableFilters.Any()) { foreach (var itemAvailableFilters in item.SearchAvailableFilters) { var fieldInfo = fieldDtos.FirstOrDefault(o => o.Id == itemAvailableFilters.FieldId); if (fieldInfo != null) { itemAvailableFilters.Field = fieldInfo; itemAvailableFilters.FieldCustomId = fieldInfo.FieldCustomId; } } } //结果集字段信息赋值 if (item.SearchResults.Any()) { foreach (var itemSearchResults in item.SearchResults) { var fieldInfo = fieldDtos.FirstOrDefault(o => o.Id == itemSearchResults.FieldId); if (fieldInfo != null) { itemSearchResults.field = fieldInfo; itemSearchResults.FieldCustomId = fieldInfo.FieldCustomId; itemSearchResults.FieldName = fieldInfo.Name; } } } } } return result; } } // 转换小驼峰方法 public static class CamelCaseHelper { // 主入口:List<dynamic> → List<dynamic> public static List<dynamic> ToCamelCaseList(List<dynamic> list) { var jArray = JArray.FromObject(list); // 转 JArray var camelJArray = (JArray)ToCamelCase(jArray); // 转 key return camelJArray.ToObject<List<dynamic>>(); // 转回 List<dynamic> } // 递归转换 JToken private static JToken ToCamelCase(JToken token) { if (token is JObject obj) { var newObj = new JObject(); foreach (var property in obj.Properties()) { string camelName = ToCamelCase(property.Name); newObj[camelName] = ToCamelCase(property.Value); } return newObj; } else if (token is JArray array) { var newArray = new JArray(); foreach (var item in array) { newArray.Add(ToCamelCase(item)); } return newArray; } else { return token.DeepClone(); } } // key 转 camelCase private static string ToCamelCase(string str) { if (string.IsNullOrEmpty(str)) return str; return char.ToLower(str[0], CultureInfo.InvariantCulture) + str.Substring(1); } } } 详细讲解
最新发布
11-27
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值