Object empty value key filter

本文介绍了一种实用的JavaScript函数,用于从对象中过滤掉空值属性,包括空数组和空对象,保留了布尔值和数值类型的键值对,提高了数据处理效率。

Object empty value key filter

过滤空值

Utils

emptykeysFilter()



"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2018.11.23
 * @modified 2018.11.23
 *
 * @description Utils 过滤空值
 * @augments
 * @example emptykeysFilter(obj);
 *
 */

const emptykeysFilter = (obj = {}, debug = false) => {
    // const newObj = {};
    let keys = Object.keys(obj);
    keys.forEach(
        (key, i) => {
            // console.log(`key`, key);
            // console.log(`obj[key]`, obj[key]);
            if (typeof (obj[key]) === "boolean" || typeof (obj[key]) === "number") {
                // do nothing
            } else if (!Object.keys(obj[key]).length) {
                delete obj[key];
            } else {
                // newObj[key] = obj[key];
            }
        }
    );
    // console.log(`new obj =`, JSON.stringify(newObj, null, 4));
    // return newObj;
    // console.log(`new obj =`, JSON.stringify(obj, null, 4));
    return obj;
};

const Utils = {
    emptykeysFilter,
};

export default Utils;

export {
    Utils,
    emptykeysFilter,
};

/*

let obj = {
    "id": "123",
    "name": [],
    "userName": {},
    "telephoneNum": [1],
    "phoneNum": {k: "v"},
    "email": "",
    "bool": false,
    "boolean": true,
    "no": 666,
};
// Object.keys(obj.bool).length

emptykeysFilter(obj);
// obj = emptykeysFilter(obj);

// {
//     "id": "123",
//     "telephoneNum": [1],
//     "phoneNum": {k: "v"},
//     "bool": false,
//     "boolean": true,
//     "no": 666,
// };

JSON.stringify(obj, null, 4);


*/

转载于:https://www.cnblogs.com/xgqfrms/p/10006273.html

