lin
2024-04-10 2d37fa5cf4ebf8bdcae40c5a9f63d561f307e2af
Merge remote-tracking branch 'origin/master'
24 files modified
13 files added
1916 ■■■■■ changed files
pom.xml 32 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/config/MyBatisPlusConfig.java 15 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/constant/EsTableConstant.java 69 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/interceptor/DataSyncInterceptor.java 225 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/param/CommonParamSet.java 74 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/common/utils/SQLParseUtils.java 41 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/config/ElasticsearchConfig.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/config/ElasticsearchInitializer.java 24 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/controller/EsController.java 79 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/service/ElasticsearchDocumentService.java 695 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/service/ElasticsearchIndexInitializer.java 33 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/service/ElasticsearchIndexService.java 37 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/service/ElasticsearchSearchService.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/test/ElasticSearchExample.java 96 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/es/vo/EsParam.java 32 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/article/controller/ArticleController.java 14 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/article/mapper/ArticleMapper.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/article/mapper/ArticleMapper.xml 21 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/article/service/ArticleService.java 12 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/article/service/impl/ArticleServiceImpl.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/backblast/mapper/BackblastPubPersonMapper.xml 2 ●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/mapper/HouseMapper.java 21 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/mapper/HouseMapper.xml 32 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/mapper/HouseholdMapper.java 20 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/mapper/HouseholdMapper.xml 34 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/service/IHouseService.java 21 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/service/IHouseholdService.java 27 ●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/service/impl/HouseServiceImpl.java 30 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/house/service/impl/HouseholdServiceImpl.java 29 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/place/entity/PlaceEntity.java 3 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/place/mapper/PlaceMapper.java 19 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/place/mapper/PlaceMapper.xml 29 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/place/service/IPlaceService.java 18 ●●●●● patch | view | raw | blame | history
src/main/java/org/springblade/modules/place/service/impl/PlaceServiceImpl.java 28 ●●●●● patch | view | raw | blame | history
src/main/resources/application-dev.yml 7 ●●●●● patch | view | raw | blame | history
src/main/resources/application-prod.yml 7 ●●●●● patch | view | raw | blame | history
src/main/resources/application-test.yml 7 ●●●●● patch | view | raw | blame | history
pom.xml
@@ -267,8 +267,36 @@
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <!-- ElasticSearch -->
<!--        <dependency>-->
<!--            <groupId>org.springframework.boot</groupId>-->
<!--            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>-->
<!--            <version>2.7.1</version>-->
<!--        </dependency>-->
        <!--导入了elasticsearch  -->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.17.4</version>
            <!--            <version>6.7.2</version>-->
            <exclusions>
                <exclusion>
                    <artifactId>elasticsearch</artifactId>
                    <groupId>org.elasticsearch</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
            <version>7.17.4</version>
<!--            <version>6.7.2</version>-->
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>
    <build>
src/main/java/org/springblade/common/config/MyBatisPlusConfig.java
New file
@@ -0,0 +1,15 @@
package org.springblade.common.config;
import com.baomidou.mybatisplus.autoconfigure.ConfigurationCustomizer;
import org.springblade.common.interceptor.DataSyncInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisPlusConfig {
    @Bean
    public DataSyncInterceptor dataSyncInterceptor() {
        return new DataSyncInterceptor();
    }
}
src/main/java/org/springblade/common/constant/EsTableConstant.java
New file
@@ -0,0 +1,69 @@
package org.springblade.common.constant;
import java.util.ArrayList;
import java.util.List;
/**
 * es 表对应的属性常量
 * @author zhongrj
 * @since 2024-04-08
 */
