package com.sdtool.webcore.rest;

import com.sdtool.common.api.NoSqlKeysService;
import com.sdtool.common.api.SupplierInitService;
import com.sdtool.common.base.BaseService;
import com.sdtool.common.datas.ESKeys;
import com.sdtool.common.entity.site.ERPTokenUser;
import com.sdtool.common.entity.system.KeyValuePair;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.dySweetFishPlugin.elasticsearch.ESClient;
import com.dySweetFishPlugin.sql.RMapUtils;
import com.dySweetFishPlugin.tool.lang.ThreadFactoryWithNamePrefix;
import com.sweetfish.net.http.RestMapping;
import com.sweetfish.net.http.RestParam;
import com.sweetfish.net.http.RestService;
import com.sweetfish.service.Local;
import com.sweetfish.util.AnyValue;
import com.sweetfish.util.AutoLoad;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetMappingsResponse;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
import org.elasticsearch.action.admin.indices.mapping.put.PutMappingResponse;
import org.elasticsearch.common.xcontent.XContentType;
import org.rex.RMap;

import javax.annotation.Priority;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Stream;

import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;

/**
 * Created by jlutt on 2020-12-25
 *
 * @author jlutt
 */
@AutoLoad(false)
@Local
@RestService(name = "erpupdate", moduleid = 4, comment = "更新模块")
@SuppressWarnings({"unused", "rawtypes"})
@Priority(1)
public class ERPUpdateRest extends BaseService {

    @Resource(name = "APP_HOME")
    String appHome;

    @Resource
    ESClient esClient;

    @Resource
    NoSqlKeysService keysService;

    @Resource
    SupplierInitService supplierService;

    private final ExecutorService watchESUpdateExecutor = Executors.newSingleThreadExecutor(new ThreadFactoryWithNamePrefix("ES更新监视线程"));

    private final Map<String, Runnable> methodMap = Map.<String, Runnable>ofEntries(

            //region 产品模块

            Map.entry("updateProduct", () -> updateESMapping(ESKeys.ES_ERP_PRODUCT_INDEX, ESKeys.ES_ERP_PRODUCT_TYPE, "product.json", 0)
            ),

            Map.entry("updateWorkProcess", () -> updateESMapping(ESKeys.ES_ERP_WORK_PROCESS_INDEX, ESKeys.ES_ERP_WORK_PROCESS_TYPE, "workProcess.json", 0)
            ),

            //endregion

            //region ERP订单模块

            Map.entry("updateOrder", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_PRINT_ORDER_TYPE, "printOrder.json", 1)
            ),

