From 5f1e778fd605054da2a50c7029c0c4f4eac8bcd2 Mon Sep 17 00:00:00 2001 From: Guo XIn <371864209@qq.com> Date: Tue, 29 Aug 2023 18:33:03 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=EF=BC=9A=E7=BB=BC=E5=90=88?= =?UTF-8?q?=E6=B5=8F=E8=A7=88=E6=96=87=E4=BB=B6=E5=85=A8=E6=96=87=E6=A3=80?= =?UTF-8?q?=E7=B4=A2=E9=A1=B5=E9=9D=A2=E5=A2=9E=E8=87=AA=E5=AE=9A=E4=B9=89?= =?UTF-8?q?=E6=8E=92=E5=BA=8F=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../browser/controller/SearchController.java | 5 +- .../browser/entity/SearchConditionVo.java | 26 +------- .../browser/entity/SearchResultSort.java | 34 +++++++++++ .../browser/service/FileSearchService.java | 41 ++++++++++++- .../service/MetadataSearchService.java | 3 +- .../src/main/resources/static/js/browser.js | 59 ++++++++++++------- 6 files changed, 117 insertions(+), 51 deletions(-) create mode 100644 shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchResultSort.java diff --git a/shandan-browser/src/main/java/com/keyware/shandan/browser/controller/SearchController.java b/shandan-browser/src/main/java/com/keyware/shandan/browser/controller/SearchController.java index 3e64f8f..fd192a3 100644 --- a/shandan-browser/src/main/java/com/keyware/shandan/browser/controller/SearchController.java +++ b/shandan-browser/src/main/java/com/keyware/shandan/browser/controller/SearchController.java @@ -10,6 +10,7 @@ import com.keyware.shandan.bianmu.entity.MetadataBasicVo; import com.keyware.shandan.bianmu.service.MetadataService; import com.keyware.shandan.browser.entity.PageVo; import com.keyware.shandan.browser.entity.SearchConditionVo; +import com.keyware.shandan.browser.entity.SearchResultSort; import com.keyware.shandan.browser.service.*; import com.keyware.shandan.common.entity.Result; import com.keyware.shandan.common.util.FileDownload; @@ -138,10 +139,10 @@ public class SearchController { */ @AppLog(operate = "文件全文检索查询") @GetMapping("/full/file") - public Result searchFile(PageVo page, String search, String metaId) { + public Result searchFile(PageVo page, String search, String metaId, SearchResultSort sort) { try { - return Result.of(fileSearchService.searchFile(page, search, metaId)); + return Result.of(fileSearchService.searchFile(page, search, metaId, sort)); } catch (IOException e) { e.printStackTrace(); return Result.of(null, false, "Elasticsearch 请求异常"); diff --git a/shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchConditionVo.java b/shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchConditionVo.java index 9801690..1ae821d 100644 --- a/shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchConditionVo.java +++ b/shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchConditionVo.java @@ -10,7 +10,6 @@ import org.elasticsearch.search.sort.SortOrder; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -35,7 +34,7 @@ public class SearchConditionVo extends PageVo implements Serializable { //搜索条件集合 private List conditions = new ArrayList<>(); // 排序 - private Sort sort = new Sort(); + private SearchResultSort sort = new SearchResultSort(); //排序字段 @Deprecated private String sortFiled; @@ -113,27 +112,4 @@ public class SearchConditionVo extends PageVo implements Serializable { return " " + logicJoin + " \"" + table + "\".\"" + fieldName + "\" " + logicJudgement + " " + fieldValue; } } - - /** - * 排序 - */ - @Getter - @Setter - public static class Sort { - //排序字段 - private String field; - //排序方式 - private String sort; - - /** - * @return order by sql语句 - */ - public String getOrderBy() { - return isEmpty() ? Strings.EMPTY : " order by " + getField() + " " + getSort(); - } - - public boolean isEmpty() { - return StringUtils.isBlankAny(this.field, this.sort); - } - } } diff --git a/shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchResultSort.java b/shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchResultSort.java new file mode 100644 index 0000000..c3b7911 --- /dev/null +++ b/shandan-browser/src/main/java/com/keyware/shandan/browser/entity/SearchResultSort.java @@ -0,0 +1,34 @@ +package com.keyware.shandan.browser.entity; + + + +import com.keyware.shandan.common.util.StringUtils; +import joptsimple.internal.Strings; +import lombok.Getter; +import lombok.Setter; + +/** + * 排序 + * + * @author GuoXin + * @date 2023/8/29 + */ +@Getter +@Setter +public class SearchResultSort { + //排序字段 + private String field; + //排序方式 + private String sort; + + /** + * @return order by sql语句 + */ + public String getOrderBy() { + return isEmpty() ? Strings.EMPTY : " order by " + getField() + " " + getSort(); + } + + public boolean isEmpty() { + return StringUtils.isBlankAny(this.field, this.sort); + } +} \ No newline at end of file diff --git a/shandan-browser/src/main/java/com/keyware/shandan/browser/service/FileSearchService.java b/shandan-browser/src/main/java/com/keyware/shandan/browser/service/FileSearchService.java index 7888f68..3b51885 100644 --- a/shandan-browser/src/main/java/com/keyware/shandan/browser/service/FileSearchService.java +++ b/shandan-browser/src/main/java/com/keyware/shandan/browser/service/FileSearchService.java @@ -1,12 +1,16 @@ package com.keyware.shandan.browser.service; +import cn.hutool.core.util.ReflectUtil; import com.keyware.shandan.bianmu.entity.DirectoryVo; import com.keyware.shandan.bianmu.enums.ReviewStatus; import com.keyware.shandan.bianmu.service.DirectoryService; import com.keyware.shandan.browser.entity.PageVo; +import com.keyware.shandan.browser.entity.SearchResultSort; import com.keyware.shandan.common.constants.DirConstant; import com.keyware.shandan.common.util.StreamUtil; import com.keyware.shandan.common.util.StringUtils; +import com.keyware.shandan.system.entity.SysFile; +import lombok.extern.slf4j.Slf4j; import org.elasticsearch.action.search.SearchRequest; import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.client.RequestOptions; @@ -17,10 +21,15 @@ import org.elasticsearch.index.query.QueryBuilder; import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.search.builder.SearchSourceBuilder; import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder; +import org.elasticsearch.search.sort.FieldSortBuilder; +import org.elasticsearch.search.sort.SortOrder; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.elasticsearch.annotations.FieldType; import org.springframework.stereotype.Service; import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; @@ -30,6 +39,7 @@ import java.util.List; * @author Administrator * @since 2021/12/21 */ +@Slf4j @Service public class FileSearchService { @@ -38,13 +48,13 @@ public class FileSearchService { @Autowired private DirectoryService directoryService; - public PageVo searchFile(PageVo page, String text, String metaId) throws IOException { + public PageVo searchFile(PageVo page, String text, String metaId, SearchResultSort sort) throws IOException { SearchRequest request = Requests.searchRequest("shandan"); SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); searchSourceBuilder.from(page.getPage() * page.getSize() - page.getSize()).size(page.getSize()); BoolQueryBuilder builder = QueryBuilders.boolQuery(); - if(!DirConstant.DIR_ROOT_ID.equals(metaId)){ + if (!DirConstant.DIR_ROOT_ID.equals(metaId)) { List ids = new ArrayList<>(); ids.add(metaId); ids.addAll(getChildrenByDirId(metaId)); @@ -75,13 +85,38 @@ public class FileSearchService { highlightBuilder.preTags("").field("*"); highlightBuilder.forceSource(true); searchSourceBuilder.query(builder).highlighter(highlightBuilder); + + // 设置排序 + if (!sort.isEmpty()) { + String sortField = sort.getField(); + // 使用反射获取文件实体类中字段上的注解设置的字段类型 + Field field = ReflectUtil.getField(SysFile.class, sortField); + if (field != null) { + org.springframework.data.elasticsearch.annotations.Field fieldAnno = field.getAnnotation(org.springframework.data.elasticsearch.annotations.Field.class); + if(fieldAnno.type() != FieldType.Text + && fieldAnno.type() != FieldType.Object + && fieldAnno.type() != FieldType.Auto + && fieldAnno.type() != FieldType.Nested + && fieldAnno.type() != FieldType.Ip + && fieldAnno.type() != FieldType.Attachment){ + if(fieldAnno.type() == FieldType.Keyword){ + sortField = sortField.concat(".keyword"); + } + searchSourceBuilder.sort(sortField, SortOrder.fromString(sort.getSort())); + }else { + log.error("不支持的排序类型:{}:{}", sortField, fieldAnno.type()); + } + } + } request.source(searchSourceBuilder); + // 设置排序 + SearchResponse response = esClient.search(request, RequestOptions.DEFAULT); return PageVo.ofSearchHits(response.getHits(), page); } - private List getChildrenByDirId(String dirId){ + private List getChildrenByDirId(String dirId) { DirectoryVo dir = directoryService.getById(dirId); return StreamUtil.as(directoryService.childrenLists(dir, ReviewStatus.SUBMITTED)).map(DirectoryVo::getId).toList(); } diff --git a/shandan-browser/src/main/java/com/keyware/shandan/browser/service/MetadataSearchService.java b/shandan-browser/src/main/java/com/keyware/shandan/browser/service/MetadataSearchService.java index 550ff53..a60ffe1 100644 --- a/shandan-browser/src/main/java/com/keyware/shandan/browser/service/MetadataSearchService.java +++ b/shandan-browser/src/main/java/com/keyware/shandan/browser/service/MetadataSearchService.java @@ -12,6 +12,7 @@ import com.keyware.shandan.bianmu.mapper.DirectoryResourceMapper; import com.keyware.shandan.bianmu.service.DirectoryService; import com.keyware.shandan.browser.entity.PageVo; import com.keyware.shandan.browser.entity.SearchConditionVo; +import com.keyware.shandan.browser.entity.SearchResultSort; import com.keyware.shandan.common.util.StreamUtil; import com.keyware.shandan.common.util.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -101,7 +102,7 @@ public class MetadataSearchService { }); // 排序设置 - SearchConditionVo.Sort sort = condition.getSort(); + SearchResultSort sort = condition.getSort(); if(sort != null && sort.getSort() != null ){ // 通过反射获取资源类字段注解中的数据库表相关的列名 Field field = ReflectUtil.getField(DirectoryResource.class, sort.getField().trim()); diff --git a/shandan-browser/src/main/resources/static/js/browser.js b/shandan-browser/src/main/resources/static/js/browser.js index 94bc6b3..6d46f0c 100644 --- a/shandan-browser/src/main/resources/static/js/browser.js +++ b/shandan-browser/src/main/resources/static/js/browser.js @@ -18,7 +18,7 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop let metaListTable, dirFileTable, tagSelector, tags = [], conditions = []; const unchecked_tags = new Set(); - // 初始化 + // 初始化 initDirectoryTree(); @@ -144,17 +144,18 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop limit: 30, cols: [[ {field: 'id', title: 'ID', hide: true}, - {field: 'resourceName', title: '数据名称', width: 300,sort: true}, - {field: 'resourceComment', title: '中文注释/描述',sort: true}, - {field: 'directoryPath', title: '资源路径',sort: true}, - {field: 'themeTask', title: '主题任务', hide: true,sort: true}, + {field: 'resourceName', title: '数据名称', width: 300, sort: true}, + {field: 'resourceComment', title: '中文注释/描述', sort: true}, + {field: 'directoryPath', title: '资源路径', sort: true}, + {field: 'themeTask', title: '主题任务', hide: true, sort: true}, { field: 'dataSource', title: '数据来源', width: 160, - templet: (data) => DICT.getText("data_source", data.dataSource) || data.dataSource || '',sort: true + templet: (data) => DICT.getText("data_source", data.dataSource) || data.dataSource || '', + sort: true }, - {field: 'taskTime', title: '任务时间', width: 180, align: 'center',sort: true}, + {field: 'taskTime', title: '任务时间', width: 180, align: 'center', sort: true}, {field: 'modifyTime', title: '注册时间', width: 160, align: 'center', hide: true}, {fixed: 'right', title: '操作', toolbar: '#rowToolBar', width: 100, align: 'center'} ]], @@ -173,13 +174,13 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop } }, }); - metaListTable.gtable.on('sort', function(data){ + metaListTable.gtable.on('sort', function (data) { const {field, type} = data; let sort = type; - if(!sort || sort === 'null'){ + if (!sort || sort === 'null') { sort = undefined; } - metaListTable.where.sort={field: field.trim(), sort: sort} + metaListTable.where.sort = {field: field.trim(), sort: sort} beginSearch(); }) metaListTable.addTableRowEvent('export', function (obj) { @@ -229,32 +230,39 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop url: `${ctx}/search/full/file?metaId=${id}`, height: 'full-110', request: {pageName: 'page', limitName: 'size'}, + autoSort: false, limit: 30, method: 'get', cols: [[ {field: 'id', title: 'ID', hide: true}, {field: 'fileName', title: '文件名称', minWidth: 300, fixed: 'left'}, { + field: 'source', title: '文件来源', minWidth: 160, + sort: true, templet: data => DICT.getText('data_source', data.source) || data.source || '' }, - {field: 'taskCode', title: '任务代号', minWidth: 160}, + {field: 'taskCode', title: '任务代号', sort: true, minWidth: 160}, { + field: 'taskNature', title: '任务性质', minWidth: 160, + sort: true, templet: data => DICT.getText('task_nature', data.taskNature) || data.taskNature || '' }, - {field: 'troopCode', title: '部队代号', minWidth: 160}, - {field: 'missileNumber', title: '导弹编号', minWidth: 160}, - {field: 'equipmentModel', title: '装备型号', minWidth: 160}, + {field: 'troopCode', title: '部队代号', sort: true, minWidth: 160}, + {field: 'missileNumber', title: '导弹编号', sort: true, minWidth: 160}, + {field: 'equipmentModel', title: '装备型号', sort: true, minWidth: 160}, { + field: 'targetNumber', title: '目标/靶标类型', minWidth: 160, + sort: true, templet: data => DICT.getText('target_type', data.targetNumber) || data.targetNumber || '' }, - {field: 'entryStaff', title: '录入人员', minWidth: 160}, - {field: 'inputDate', title: '收文时间', width: 160, align: 'center'}, + {field: 'entryStaff', title: '录入人员', sort: true, minWidth: 160}, + {field: 'inputDate', title: '收文时间', sort: true, width: 160, align: 'center'}, {field: 'remark', title: '文件描述', width: 300}, {field: 'text', title: '文件内容', width: 300}, {fixed: 'right', title: '操作', toolbar: '#fileRowToolBar', width: 100, align: 'center'} @@ -262,6 +270,17 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop }, }); + dirFileTable.gtable.on('sort', function (data) { + const {field, type} = data; + let sort = type; + if (!sort || sort === 'null') { + sort = undefined; + } + dirFileTable.table.where.field = field.trim(); + dirFileTable.table.where.sort = sort; + dirFileTable.reloadTable({table: dirFileTable.table}) + }) + // 查看按钮监听 dirFileTable.addTableRowEvent('details-file', function (obj) { openMaxLayerWithURL(`${ctx}/sys/file/view?fileId=${obj.id}`) @@ -305,7 +324,7 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop // 监听条件标签删除事件 element.on('tabDelete(condition-tab)', function (data) { let key = $(this).parent().data('key'); - if(key === 'markTag'){ + if (key === 'markTag') { tags = []; } let formVal = form.val('search-form'); @@ -427,7 +446,7 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop } tag_htm += ``; } - if (tag_htm){ + if (tag_htm) { htm += `
  • 置标标签:${tag_htm}
  • `; } @@ -438,9 +457,9 @@ layui.use(['layer', 'listPage', 'globalTree', 'gtable', 'form', 'element', 'drop $('li[data-key="markTag"] .layui-form-checkbox').on('click', function () { let val = $(this).prev().val(); - if(unchecked_tags.has(val)){ + if (unchecked_tags.has(val)) { unchecked_tags.delete(val); - }else{ + } else { unchecked_tags.add(val); } beginSearch();