package com.ankaibei.workFlow.common.online.controller;

import io.swagger.annotations.Api;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.CharUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ankaibei.workFlow.common.core.annotation.MyRequestBody;
import com.ankaibei.workFlow.common.core.constant.ErrorCodeEnum;
import com.ankaibei.workFlow.common.core.object.*;
import com.ankaibei.workFlow.common.core.util.*;
import com.ankaibei.workFlow.common.log.annotation.OperationLog;
import com.ankaibei.workFlow.common.log.model.constant.SysOperationLogType;
import com.ankaibei.workFlow.common.redis.util.CommonRedisUtil;
import com.ankaibei.workFlow.common.online.util.OnlineOperationHelper;
import com.ankaibei.workFlow.common.online.dto.OnlineFilterDto;
import com.ankaibei.workFlow.common.online.model.*;
import com.ankaibei.workFlow.common.online.model.constant.DictType;
import com.ankaibei.workFlow.common.online.model.constant.RelationType;
import com.ankaibei.workFlow.common.online.model.constant.FieldFilterType;
import com.ankaibei.workFlow.common.online.object.ColumnData;
import com.ankaibei.workFlow.common.online.service.*;
import com.ankaibei.workFlow.common.online.util.OnlineConstant;
import com.github.pagehelper.page.PageMethod;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 在线操作接口的控制器类。
 *
 * @author Buzhanyi
 * @date 2022-09-25
 */
@Api(tags = "在线表单操作接口")
@Slf4j
@RestController
@ConditionalOnProperty(name = "common-online.operationEnabled", havingValue = "true")
@RequestMapping("${common-online.operationUrlPrefix}/onlineOperation")
public class OnlineOperationController {

    @Autowired
    private OnlineOperationService onlineOperationService;
    @Autowired
    private OnlineDictService onlineDictService;
    @Autowired
    private OnlineDatasourceService onlineDatasourceService;
    @Autowired
    private OnlineTableService onlineTableService;
    @Autowired
    private OnlineOperationHelper onlineOperationHelper;
    @Autowired
    private OnlineVirtualColumnService onlineVirtualColumnService;
    @Autowired
    private CommonRedisUtil commonRedisUtil;