            Map.entry("updateOrderImageDispatchItem", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_IMAGE_DISPATCH_ITEM_TYPE, "orderImageDispatchItem.json", 1)
            ),

            Map.entry("updateOrderDeliverInform", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_DELIVER_INFORM_TYPE, "orderDeliverInform.json", 1)
            ),

            Map.entry("updateOrderPart", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PART_TYPE, "orderPart.json", 1)
            ),

            Map.entry("updateOrderPartParams", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PART_PARAMS_TYPE, "orderPartParamValue.json", 1)
            ),

            Map.entry("updateOrderPartProcess", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PART_PROCESS_TYPE, "orderPartProcess.json", 1)
            ),

            Map.entry("updateWorkPart", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_WORK_PART_TYPE, "workPart.json", 1)
            ),

            Map.entry("updateOrderMaterial", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_MATERIAL_TYPE, "orderMaterialItem.json", 1)
            ),

            Map.entry("updateOrderReceivable", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_RECEIVABLE_TYPE, "orderReceivable.json", 1)
            ),

            Map.entry("updateOrderChargeData", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_CHARGE_DATA_TYPE, "orderChargeData.json", 1)
            ),

            Map.entry("updateOrderLifeCycle", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_LIFECYCLE_TYPE, "orderLifecycle.json", 1)
            ),

            Map.entry("updateOrderFile", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_FILE_TYPE, "orderFile.json", 1)
            ),

            Map.entry("updateOrderDeliveryFeedBackInfo", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_DELIVERY_FEED_BACK_INFO_TYPE, "deliveryFeedBackInfo.json", 1)
            ),

            Map.entry("updateOrderStockItem", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_STOCK_ITEM_TYPE, "orderStockItem.json", 1)
            ),

            Map.entry("updateOrderStockLabel", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_STOCK_LABEL_TYPE, "orderStockLabel.json", 1)
            ),

            Map.entry("updateOrderStep", () -> updateESMapping(ESKeys.ES_ERP_ORDER_STEP_INDEX, ESKeys.ES_ERP_ORDER_STEP_TYPE, "orderStep.json", 1)
            ),

            Map.entry("updateOrderTradeBill", () -> updateESMapping(ESKeys.ES_ERP_ORDER_TRADE_BILL_INDEX, ESKeys.ES_ERP_ORDER_TRADE_BILL_TYPE, "orderTradeBill.json", 1)
            ),

            Map.entry("updateOrderProcessTask", () -> updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PROCESS_TASK_TYPE, "orderProcessTask.json", 1)
            ),

            Map.entry("updateOrderTaskFeedBackRecord", () -> updateESMapping(ESKeys.ES_ERP_ORDER_TASK_FEEDBACK_RECORD_INDEX, ESKeys.ES_ERP_ORDER_TASK_FEEDBACK_RECORD_TYPE,
                    "orderTaskFeedbackRecord.json", 1)
            ),

            //endregion

            //region 商城订单

            Map.entry("updateMaOrder", () -> updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_PRINT_ORDER_TYPE, "printOrder.json", 1)
            ),

            Map.entry("updateMaOrderDeliverInform", () -> updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_DELIVER_INFORM_TYPE, "orderDeliverInform.json", 1)
            ),

            Map.entry("updateMaOrderPart", () -> updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_PART_TYPE, "orderPart.json", 1)
            ),

            Map.entry("updateMaOrderPartParams", () -> updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_PART_PARAMS_TYPE, "orderPartParamValue.json", 1)
            ),

            Map.entry("updateMaOrderReceivable", () -> updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_RECEIVABLE_TYPE, "orderReceivable.json", 1)
            ),

            Map.entry("updateMaOrderChargeData", () -> updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_CHARGE_DATA_TYPE, "orderChargeData.json", 1)
            ),

            Map.entry("updateMaOrderLifeCycle", () -> updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_FILE_TYPE, "orderReceivable.json", 1)
            ),

            Map.entry("updateMaOrderStep", () -> updateESMapping(ESKeys.ES_MALL_ORDER_STEP_INDEX, ESKeys.ES_MALL_ORDER_STEP_TYPE, "orderStep.json", 1)
            ),

            Map.entry("updateMaOrderCancel", () -> updateESMapping(ESKeys.ES_MALL_ORDER_CANCEL_INDEX, ESKeys.ES_MALL_ORDER_CANCEL_TYPE, "mallOrderCancelRequest.json", 1)
            ),

            Map.entry("updateMaOrderQuote", () -> updateESMapping(ESKeys.ES_MALL_ORDER_QUOTE_INDEX, ESKeys.ES_MALL_ORDER_QUOTE_TYPE, "quoteOrder.json", 0)
            ),

            //endregion

            //region 施工单
            Map.entry("updatePrintBill", () -> updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINTBILL_TYPE, "printBill.json", 1)
            ),

            Map.entry("updatePrintBillBreed", () -> updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINTBILL_BREED_TYPE, "printBillBreed.json", 1)
            ),

            Map.entry("updatePrintBillLifeCycle", () -> updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINTBILL_LIFECYCLE_TYPE, "printBillLifeCycle.json", 1)
            ),

            Map.entry("updatePrintBillBreedPart", () -> updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINT_BREED_PART_TYPE, "printBreedPart.json", 1)
            ),

            Map.entry("updatePrintBillBreedTask", () -> updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_MACHINE_BREED_TASK_TYPE, "machineBreedTask.json", 1)
            ),

            Map.entry("updatePrintOrderStep", () -> updateESMapping(ESKeys.ES_ERP_PRINTBILL_STEP_INDEX, ESKeys.ES_ERP_PRINTBILL_STEP_TYPE, "printBillStep.json", 1)
            ),

            Map.entry("updatePrintBreedProcess", () -> updateESMapping(ESKeys.ES_ERP_PRINTBREED_PROCESS_INDEX, ESKeys.ES_ERP_PRINTBREED_PROCESS_TYPE, "printBreedProcess.json", 1)
            ),

            Map.entry("updateTaskFeedBackRecord", () -> updateESMapping(ESKeys.ES_ERP_TASK_FEEDBACK_RECORD_INDEX, ESKeys.ES_ERP_TASK_FEEDBACK_RECORD_TYPE, "taskFeedbackRecord.json", 1)
            ),

            Map.entry("updateExclusiveSpliceTask", () -> updateESMapping(ESKeys.ESERPEXCLUSIVESPLICETASK_INDEX, ESKeys.ESERPEXCLUSIVESPLICETASK_TYPE, "exclusiveBillSpliceTask.json", 1)
            ),

            //endregion

            //region 客户、外协、供应商
            Map.entry("updateClient", () -> updateESMapping(ESKeys.ES_ERP_CLIENT_INFO_INDEX, ESKeys.ES_ERP_CLIENT_INFO_TYPE, "clientInfo.json", 0)
            ),

            Map.entry("updateClientAddress", () -> updateESMapping(ESKeys.ES_ERP_CLIENT_RECEIVEADDRESS_INDEX, ESKeys.ES_ERP_CLIENT_RECEIVEADDRESS_TYPE, "clientReceiveAddress.json", 0)
            ),

            Map.entry("updateOutAssistInfo", () -> updateESMapping(ESKeys.ES_ERP_OUTASSIST_INFO_INDEX, ESKeys.ES_ERP_OUTASSIST_INFO_TYPE, "outAssistInfo.json", 0)
            ),

            Map.entry("updateSupplierInfo", () -> updateESMapping(ESKeys.ES_ERP_SUPPLIER_INFO_INDEX, ESKeys.ES_ERP_SUPPLIER_INFO_TYPE, "supplierInfo.json", 0)
            ),

            //endregion

            //region 辅料 纸张
            Map.entry("updateMaterialInfo", () -> updateESMapping(ESKeys.ES_ERP_MATERIALINFO_INDEX, ESKeys.ES_ERP_MATERIALINFO_TYPE, "materialInfo.json", 0)
            ),

            Map.entry("updatePaperType", () -> updateESMapping(ESKeys.ES_ERP_PAPERTYPE_INDEX, ESKeys.ES_ERP_PAPERTYPE_TYPE, "paperType.json", 0)
            ),

            Map.entry("updatePaperBaseInfo", () -> updateESMapping(ESKeys.ES_ERP_PAPERBASEINFO_INDEX, ESKeys.ES_ERP_PAPERBASEINFO_TYPE, "paperBaseInfo.json", 0)
            ),

            Map.entry("updatePaperQuoteInfo", () -> updateESMapping(ESKeys.ES_ERP_PAPERQUOTEINFO_INDEX, ESKeys.ES_ERP_PAPERQUOTEINFO_TYPE, "paperQuoteInfo.json", 0)
            ),

            Map.entry("updatePaperInfo", () -> updateESMapping(ESKeys.ES_ERP_PAPERINFO_INDEX, ESKeys.ES_ERP_PAPERINFO_TYPE, "paperInfo.json", 0)
            ),

            //endregion

            //region 物流
            Map.entry("updateLogisticsInfo", () -> updateESMapping(ESKeys.ES_ERP_LOGISTICS_INFO_INDEX, ESKeys.ES_ERP_LOGISTICS_INFO_TYPE, "logisticsInfo.json", 0)
            ),

            //endregion

            //region 进销存
            Map.entry("updateStockBill", () -> updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_TYPE, "stockBill.json", 1)
            ),

            Map.entry("updateStockBillItemM", () -> updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_M_TYPE, "stockBillItemM.json", 1)
            ),

            Map.entry("updateStockBillItemA", () -> updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_A_TYPE, "stockBillItemA.json", 1)
            ),

            Map.entry("updateStockBillItemP", () -> updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_P_TYPE, "stockBillItemP.json", 1)
            ),

            Map.entry("updateStockBillReference", () -> updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_REFERENCE_TYPE, "stockBillReference.json", 1)
            ),

            Map.entry("updateStockBillItemReference", () -> updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_REFERENCE_TYPE, "stockBillItemReference.json", 1)
            ),

            Map.entry("updateStockBillStep", () -> updateESMapping(ESKeys.ES_ERP_STOCK_BILL_STEP_INDEX, ESKeys.ESERPDEFAULT_TYPE, "stockBillStepBy.json", 1)
            ),

            Map.entry("updateCorpBillStatement", () -> updateESMapping(ESKeys.ES_ERP_CORP_BILL_STATEMENT_INDEX, ESKeys.ESERPDEFAULT_TYPE, "corpBillStatement.json", 1)
            ),

            //endregion

            //region 外协单
            Map.entry("updateOutAssistBill", () -> updateESMapping(ESKeys.ES_ERP_OUTASSIST_BILL_INDEX, ESKeys.ES_ERP_OUTASSIST_BILL_TYPE, "outAssistBill.json", 1)
            ),

            Map.entry("updateOutAssistBillItem", () -> updateESMapping(ESKeys.ES_ERP_OUTASSIST_BILL_INDEX, ESKeys.ES_ERP_OUTASSIST_BILL_ITEM_TYPE, "outAssistBillItem.json", 1)
            ),

            Map.entry("updateOutAssistPackMaterial", () -> updateESMapping(ESKeys.ES_ERP_OUTASSIST_BILL_INDEX, ESKeys.ES_ERP_OUTASSIST_PACK_MATERIAL_TYPE, "outAssistPackMaterial.json", 1)
            ),

            //endregion

            //region 在线支付
            Map.entry("updatePaymentOrderGroup", () -> updateESMapping(ESKeys.ES_ERP_PAYMENT_ORDER_GROUP_INDEX, ESKeys.ES_ERP_PAYMENT_ORDER_GROUP_TYPE, "paymentOrderGroup.json", 1)
            )

            //endregion
    );

    @Override
    public void init(AnyValue config) {
        super.init(config);
    }

    @Override
    @SuppressWarnings("unchecked")
    public void start(AnyValue config) {
        Path esUpdateFilePath = Paths.get(appHome + File.separator + "conf" + File.separator + "esupdate" + File.separator + "esupdate.txt");

        //初始化的时候也更新一次
        if (Files.exists(esUpdateFilePath)) {
            try (Stream<String> lines = Files.lines(esUpdateFilePath, StandardCharsets.UTF_8)) {
                lines.forEach((line) -> {
                    if ((!line.isEmpty()) && (!line.startsWith("#"))) {
                        if (line.contains(",")) {
                            //参数的写法
                            String[] esArray = line.split(",");
                            updateESMapping(esArray[0], esArray[1], esArray[2], Integer.parseInt(esArray[3]));
                        } else if (methodMap.containsKey(line)) {
                            methodMap.get(line).run();
                        }
                    }
                });
            } catch (IOException e) {
                logger.error(e.getMessage(), e);
            }
        }

        watchESUpdateExecutor.submit(() -> {
            // 获取文件系统的WatchService
            try (WatchService watchService = esUpdateFilePath.getParent().getFileSystem().newWatchService()) {
                // 注册你想要监视的事件类型
                esUpdateFilePath.getParent().register(watchService, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY);
                // 无限循环，等待事件的到来
                while (!Thread.currentThread().isInterrupted()) {
                    WatchKey key = watchService.take(); // 阻塞，直到一个事件发生

                    //https://stackoverflow.com/questions/16777869/java-7-watchservice-ignoring-multiple-occurrences-of-the-same-event
                    // Prevent receiving two separate ENTRY_MODIFY events: file modified
                    // and timestamp updated. Instead, receive one ENTRY_MODIFY event
                    // with two counts.
                    Thread.sleep(50);

                    key.pollEvents().forEach((event) -> {
                        if (event.kind() == ENTRY_MODIFY) {
                            // 获取引起事件的文件
                            WatchEvent<Path> ev = (WatchEvent<Path>) event;
                            Path fileName = ev.context();

                            if (fileName.toString().equals(esUpdateFilePath.getFileName().toString())) {
                                long d;
                                for (; ; ) {
                                    d = fileName.toFile().lastModified();
                                    try {
                                        Thread.sleep(5000L);
                                    } catch (InterruptedException e) {
                                        throw new RuntimeException(e);
                                    }
                                    if (d == fileName.toFile().lastModified()) break;
                                }

                                logger.info("ES更新文件发生变动，准备更新");
                                try (Stream<String> lines = Files.lines(esUpdateFilePath, StandardCharsets.UTF_8)) {
                                    lines.forEach((line) -> {
                                        if ((!line.isEmpty()) && (!line.startsWith("#"))) {
                                            if (line.contains(",")) {
                                                //参数的写法
                                                String[] esArray = line.split(",");
                                                updateESMapping(esArray[0], esArray[1], esArray[2], Integer.parseInt(esArray[3]));
                                            } else if (methodMap.containsKey(line)) {
                                                methodMap.get(line).run();
                                            }
                                        }
                                    });
                                } catch (IOException e) {
                                    logger.error(e.getMessage(), e);
                                }
                            }

                        }
                    });

                    // 重置key以便接收下一个事件
                    boolean valid = key.reset();
                    if (!valid) {
                        break;
                    }
                }
            } catch (Exception e) {
                logger.error(e.getMessage(), e);
            }
        });
    }

    @Override
    public void destroy(AnyValue config) {
        watchESUpdateExecutor.shutdownNow();

        super.destroy(config);
    }

    //region es更新函数

    //1、注意es只能增加字段，所以mappingFile可以为单独的增加字段的json文件，可对照【增加字段示例.json】增加
    //2、es不能修改已有字段类型，需要情况下只能增加字段
    //3、只增加Index带ERP的 其他的应该不会化
    // todo ESKeys里没有加的 如：投诉模块、发货模块、外协分厂模块等等 等代码转移过再加

    /**
     * 更新单主表表示例
     *
     * @param esIndexName 索引名称，对应为ESKeys中的值
     * @param type        estype名称
     * @param mappingFile mapping文件名
     * @param kind        0表示索引名无需_current标记，1表示索引名有_current
     */
    @SuppressWarnings("unchecked")
    private void updateESMapping(String esIndexName, String type, String mappingFile, int kind) {
        List<KeyValuePair> dataItemList = supplierService.getDataBaseItemList();
        if (dataItemList.isEmpty()) {
            return;
        }
        dataItemList.forEach((x) -> {
            String index = (kind == 0) ?
                    keysService.getESKey(esIndexName, Long.parseLong(x.getValue())) :
                    supplierService.getDateYearESIndex(Long.parseLong(x.getValue()), esIndexName, 1);

            if (esClient.checkTypeExists(index, type)) {
                //由于ES更新也不能更新已经存在的字段，这里就不在纠结，过滤掉现有的字段，只更新增加的字段，免得每次更新不下去，所以要求开发人员不要修改字段类型，有变化则增加索引字段
                try {
                    GetMappingsRequest mappingRequest = new GetMappingsRequest().indices(index);
                    GetMappingsResponse mappingResponse = esClient.getClient().admin().indices().getMappings(mappingRequest).get();


                    Map<String, Object> existsTypeMap = (Map<String, Object>) mappingResponse.getMappings().get(index).get(type).getSourceAsMap().get("properties");

                    String jsonStr = readUTF8File(Paths.get(appHome + File.separator + "conf" + File.separator + "esTemplate" + File.separator + mappingFile), false);
                    JSONObject jsonObject = JSON.parseObject(jsonStr);
                    //这里注意，更新文件的内容有两种，无论什么更新文件，properties肯定是有的
                    JSONObject properties = jsonObject.getJSONObject("properties");
                    if (properties == null) {
                        properties = jsonObject.getJSONObject(type).getJSONObject("properties");
                    }
                    // 过滤掉已经存在的字段
                    for (String key : existsTypeMap.keySet()) {
                        properties.remove(key);
                    }

                    if (!properties.isEmpty()) {
                        // 生成json字符串
                        String updatedJsonStr = jsonObject.toJSONString();

                        PutMappingRequest request = new PutMappingRequest(index)
                                .type(type)
                                .source(updatedJsonStr, XContentType.JSON);

                        PutMappingResponse mapPuttingResponse = esClient.getClient().admin().indices().putMapping(request).actionGet();
                        if (mapPuttingResponse.isAcknowledged()) {
                            logger.info("更新ES：" + index + "_" + type + "成功");
                        } else {
                            logger.info("更新ES：" + index + "_" + type + "失败");
                        }
                    } else {
                        logger.info("更新ES：" + index + "_" + type + "无新增字段，无需更新");
                    }


                    //if (esClient.updateTypeMapping(index, type, mappingFile)) {
                    //    logger.info("更新ES：" + esIndexName + "_" + type + "成功");
                    //}
                } catch (Exception e) {
                    logger.error(e.getMessage());
                }
            } else {
                //type不存在，测试下是否可以直接更新，测试后可以直接新增
                String jsonStr = readUTF8File(Paths.get(appHome + File.separator + "conf" + File.separator + "esTemplate" + File.separator + mappingFile), false);

                PutMappingRequest request = new PutMappingRequest(index)
                        .type(type)
                        .source(jsonStr, XContentType.JSON);

                PutMappingResponse mapPuttingResponse = esClient.getClient().admin().indices().putMapping(request).actionGet();
                if (mapPuttingResponse.isAcknowledged()) {
                    logger.info("更新ES：" + index + "_" + type + "成功(不存在新增type)");
                } else {
                    logger.info("更新ES：" + index + "_" + type + "失败(不存在新增type)");
                }
            }

        });
    }

    //endregion

    @RestMapping(name = "update20230908V1", auth = true, sort = 1, comment = "演示更新用法", methods = {"GET", "POST"})
    public CompletableFuture<RMap> update20230908V1(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRODUCT_IMAGE_INDEX, ESKeys.ES_ERP_PRODUCT_IMAGE_TYPE, "xxxxxxxxxxxxx.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //region 产品模块

    @RestMapping(name = "updateProduct", auth = true, sort = 2, comment = "产品档案", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateProduct(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRODUCT_INDEX, ESKeys.ES_ERP_PRODUCT_TYPE, "product.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateWorkProcess", auth = true, sort = 3, comment = "工序档案", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateWorkProcess(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_WORK_PROCESS_INDEX, ESKeys.ES_ERP_WORK_PROCESS_TYPE, "workProcess.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region ERP订单模块
    @RestMapping(name = "updateOrder", auth = true, sort = 5, comment = "订单", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrder(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_PRINT_ORDER_TYPE, "printOrder.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderImageDispatchItem", auth = true, sort = 6, comment = "订单修图处理", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderImageDispatchItem(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_IMAGE_DISPATCH_ITEM_TYPE, "orderImageDispatchItem.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderDeliverInform", auth = true, sort = 7, comment = "订单发货通知", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderDeliverInform(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_DELIVER_INFORM_TYPE, "orderDeliverInform.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderPart", auth = true, sort = 8, comment = "订单部件", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderPart(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PART_TYPE, "orderPart.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderPartParams", auth = true, sort = 9, comment = "订单部件参数", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderPartParams(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PART_PARAMS_TYPE, "orderPartParamValue.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderPartProcess", auth = true, sort = 10, comment = "订单部件工序", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderPartProcess(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PART_PROCESS_TYPE, "orderPartProcess.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateWorkPart", auth = true, sort = 11, comment = "组版部件", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateWorkPart(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_WORK_PART_TYPE, "workPart.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderMaterial", auth = true, sort = 12, comment = "订单物料", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderMaterial(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_MATERIAL_TYPE, "orderMaterialItem.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderReceivable", auth = true, sort = 13, comment = "订单应收账款", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderReceivable(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_RECEIVABLE_TYPE, "orderReceivable.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderChargeData", auth = true, sort = 14, comment = "订单收款记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderChargeData(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_CHARGE_DATA_TYPE, "orderChargeData.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderLifeCycle", auth = true, sort = 15, comment = "订单生命周期", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderLifeCycle(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_LIFECYCLE_TYPE, "orderLifecycle.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderFile", auth = true, sort = 16, comment = "订单文件", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderFile(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_FILE_TYPE, "orderFile.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderDeliveryFeedBackInfo", auth = true, sort = 17, comment = "订单发货反馈记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderDeliveryFeedBackInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_DELIVERY_FEED_BACK_INFO_TYPE, "deliveryFeedBackInfo.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderStockItem", auth = true, sort = 18, comment = "订单入库记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderStockItem(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_STOCK_ITEM_TYPE, "orderStockItem.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderStockLabel", auth = true, sort = 19, comment = "订单入库标签", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderStockLabel(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_STOCK_LABEL_TYPE, "orderStockLabel.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderStep", auth = true, sort = 20, comment = "订单脚印", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderStep(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_ORDER_STEP_INDEX, ESKeys.ES_ERP_ORDER_STEP_TYPE, "orderStep.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderTradeBill", auth = true, sort = 21, comment = "订单入账流水", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderTradeBill(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_ORDER_TRADE_BILL_INDEX, ESKeys.ES_ERP_ORDER_TRADE_BILL_TYPE, "orderTradeBill.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderProcessTask", auth = true, sort = 21, comment = "订单后工任务", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderProcessTask(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINT_ORDER_INDEX, ESKeys.ES_ERP_ORDER_PROCESS_TASK_TYPE, "orderProcessTask.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOrderTaskFeedBackRecord", auth = true, sort = 21, comment = "订单后工任务反馈记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOrderTaskFeedBackRecord(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_ORDER_TASK_FEEDBACK_RECORD_INDEX, ESKeys.ES_ERP_ORDER_TASK_FEEDBACK_RECORD_TYPE,
                            "orderTaskFeedbackRecord.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 商城订单
    @RestMapping(name = "updateMaOrder", auth = true, sort = 22, comment = "商城订单", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMallOrder(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_PRINT_ORDER_TYPE, "printOrder.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderDeliverInform", auth = true, sort = 23, comment = "商城订单发货通知", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMallOrderDeliverInform(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_DELIVER_INFORM_TYPE, "orderDeliverInform.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderPart", auth = true, sort = 24, comment = "商城订单部件", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMallOrderPart(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_PART_TYPE, "orderPart.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderPartParams", auth = true, sort = 25, comment = "商城订单部件参数", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMallOrderPartParams(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_PART_PARAMS_TYPE, "orderPartParamValue.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderReceivable", auth = true, sort = 26, comment = "商城订单应收账款", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMaOrderReceivable(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_RECEIVABLE_TYPE, "orderReceivable.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderChargeData", auth = true, sort = 27, comment = "商城订单收款记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMaOrderChargeData(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_CHARGE_DATA_TYPE, "orderChargeData.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderLifeCycle", auth = true, sort = 27, comment = "商城订单生命周期", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMaOrderLifeCycle(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_PRINT_ORDER_INDEX, ESKeys.ES_MALL_ORDER_FILE_TYPE, "orderReceivable.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderStep", auth = true, sort = 28, comment = "商城订单脚印", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMaOrderStep(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_ORDER_STEP_INDEX, ESKeys.ES_MALL_ORDER_STEP_TYPE, "orderStep.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderCancel", auth = true, sort = 29, comment = "商城订单取消请求记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMaOrderCancel(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_ORDER_CANCEL_INDEX, ESKeys.ES_MALL_ORDER_CANCEL_TYPE, "mallOrderCancelRequest.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateMaOrderQuote", auth = true, sort = 30, comment = "商城订单报价记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMaOrderQuote(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_MALL_ORDER_QUOTE_INDEX, ESKeys.ES_MALL_ORDER_QUOTE_TYPE, "quoteOrder.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 施工单
    @RestMapping(name = "updatePrintBill", auth = true, sort = 31, comment = "施工单", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePrintBill(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINTBILL_TYPE, "printBill.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePrintBillBreed", auth = true, sort = 32, comment = "施工单版", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePrintBillBreed(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINTBILL_BREED_TYPE, "printBillBreed.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePrintBillLifeCycle", auth = true, sort = 33, comment = "施工单生命周期", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePrintBillLifeCycle(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINTBILL_LIFECYCLE_TYPE, "printBillLifeCycle.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePrintBillBreedPart", auth = true, sort = 34, comment = "施工单版部件", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePrintBillBreedPart(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_PRINT_BREED_PART_TYPE, "printBreedPart.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePrintBillBreedTask", auth = true, sort = 35, comment = "施工单版任务", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePrintBillBreedTask(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINTBILL_INDEX, ESKeys.ES_ERP_MACHINE_BREED_TASK_TYPE, "machineBreedTask.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePrintOrderStep", auth = true, sort = 37, comment = "施工单脚印", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePrintOrderStep(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINTBILL_STEP_INDEX, ESKeys.ES_ERP_PRINTBILL_STEP_TYPE, "printBillStep.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePrintBreedProcess", auth = true, sort = 38, comment = "施工单版工序", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePrintBreedProcess(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PRINTBREED_PROCESS_INDEX, ESKeys.ES_ERP_PRINTBREED_PROCESS_TYPE, "printBreedProcess.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateTaskFeedBackRecord", auth = true, sort = 39, comment = "施工单任务反馈记录", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateTaskFeedBackRecord(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_TASK_FEEDBACK_RECORD_INDEX, ESKeys.ES_ERP_TASK_FEEDBACK_RECORD_TYPE, "taskFeedbackRecord.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateExclusiveSpliceTask", auth = true, sort = 40, comment = "专版施工单拼版任务", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateExclusiveSpliceTask(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ESERPEXCLUSIVESPLICETASK_INDEX, ESKeys.ESERPEXCLUSIVESPLICETASK_TYPE, "exclusiveBillSpliceTask.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 客户、外协、供应商
    @RestMapping(name = "updateClient", auth = true, sort = 41, comment = "客户", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateClient(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_CLIENT_INFO_INDEX, ESKeys.ES_ERP_CLIENT_INFO_TYPE, "clientInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateClientAddress", auth = true, sort = 42, comment = "客户收货地址", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateClientAddress(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_CLIENT_RECEIVEADDRESS_INDEX, ESKeys.ES_ERP_CLIENT_RECEIVEADDRESS_TYPE, "clientReceiveAddress.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOutAssistInfo", auth = true, sort = 43, comment = "外加工档案", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOutAssistInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_OUTASSIST_INFO_INDEX, ESKeys.ES_ERP_OUTASSIST_INFO_TYPE, "outAssistInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateSupplierInfo", auth = true, sort = 44, comment = "供应商", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateSupplierInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_SUPPLIER_INFO_INDEX, ESKeys.ES_ERP_SUPPLIER_INFO_TYPE, "supplierInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 辅料 纸张
    @RestMapping(name = "updateMaterialInfo", auth = true, sort = 45, comment = "辅料档案", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateMaterialInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_MATERIALINFO_INDEX, ESKeys.ES_ERP_MATERIALINFO_TYPE, "materialInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePaperType", auth = true, sort = 46, comment = "纸张类型（铜版）", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePaperType(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PAPERTYPE_INDEX, ESKeys.ES_ERP_PAPERTYPE_TYPE, "paperType.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePaperBaseInfo", auth = true, sort = 47, comment = "基础纸张档案（xxx克铜版）", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePaperBaseInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PAPERBASEINFO_INDEX, ESKeys.ES_ERP_PAPERBASEINFO_TYPE, "paperBaseInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePaperQuoteInfo", auth = true, sort = 48, comment = "纸张报价档案", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePaperQuoteInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PAPERQUOTEINFO_INDEX, ESKeys.ES_ERP_PAPERQUOTEINFO_TYPE, "paperQuoteInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updatePaperInfo", auth = true, sort = 49, comment = "纸张档案", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePaperInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PAPERINFO_INDEX, ESKeys.ES_ERP_PAPERINFO_TYPE, "paperInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 物流
    @RestMapping(name = "updateLogisticsInfo", auth = true, sort = 50, comment = "物流档案", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateLogisticsInfo(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_LOGISTICS_INFO_INDEX, ESKeys.ES_ERP_LOGISTICS_INFO_TYPE, "logisticsInfo.json", 0);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 进销存
    @RestMapping(name = "updateStockBill", auth = true, sort = 51, comment = "进销存单据", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateStockBill(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_TYPE, "stockBill.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateStockBillItemM", auth = true, sort = 52, comment = "进销存单据明细M", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateStockBillItemM(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_M_TYPE, "stockBillItemM.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateStockBillItemA", auth = true, sort = 53, comment = "进销存单据明细A", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateStockBillItemA(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_A_TYPE, "stockBillItemA.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateStockBillItemP", auth = true, sort = 54, comment = "进销存单据明细P", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateStockBillItemP(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_P_TYPE, "stockBillItemP.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateStockBillReference", auth = true, sort = 55, comment = "进销存单据引用", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateStockBillReference(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_REFERENCE_TYPE, "stockBillReference.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateStockBillItemReference", auth = true, sort = 56, comment = "进销存单据明细引用", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateStockBillItemReference(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_STOCK_BILL_INDEX, ESKeys.ES_ERP_STOCK_BILL_ITEM_REFERENCE_TYPE, "stockBillItemReference.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateStockBillStep", auth = true, sort = 57, comment = "进销存单据脚印", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateStockBillStep(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_STOCK_BILL_STEP_INDEX, ESKeys.ESERPDEFAULT_TYPE, "stockBillStepBy.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateCorpBillStatement", auth = true, sort = 58, comment = "供应商对账明细", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateCorpBillStatement(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_CORP_BILL_STATEMENT_INDEX, ESKeys.ESERPDEFAULT_TYPE, "corpBillStatement.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 外协单
    @RestMapping(name = "updateOutAssistBill", auth = true, sort = 59, comment = "外协单", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOutAssistBill(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_OUTASSIST_BILL_INDEX, ESKeys.ES_ERP_OUTASSIST_BILL_TYPE, "outAssistBill.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOutAssistBillItem", auth = true, sort = 60, comment = "外协单明细", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOutAssistBillItem(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_OUTASSIST_BILL_INDEX, ESKeys.ES_ERP_OUTASSIST_BILL_ITEM_TYPE, "outAssistBillItem.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    @RestMapping(name = "updateOutAssistPackMaterial", auth = true, sort = 61, comment = "外协单打包物料", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updateOutAssistPackMaterial(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_OUTASSIST_BILL_INDEX, ESKeys.ES_ERP_OUTASSIST_PACK_MATERIAL_TYPE, "outAssistPackMaterial.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion

    //region 在线支付
    @RestMapping(name = "updatePaymentOrderGroup", auth = true, sort = 62, comment = "在线支付", methods = {"GET", "POST"})
    public CompletableFuture<RMap> updatePaymentOrderGroup(
            @RestParam(name = "&", comment = "登录用户，无需传入") ERPTokenUser currentUser) {
        return CompletableFuture.supplyAsync(
                () -> {
                    updateESMapping(ESKeys.ES_ERP_PAYMENT_ORDER_GROUP_INDEX, ESKeys.ES_ERP_PAYMENT_ORDER_GROUP_TYPE, "paymentOrderGroup.json", 1);
                    //更新
                    return RMapUtils.successV2("更新成功", null, null);
                }, getExecutor()
        );
    }

    //endregion
}