public class EsTableConstant {
    /**
     * 1. 通知
     */
    public static List<String> articleList = new ArrayList<String>()
    {{
        add("tableId");
        add("tableName");
        add("title");
        add("type");
        add("content");
        add("articleType");
        add("articleRange");
    }};
    /**
     * 2. 场所
     */
    public static List<String> placeList = new ArrayList<String>()
    {{
        add("tableId");
        add("tableName");
        add("placeName");
        add("principal");
        add("principalPhone");
        add("principalIdCard");
        add("location");
    }};
    /**
     * 3. 房屋
     */
    public static List<String> houseList = new ArrayList<String>()
    {{
        add("tableId");
        add("tableName");
        add("houseName");
    }};
    /**
     * 4. 住户
     */
    public static List<String> householdList = new ArrayList<String>()
    {{
        add("tableId");
        add("tableName");
        add("name");
        add("idCard");
        add("phoneNumber");
        add("address");
    }};
}
src/main/java/org/springblade/common/interceptor/DataSyncInterceptor.java
New file
@@ -0,0 +1,225 @@
package org.springblade.common.interceptor;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.logging.log4j.util.Strings;
import org.springblade.common.constant.EsTableConstant;
import org.springblade.common.utils.SQLParseUtils;
import org.springblade.es.service.ElasticsearchDocumentService;
import org.springblade.es.vo.EsParam;
import org.springblade.modules.article.entity.Article;
import org.springblade.modules.house.entity.HouseEntity;
import org.springblade.modules.house.entity.HouseholdEntity;
import org.springblade.modules.house.vo.HouseVO;
import org.springblade.modules.house.vo.HouseholdVO;
import org.springblade.modules.place.entity.PlaceEntity;
import org.springblade.modules.place.vo.PlaceVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@Component
@Intercepts({
    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class DataSyncInterceptor implements Interceptor {
    @Lazy
    @Autowired
    private ElasticsearchDocumentService elasticsearchDocumentService;
    @Value("${elasticsearch.indexName}")
    private String indexName;
    /**
     * 拦截器在sql执行成功后同步到es,
     * 如果同步失败抛出异常,保证数据一致性
     *
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 获取StatementHandler,进行自定义处理
//        StatementHandler statementHandler = PluginUtils.realTarget(invocation.getTarget());
        Object res = invocation.proceed();
        System.out.println("res = " + res);
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        if (args.length >= 2) {
            //参数
            Object parameter = invocation.getArgs()[1];
            BoundSql boundSql = ms.getBoundSql(parameter);
            //sql
            String sql = boundSql.getSql();
            sql = sql.replaceAll("\n", "");
            //获取表名
            String tableName = SQLParseUtils.getTableName(sql);
            String sqlType = SQLParseUtils.parseSQLType(sql);
            if (!Strings.isBlank(tableName)) {
                if (tableName.equals("jczz_article") ||
                    tableName.equals("jczz_house") ||
                    tableName.equals("jczz_household") ||
                    tableName.equals("jczz_place"))
                syncDataAfterUpdate(tableName,sqlType,invocation.getArgs()[1]);
            }
        }
        return res;
    }
    /**
     * 数据同步
     * @param tableName
     * @param sqlType
     * @param parameter
     */
    private void syncDataAfterUpdate(String tableName,String sqlType,Object parameter) {
        EsParam esParam = new EsParam();
        esParam.setIndexName(indexName);
        esParam.setTableName(tableName);
        // 判断操作类型
        if (sqlType.equals("INSERT")){
            //insert 可用直接拦截到实体类
            if (tableName.equals("jczz_article")) {
                Article entity = (Article) parameter;
                elasticsearchDocumentService.addArticle(esParam,entity);
            }
            if (tableName.equals("jczz_place")) {
                PlaceVO entity = (PlaceVO) parameter;
                elasticsearchDocumentService.addPlace(esParam,entity);
            }
            if (tableName.equals("jczz_house")) {
                HouseVO entity = (HouseVO) parameter;
                elasticsearchDocumentService.addHouse(esParam,entity);
            }
            if (tableName.equals("jczz_household")) {
                HouseholdVO entity = (HouseholdVO) parameter;
                elasticsearchDocumentService.addHousehold(esParam,entity);
            }
        }
        if(sqlType.equals("UPDATE")){
            //update 方法需要特殊处理
            if (tableName.equals("jczz_article")) {
                Article entity = (Article) ((MapperMethod.ParamMap) parameter).get("param1");
                if (null!=entity.getId()) {
                    esParam.setTableId(entity.getId().toString());
                    elasticsearchDocumentService.update(esParam, entity, EsTableConstant.articleList);
                }
            }
            if (tableName.equals("jczz_place")) {
                PlaceEntity entity = new PlaceEntity();
                PlaceEntity placeEntity = new PlaceEntity();
                if (parameter instanceof MapperMethod.ParamMap){
                    placeEntity = (PlaceEntity) ((MapperMethod.ParamMap) parameter).get("param1");
                    if (null!=placeEntity.getId()) {
                        setPlaceInfo(entity, placeEntity);
                        esParam.setTableId(entity.getId().toString());
                        elasticsearchDocumentService.update(esParam, entity, EsTableConstant.placeList);
                    }
                }else {
                    placeEntity = (PlaceEntity) parameter;
                    // 删除
                    esParam.setTableId(placeEntity.getId().toString());
                    elasticsearchDocumentService.removeByQuery(esParam);
                }
            }
            if (tableName.equals("jczz_house")) {
                HouseEntity houseEntity = new HouseEntity();
                HouseEntity entity = new HouseEntity();
                if (parameter instanceof MapperMethod.ParamMap){
                    entity = (HouseEntity) ((MapperMethod.ParamMap) parameter).get("param1");
                    if (null!=entity.getId()) {
                        setHouseInfo(houseEntity, entity);
                        esParam.setTableId(entity.getId().toString());
                        elasticsearchDocumentService.update(esParam, entity, EsTableConstant.houseList);
                    }
                }else {
                    entity = (HouseEntity) parameter;
                    // 删除
                    esParam.setTableId(entity.getId().toString());
                    elasticsearchDocumentService.removeByQuery(esParam);
                }
            }
            if (tableName.equals("jczz_household")) {
                HouseholdEntity householdEntity = new HouseholdEntity();
                HouseholdEntity entity = new HouseholdEntity();
                if (parameter instanceof MapperMethod.ParamMap){
                    entity = (HouseholdEntity) ((MapperMethod.ParamMap) parameter).get("param1");
                    if (null!=entity.getId()) {
                        setHouseholdInfo(householdEntity, entity);
                        esParam.setTableId(entity.getId().toString());
                        elasticsearchDocumentService.update(esParam, entity, EsTableConstant.householdList);
                    }
                }else {
                    entity = (HouseholdEntity) parameter;
                    // 删除
                    esParam.setTableId(entity.getId().toString());
                    elasticsearchDocumentService.removeByQuery(esParam);
                }
            }
        }
        // 删除处理
        if(sqlType.equals("DELETE")){
            List<Long> list =(List<Long>) ((MapperMethod.ParamMap) parameter).get("param1");
            esParam.setTableId(list.get(0).toString());
            elasticsearchDocumentService.removeByQuery(esParam);
        }
    }
    /**
     * 场所值复制
     * @param entity
     * @param placeEntity
     */
    private void setPlaceInfo(PlaceEntity entity, PlaceEntity placeEntity) {
        entity.setId(placeEntity.getId());
        entity.setPlaceName(placeEntity.getPlaceName());
        entity.setPrincipal(placeEntity.getPrincipal());
        entity.setPrincipalPhone(placeEntity.getPrincipalPhone());
        entity.setPrincipalIdCard(placeEntity.getPrincipalIdCard());
        entity.setLocation(placeEntity.getLocation());
    }
    /**
     * 房屋值复制
     * @param entity
     * @param houseEntity
     */
    private void setHouseInfo(HouseEntity entity, HouseEntity houseEntity) {
        entity.setId(houseEntity.getId());
        entity.setHouseName(houseEntity.getHouseName());
    }
    /**
     * 住户值复制
     * @param entity
     * @param householdEntity
     */
    private void setHouseholdInfo(HouseholdEntity entity, HouseholdEntity householdEntity) {
        entity.setId(householdEntity.getId());
        entity.setName(householdEntity.getName());
        entity.setPhoneNumber(householdEntity.getPhoneNumber());
        entity.setIdCard(householdEntity.getIdCard());
        entity.setCurrentAddress(householdEntity.getCurrentAddress());
    }
    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    @Override
    public void setProperties(Properties properties) {
    }
}
src/main/java/org/springblade/common/param/CommonParamSet.java
@@ -2,6 +2,7 @@
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.apache.poi.hssf.record.DVALRecord;
import org.springblade.common.cache.SysCache;
import org.springblade.common.utils.AuthUtils;
import org.springblade.common.utils.SpringUtils;
@@ -15,6 +16,7 @@
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static org.springblade.core.secure.utils.AuthUtil.getUserRole;
@@ -32,6 +34,11 @@
     */
    private List<String> gridCodeList = new ArrayList<>();
    /**
     *
     */
    private String str = null;
    public List<String> getRegionChildCodesList() {
        return regionChildCodesList;
    }
@@ -42,6 +49,10 @@
    public List<String> getGridCodeList() {
        return gridCodeList;
    }
    public String getStr() {
        return str;
    }
    public <U> CommonParamSet invoke(Class<U> clazz, T t) {
@@ -108,5 +119,68 @@
        return this;
    }
    /**
     * 设置对应的属性值
     * @param clazz
     * @param t
     * @param list 字段属性集合
     * @param pre 字段拼接
     * @return
     */
    public <U> CommonParamSet setFieldValue(Class<U> clazz, T t,List<String> list,String pre) {
        //获取传入对象信息
        U u = clazz.cast(t);
        try {
            StringBuilder builder = new StringBuilder(pre);
            for (String fieldName : list) {
                if (!fieldName.equals("tableName")) {
                    if (fieldName.equals("tableId")) {
                        fieldName = "id";
                    }
                    Field field = u.getClass().getDeclaredField(fieldName);
                    field.setAccessible(true);
                    builder.append(field.get(t).toString()).append(",");
                }
            }
            String toString = builder.toString();
            str = toString.substring(0,toString.length()-1);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }
    /**
     * 设置对应的属性值
     * @param clazz
     * @param t
     * @param list 字段属性集合
     * @param map
     * @return
     */
    public <U> CommonParamSet setFieldValueByMap(Class<U> clazz, T t, List<String> list, Map<String,Object> map) {
        //获取传入对象信息
        U u = clazz.cast(t);
        try {
            for (String fieldName : list) {
                if (!fieldName.equals("tableName")){
                    if (fieldName.equals("tableId")){
                        fieldName = "id";
                    }
                    Field field = u.getClass().getDeclaredField(fieldName);
                    field.setAccessible(true);
                    String value = field.get(t).toString();
                    if (fieldName.equals("id")){
                        fieldName = "tableId";
                    }
                    map.put(fieldName,value);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return this;
    }
}
src/main/java/org/springblade/common/utils/SQLParseUtils.java
New file
@@ -0,0 +1,41 @@
package org.springblade.common.utils;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class SQLParseUtils {
    public static String parseSQLType(String sql){
        if (sql==null){
            return null;
        }
        String type = sql.split(" ")[0];
        if (type.equalsIgnoreCase("INSERT")){
            return "INSERT";
        } else if (type.equalsIgnoreCase("UPDATE")) {
            return "UPDATE";
        } else if (type.equalsIgnoreCase("DELETE")) {
            return "DELETE";
        }else {
            return null;
        }
    }
    public static String getTableName(String sql) {
        String tableName = null;
        // 正则表达式匹配 INSERT、UPDATE 和 DELETE 语句
        String regex = "(?i)(?:INSERT\\s+INTO|UPDATE|DELETE\\s+FROM)\\s+(\\w+)";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(sql.trim());
        if (matcher.find()) {
            tableName = matcher.group(1);
        }
        return tableName;
    }
    public static void main(String[] args) {
        String tableName = getTableName("INSERT INTO orders (customer_id, product_id, quantity) VALUES (789, 123, 5)");
        System.out.println(tableName);
    }
}
src/main/java/org/springblade/es/config/ElasticsearchConfig.java
New file
@@ -0,0 +1,24 @@
package org.springblade.es.config;
import org.springframework.beans.factory.annotation.Value;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConditionalOnProperty(value = "elasticsearch.enabled")
public class ElasticsearchConfig {
    @Value("${elasticsearch.host}")
    private String elasticsearchHost;
    @Bean
    public RestHighLevelClient elasticsearchClient() {
        RestClientBuilder builder = RestClient.builder(new HttpHost(elasticsearchHost, 9200, "http"));
        return new RestHighLevelClient(builder);
    }
}
src/main/java/org/springblade/es/config/ElasticsearchInitializer.java
New file
@@ -0,0 +1,24 @@
package org.springblade.es.config;
import org.springblade.es.service.ElasticsearchIndexInitializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
// 暂时关闭
//@Component
public class ElasticsearchInitializer implements CommandLineRunner {
    private final ElasticsearchIndexInitializer indexInitializer;
    @Autowired
    public ElasticsearchInitializer(ElasticsearchIndexInitializer indexInitializer) {
        this.indexInitializer = indexInitializer;
    }
    @Override
    public void run(String... args) {
        String indexName = "your_index_name";
        String mappingJson = "{\"properties\":{\"your_field\":{\"type\":\"text\"}}}";
        indexInitializer.initializeIndex(indexName, mappingJson);
    }
}
src/main/java/org/springblade/es/controller/EsController.java
New file
@@ -0,0 +1,79 @@
package org.springblade.es.controller;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.Api;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.es.service.ElasticsearchDocumentService;
import org.springblade.es.vo.EsParam;
import org.springframework.web.bind.annotation.*;
/**
 * es 全文检索
 */
@RestController
@RequestMapping("/es/es")
@AllArgsConstructor
@Api(value = "es 全文检索", tags = "es 全文检索")
public class EsController {
    private final ElasticsearchDocumentService elasticsearchDocumentService;
    /**
     * 查询
     */
    @GetMapping("/page")
    @ApiOperationSupport(order = 1)
    public R page(EsParam esParam, Query query) {
        return R.data(elasticsearchDocumentService.selectDocumentPage(Condition.getPage(query), esParam));
    }
    /**
     * 初始化
     */
    @GetMapping("/init")
    @ApiOperationSupport(order = 2)
    public R init(EsParam esParam) {
        return R.status(elasticsearchDocumentService.init(esParam));
    }
    /**
     * 新增数据
     */
    @GetMapping("/add")
    @ApiOperationSupport(order = 3)
    public R add(EsParam esParam) {
        return R.status(elasticsearchDocumentService.add(esParam,null));
    }
    /**
     * 修改数据
     */
    @GetMapping("/update")
    @ApiOperationSupport(order = 4)
    public R update(EsParam esParam) {
        elasticsearchDocumentService.update(esParam,null,null);
        return R.status(true);
    }
    /**
     * 根据索引删除
     */
    @PostMapping("/removeBatchByIndexNames")
    @ApiOperationSupport(order = 5)
    public R removeBatchByIndexNames(@RequestParam String indexNames) {
        return R.status(elasticsearchDocumentService.removeBatchByIndexNames(Func.toStrList(indexNames)));
    }
    /**
     * 根据条件删除
     */
    @PostMapping("/removeByQuery")
    @ApiOperationSupport(order = 6)
    public R removeByQuery(EsParam esParam) {
        return R.status(elasticsearchDocumentService.removeByQuery(esParam));
    }
}
src/main/java/org/springblade/es/service/ElasticsearchDocumentService.java
New file
@@ -0,0 +1,695 @@
package org.springblade.es.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.logging.log4j.util.Strings;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.*;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springblade.common.constant.EsTableConstant;
import org.springblade.common.param.CommonParamSet;
import org.springblade.common.utils.SpringUtils;
import org.springblade.es.vo.EsParam;
import org.springblade.modules.article.entity.Article;
import org.springblade.modules.article.service.ArticleService;
import org.springblade.modules.house.entity.HouseEntity;
import org.springblade.modules.house.entity.HouseholdEntity;
import org.springblade.modules.house.service.IHouseService;
import org.springblade.modules.house.service.IHouseholdService;
import org.springblade.modules.house.vo.HouseVO;
import org.springblade.modules.house.vo.HouseholdVO;
import org.springblade.modules.place.entity.PlaceEntity;
import org.springblade.modules.place.service.IPlaceService;
import org.springblade.modules.place.vo.PlaceVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.elasticsearch.script.Script;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class ElasticsearchDocumentService<T> {
    @Autowired
    private RestHighLevelClient client;
    @Autowired
    private ArticleService articleService;
    @Autowired
    private IPlaceService placeService;
    @Autowired
    private IHouseService houseService;
    @Autowired
    private IHouseholdService householdService;
    @Value("${elasticsearch.sync}")
    private boolean elasticsearchSync;
    @Value("${elasticsearch.indexName}")
    private String indexName;
    /**
     * 检查索引是否已存在
     *
     * @param indexName
     * @return
     */
    public boolean isIndexExists(String indexName) {
        // 检查索引是否已存在
        GetIndexRequest request = new GetIndexRequest(indexName);
        try {
            return client.indices().exists(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }
    /**
     * 初始化数据
     *
     * @param esParam
     * @return
     */
    public boolean init(EsParam esParam) {
        // 场所
        initPlace(esParam);
        // 通知文章
        initArticle(esParam);
        // 房屋
        initHouse(esParam);
        // 住户
        initHousehold(esParam);
        // 返回
        return true;
    }
    /**
     * 初始化数据
     *
     * @param esParam
     * @return
     */
    public boolean initPlace(EsParam esParam) {
        // 查询
        int total = placeService.getAllListTotal();
        int size = 1000;
        int num = total / size;
        for (int i = 1; i <= num + 1; i++) {
            List<PlaceVO> placeVOList = placeService.getAllList((i - 1) * size, size);
            // 遍历
            if (placeVOList.size() > 0) {
                // 创建批量请求对象
                BulkRequest bulkRequest = new BulkRequest();
                for (PlaceVO place : placeVOList) {
                    // 入es库
                    // 初始化Elasticsearch客户端
                    IndexRequest indexRequest = new IndexRequest(esParam.getIndexName());
                    // 不设置id
                    // indexRequest.id("1");
                    indexRequest.source(
                        "tableId", place.getId().toString(),
                        "tableName", "jczz_place",
                        "title", place.getPlaceName(),
                        "name", place.getPrincipal(),
                        "phone", place.getPrincipalPhone(),
                        "idCard", place.getPrincipalIdCard(),
                        "content", place.getLocation(),
                        "communityCode", place.getCommunityCode()
                    );
                    // 加入集合
                    bulkRequest.add(indexRequest);
                }
                BulkResponse bulkResponse = null;
                try {
                    // 执行批量插入
                    bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
                    // 刷新索引,确保文档可搜索
                    client.indices().refresh(new RefreshRequest(esParam.getIndexName()), RequestOptions.DEFAULT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("批量插入结果: " + !bulkResponse.hasFailures());
            }
        }
        // 返回
        return true;
    }
    /**
     * 初始化公告数据
     *
     * @param esParam
     * @return
     */
    public boolean initArticle(EsParam esParam) {
        // 查询
        int total = articleService.getAllListTotal();
        int size = 10;
        int num = total / size;
        for (int i = 1; i <= num + 1; i++) {
            // 查询
            List<Article> articleList = articleService.getAllList((i - 1) * size, size);
            // 遍历
            if (articleList.size() > 0) {
                BulkRequest bulkRequest = new BulkRequest();
                for (Article article : articleList) {
                    // 初始化Elasticsearch客户端
                    IndexRequest indexRequest = new IndexRequest(esParam.getIndexName());
                    // 不设置id
                    // indexRequest.id("1");
                    indexRequest.source("tableId", article.getId().toString(),
                        "tableName", "jczz_article",
                        "title", article.getTitle(),
                        "communityCode", article.getArticleRange(),
                        "type", null != article.getType() ? article.getType().toString() : "",
                        "content", article.getContent(),
                        "articleType", article.getArticleType());
                    // 加入集合
                    bulkRequest.add(indexRequest);
                }
                BulkResponse bulkResponse = null;
                try {
                    // 执行批量插入
                    bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
                    // 刷新索引,确保文档可搜索
                    client.indices().refresh(new RefreshRequest(esParam.getIndexName()), RequestOptions.DEFAULT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("批量插入结果: " + !bulkResponse.hasFailures());
            }
        }
        // 返回
        return true;
    }
    /**
     * 初始化住户数据
     *
     * @param esParam
     * @return
     */
    public boolean initHousehold(EsParam esParam) {
        // 查询
        int total = householdService.getAllListTotal();
        int size = 1000;
        int num = total / size;
        for (int i = 1; i <= num + 1; i++) {
            // 查询
            List<HouseholdVO> householdVOList = householdService.getAllList((i - 1) * size, size);
            // 遍历
            if (householdVOList.size() > 0) {
                BulkRequest bulkRequest = new BulkRequest();
                for (HouseholdVO household : householdVOList) {
                    // 初始化Elasticsearch客户端
                    IndexRequest indexRequest = new IndexRequest(esParam.getIndexName());
                    // 不设置id
                    // indexRequest.id("1");
                    indexRequest.source(
                        "tableId", household.getId().toString(),
                        "tableName", "jczz_household",
                        "title", household.getName(),
                        "name", household.getName(),
                        "phone", household.getPhoneNumber(),
                        "idCard", household.getIdCard(),
                        "content", household.getAddress(),
                        "communityCode", household.getCommunityCode()
                    );
                    // 加入集合
                    bulkRequest.add(indexRequest);
                }
                BulkResponse bulkResponse = null;
                try {
                    // 执行批量插入
                    bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
                    // 刷新索引,确保文档可搜索
                    client.indices().refresh(new RefreshRequest(esParam.getIndexName()), RequestOptions.DEFAULT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("批量插入结果: " + !bulkResponse.hasFailures());
            }
        }
        // 返回
        return true;
    }
    /**
     * 初始化房屋数据
     *
     * @param esParam
     * @return
     */
    public boolean initHouse(EsParam esParam) {
        // 查询
        int total = houseService.getAllListTotal();
        int size = 1000;
        int num = total / size;
        for (int i = 1; i <= num + 1; i++) {
            // 查询
            List<HouseVO> houseVOList = houseService.getAllList((i - 1) * size, size);
            // 遍历
            if (houseVOList.size() > 0) {
                BulkRequest bulkRequest = new BulkRequest();
                for (HouseVO house : houseVOList) {
                    // 初始化Elasticsearch客户端
                    IndexRequest indexRequest = new IndexRequest(esParam.getIndexName());
                    // 不设置id
                    // indexRequest.id("1");
                    indexRequest.source(
                        "tableId", house.getId().toString(),
                        "tableName", "jczz_house",
                        "title", house.getHouseName(),
                        "name", null,
                        "phone", null,
                        "idCard", null,
                        "content", null,
                        "communityCode", house.getCommunityCode()
                    );
                    // 加入集合
                    bulkRequest.add(indexRequest);
                }
                BulkResponse bulkResponse = null;
                try {
                    // 执行批量插入
                    bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT);
                    // 刷新索引,确保文档可搜索
                    client.indices().refresh(new RefreshRequest(esParam.getIndexName()), RequestOptions.DEFAULT);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                System.out.println("批量插入结果: " + !bulkResponse.hasFailures());
            }
        }
        // 返回
        return true;
    }
    /**
     * 新增公告同步
     *
     * @param esParam
     * @param article
     */
    @Async
    public void addArticle(EsParam esParam, Article article) {
        if (elasticsearchSync) {
            try {
                indexDocument(esParam.getIndexName(),
                    "tableId", article.getId().toString(),
                    "tableName", "jczz_article",
                    "title", article.getTitle(),
                    "communityCode", article.getArticleRange(),
                    "type", null != article.getType() ? article.getType().toString() : "",
                    "content", article.getContent(),
                    "articleType", article.getArticleType()
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 新增场所同步
     *
     * @param esParam
     * @param place
     */
    @Async
    public void addPlace(EsParam esParam, PlaceVO place) {
        if (elasticsearchSync) {
            if (!Strings.isBlank(place.getCommunityCode())) {
                place.setCommunityCode(placeService.getCommunityCode(place.getId()));
            }
            try {
                indexDocument(esParam.getIndexName(),
                    "tableId", place.getId().toString(),
                    "tableName", "jczz_place",
                    "title", place.getPlaceName(),
                    "name", place.getPrincipal(),
                    "phone", place.getPrincipalPhone(),
                    "idCard", place.getPrincipalIdCard(),
                    "content", place.getLocation(),
                    "communityCode", place.getCommunityCode()
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 新增房屋同步
     *
     * @param esParam
     * @param house
     */
    @Async
    public void addHouse(EsParam esParam, HouseVO house) {
        if (elasticsearchSync) {
            if (!Strings.isBlank(house.getCommunityCode())) {
                house.setCommunityCode(houseService.getCommunityCode(house.getId()));
            }
            try {
                indexDocument(esParam.getIndexName(),
                    "tableId", house.getId().toString(),
                    "tableName", "jczz_house",
                    "title", house.getHouseName(),
                    "name", null,
                    "phone", null,
                    "idCard", null,
                    "content", null,
                    "communityCode", house.getCommunityCode()
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 新增住户同步
     *
     * @param esParam
     * @param household
     */
    @Async
    public void addHousehold(EsParam esParam, HouseholdVO household) {
        if (elasticsearchSync) {
            if (!Strings.isBlank(household.getCommunityCode())) {
                household.setCommunityCode(householdService.getCommunityCode(household.getId()));
            }
            try {
                indexDocument(esParam.getIndexName(),
                    "tableId", household.getId().toString(),
                    "tableName", "jczz_household",
                    "title", household.getName(),
                    "name", household.getName(),
                    "phone", household.getPhoneNumber(),
                    "idCard", household.getIdCard(),
                    "content", household.getAddress(),
                    "communityCode", household.getCommunityCode()
                );
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 插入数据到es
     *
     * @param index
     * @param values
     * @throws IOException
     */
    public void indexDocument(String index, String... values) throws IOException {
        // 初始化Elasticsearch客户端
        IndexRequest indexRequest = new IndexRequest(index);
        // 不设置id
//        indexRequest.id("1");
        indexRequest.source(values);
        IndexResponse indexResponse = client.index(indexRequest, RequestOptions.DEFAULT);
        // 刷新索引,确保文档可搜索
        client.indices().refresh(new RefreshRequest(index), RequestOptions.DEFAULT);
        System.out.println("Indexed document with id: " + indexResponse.getId());
    }
    /**
     * 查询数据
     *
     * @param page
     * @param esParam
     * @return
     */
    public Object selectDocumentPage(IPage<Object> page, EsParam esParam) {
        if (Strings.isBlank(esParam.getIndexName())){
            esParam.setIndexName(indexName);
        }
        // 判断索引是否存在
        if (isIndexExists(esParam.getIndexName())) {
            // 全文搜索
            SearchRequest searchRequest = new SearchRequest(esParam.getIndexName());
            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //        searchSourceBuilder.query(QueryBuilders.multiMatchQuery(esParam.getSearchKey(),
            //            "content",
            //            "name",
            //            "title",
            //            "location",
            //            "phone",
            //            "idCard",
            //            "communityCode")
            //            .type(MultiMatchQueryBuilder.Type.BEST_FIELDS)
            //        );
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//            boolQueryBuilder.should(QueryBuilders.matchQuery("content", esParam.getSearchKey()));
//            boolQueryBuilder.should(QueryBuilders.matchQuery("name", esParam.getSearchKey()));
            boolQueryBuilder.should(QueryBuilders.matchQuery("title", esParam.getSearchKey()));
//            boolQueryBuilder.should(QueryBuilders.matchQuery("location", esParam.getSearchKey()));
//            boolQueryBuilder.should(QueryBuilders.matchQuery("phone", esParam.getSearchKey()));
//            boolQueryBuilder.should(QueryBuilders.matchQuery("idCard", esParam.getSearchKey()));
            String communityCode = SpringUtils.getRequestParam("communityCode");
            if (!Strings.isBlank(communityCode)) {
                boolQueryBuilder.must(QueryBuilders.matchQuery("communityCode", communityCode));
            }
            if (!Strings.isBlank(esParam.getTableName())) {
                boolQueryBuilder.must(QueryBuilders.matchQuery("tableName", esParam.getTableName()));
            }
            boolQueryBuilder.minimumShouldMatch(1);
            searchSourceBuilder.query(boolQueryBuilder);
            int current = (int) page.getCurrent();
            int size = (int) page.getSize();
            //设置分页
            searchSourceBuilder.size(size);
            searchSourceBuilder.from((current - 1) * size);
            //将搜索资源对象设置到搜索客户端中
            searchRequest.source(searchSourceBuilder);
            //查询
            SearchResponse searchResponse = null;
            try {
                searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }
            //解析搜索返回值
            SearchHits searchHits = searchResponse.getHits();
            //查询的总数
            long count = searchHits.getTotalHits().value;
            List<Object> list = new ArrayList<>();
            for (SearchHit hit : searchHits) {
//                System.out.println("hit.getId() = " + hit.getId());
                Map<String, Object> result = hit.getSourceAsMap();
                if (null != result){
                    if (result.get("tableName").toString().equals("jczz_article")){
                        result.put("typeName","通知公告");
                    }
                    if (result.get("tableName").toString().equals("jczz_place")){
                        result.put("typeName","经营场所");
                    }
                    if (result.get("tableName").toString().equals("jczz_house")){
                        result.put("typeName","房屋");
                    }
                    if (result.get("tableName").toString().equals("jczz_household")){
                        result.put("typeName","住户");
                    }
                }
                // 文档源数据
//            String source = hit.getSourceAsString();
                list.add(result);
            }
            page.setRecords(list);
            page.setTotal(count);
        }
        return page;
    }
    /**
     * 根据索引删除
     */
    public boolean removeBatchByIndexNames(List<String> indexNames) {
        for (String indexName : indexNames) {
            DeleteIndexRequest deleteIndexRequest = new DeleteIndexRequest(indexName);
            try {
                // 执行删除索引操作
                AcknowledgedResponse deleteResponse = client.indices().delete(deleteIndexRequest, RequestOptions.DEFAULT);
                // 输出操作结果
                boolean acknowledged = deleteResponse.isAcknowledged();
                System.out.println("索引删除成功: " + acknowledged);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }
    /**
     * 新增数据--有问题,待调整
     */
    @Async
    public boolean add(EsParam esParam, T item) {
        String str = "tableName," + esParam.getTableName() + ",";
        CommonParamSet commonParamSet =
            new CommonParamSet().setFieldValue(item.getClass(), item, EsTableConstant.articleList, str);
        try {
            indexDocument(esParam.getIndexName(), str);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return true;
    }
    /**
     * 修改数据
     */
    @Async
    public void update(EsParam esParam, T item,List<String> columnList) {
        if (elasticsearchSync) {
            // 创建更新请求
            UpdateByQueryRequest updateRequest = new UpdateByQueryRequest(esParam.getIndexName());
            // 设置查询条件,例如:更新所有字段text包含"old text"的文档
            updateRequest.setQuery(
                QueryBuilders.boolQuery()
                    .must(QueryBuilders.matchQuery("tableId", esParam.getTableId()))
                    .must(QueryBuilders.matchQuery("tableName", esParam.getTableName()))
            );
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("tableName", esParam.getTableName());
            if (esParam.getTableName().equals("jczz_article")){
                setArticleMap((Article)item,data);
            }
            if (esParam.getTableName().equals("jczz_place")){
                setPlaceMap((PlaceEntity) item,data);
            }
            if (esParam.getTableName().equals("jczz_house")){
                setHouseMap((HouseEntity) item,data);
            }
            if (esParam.getTableName().equals("jczz_household")){
                setHousehouldMap((HouseholdEntity) item,data);
            }
            Map<String, Object> param = new HashMap<String, Object>();
            param.put("data", data);
            // script will read data param value and assign to document source
            String source = "ctx._source=params.data";
            Script script = new Script(ScriptType.INLINE, "painless", source, param);
            updateRequest.setScript(script);
            // 执行更新操作
            try {
                client.updateByQuery(updateRequest, RequestOptions.DEFAULT);
                // 刷新索引,确保文档可搜索
                client.indices().refresh(new RefreshRequest(esParam.getIndexName()), RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 设置公告map
     * @param item
     * @param data
     */
    private void setArticleMap(Article item, Map<String, Object> data) {
        data.put("tableId",item.getId());
        data.put("title",item.getTitle());
        data.put("type",item.getType());
        data.put("content",item.getContent());
        data.put("articleType",item.getArticleType());
        data.put("communityCode",item.getArticleRange());
    }
    /**
     * 设置场所map
     * @param item
     * @param data
     */
    private void setPlaceMap(PlaceEntity item, Map<String, Object> data) {
        data.put("communityCode",placeService.getCommunityCode(item.getId()));
        data.put("tableId",item.getId());
        data.put("title",item.getPlaceName());
        data.put("name",item.getPrincipal());
        data.put("phone",item.getPrincipalPhone());
        data.put("idCard",item.getPrincipalIdCard());
        data.put("content",item.getLocation());
    }
    /**
     * 设置房屋map
     * @param item
     * @param data
     */
    private void setHouseMap(HouseEntity item, Map<String, Object> data) {
        data.put("communityCode",houseService.getCommunityCode(item.getId()));
        data.put("tableId",item.getId());
        data.put("title",item.getHouseName());
    }
    /**
     * 设置住户map
     * @param item
     * @param data
     */
    private void setHousehouldMap(HouseholdEntity item, Map<String, Object> data) {
        data.put("communityCode",householdService.getCommunityCode(item.getId()));
        data.put("tableId",item.getId());
        data.put("title",item.getName());
        data.put("name",item.getName());
        data.put("phone",item.getPhoneNumber());
        data.put("idCard",item.getIdCard());
        data.put("content",item.getCurrentAddress());
    }
    /**
     * 删除数据--根据条件
     */
    public boolean removeByQuery(EsParam esParam) {
        if (elasticsearchSync) {
            DeleteByQueryRequest deleteByQueryRequest = new DeleteByQueryRequest(esParam.getIndexName());
            // 根据多个条件 生成 boolQueryBuilder
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
            boolQueryBuilder
                .must(QueryBuilders.matchQuery("tableId", esParam.getTableId()))
                .must(QueryBuilders.matchQuery("tableName", esParam.getTableName()));
            deleteByQueryRequest.setQuery(boolQueryBuilder);
            try {
                BulkByScrollResponse bulkResponse =
                    client.deleteByQuery(deleteByQueryRequest, RequestOptions.DEFAULT);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return true;
    }
}
src/main/java/org/springblade/es/service/ElasticsearchIndexInitializer.java
New file
@@ -0,0 +1,33 @@
package org.springblade.es.service;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.indices.CreateIndexRequest;
import org.elasticsearch.client.indices.GetIndexRequest;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ElasticsearchIndexInitializer {
    @Autowired
    private RestHighLevelClient client;
    public void initializeIndex(String indexName, String mappingJson) {
        try {
            // 检查索引是否已存在
            GetIndexRequest request = new GetIndexRequest(indexName);
            boolean indexExists = client.indices().exists(request, RequestOptions.DEFAULT);
            // 如果索引不存在,则创建索引并设置映射
            if (!indexExists) {
                CreateIndexRequest createIndexRequest = new CreateIndexRequest(indexName);
                createIndexRequest.mapping(mappingJson, XContentType.JSON);
                client.indices().create(createIndexRequest, RequestOptions.DEFAULT);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
src/main/java/org/springblade/es/service/ElasticsearchIndexService.java
New file
@@ -0,0 +1,37 @@
package org.springblade.es.service;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.xcontent.XContentBuilder;
import org.elasticsearch.xcontent.json.JsonXContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
@Service
public class ElasticsearchIndexService {
    @Autowired
    private RestHighLevelClient client;
    public void createIndex() throws IOException {
        CreateIndexRequest request = new CreateIndexRequest("your_index");
        XContentBuilder builder = JsonXContent.contentBuilder()
            .startObject()
            .startObject("properties")
            .startObject("field1").field("type", "text").endObject()
            .startObject("field2").field("type", "text").endObject()
            // ... 定义其他字段
            .endObject()
            .endObject();
        request.mapping("_doc", builder);
        CreateIndexResponse createIndexResponse = client.indices().create(request, RequestOptions.DEFAULT);
        boolean acknowledged = createIndexResponse.isAcknowledged();
        System.out.println(acknowledged);
    }
}
src/main/java/org/springblade/es/service/ElasticsearchSearchService.java
New file
@@ -0,0 +1,29 @@
package org.springblade.es.service;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
@Service
public class ElasticsearchSearchService {
    @Autowired
    private RestHighLevelClient client;
    public SearchResponse search(String index, String query) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("field1", query)); // 搜索field1字段
        searchSourceBuilder.query(QueryBuilders.matchQuery("field2", query)); // 搜索field2字段
        searchRequest.source(searchSourceBuilder);
        return client.search(searchRequest, RequestOptions.DEFAULT);
    }
}
src/main/java/org/springblade/es/test/ElasticSearchExample.java
New file
@@ -0,0 +1,96 @@
package org.springblade.es.test;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.admin.indices.refresh.RefreshRequest;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import java.io.IOException;
import java.util.Map;
public class ElasticSearchExample {
    public static void main(String[] args) throws IOException {
        // 初始化Elasticsearch客户端
        RestClientBuilder builder = RestClient.builder(new HttpHost("localhost", 9200, "http"));
        RestHighLevelClient client = new RestHighLevelClient(builder);
        // 索引用户数据
        IndexRequest userIndexRequest = new IndexRequest("users_articles");
        userIndexRequest.source("name", "John Doe", "type", "user");
        IndexResponse userIndexResponse = client.index(userIndexRequest, RequestOptions.DEFAULT);
        // 索引文章数据
        IndexRequest articleIndexRequest = new IndexRequest("users_articles");
        articleIndexRequest.source("title", "Elasticsearch Introduction", "type", "article");
        IndexResponse articleIndexResponse = client.index(articleIndexRequest, RequestOptions.DEFAULT);
        // 刷新索引,确保文档可搜索
        client.indices().refresh(new RefreshRequest("users_articles"), RequestOptions.DEFAULT);
        // 全文搜索
        SearchRequest searchRequest = new SearchRequest("users_articles");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.multiMatchQuery("Elasticsearch", "name", "title"));
        //设置分页
        searchSourceBuilder.size(10);
        searchSourceBuilder.from(0);
        //将搜索资源对象设置到搜索客户端中
        searchRequest.source(searchSourceBuilder);
        //查询
        SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        //解析搜索返回值
        SearchHits searchHits = searchResponse.getHits();
        //查询的总数
        long count = searchHits.getTotalHits().value;
        for (SearchHit hit : searchHits) {
            Map<String, Object> result = hit.getSourceAsMap();
            // 根据类型处理结果
            String type = (String) result.get("type");
            if ("user".equals(type)) {
                // 处理用户名
                String name = (String) result.get("name");
                System.out.println("User: " + name);
            } else if ("article".equals(type)) {
                // 处理文章标题
                String title = (String) result.get("title");
                System.out.println("Article: " + title);
            }
        }
        // 关闭客户端
        client.close();
    }
    /**
     * 设置高亮
     * @param keywords
     * @param info
     * @return
     */
    public static String setHighLight(String keywords, String info) {
        if (StringUtils.isBlank(keywords)|| StringUtils.isBlank(info)) {
            return info;
        }
        String[] keywordArray = keywords.split(" ");
        String newInfo = info;
        for (String keyword : keywordArray) {
            newInfo = newInfo.replace(keyword, "<em style=\"color:red\">" + keyword + "</em>");
        }
        return newInfo;
    }
}
src/main/java/org/springblade/es/vo/EsParam.java
New file
@@ -0,0 +1,32 @@
package org.springblade.es.vo;
import lombok.Data;
@Data
public class EsParam {
    /**
     * 索引名称
     */
    private String indexName;
    /**
     * 表名称
     */
    private String tableName;
    /**
     * searchKey
     */
    private String searchKey;
    /**
     * 表id
     */
    private String tableId;
    /**
     * 社区编号
     */
    private String communityCode;
}
src/main/java/org/springblade/modules/article/controller/ArticleController.java
@@ -11,6 +11,8 @@
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springblade.es.service.ElasticsearchDocumentService;
import org.springblade.es.vo.EsParam;
import org.springblade.modules.article.entity.Article;
import org.springblade.modules.article.service.ArticleService;
import org.springblade.modules.article.vo.ArticleVO;
@@ -31,6 +33,7 @@
public class ArticleController {
    private final ArticleService articleService;
    private final ElasticsearchDocumentService elasticsearchDocumentService;
    /**
     * 查询资讯分页信息
@@ -165,14 +168,17 @@
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "新增或修改资讯信息", notes = "传入article")
    public R submit(@RequestBody ArticleVO article) {
    public R submit(@RequestBody Article article) {
        boolean flag = false;
        if (null == article.getId()) {
            flag = true;
            if (null == article.getCreateTime()) {
                article.setCreateTime(new Date());
            }
        }
        article.setUpdateTime(new Date());
        return R.status(articleService.saveOrUpdate(article));
        boolean saveOrUpdate = articleService.saveOrUpdate(article);
        return R.status(saveOrUpdate);
    }
@@ -185,7 +191,9 @@
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "删除", notes = "传入ids")
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        return R.status(articleService.removeByIds(Func.toLongList(ids)));
        List<Long> longs = Func.toLongList(ids);
        boolean removeByIds = articleService.removeByIds(longs);
        return R.status(removeByIds);
    }
    /**
src/main/java/org/springblade/modules/article/mapper/ArticleMapper.java
@@ -59,4 +59,16 @@
    String getDistrictId(String houseCode);
    List<ArticleVO> getArticleByDistrictId(@Param("article") ArticleVO article);
    /**
     * 查询所有文章数据
     * @return
     */
    List<Article> getAllList(@Param("i") int i,@Param("size") int size);
    /**
     * 查询所有文章数据总数
     * @return
     */
    int getAllListTotal();
}
src/main/java/org/springblade/modules/article/mapper/ArticleMapper.xml
@@ -598,4 +598,25 @@
        order by ja.create_time desc
    </select>
    <select id="getAllList" resultType="org.springblade.modules.article.entity.Article">
        SELECT
        ja.*
        FROM
        jczz_article ja
        where 1=1
        and ja.is_deleted = 0
        and ja.publish = 1
        limit #{i},#{size}
    </select>
    <select id="getAllListTotal" resultType="java.lang.Integer">
        SELECT
        count(*)
        FROM
        jczz_article ja
        where 1=1
        and ja.is_deleted = 0
        and ja.publish = 1
    </select>
</mapper>
src/main/java/org/springblade/modules/article/service/ArticleService.java
@@ -75,4 +75,16 @@
     * @return
     */
    boolean updateArticle(UpdateWrapper<Article> objectUpdateWrapper,Long id,String houseCode);
    /**
     * 查询所有文章数据
     * @return
     */
    List<Article> getAllList(int i,int size);
    /**
     * 查询所有文章数据总数
     * @return
     */
    int getAllListTotal();
}
src/main/java/org/springblade/modules/article/service/impl/ArticleServiceImpl.java
@@ -226,4 +226,22 @@
        // 返回
        return update;
    }
    /**
     * 查询所有文章数据
     * @return
     */
    @Override
    public List<Article> getAllList(int i,int size) {
        return baseMapper.getAllList(i,size);
    }
    /**
     * 查询所有文章数据总数
     * @return
     */
    @Override
    public int getAllListTotal() {
        return baseMapper.getAllListTotal();
    }
}
src/main/java/org/springblade/modules/backblast/mapper/BackblastPubPersonMapper.xml
@@ -35,7 +35,7 @@
            ifnull(jbpp.id_card,''),
            ifnull(jbpp.address,''),
            ifnull(jbpp.name,''),
            ifnull(jbpp.name,'')
            ifnull(jbpp.telephone,'')
            ) like CONCAT ('%', #{backblastPubPerson.searchKey},'%')
        </if>
        order by jbpp.id desc,jbpp.create_time desc
src/main/java/org/springblade/modules/house/mapper/HouseMapper.java
@@ -123,4 +123,25 @@
                                                     @Param("isAdministrator") Integer isAdministrator,
                                                     @Param("regionChildCodesList")List<String> regionChildCodesList,
                                                     @Param("gridCodeList")List<String> gridCodeList);
    /**
     * 查询对应的社区编号
     * @param id
     * @return
     */
    String getCommunityCode(@Param("id") Long id);
    /**
     * 查询所有房屋总数
     * @return
     */
    int getAllListTotal();
    /**
     * 查询所有的房屋
     * @param i
     * @param size
     * @return
     */
    List<HouseVO> getAllList(@Param("i") int i,@Param("size") int size);
}
src/main/java/org/springblade/modules/house/mapper/HouseMapper.xml
@@ -890,5 +890,37 @@
        ) b on a.label_name =b.labelName
    </select>
    <!--查询对应的社区编号-->
    <select id="getCommunityCode" resultType="java.lang.String">
        SELECT
        jpag.community_code
        FROM
        jczz_house jh
        LEFT JOIN jczz_police_affairs_grid jpag on jh.jw_grid_code= jpag.jw_grid_code and jpag.is_deleted = 0
        where jh.is_deleted = 0
        and jh.id = #{id}
    </select>
    <!--查询所有房屋总数-->
    <select id="getAllListTotal" resultType="java.lang.Integer">
        SELECT
        count(*)
        FROM
        jczz_house jh
        where jh.is_deleted = 0
    </select>
    <!--查询所有的房屋-->
    <select id="getAllList" resultType="org.springblade.modules.house.vo.HouseVO">
        SELECT
        jh.*,
        jpag.community_code
        FROM
        jczz_house jh
        LEFT JOIN jczz_police_affairs_grid jpag on jh.jw_grid_code= jpag.jw_grid_code and jpag.is_deleted = 0
        where jh.is_deleted = 0
        limit #{i},#{size}
    </select>
</mapper>
src/main/java/org/springblade/modules/house/mapper/HouseholdMapper.java
@@ -161,4 +161,24 @@
     */
    List<HouseholdVO> getUserInfoByDistrictIds(@Param("list") List<String> list, @Param("vo") HouseholdVO householdVO, IPage<HouseholdVO> page);
    /**
     * 查询住户对应的社区编号
     * @param id
     * @return
     */
    String getCommunityCode(@Param("id") Long id);
    /**
     * 查询所有住户总数
     * @return
     */
    int getAllListTotal();
    /**
     * 查询对应的住户集合
     * @param i
     * @param size
     * @return
     */
    List<HouseholdVO> getAllList(@Param("i") int i,@Param("size") int size);
}
src/main/java/org/springblade/modules/house/mapper/HouseholdMapper.xml
@@ -1249,4 +1249,38 @@
        </where>
    </select>
    <!--查询住户对应的社区编号-->
    <select id="getCommunityCode" resultType="java.lang.String">
        SELECT
        jpag.community_code
        FROM
        jczz_household jh
        LEFT JOIN jczz_house jhs ON jh.house_code = jhs.house_code and jhs.is_deleted = 0
        LEFT JOIN jczz_police_affairs_grid jpag on jhs.jw_grid_code= jpag.jw_grid_code and jpag.is_deleted = 0
        where jh.is_deleted = 0
        and jh.id = #{id}
    </select>
    <!--查询所有住户总数-->
    <select id="getAllListTotal" resultType="java.lang.Integer">
        SELECT
        count(*)
        FROM
        jczz_household jh
        where jh.is_deleted = 0
    </select>
    <!--查询对应的住户集合-->
    <select id="getAllList" resultType="org.springblade.modules.house.vo.HouseholdVO">
        SELECT
        jh.*,
        jpag.community_code
        FROM
        jczz_household jh
        LEFT JOIN jczz_house jhs ON jh.house_code = jhs.house_code and jhs.is_deleted = 0
        LEFT JOIN jczz_police_affairs_grid jpag on jhs.jw_grid_code= jpag.jw_grid_code and jpag.is_deleted = 0
        where jh.is_deleted = 0
        limit #{i},#{size}
    </select>
</mapper>
src/main/java/org/springblade/modules/house/service/IHouseService.java
@@ -109,4 +109,25 @@
     * @return
     */
    List<Map<String,Object>> getHouseLabelStatistic(HouseVO house);
    /**
     * 查询对应的社区编号
     * @param id
     * @return
     */
    String getCommunityCode(Long id);
    /**
     * 查询所有房屋总数
     * @return
     */
    int getAllListTotal();
    /**
     * 查询所有的房屋
     * @param i
     * @param size
     * @return
     */
    List<HouseVO> getAllList(int i, int size);
}
src/main/java/org/springblade/modules/house/service/IHouseholdService.java
@@ -120,11 +120,30 @@
    /**
     * 通过小区id查询用户
     * @param districtIds
     * @param building
     * @param unit
     * @param name
     * @param householdVO
     * @param page
     * @return
     */
    IPage<HouseholdVO> getUserInfoByDistrictIds(HouseholdVO householdVO,IPage<HouseholdVO> page);
    /**
     * 查询住户对应的社区编号
     * @param id
     * @return
     */
    String getCommunityCode(Long id);
    /**
     * 查询所有住户总数
     * @return
     */
    int getAllListTotal();
    /**
     * 查询对应的住户集合
     * @param i
     * @param size
     * @return
     */
    List<HouseholdVO> getAllList(int i, int size);
}
src/main/java/org/springblade/modules/house/service/impl/HouseServiceImpl.java
@@ -830,4 +830,34 @@
        // 返回
        return list;
    }
    /**
     * 查询对应的社区编号
     * @param id
     * @return
     */
    @Override
    public String getCommunityCode(Long id) {
        return baseMapper.getCommunityCode(id);
    }
    /**
     * 查询所有房屋总数
     * @return
     */
    @Override
    public int getAllListTotal() {
        return baseMapper.getAllListTotal();
    }
    /**
     * 查询所有的房屋
     * @param i
     * @param size
     * @return
     */
    @Override
    public List<HouseVO> getAllList(int i, int size) {
        return baseMapper.getAllList(i,size);
    }
}
src/main/java/org/springblade/modules/house/service/impl/HouseholdServiceImpl.java
@@ -596,4 +596,33 @@
        return page.setRecords(userInfoByDistrictIds);
    }
    /**
     * 查询住户对应的社区编号
     * @param id
     * @return
     */
    @Override
    public String getCommunityCode(Long id) {
        return baseMapper.getCommunityCode(id);
    }
    /**
     * 查询所有住户总数
     * @return
     */
    @Override
    public int getAllListTotal() {
        return baseMapper.getAllListTotal();
    }
    /**
     * 查询对应的住户集合
     * @param i
     * @param size
     * @return
     */
    @Override
    public List<HouseholdVO> getAllList(int i, int size) {
        return baseMapper.getAllList(i,size);
    }
}
src/main/java/org/springblade/modules/place/entity/PlaceEntity.java
@@ -199,7 +199,4 @@
    @ApiModelProperty(value = "1:是 2:否  三级消防单位", example = "")
    @TableField("three_fire_protection")
    private Integer threeFireProtection;
}
src/main/java/org/springblade/modules/place/mapper/PlaceMapper.java
@@ -214,4 +214,23 @@
                                 @Param("gridCodeList") List<String> gridCodeList,
                                 @Param("regionChildCodesList") List<String> regionChildCodesList,
                                 @Param("isAdministrator") Integer isAdministrator);
    /**
     * 查询所有场所数据
     * @return
     */
    List<PlaceVO> getAllList(@Param("i") int i,@Param("size") int size);
    /**
     * 查询所有场所数据总数
     * @return
     */
    int getAllListTotal();
    /**
     * 查询对应的社区编号
     * @param id
     * @return
     */
    String getCommunityCode(@Param("id") Long id);
}
src/main/java/org/springblade/modules/place/mapper/PlaceMapper.xml
@@ -911,4 +911,33 @@
        order by jp.create_time desc,jp.id desc
    </select>
    <!--查询所有场所数据-->
    <select id="getAllList" resultType="org.springblade.modules.place.vo.PlaceVO">
        select
        jp.*,
        jpag.community_code
        from jczz_place jp
        left join jczz_police_affairs_grid jpag on jp.jw_grid_code = jpag.jw_grid_code and jpag.is_deleted =0
        where jp.is_deleted = 0
        limit #{i},#{size}
    </select>
    <!--查询所有场所数据-->
    <select id="getAllListTotal" resultType="java.lang.Integer">
        select
        count(*)
        from jczz_place jp
        where jp.is_deleted = 0
    </select>
    <!--查询对应的社区编号-->
    <select id="getCommunityCode" resultType="java.lang.String">
        select
        jpag.community_code
        from jczz_place jp
        left join jczz_police_affairs_grid jpag on jp.jw_grid_code = jpag.jw_grid_code and jpag.is_deleted =0
        where jp.is_deleted = 0
        and jp.id = #{id}
    </select>
</mapper>
src/main/java/org/springblade/modules/place/service/IPlaceService.java
@@ -192,4 +192,22 @@
     * @param place
     */
    void jwGridCodeBind(PlaceVO place);
    /**
     * 查询所有场所数据
     * @return
     */
    List<PlaceVO> getAllList(int i,int size);
    /**
     * 查询所有场所数据总数
     * @return
     */
    int getAllListTotal();
    /**
     * 查询对应的社区编号
     * @param id
     * @return
     */
    String getCommunityCode(Long id);
}
src/main/java/org/springblade/modules/place/service/impl/PlaceServiceImpl.java
@@ -1574,4 +1574,32 @@
        // 返回
        return page.setRecords(placeVOS);
    }
    /**
     * 查询所有场所数据
     * @return
     */
    @Override
    public List<PlaceVO> getAllList(int i,int size) {
        return baseMapper.getAllList(i,size);
    }
    /**
     * 查询所有场所数据总数
     * @return
     */
    @Override
    public int getAllListTotal() {
        return baseMapper.getAllListTotal();
    }
    /**
     * 查询对应的社区编号
     * @param id
     * @return
     */
    @Override
    public String getCommunityCode(Long id) {
        return baseMapper.getCommunityCode(id);
    }
}
src/main/resources/application-dev.yml
@@ -83,3 +83,10 @@
      url: jdbc:mysql://106.225.193.35:3306/srjw?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
      username: root
      password: HCyj@2022
#es
elasticsearch:
  enabled: false
  host: localhost
  sync: true
  indexName: jczz
src/main/resources/application-prod.yml
@@ -71,3 +71,10 @@
      url: jdbc:mysql://czfw_wx_web.xzga.top:13005/srjw?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
      username: ewm_user
      password: ft@135246
#es
elasticsearch:
  enabled: false
  host: localhost
  sync: false
  indexName: jczz
src/main/resources/application-test.yml
@@ -71,3 +71,10 @@
      url: jdbc:mysql://106.225.193.35:3306/srjw?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8&nullCatalogMeansCurrent=true&allowPublicKeyRetrieval=true
      username: root
      password: HCyj@2022
#es
elasticsearch:
  enabled: false
  host: localhost
  sync: true
  indexName: test