package jnpf.util; import jnpf.consts.RedisConst; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; /** * * @author JNPF开发平台组 * @version V3.1.0 * @copyright 引迈信息技术有限公司 * @date 2021/3/16 10:51 */ @Slf4j @Component public class RedisUtil { /** * 默认缓存时间 60S */ public final static int CAHCETIME = 60; /** * 默认缓存时间 1hr */ public final static int CAHCEHOUR = 60 * 60; /** * 默认缓存时间 1Day */ public final static int CAHCEDAY = 60 * 60 * 24; /** * 默认缓存时间 1week */ public final static int CAHCEWEEK = 60 * 60 * 24 * 7; /** * 默认缓存时间 1month */ public final static int CAHCEMONTH = 60 * 60 * 24 * 7 * 30; /** * 默认缓存时间 1年 */ public final static int CAHCEYEAR = 60 * 60 * 24 * 7 * 30 * 12; private static long expiresIn = TimeUnit.SECONDS.toSeconds(CAHCEHOUR * 8); @Autowired private RedisTemplate redisTemplate; @Autowired private CacheKeyUtil cacheKeyUtil; // =============================common============================ /** * 获取所有的key * * @return */ public Set<String> getAllVisiualKeys() { Set<String> allKey = new HashSet<>(16); allKey.addAll(Objects.requireNonNull(redisTemplate.keys("*" + cacheKeyUtil.getAllUser() + "*"))); allKey.addAll(Objects.requireNonNull(redisTemplate.keys("*" + cacheKeyUtil.getCompanySelect() + "*"))); allKey.addAll(Objects.requireNonNull(redisTemplate.keys("*" + cacheKeyUtil.getDictionary() + "*"))); allKey.addAll(Objects.requireNonNull(redisTemplate.keys("*" + cacheKeyUtil.getDynamic() + "*"))); allKey.addAll(Objects.requireNonNull(redisTemplate.keys("*" + cacheKeyUtil.getOrganizeList() + "*"))); allKey.addAll(Objects.requireNonNull(redisTemplate.keys("*" + cacheKeyUtil.getPositionList() + "*"))); allKey.addAll(Objects.requireNonNull(redisTemplate.keys("*" + cacheKeyUtil.getVisiualData() + "*"))); return allKey; } /** * 获取所有的key * * @return */ public Set<String> getAllKeys() { Set<String> keys = redisTemplate.keys("*"); if(CollectionUtils.isNotEmpty(keys)) { //排除ID生成器的缓存记录, 如果删除在集群情况下ID生成器的机器编号可能会重复导致生成的ID重复 keys = keys.stream().filter(s -> !s.startsWith(CacheKeyUtil.IDGENERATOR) && !s.startsWith(RedisConst.REDIS_LOCK4J_PREFIX) ).collect(Collectors.toSet()); } return keys; } /** * 返回 key 的剩余的过期时间 * * @param key * @return */ public Long getLiveTime(String key) { return redisTemplate.getExpire(key); } /** * 删除指定key * * @param key */ public void remove(String key) { if (exists(key)) { redisTemplate.delete(key); } } /** * 删除全部redis */ public void removeAll() { Set<String> keys = getAllKeys(); if (CollectionUtils.isNotEmpty(keys)) { //兼容Redis集群, 不同的KEY在不同服务器上不允许同时联合操作 keys.forEach(k->redisTemplate.delete(k)); } } /** * 判断缓存中是否有对应的value * * @param key * @return */ public boolean exists(final String key) { return redisTemplate.hasKey(key); } /** * 指定缓存失效时间 * * @param key * @param time * @return */ public void expire(String key, long time) { if (time > 0) { redisTemplate.expire(key, time, TimeUnit.SECONDS); } else { redisTemplate.expire(key, expiresIn, TimeUnit.SECONDS); } } /** * 插入缓存(无时间) * * @param key * @param object */ public void insert(String key, Object object) { insert(key, object, 0); } /** * 插入缓存(有时间) * * @param key * @param object */ public void insert(String key, Object object, long time) { if (object instanceof Map) { redisTemplate.opsForHash().putAll(key, (Map<String, String>) object); } else if (object instanceof List) { redisTemplate.opsForList().rightPushAll(key, (List)object); } else if (object instanceof Set) { redisTemplate.opsForSet().add(key, ((Set<?>) object).toArray()); } else { redisTemplate.opsForValue().set(key, toJson(object)); } expire(key, time); } /** * Object转成JSON数据 */ private String toJson(Object object) { if (object instanceof Integer || object instanceof Long || object instanceof Float || object instanceof Double || object instanceof Boolean || object instanceof String) { return String.valueOf(object); } return JsonUtil.getObjectToString(object); } /** * 修改key * * @param oldKey 旧的key * @param newKey 新的key */ public void rename(String oldKey, String newKey) { redisTemplate.rename(oldKey, newKey); } /** * 返回key存储的类型 * * @param key */ public String getType(String key) { return redisTemplate.type(key).code(); } // ============================String============================= /** * 获取redis的String值 * * @param key * @return */ public Object getString(String key) { return redisTemplate.opsForValue().get(key); } // ============================Map============================= /** * 判断hash表中是否有对应的value * * @param hashId * @param key * @return */ public boolean hasKey(String hashId, String key) { return redisTemplate.opsForHash().hasKey(hashId, key); } /** * 获取hashKey对应的所有键 * * @param hashId 键 */ public List<String> getHashKeys(String hashId) { List<String> list = new ArrayList<>(); Map<Object, Object> map = this.getMap(hashId); for (Object object : map.keySet()) { if (object instanceof String) { list.add(String.valueOf(object)); } } return list; } /** * 获取hashKey对应的所有值 * * @param hashId 键 */ public List<String> getHashValues(String hashId) { List<String> list = new ArrayList<>(); Map<Object, Object> map = this.getMap(hashId); for (Object object : map.keySet()) { if (map.get(object) instanceof String) { list.add(String.valueOf(map.get(object))); } } return list; } /** * 查询具体map的值 * * @param hashId * @param key * @return */ public String getHashValues(String hashId, String key) { Object object = redisTemplate.opsForHash().get(hashId, key); if (object != null) { return String.valueOf(object); } else { return null; } } /** * 删除指定map的key * * @param key */ public void removeHash(String hashId, String key) { if (hasKey(hashId, key)) { redisTemplate.opsForHash().delete(hashId, key); } } /** * 获取所有的map缓存 * * @param key * @return */ public <K,V> Map<K, V> getMap(String key) { return (Map<K, V>) redisTemplate.opsForHash().entries(key); } /** * 插入map的值 * * @param hashId 主键id * @param key map的key * @param value map的值 */ public void insertHash(String hashId, String key, String value) { redisTemplate.opsForHash().put(hashId, key, value); } // ============================set============================= /** * 根据key获取Set中的所有值 * * @param key 键 * @return */ public Set<Object> getSet(String key) { try { return redisTemplate.opsForSet().members(key); } catch (Exception e) { log.error(key, e); return null; } } /** * 获取set缓存的长度 * * @param key 键 * @return */ public long getSetSize(String key) { try { return redisTemplate.opsForSet().size(key); } catch (Exception e) { log.error(key, e); return 0; } } // ===============================list================================= /** * 获取list缓存的内容 * * @param key 键 * @param start 开始 0 是第一个元素 * @param end 结束 -1代表所有值 * @return * @取出来的元素 总数 end-start+1 */ public List<Object> get(String key, long start, long end) { try { return redisTemplate.opsForList().range(key, start, end); } catch (Exception e) { log.error(key, e); return null; } } /** * 获取list缓存的长度 * * @param key 键 * @return */ public long getListSize(String key) { try { return redisTemplate.opsForList().size(key); } catch (Exception e) { log.error(key, e); return 0; } } /** * 通过索引 获取list中的值 * * @param key 键 * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推 * @return */ public Object getIndex(String key, long index) { try { return redisTemplate.opsForList().index(key, index); } catch (Exception e) { log.error(key, e); return null; } } /** * 存储对象为JSON字符串 */ public void insertAsJson(String key, Object object, long time) { String json = JsonUtil.getObjectToString(object); redisTemplate.opsForValue().set(key, json); expire(key, time); } /** * 获取JSON并转换为对象 */ public <T> T getJsonObject(String key, Class<T> clazz) { Object value = redisTemplate.opsForValue().get(key); if (value instanceof String) { return JsonUtil.getJsonToBean((String) value, clazz); } return null; } /** * 获取JSON并转换为列表 */ public <T> List<T> getJsonList(String key, Class<T> elementType) { Object value = redisTemplate.opsForValue().get(key); if (value instanceof String) { return JsonUtil.getJsonToList((String) value, elementType); } return Collections.emptyList(); } } 我存了个keyvalue值进去,怎么通过key获取value
10-11
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、付费专栏及课程。

余额充值