    /**
     * 新增数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表的数据源Id。
     * @param masterData             主表新增数据。
     * @param slaveData              一对多从表新增数据列表。
     * @return 应答结果。
     */
    @OperationLog(type = SysOperationLogType.ADD)
    @PostMapping("/addDatasource/{datasourceVariableName}")
    public ResponseResult<Void> addDatasource(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) JSONObject masterData,
            @MyRequestBody JSONObject slaveData) throws IOException {
        String errorMessage;
        // 验证数据源的合法性，同时获取主表对象。
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId + "");
        if (!datasourceResult.isSuccess()) {
            return ResponseResult.errorFrom(datasourceResult);
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        OnlineTable masterTable = datasource.getMasterTable();
        ResponseResult<List<ColumnData>> columnDataListResult =
                onlineOperationHelper.buildTableData(masterTable, masterData, false, null);
        if (!columnDataListResult.isSuccess()) {
            return ResponseResult.errorFrom(columnDataListResult);
        }
        if (slaveData == null) {
            onlineOperationService.saveNew(masterTable, columnDataListResult.getData());
        } else {
            ResponseResult<Map<OnlineDatasourceRelation, List<List<ColumnData>>>> slaveDataListResult =
                    onlineOperationHelper.buildSlaveDataList(datasourceId + "", slaveData);
            if (!slaveDataListResult.isSuccess()) {
                return ResponseResult.errorFrom(slaveDataListResult);
            }
            onlineOperationService.saveNewAndSlaveRelation(
                    masterTable, columnDataListResult.getData(), slaveDataListResult.getData());
        }
        return ResponseResult.success();
    }

    /**
     * 新增一对多从表数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表的数据源Id。
     * @param relationId             一对多的关联Id。
     * @param slaveData              一对多从表的新增数据列表。
     * @return 应答结果。
     */
    @OperationLog(type = SysOperationLogType.ADD)
    @PostMapping("/addOneToManyRelation/{datasourceVariableName}")
    public ResponseResult<Void> addOneToManyRelation(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) Long relationId,
            @MyRequestBody(required = true) JSONObject slaveData) {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId + "");
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId + "", relationId + "");
        if (!relationResult.isSuccess()) {
            return ResponseResult.errorFrom(relationResult);
        }
        OnlineDatasourceRelation relation = relationResult.getData();
        OnlineTable slaveTable = relation.getSlaveTable();
        // 拆解主表和一对多关联从表的输入参数，并构建出数据表的待插入数据列表。
        ResponseResult<List<ColumnData>> columnDataListResult =
                onlineOperationHelper.buildTableData(slaveTable, slaveData, false, null);
        if (!columnDataListResult.isSuccess()) {
            return ResponseResult.errorFrom(columnDataListResult);
        }
        onlineOperationService.saveNew(slaveTable, columnDataListResult.getData());
        return ResponseResult.success();
    }

    /**
     * 更新主数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表数据源Id。
     * @param masterData             表数据。这里没有包含的字段将视为NULL。
     * @return 应该结果。
     */
    @OperationLog(type = SysOperationLogType.UPDATE)
    @PostMapping("/updateDatasource/{datasourceVariableName}")
    public ResponseResult<Void> updateDatasource(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) JSONObject masterData) {
        String errorMessage;
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId + "");
        if (!datasourceResult.isSuccess()) {
            return ResponseResult.errorFrom(datasourceResult);
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        OnlineTable masterTable = datasource.getMasterTable();
        ResponseResult<List<ColumnData>> columnDataListResult =
                onlineOperationHelper.buildTableData(masterTable, masterData, true, null);
        if (!columnDataListResult.isSuccess()) {
            return ResponseResult.errorFrom(columnDataListResult);
        }
        if (!onlineOperationService.update(masterTable, columnDataListResult.getData())) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        return ResponseResult.success();
    }

    /**
     * 更新一对多关联数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表数据源Id。
     * @param relationId             一对多关联Id。
     * @param slaveData              一对多关联从表数据。这里没有包含的字段将视为NULL。
     * @return 应该结果。
     */
    @OperationLog(type = SysOperationLogType.UPDATE)
    @PostMapping("/updateOneToManyRelation/{datasourceVariableName}")
    public ResponseResult<Void> updateOneToManyRelation(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) Long relationId,
            @MyRequestBody(required = true) JSONObject slaveData) {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId + "");
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId + "", relationId + "");
        if (!relationResult.isSuccess()) {
            return ResponseResult.errorFrom(relationResult);
        }
        OnlineTable slaveTable = relationResult.getData().getSlaveTable();
        ResponseResult<List<ColumnData>> columnDataListResult =
                onlineOperationHelper.buildTableData(slaveTable, slaveData, true, null);
        if (!columnDataListResult.isSuccess()) {
            return ResponseResult.errorFrom(columnDataListResult);
        }
        if (!onlineOperationService.update(slaveTable, columnDataListResult.getData())) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        return ResponseResult.success();
    }

    /**
     * 删除主数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表数据源Id。
     * @param dataId                 待删除的数据表主键Id。
     * @return 应该结果。
     */
    @OperationLog(type = SysOperationLogType.DELETE)
    @PostMapping("/deleteDatasource/{datasourceVariableName}")
    public ResponseResult<Void> deleteDatasource(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) String dataId) {
        return this.doDelete(datasourceVariableName, datasourceId + "", CollUtil.newArrayList(dataId));
    }

    /**
     * 批量删除主数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表数据源Id。
     * @param dataIdList             待删除的数据表主键Id列表。
     * @return 应该结果。
     */
    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
    @PostMapping("/deleteBatchDatasource/{datasourceVariableName}")
    public ResponseResult<Void> deleteBatchDatasource(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) List<String> dataIdList) {
        return this.doDelete(datasourceVariableName, datasourceId + "", dataIdList);
    }

    /**
     * 删除一对多关联表单条数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表数据源Id。
     * @param relationId             一对多关联Id。
     * @param dataId                 一对多关联表主键Id。
     * @return 应该结果。
     */
    @OperationLog(type = SysOperationLogType.DELETE)
    @PostMapping("/deleteOneToManyRelation/{datasourceVariableName}")
    public ResponseResult<Void> deleteOneToManyRelation(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) Long relationId,
            @MyRequestBody(required = true) String dataId) {
        return this.doDelete(datasourceVariableName, datasourceId + "", relationId + "", CollUtil.newArrayList(dataId));
    }

    /**
     * 批量删除一对多关联表单条数据接口。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           主表数据源Id。
     * @param relationId             一对多关联Id。
     * @param dataIdList             一对多关联表主键Id列表。
     * @return 应该结果。
     */
    @OperationLog(type = SysOperationLogType.DELETE_BATCH)
    @PostMapping("/deleteBatchOneToManyRelation/{datasourceVariableName}")
    public ResponseResult<Void> deleteBatchOneToManyRelation(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) Long relationId,
            @MyRequestBody(required = true) List<String> dataIdList) {
        return this.doDelete(datasourceVariableName, datasourceId + "", relationId + "", dataIdList);
    }

    /**
     * 根据数据源Id为动态表单查询数据详情。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param dataId                 数据主键Id。
     * @return 详情结果。
     */
    @GetMapping("/viewByDatasourceId/{datasourceVariableName}")
    public ResponseResult<Map<String, Object>> viewByDatasourceId(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @RequestParam Long datasourceId,
            @RequestParam String dataId) {
        String errorMessage;
        // 验证数据源及其关联
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId + "");
        if (!datasourceResult.isSuccess()) {
            return ResponseResult.errorFrom(datasourceResult);
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        OnlineTable masterTable = datasource.getMasterTable();
        ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
                onlineOperationHelper.verifyAndGetRelationList(datasourceId + "", null);
        if (!relationListResult.isSuccess()) {
            return ResponseResult.errorFrom(relationListResult);
        }
        List<OnlineDatasourceRelation> allRelationList = relationListResult.getData();
        List<OnlineDatasourceRelation> oneToOneRelationList = allRelationList.stream()
                .filter(r -> r.getRelationType().equals(RelationType.ONE_TO_ONE)).collect(Collectors.toList());
        Map<String, Object> result =
                onlineOperationService.getMasterData(masterTable, oneToOneRelationList, allRelationList, dataId);
        return ResponseResult.success(result);
    }

    /**
     * 根据数据源关联Id为动态表单查询数据详情。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param relationId             一对多关联Id。
     * @param dataId                 一对多关联数据主键Id。
     * @return 详情结果。
     */
    @GetMapping("/viewByOneToManyRelationId/{datasourceVariableName}")
    public ResponseResult<Map<String, Object>> viewByOneToManyRelationId(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @RequestParam Long datasourceId,
            @RequestParam Long relationId,
            @RequestParam String dataId) {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId + "");
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId + "", relationId + "");
        if (!relationResult.isSuccess()) {
            return ResponseResult.errorFrom(relationResult);
        }
        OnlineDatasourceRelation relation = relationResult.getData();
        Map<String, Object> result = onlineOperationService.getSlaveData(relation, dataId);
        return ResponseResult.success(result);
    }

    /**
     * 为数据源主表字段下载文件。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param dataId                 附件所在记录的主键Id。
     * @param fieldName              数据表字段名。
     * @param asImage                是否为图片文件。
     * @param response               Http 应答对象。
     */
    @OperationLog(type = SysOperationLogType.DOWNLOAD, saveResponse = false)
    @GetMapping("/downloadDatasource/{datasourceVariableName}")
    public void downloadDatasource(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @RequestParam Long datasourceId,
            @RequestParam(required = false) String dataId,
            @RequestParam String fieldName,
            @RequestParam String filename,
            @RequestParam Boolean asImage,
            HttpServletResponse response) throws Exception {
        if (MyCommonUtil.existBlankArgument(fieldName, filename, asImage)) {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            return;
        }
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId + "");
        if (!datasourceResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(datasourceResult));
            return;
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
            return;
        }
        OnlineTable masterTable = datasource.getMasterTable();
        onlineOperationHelper.doDownload(masterTable, dataId, fieldName, filename, asImage, response);
    }

    /**
     * 为数据源一对多关联的从表字段下载文件。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param relationId             数据源的一对多关联Id。
     * @param dataId                 附件所在记录的主键Id。
     * @param fieldName              数据表字段名。
     * @param asImage                是否为图片文件。
     * @param response               Http 应答对象。
     */
    @OperationLog(type = SysOperationLogType.DOWNLOAD, saveResponse = false)
    @GetMapping("/downloadOneToManyRelation/{datasourceVariableName}")
    public void downloadOneToManyRelation(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @RequestParam Long datasourceId,
            @RequestParam Long relationId,
            @RequestParam(required = false) String dataId,
            @RequestParam String fieldName,
            @RequestParam String filename,
            @RequestParam Boolean asImage,
            HttpServletResponse response) throws Exception {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId + "");
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage));
            return;
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
            return;
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId + "", relationId + "");
        if (!relationResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(relationResult));
            return;
        }
        OnlineTable slaveTable = relationResult.getData().getSlaveTable();
        onlineOperationHelper.doDownload(slaveTable, dataId, fieldName, filename, asImage, response);
    }

    /**
     * 为数据源主表字段上传文件。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param fieldName              数据表字段名。
     * @param asImage                是否为图片文件。
     * @param uploadFile             上传文件对象。
     */
    @OperationLog(type = SysOperationLogType.UPLOAD, saveResponse = false)
    @PostMapping("/uploadDatasource/{datasourceVariableName}")
    public void uploadDatasource(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @RequestParam Long datasourceId,
            @RequestParam String fieldName,
            @RequestParam Boolean asImage,
            @RequestParam("uploadFile") MultipartFile uploadFile) throws Exception {
        String errorMessage;
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId + "");
        if (!datasourceResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(datasourceResult));
            return;
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
            return;
        }
        OnlineTable masterTable = datasource.getMasterTable();
        onlineOperationHelper.doUpload(masterTable, fieldName, asImage, uploadFile);
    }

    /**
     * 为数据源一对多关联的从表字段上传文件。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param relationId             数据源的一对多关联Id。
     * @param fieldName              数据表字段名。
     * @param asImage                是否为图片文件。
     * @param uploadFile             上传文件对象。
     */
    @OperationLog(type = SysOperationLogType.UPLOAD, saveResponse = false)
    @PostMapping("/uploadOneToManyRelation/{datasourceVariableName}")
    public void uploadOneToManyRelation(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @RequestParam Long datasourceId,
            @RequestParam Long relationId,
            @RequestParam String fieldName,
            @RequestParam Boolean asImage,
            @RequestParam("uploadFile") MultipartFile uploadFile) throws Exception {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId + "");
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage));
            return;
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN,
                    ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION));
            return;
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId + "", relationId + "");
        if (!relationResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN, ResponseResult.errorFrom(relationResult));
            return;
        }
        OnlineTable slaveTable = relationResult.getData().getSlaveTable();
        onlineOperationHelper.doUpload(slaveTable, fieldName, asImage, uploadFile);
    }

    /**
     * 根据数据源Id，以及接口参数，为动态表单查询数据列表。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param filterDtoList          多虑数据对象列表。
     * @param orderParam             排序对象。
     * @param pageParam              分页对象。
     * @return 查询结果。
     */
    @PostMapping("/listByDatasourceId/{datasourceVariableName}")
    public ResponseResult<MyPageData<Map<String, Object>>> listByDatasourceId(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody List<OnlineFilterDto> filterDtoList,
            @MyRequestBody MyOrderParam orderParam,
            @MyRequestBody MyPageParam pageParam) {
        String errorMessage;
        // 1. 验证数据源及其关联
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId + "");
        if (!datasourceResult.isSuccess()) {
            return ResponseResult.errorFrom(datasourceResult);
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        OnlineTable masterTable = datasource.getMasterTable();
        ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
                onlineOperationHelper.verifyAndGetRelationList(datasourceId + "", null);
        if (!relationListResult.isSuccess()) {
            return ResponseResult.errorFrom(relationListResult);
        }
        List<OnlineDatasourceRelation> allRelationList = relationListResult.getData();
        // 2. 验证数据过滤对象中的表名和字段，确保没有sql注入。
        ResponseResult<Void> filterDtoListResult = this.verifyFilterDtoList(filterDtoList);
        if (!filterDtoListResult.isSuccess()) {
            return ResponseResult.errorFrom(filterDtoListResult);
        }
        // 3. 解析排序参数，同时确保没有sql注入。
        Map<String, OnlineTable> tableMap = new HashMap<>(4);
        tableMap.put(masterTable.getTableName(), masterTable);
        List<OnlineDatasourceRelation> oneToOneRelationList = relationListResult.getData().stream()
                .filter(r -> r.getRelationType().equals(RelationType.ONE_TO_ONE)).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(oneToOneRelationList)) {
            Map<String, OnlineTable> relationTableMap = oneToOneRelationList.stream()
                    .map(OnlineDatasourceRelation::getSlaveTable).collect(Collectors.toMap(OnlineTable::getTableName, c -> c));
            tableMap.putAll(relationTableMap);
        }
        ResponseResult<String> orderByResult = this.makeOrderBy(orderParam, masterTable, tableMap);
        if (!orderByResult.isSuccess()) {
            return ResponseResult.errorFrom(orderByResult);
        }
        String orderBy = orderByResult.getData();
        if (pageParam != null) {
            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        }
        List<Map<String, Object>> resultList = onlineOperationService.getMasterDataList(
                masterTable, oneToOneRelationList, allRelationList, filterDtoList, orderBy);
        return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
    }

    /**
     * 根据数据源Id，以及接口参数，为动态表单导出数据列表。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param filterDtoList          多虑数据对象列表。
     * @param orderParam             排序对象。
     * @param exportInfoList         导出字段信息列表。
     */
    @PostMapping("/exportByDatasourceId/{datasourceVariableName}")
    public void exportByDatasourceId(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody List<OnlineFilterDto> filterDtoList,
            @MyRequestBody MyOrderParam orderParam,
            @MyRequestBody(required = true) List<ExportInfo> exportInfoList) throws IOException {
        // 1. 验证数据源及其关联
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId + "");
        if (!datasourceResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, datasourceResult);
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
        }
        OnlineTable masterTable = datasource.getMasterTable();
        ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
                onlineOperationHelper.verifyAndGetRelationList(datasourceId + "", null);
        if (!relationListResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, relationListResult);
        }
        List<OnlineDatasourceRelation> allRelationList = relationListResult.getData();
        // 2. 验证数据过滤对象中的表名和字段，确保没有sql注入。
        ResponseResult<Void> filterDtoListResult = this.verifyFilterDtoList(filterDtoList);
        if (!filterDtoListResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, filterDtoListResult);
        }
        // 3. 解析排序参数，同时确保没有sql注入。
        Map<String, OnlineTable> tableMap = new HashMap<>(4);
        tableMap.put(masterTable.getTableName(), masterTable);
        List<OnlineDatasourceRelation> oneToOneRelationList = relationListResult.getData().stream()
                .filter(r -> r.getRelationType().equals(RelationType.ONE_TO_ONE)).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(oneToOneRelationList)) {
            Map<String, OnlineTable> relationTableMap = oneToOneRelationList.stream()
                    .map(OnlineDatasourceRelation::getSlaveTable).collect(Collectors.toMap(OnlineTable::getTableName, c -> c));
            tableMap.putAll(relationTableMap);
        }
        ResponseResult<String> orderByResult = this.makeOrderBy(orderParam, masterTable, tableMap);
        if (!orderByResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, orderByResult);
        }
        String orderBy = orderByResult.getData();
        List<Map<String, Object>> resultList = onlineOperationService.getMasterDataList(
                masterTable, oneToOneRelationList, allRelationList, filterDtoList, orderBy);
        Map<String, String> headerMap = this.makeExportHeaderMap(masterTable, allRelationList, exportInfoList);
        if (MapUtil.isEmpty(headerMap)) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST,
                    ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "数据验证失败，没有指定导出头信息！"));
            return;
        }
        String filename = datasourceVariableName + "-" + MyDateUtil.toDateTimeString(DateTime.now()) + ".xlsx";
        ExportUtil.doExport(resultList, headerMap, filename);
    }

    /**
     * 根据数据源Id和数据源关联Id，以及接口参数，为动态表单查询该一对多关联的数据列表。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param relationId             数据源的一对多关联Id。
     * @param filterDtoList          多虑数据对象列表。
     * @param orderParam             排序对象。
     * @param pageParam              分页对象。
     * @return 查询结果。
     */
    @PostMapping("/listByOneToManyRelationId/{datasourceVariableName}")
    public ResponseResult<MyPageData<Map<String, Object>>> listByOneToManyRelationId(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) Long relationId,
            @MyRequestBody List<OnlineFilterDto> filterDtoList,
            @MyRequestBody MyOrderParam orderParam,
            @MyRequestBody MyPageParam pageParam) {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId + "");
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId + "", relationId + "");
        if (!relationResult.isSuccess()) {
            return ResponseResult.errorFrom(relationResult);
        }
        OnlineDatasourceRelation relation = relationResult.getData();
        OnlineTable slaveTable = relation.getSlaveTable();
        // 验证数据过滤对象中的表名和字段，确保没有sql注入。
        ResponseResult<Void> filterDtoListResult = this.verifyFilterDtoList(filterDtoList);
        if (!filterDtoListResult.isSuccess()) {
            return ResponseResult.errorFrom(filterDtoListResult);
        }
        Map<String, OnlineTable> tableMap = new HashMap<>(1);
        tableMap.put(slaveTable.getTableName(), slaveTable);
        if (CollUtil.isNotEmpty(orderParam)) {
            for (MyOrderParam.OrderInfo orderInfo : orderParam) {
                orderInfo.setFieldName(StrUtil.removePrefix(orderInfo.getFieldName(),
                        relation.getVariableName() + OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR));
            }
        }
        ResponseResult<String> orderByResult = this.makeOrderBy(orderParam, slaveTable, tableMap);
        if (!orderByResult.isSuccess()) {
            return ResponseResult.errorFrom(orderByResult);
        }
        String orderBy = orderByResult.getData();
        // 分页。
        if (pageParam != null) {
            PageMethod.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        }
        List<Map<String, Object>> resultList =
                onlineOperationService.getSlaveDataList(relation, filterDtoList, orderBy);
        return ResponseResult.success(MyPageUtil.makeResponseData(resultList));
    }

    /**
     * 根据数据源Id和数据源关联Id，以及接口参数，为动态表单查询该一对多关联的数据列表。
     *
     * @param datasourceVariableName 数据源名称。
     * @param datasourceId           数据源Id。
     * @param relationId             数据源的一对多关联Id。
     * @param filterDtoList          多虑数据对象列表。
     * @param orderParam             排序对象。
     * @param exportInfoList         导出字段信息列表。
     */
    @PostMapping("/exportByOneToManyRelationId/{datasourceVariableName}")
    public void exportByOneToManyRelationId(
            @PathVariable("datasourceVariableName") String datasourceVariableName,
            @MyRequestBody(required = true) Long datasourceId,
            @MyRequestBody(required = true) Long relationId,
            @MyRequestBody List<OnlineFilterDto> filterDtoList,
            @MyRequestBody MyOrderParam orderParam,
            @MyRequestBody(required = true) List<ExportInfo> exportInfoList) throws IOException {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId + "");
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST,
                    ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST, errorMessage));
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ResponseResult.output(HttpServletResponse.SC_FORBIDDEN);
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId + "", relationId + "");
        if (!relationResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, relationResult);
        }
        OnlineDatasourceRelation relation = relationResult.getData();
        OnlineTable slaveTable = relation.getSlaveTable();
        // 验证数据过滤对象中的表名和字段，确保没有sql注入。
        ResponseResult<Void> filterDtoListResult = this.verifyFilterDtoList(filterDtoList);
        if (!filterDtoListResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, filterDtoListResult);
        }
        Map<String, OnlineTable> tableMap = new HashMap<>(1);
        tableMap.put(slaveTable.getTableName(), slaveTable);
        if (CollUtil.isNotEmpty(orderParam)) {
            for (MyOrderParam.OrderInfo orderInfo : orderParam) {
                orderInfo.setFieldName(StrUtil.removePrefix(orderInfo.getFieldName(),
                        relation.getVariableName() + OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR));
            }
        }
        ResponseResult<String> orderByResult = this.makeOrderBy(orderParam, slaveTable, tableMap);
        if (!orderByResult.isSuccess()) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST, orderByResult);
        }
        String orderBy = orderByResult.getData();
        List<Map<String, Object>> resultList =
                onlineOperationService.getSlaveDataList(relation, filterDtoList, orderBy);
        Map<String, String> headerMap = this.makeExportHeaderMap(
                null, CollUtil.newArrayList(relation), exportInfoList);
        if (MapUtil.isEmpty(headerMap)) {
            ResponseResult.output(HttpServletResponse.SC_BAD_REQUEST,
                    ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, "数据验证失败，没有指定导出头信息！"));
            return;
        }
        String filename = datasourceVariableName + "-relation-"
                + MyDateUtil.toDateTimeString(DateTime.now()) + ".xlsx";
        ExportUtil.doExport(resultList, headerMap, filename);
    }

    /**
     * 查询字典数据，并以字典的约定方式，返回数据结果集。
     *
     * @param dictId        字典Id。
     * @param filterDtoList 字典的过滤对象列表。
     * @return 字典数据列表。
     */
    @PostMapping("/listDict")
    public ResponseResult<List<Map<String, Object>>> listDict(
            @MyRequestBody(required = true) Long dictId,
            @MyRequestBody List<OnlineFilterDto> filterDtoList) {
        String errorMessage;
        OnlineDict dict = onlineDictService.getOnlineDictFromCache(dictId + "");
        if (dict == null) {
            errorMessage = "数据验证失败，字典Id并不存在！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        if (!dict.getDictType().equals(DictType.TABLE)) {
            errorMessage = "数据验证失败，该接口仅支持数据表字典！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        if (CollUtil.isNotEmpty(filterDtoList)) {
            for (OnlineFilterDto filter : filterDtoList) {
                if (!this.checkTableAndColumnName(filter.getColumnName())) {
                    errorMessage = "数据验证失败，过滤字段名 ["
                            + filter.getColumnName() + " ] 包含 (数字、字母和下划线) 之外的非法字符！";
                    return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
                }
            }
        }
        List<Map<String, Object>> resultList = onlineOperationService.getDictDataList(dict, filterDtoList);
        return ResponseResult.success(resultList);
    }

    /**
     * 获取编码字段的编码值。
     *
     * @param tableId  表Id。
     * @param columnId 字段Id。
     * @return 计算后的编码值。
     */
    @GetMapping("/getColumnRuleCode")
    public ResponseResult<String> getColumnRuleCode(@RequestParam Long tableId, @RequestParam Long columnId) {
        String errorMessage;
        OnlineColumn column = onlineTableService.getOnlineColumnFromCache(tableId + "", columnId + "");
        if (column == null) {
            return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
        }
        if (StrUtil.isBlank(column.getEncodedRule())) {
            errorMessage = "数据验证失败，当前字段尚未设置自定义编码规则！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        ColumnEncodedRule rule = JSON.parseObject(column.getEncodedRule(), ColumnEncodedRule.class);
        String code = commonRedisUtil.generateTransId(
                rule.getPrefix(), rule.getPrecisionTo(), rule.getMiddle(), rule.getIdWidth());
        return ResponseResult.success(code);
    }

    private ResponseResult<Void> doDelete(
            String datasourceVariableName, String datasourceId, List<String> dataIdList) {
        String errorMessage;
        ResponseResult<OnlineDatasource> datasourceResult =
                onlineOperationHelper.verifyAndGetDatasource(datasourceId);
        if (!datasourceResult.isSuccess()) {
            return ResponseResult.errorFrom(datasourceResult);
        }
        OnlineDatasource datasource = datasourceResult.getData();
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        OnlineTable masterTable = datasource.getMasterTable();
        ResponseResult<List<OnlineDatasourceRelation>> relationListResult =
                onlineOperationHelper.verifyAndGetRelationList(datasourceId, RelationType.ONE_TO_MANY);
        if (!relationListResult.isSuccess()) {
            return ResponseResult.errorFrom(relationListResult);
        }
        List<OnlineDatasourceRelation> relationList = relationListResult.getData();
        for (String dataId : dataIdList) {
            if (!onlineOperationService.delete(masterTable, relationList, dataId)) {
                return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
            }
        }
        return ResponseResult.success();
    }

    private ResponseResult<Void> doDelete(
            String datasourceVariableName, String datasourceId, String relationId, List<String> dataIdList) {
        String errorMessage;
        OnlineDatasource datasource = onlineDatasourceService.getOnlineDatasourceFromCache(datasourceId);
        if (datasource == null) {
            errorMessage = "数据验证失败，数据源Id并不存在！";
            return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
        }
        if (!datasource.getVariableName().equals(datasourceVariableName)) {
            ContextUtil.getHttpResponse().setStatus(HttpServletResponse.SC_FORBIDDEN);
            return ResponseResult.error(ErrorCodeEnum.NO_OPERATION_PERMISSION);
        }
        ResponseResult<OnlineDatasourceRelation> relationResult =
                onlineOperationHelper.verifyAndGetOneToManyRelation(datasourceId, relationId);
        if (!relationResult.isSuccess()) {
            return ResponseResult.errorFrom(relationResult);
        }
        OnlineDatasourceRelation relation = relationResult.getData();
        for (String dataId : dataIdList) {
            if (!onlineOperationService.delete(relation.getSlaveTable(), null, dataId)) {
                return ResponseResult.error(ErrorCodeEnum.DATA_NOT_EXIST);
            }
        }
        return ResponseResult.success();
    }

    private ResponseResult<Void> verifyFilterDtoList(List<OnlineFilterDto> filterDtoList) {
        if (CollUtil.isEmpty(filterDtoList)) {
            return ResponseResult.success();
        }
        String errorMessage;
        for (OnlineFilterDto filter : filterDtoList) {
            if (!this.checkTableAndColumnName(filter.getTableName())) {
                errorMessage = "数据验证失败，过滤表名 ["
                        + filter.getColumnName() + " ] 包含 (数字、字母和下划线) 之外的非法字符！";
                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
            }
            if (!this.checkTableAndColumnName(filter.getColumnName())) {
                errorMessage = "数据验证失败，过滤字段名 ["
                        + filter.getColumnName() + " ] 包含 (数字、字母和下划线) 之外的非法字符！";
                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
            }
            if (!filter.getFilterType().equals(FieldFilterType.RANGE_FILTER)
                    && ObjectUtil.isEmpty(filter.getColumnValue())) {
                errorMessage = "数据验证失败，过滤字段名 [" + filter.getColumnName() + " ] 过滤值不能为空！";
                return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
            }
        }
        return ResponseResult.success();
    }

    private boolean checkTableAndColumnName(String name) {
        if (StrUtil.isBlank(name)) {
            return true;
        }
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (!CharUtil.isLetterOrNumber(c) && !CharUtil.equals('_', c, false)) {
                return false;
            }
        }
        return true;
    }

    private ResponseResult<String> makeOrderBy(
            MyOrderParam orderParam, OnlineTable masterTable, Map<String, OnlineTable> tableMap) {
        if (CollUtil.isEmpty(orderParam)) {
            return ResponseResult.success(null);
        }
        String errorMessage;
        StringBuilder sb = new StringBuilder(128);
        for (int i = 0; i < orderParam.size(); i++) {
            MyOrderParam.OrderInfo orderInfo = orderParam.get(i);
            boolean found = false;
            String[] orderArray = StrUtil.splitToArray(orderInfo.getFieldName(), '.');
            // 如果没有前缀，我们就可以默认为主表的字段。
            if (orderArray.length == 1) {
                for (OnlineColumn column : masterTable.getColumnMap().values()) {
                    if (column.getColumnName().equals(orderArray[0])) {
                        sb.append(masterTable.getTableName()).append(".").append(column.getColumnName());
                        if (!orderInfo.getAsc()) {
                            sb.append(" DESC");
                        }
                        if (i != orderParam.size() - 1) {
                            sb.append(", ");
                        }
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    errorMessage = "数据验证失败，排序字段 ["
                            + orderInfo.getFieldName() + "] 在主表 [" + masterTable.getTableName() + "] 中并不存在！";
                    return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
                }
            } else {
                String tableName = orderArray[0];
                String columnName = orderArray[1];
                OnlineTable table = tableMap.get(tableName);
                if (table == null) {
                    errorMessage = "数据验证失败，排序字段 ["
                            + orderInfo.getFieldName() + "] 的数据表 [" + tableName + "] 并不属于当前数据源！";
                    return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
                }
                for (OnlineColumn column : table.getColumnMap().values()) {
                    if (column.getColumnName().equals(columnName)) {
                        sb.append(tableName).append(".").append(columnName);
                        if (!orderInfo.getAsc()) {
                            sb.append(" DESC");
                        }
                        if (i != orderParam.size() - 1) {
                            sb.append(", ");
                        }
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    errorMessage = "数据验证失败，排序字段 ["
                            + orderInfo.getFieldName() + "] 在数据表 [" + tableName + "] 中并不存在！";
                    return ResponseResult.error(ErrorCodeEnum.DATA_VALIDATED_FAILED, errorMessage);
                }
            }
        }
        return ResponseResult.success(sb.toString());
    }

    private Map<String, String> makeExportHeaderMap(
            OnlineTable masterTable,
            List<OnlineDatasourceRelation> allRelationList,
            List<ExportInfo> exportInfoList) {
        Map<String, String> headerMap = new LinkedHashMap<>(16);
        Map<String, OnlineDatasourceRelation> allRelationMap = null;
        if (CollUtil.isNotEmpty(allRelationList)) {
            allRelationMap = allRelationList.stream()
                    .collect(Collectors.toMap(OnlineDatasourceRelation::getSlaveTableId, r -> r));
        }
        for (ExportInfo exportInfo : exportInfoList) {
            if (masterTable != null && exportInfo.getTableId().equals(masterTable.getTableId())) {
                if (exportInfo.getVirtualColumnId() != null) {
                    OnlineVirtualColumn virtualColumn =
                            onlineVirtualColumnService.getById(exportInfo.getVirtualColumnId());
                    if (virtualColumn != null) {
                        headerMap.put(virtualColumn.getObjectFieldName(), exportInfo.showName);
                    }
                } else {
                    OnlineColumn column = masterTable.getColumnMap().get(exportInfo.getColumnId());
                    if (column.getDictId() != null) {
                        headerMap.put(column.getColumnName() + "__DictMap.name", exportInfo.getShowName());
                    } else {
                        headerMap.put(column.getColumnName(), exportInfo.getShowName());
                    }
                }
            } else {
                if (MapUtil.isEmpty(allRelationMap)) {
                    continue;
                }
                OnlineDatasourceRelation relation = allRelationMap.get(exportInfo.getTableId());
                if (relation != null) {
                    OnlineColumn column = relation.getSlaveTable().getColumnMap().get(exportInfo.getColumnId());
                    String columnName = relation.getVariableName()
                            + OnlineConstant.RELATION_TABLE_COLUMN_SEPARATOR + column.getColumnName();
                    if (column.getDictId() != null) {
                        columnName = columnName + "__DictMap.name";
                    }
                    headerMap.put(columnName, exportInfo.getShowName());
                }
            }
        }
        return headerMap;
    }

    @Data
    public static class ExportInfo {
        private String tableId;
        private String columnId;
        private String virtualColumnId;
        private String showName;
    }
}
