package com.yunzhupaas.onlinedev.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.xuyanwu.spring.file.storage.FileInfo;
import com.google.common.collect.ImmutableList;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.ActionResultCode;
import com.yunzhupaas.base.controller.SuperController;
import com.yunzhupaas.base.entity.ModuleEntity;
import com.yunzhupaas.base.entity.VisualAliasEntity;
import com.yunzhupaas.base.entity.VisualdevEntity;
import com.yunzhupaas.base.entity.VisualdevReleaseEntity;
import com.yunzhupaas.base.model.ColumnDataModel;
import com.yunzhupaas.base.model.OnlineImport.ExcelImportModel;
import com.yunzhupaas.base.model.OnlineImport.ImportExcelFieldModel;
import com.yunzhupaas.base.model.OnlineImport.VisualImportModel;
import com.yunzhupaas.base.model.OnlineImport.VisualdevModelDataInfoVO;
import com.yunzhupaas.base.model.VisualDevJsonModel;
import com.yunzhupaas.base.model.VisualWebTypeEnum;
import com.yunzhupaas.base.model.flow.DataModel;
import com.yunzhupaas.base.model.flow.FlowLaunchModel;
import com.yunzhupaas.base.model.module.PropertyJsonModel;
import com.yunzhupaas.base.service.ModuleService;
import com.yunzhupaas.base.service.VisualAliasService;
import com.yunzhupaas.base.service.VisualdevReleaseService;
import com.yunzhupaas.base.service.VisualdevService;
import com.yunzhupaas.base.util.FormExecelUtils;
import com.yunzhupaas.base.util.VisualUtil;
import com.yunzhupaas.base.util.VisualUtils;
import com.yunzhupaas.base.vo.DownloadVO;
import com.yunzhupaas.base.vo.PaginationVO;
import com.yunzhupaas.config.ConfigValueUtil;
import com.yunzhupaas.constant.YunzhupaasConst;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.constant.PermissionConst;
import com.yunzhupaas.emnus.ExportModelTypeEnum;
import com.yunzhupaas.emnus.ModuleTypeEnum;
import com.yunzhupaas.exception.DataException;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.flowable.entity.TaskEntity;
import com.yunzhupaas.flowable.model.task.FlowModel;
import com.yunzhupaas.integrate.util.IntegrateUtil;
import com.yunzhupaas.model.ExcelModel;
import com.yunzhupaas.model.OnlineDevData;
import com.yunzhupaas.model.TransferModel;
import com.yunzhupaas.model.visualJson.FieLdsModel;
import com.yunzhupaas.model.visualJson.FormDataModel;
import com.yunzhupaas.model.visualJson.UploaderTemplateModel;
import com.yunzhupaas.model.visualJson.config.HeaderModel;
import com.yunzhupaas.onlinedev.entity.VisualdevModelDataEntity;
import com.yunzhupaas.onlinedev.model.*;
import com.yunzhupaas.onlinedev.service.VisualDevInfoService;
import com.yunzhupaas.onlinedev.service.VisualDevListService;
import com.yunzhupaas.onlinedev.service.VisualPersonalService;
import com.yunzhupaas.onlinedev.service.VisualdevModelDataService;
import com.yunzhupaas.onlinedev.util.onlineDevUtil.OnlineDevListUtils;
import com.yunzhupaas.onlinedev.util.onlineDevUtil.OnlinePublicUtils;
import com.yunzhupaas.onlinedev.util.onlineDevUtil.OnlineSwapDataUtils;
import com.yunzhupaas.permission.service.UserService;
import com.yunzhupaas.util.*;
import com.yunzhupaas.util.context.RequestContext;
import com.yunzhupaas.util.visiual.YunzhupaasKeyConsts;
import com.yunzhupaas.workflow.service.TaskApi;
import com.yunzhupaas.workflow.service.TriggerApi;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 0代码无表开发
 *
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @copyright 深圳市乐程软件有限公司
 * @date 2023/09/27
 */
@Slf4j
@Tag(name = "0代码无表开发", description = "OnlineDev")
@RestController
@RequestMapping("/api/visualdev/OnlineDev")
public class VisualdevModelDataController extends SuperController<VisualdevModelDataService, VisualdevModelDataEntity> {

    @Autowired
    private VisualdevModelDataService visualdevModelDataService;
    @Autowired
    private VisualdevService visualdevService;

    @Autowired
    private FileExport fileExport;
    @Autowired
    private VisualDevListService visualDevListService;
    @Autowired
    private VisualDevInfoService visualDevInfoService;
    @Autowired
    private VisualdevReleaseService visualdevReleaseService;
    @Autowired
    private ConfigValueUtil configValueUtil;
    @Autowired
    private OnlineSwapDataUtils onlineSwapDataUtils;
    @Autowired
    private IntegrateUtil integrateUtil;
    @Autowired
    private ModuleService moduleService;
    @Autowired
    private VisualAliasService aliasService;
    @Autowired
    private TaskApi taskApi;
    @Autowired
    private TriggerApi triggerApi;
    @Autowired
    private VisualPersonalService visualPersonalService;
    @Autowired
    private UserService userService;

    // 流程可删除状态
    private List<Integer> FLOW_STATE_DELETE = ImmutableList.of(0, 9);

    @Operation(summary = "获取数据列表")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
    })
    @PostMapping("/{modelId}/List")
    public ActionResult list(@PathVariable("modelId") String modelId, @RequestBody PaginationModel paginationModel)
            throws WorkFlowException {
        StpUtil.checkPermission(modelId);

        VisualdevReleaseEntity visualdevEntity = visualdevReleaseService.getById(modelId);
        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);

        // 判断请求客户端来源
        if (!RequestContext.isOrignPc()) {
            visualJsonModel.setColumnData(visualJsonModel.getAppColumnData());
        }
        ColumnDataModel columnDataModel = visualJsonModel.getColumnData();
        List<Map<String, Object>> realList;
        if (VisualWebTypeEnum.FORM.getType().equals(visualdevEntity.getWebType())) {
            realList = new ArrayList<>();
        } else if (VisualWebTypeEnum.DATA_VIEW.getType().equals(visualdevEntity.getWebType())) {//
            // 数据视图的接口数据获取、
            realList = onlineSwapDataUtils.getInterfaceData(visualdevEntity, paginationModel, columnDataModel);
        } else {
            realList = visualDevListService.getDataList(visualJsonModel, paginationModel);
        }

        // 判断数据是否分组
        if (OnlineDevData.COLUMNTYPE_THREE.equals(columnDataModel.getType())
                && StringUtil.isEmpty(paginationModel.getExtraQueryJson())) {
            realList = OnlineDevListUtils.groupData(realList, columnDataModel);
        }
        // 树形列表
        if (OnlineDevData.COLUMNTYPE_FIVE.equals(columnDataModel.getType())
                && StringUtil.isEmpty(paginationModel.getExtraQueryJson())) {
            realList = OnlineDevListUtils.treeListData(realList, columnDataModel);
        }
        PaginationVO paginationVO = JsonUtil.getJsonToBean(paginationModel, PaginationVO.class);

        return ActionResult.page(realList, paginationVO);
    }

    @Operation(summary = "树形异步查询子列表接口")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "id", description = "数据id"),
    })
    @PostMapping("/{modelId}/List/{id}")
    public ActionResult listTree(@PathVariable("modelId") String modelId, @RequestBody PaginationModel paginationModel,
            @PathVariable("id") String id) throws WorkFlowException {
        StpUtil.checkPermission(modelId);

        VisualdevReleaseEntity visualdevEntity = visualdevReleaseService.getById(modelId);
        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);
        // 判断请求客户端来源
        if (!RequestContext.isOrignPc()) {
            visualJsonModel.setColumnData(visualJsonModel.getAppColumnData());
        }

        List<Map<String, Object>> realList = visualDevListService.getDataList(visualJsonModel, paginationModel);
        ColumnDataModel columnDataModel = visualJsonModel.getColumnData();
        String parentField = columnDataModel.getParentField() + "_id";

        List<Map<String, Object>> collect = realList.stream().filter(item -> id.equals(item.get(parentField)))
                .collect(Collectors.toList());
        PaginationVO paginationVO = JsonUtil.getJsonToBean(paginationModel, PaginationVO.class);
        return ActionResult.page(collect, paginationVO);
    }

    @Operation(summary = "获取列表表单配置JSON")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "type", description = "类型0-草稿，1-发布"),
    })
    @GetMapping("/{modelId}/Config")
    public ActionResult getData(@PathVariable("modelId") String modelId,
            @RequestParam(value = "type", required = false) String type,
            @RequestParam(value = "personal", required = false) Integer personal,
            @RequestParam(value = "menuId", required = false) String menuId) throws WorkFlowException {
        StpUtil.checkPermissionOr(modelId, "onlineDev.webDesign", "generator.webForm", "generator.flowForm");

        VisualdevEntity entity;
        // 线上版本
        if ("0".equals(type)) {
            entity = visualdevService.getInfo(modelId);
        } else {
            VisualdevReleaseEntity releaseEntity = visualdevReleaseService.getById(modelId);
            entity = JsonUtil.getJsonToBean(releaseEntity, VisualdevEntity.class);
        }
        if (entity == null) {
            return ActionResult.fail(MsgCode.VS412.get());
        }
        String s = VisualUtil.checkPublishVisualModel(entity, MsgCode.VS005.get());
        if (s != null) {
            return ActionResult.fail(s);
        }

        DataInfoVO vo = JsonUtil.getJsonToBean(entity, DataInfoVO.class);
        if (Objects.equals(entity.getType(), 1) && !VisualWebTypeEnum.DATA_VIEW.getType().equals(entity.getWebType())) {
            vo.setPropsValueList(visualdevService.storedFieldList(entity));
        }

        // 页面初始化获取个性化配置
        if (Objects.equals(1, personal)) {
            visualPersonalService.setDataInfoVO(menuId, vo);
        }
        return ActionResult.success(vo);
    }

    @Operation(summary = "获取表单配置JSON")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
    })
    @GetMapping("/{modelId}/FormData")
    public ActionResult<ColumnDataInfoVO> getFormData(@PathVariable("modelId") String modelId) {
        StpUtil.checkPermission(modelId);

        VisualdevEntity entity = visualdevService.getInfo(modelId);
        return ActionResult.success(entity.getFormData());
    }

    @Operation(summary = "获取数据信息")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
    })
    @GetMapping("/{modelId}/{id}")
    public ActionResult info(@PathVariable("id") String id,
            @PathVariable("modelId") String modelId,
            @RequestParam(name = "menuId", required = false) String menuId) throws DataException {
        StpUtil.checkPermission(modelId);
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        VisualdevModelDataInfoVO editDataInfo = visualDevInfoService.getEditDataInfo(id, visualdevEntity,
                OnlineInfoModel.builder().menuId(menuId).build());
        return ActionResult.success(editDataInfo);
    }

    @Operation(summary = "获取数据信息(带转换数据)")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "id", description = "数据id"),
            @Parameter(name = "propsValue", description = "存储字段（非必传）")
    })
    @PostMapping("/{modelId}/DataChange")
    public ActionResult infoWithDataChange(@PathVariable("modelId") String modelId,
            @RequestBody VisualInfoParam visualInfoParam) {
        StpUtil.checkPermission(modelId);
        String id = visualInfoParam.getId() instanceof String ? (String) visualInfoParam.getId()
                : JsonUtil.getObjectToString(visualInfoParam.getId());
        String propsValue = StringUtil.isNotEmpty(visualInfoParam.getPropsValue())
                && visualInfoParam.getPropsValue().contains(YunzhupaasConst.FIELD_SUFFIX_YUNZHUPAASID)
                        ? visualInfoParam.getPropsValue().split(YunzhupaasConst.FIELD_SUFFIX_YUNZHUPAASID)[0]
                        : visualInfoParam.getPropsValue();

        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        String columnData = RequestContext.isOrignPc() ? visualdevEntity.getColumnData()
                : visualdevEntity.getAppColumnData();
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(columnData, ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_DETAIL);
        }

        VisualdevModelDataInfoVO vo = visualDevInfoService.getDetailsDataInfo(id, visualdevEntity,
                OnlineInfoModel.builder().needRlationFiled(true).needSwap(true).propsValue(propsValue)
                        .menuId(visualInfoParam.getMenuId()).build());
        return ActionResult.success(vo);
    }

    @Operation(summary = "添加数据")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "visualdevModelDataCrForm", description = "功能数据创建表单"),
    })
    @PostMapping("/{modelId}")
    public ActionResult create(@PathVariable("modelId") String modelId,
            @RequestBody VisualdevModelDataCrForm visualdevModelDataCrForm) throws Exception {
        StpUtil.checkPermission(modelId);

        String menuId = visualdevModelDataCrForm.getMenuId();
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        String columnData = RequestContext.isOrignPc() ? visualdevEntity.getColumnData()
                : visualdevEntity.getAppColumnData();
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(columnData, ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_ADD);
        }
        Map<String, Object> map = JsonUtil.stringToMap(visualdevModelDataCrForm.getData());
        DataModel dataModel = visualdevModelDataService.visualCreate(
                VisualParamModel.builder().visualdevEntity(visualdevEntity).data(map).menuId(menuId).build());
        AsyncExecuteModel build = AsyncExecuteModel.builder().modelId(modelId).trigger(1)
                .dataId(ImmutableList.of(dataModel.getMainId()))
                .userInfo(UserProvider.getUser()).build();
        integrateUtil.asyncExecute(build);

        return ActionResult.success(MsgCode.SU001.get());
    }

    @Operation(summary = "修改数据")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "id", description = "数据id"),
            @Parameter(name = "visualdevModelDataUpForm", description = "功能数据修改表单"),
    })
    @PutMapping("/{modelId}/{id}")
    public ActionResult update(@PathVariable("id") String id, @PathVariable("modelId") String modelId,
            @RequestBody VisualdevModelDataUpForm visualdevModelDataUpForm) throws Exception {
        StpUtil.checkPermission(modelId);
        String menuId = visualdevModelDataUpForm.getMenuId();
        Map<String, Object> data = JsonUtil.stringToMap(visualdevModelDataUpForm.getData());
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        String columnData = RequestContext.isOrignPc() ? visualdevEntity.getColumnData()
                : visualdevEntity.getAppColumnData();
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(columnData, ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_EDIT);
        }
        DataModel dataModel = visualdevModelDataService.visualUpdate(
                VisualParamModel.builder().visualdevEntity(visualdevEntity).data(data).menuId(menuId).id(id).build());
        AsyncExecuteModel build = AsyncExecuteModel.builder().modelId(modelId).trigger(2).dataId(ImmutableList.of(id))
                .dataModel(dataModel).userInfo(UserProvider.getUser()).build();
        integrateUtil.asyncExecute(build);
        return ActionResult.success(MsgCode.SU004.get());
    }

    // 接口废弃全部走批量接口
    @Operation(summary = "删除数据")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "id", description = "数据id"),
    })
    @DeleteMapping("/{modelId}/{id}")
    public ActionResult delete(@PathVariable("id") String id, @PathVariable("modelId") String modelId)
            throws Exception {
        StpUtil.checkPermission(modelId);

        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        String columnData = RequestContext.isOrignPc() ? visualdevEntity.getColumnData()
                : visualdevEntity.getAppColumnData();
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(columnData, ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermissionOr(modelId + "::" + PermissionConst.BTN_REMOVE,
                    modelId + "::" + PermissionConst.BTN_BATCHREMOVE);
        }

        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);

        // 判断请求客户端来源
        if (!RequestContext.isOrignPc()) {
            visualJsonModel.setColumnData(visualJsonModel.getAppColumnData());
        }

        if (!StringUtil.isEmpty(visualdevEntity.getVisualTables())
                && !OnlineDevData.TABLE_CONST.equals(visualdevEntity.getVisualTables())) {
            // 树形递归删除
            if (OnlineDevData.COLUMNTYPE_FIVE.equals(visualJsonModel.getColumnData().getType())) {
                try {
                    ActionResult listTreeAction = listTree(modelId, new PaginationModel(), id);
                    if (listTreeAction != null && listTreeAction.getCode() == 200
                            && listTreeAction.getData() instanceof Object) {
                        Map map = JsonUtil.getJsonToBean(listTreeAction.getData(), Map.class);
                        List<Map<String, Object>> list = JsonUtil.getJsonToListMap(map.get("list").toString());
                        if (list.size() > 0) {
                            for (Map<String, Object> item : list) {
                                this.delete(item.get("id").toString(), modelId);
                            }
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("子数据删除异常:{}", e.getMessage());
                }
            }
            List<VisualdevModelDataInfoVO> dataInfoVOList = new ArrayList<>();
            VisualdevModelDataInfoVO editDataInfo = visualDevInfoService.getEditDataInfo(id, visualdevEntity,
                    OnlineInfoModel.builder().build());
            dataInfoVOList.add(editDataInfo);

            List<VisualdevModelDataInfoVO> deleteData = integrateUtil.dataList(modelId, 3, ImmutableList.of(id));

            // Map<String, Object> map = JsonUtil.stringToMap(editDataInfo.getData());
            // TaskEntity taskEntity =
            // taskApi.getInfoSubmit(map.get(FlowFormConstant.FLOWTASKID).toString(),
            // TaskEntity::getId,
            // TaskEntity::getParentId, TaskEntity::getFullName, TaskEntity::getStatus);
            // if(taskEntity != null){
            // return ActionResult.fail(MsgCode.WF063.get());
            // }

            boolean result = visualdevModelDataService.tableDelete(id, visualJsonModel);
            if (result) {
                AsyncExecuteModel build = AsyncExecuteModel.builder().modelId(modelId).trigger(3)
                        .dataId(ImmutableList.of(id))
                        .userInfo(UserProvider.getUser()).build();
                integrateUtil.asyncExecute(build);
                return ActionResult.success(MsgCode.SU003.get());
            } else {
                return ActionResult.fail(MsgCode.FA003.get());
            }
        }
        return ActionResult.fail(MsgCode.FA003.get());
    }

    @Operation(summary = "批量删除数据")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "idsVo", description = "批量处理参数"),
    })
    @PostMapping("/batchDelete/{modelId}")
    public ActionResult batchDelete(@RequestBody BatchRemoveIdsVo idsVo, @PathVariable("modelId") String modelId)
            throws Exception {
        StpUtil.checkPermission(modelId);

        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        String columnData = RequestContext.isOrignPc() ? visualdevEntity.getColumnData()
                : visualdevEntity.getAppColumnData();
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(columnData, ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermissionOr(modelId + "::" + PermissionConst.BTN_REMOVE,
                    modelId + "::" + PermissionConst.BTN_BATCHREMOVE);
        }
        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);

        // 判断请求客户端来源
        if (!RequestContext.isOrignPc()) {
            visualJsonModel.setColumnData(visualJsonModel.getAppColumnData());
        }

        List<String> idsList = new ArrayList<>();
        List<String> idsVoList = Arrays.asList(idsVo.getIds());
        String errMess = "";

        List<Map<String, Object>> dataMap = new ArrayList<>();
        for (String id : idsVoList) {
            VisualdevModelDataInfoVO editDataInfo = visualDevInfoService.getEditDataInfo(id, visualdevEntity,
                    OnlineInfoModel.builder().build());
            Map<String, Object> map = JsonUtil.stringToMap(editDataInfo.getData());
            dataMap.add(map);

            if (StringUtil.isNotBlank(idsVo.getFlowId())) {
                TaskEntity taskEntity = taskApi.getInfoSubmit(map.get(FlowFormConstant.FLOWTASKID).toString(),
                        TaskEntity::getId,
                        TaskEntity::getParentId, TaskEntity::getFullName, TaskEntity::getStatus);
                if (taskEntity != null) {
                    try {
                        taskApi.delete(taskEntity);
                        idsList.add(id);
                    } catch (Exception e) {
                        errMess = e.getMessage();
                    }
                } else {
                    idsList.add(id);
                }
            } else {
                idsList.add(id);
            }
        }

        if (idsList.size() == 0) {
            return ActionResult.fail(errMess);
        }
        List<VisualdevModelDataInfoVO> dataInfoVOList = integrateUtil.dataList(modelId, 3, idsList);

        if (!StringUtil.isEmpty(visualdevEntity.getVisualTables())
                && !OnlineDevData.TABLE_CONST.equals(visualdevEntity.getVisualTables())) {
            ActionResult result = visualdevModelDataService.tableDeleteMore(idsList, visualJsonModel);
            AsyncExecuteModel build = AsyncExecuteModel.builder().modelId(modelId).trigger(3).dataId(idsList)
                    .dataMap(dataMap).userInfo(UserProvider.getUser()).build();
            integrateUtil.asyncExecute(build);
            return result;
        }
        return ActionResult.fail(MsgCode.FA003.get());
    }

    @Operation(summary = "导入数据")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "visualImportModel", description = "导入参数"),
    })
    @PostMapping("{modelId}/ImportData")
    public ActionResult<ExcelImportModel> imports(@PathVariable("modelId") String modelId,
            @RequestBody VisualImportModel visualImportModel) throws Exception {
        StpUtil.checkPermission(modelId);

        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(visualdevEntity.getColumnData(),
                ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_UPLOAD);
        }
        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);
        FormDataModel formData = visualJsonModel.getFormData();
        List<FieLdsModel> fieldsModelList = JsonUtil.getJsonToList(formData.getFields(), FieLdsModel.class);
        List<FieLdsModel> allFieLds = new ArrayList<>();
        VisualUtils.recursionFields(fieldsModelList, allFieLds);
        visualJsonModel.setFormListModels(allFieLds);
        visualJsonModel.setFlowId(visualImportModel.getFlowId());
        // 复杂表头数据 还原成普通数据
        List<Map<String, Object>> listData = new ArrayList<>();
        List<Map<String, Object>> headerRow = new ArrayList<>();
        if (visualImportModel.isType()) {
            ActionResult result = ImportPreview(modelId, visualImportModel.getFileName());
            if (result == null) {
                throw new Exception(MsgCode.FA018.get());
            }
            if (result.getCode() != 200) {
                return result;
            }
            if (result.getData() instanceof Map) {
                Map<String, Object> data = (Map<String, Object>) result.getData();
                listData = (List<Map<String, Object>>) data.get("dataRow");
                headerRow = (List<Map<String, Object>>) data.get("headerRow");
            }
        } else {
            listData = visualImportModel.getList();
        }
        List<Map<String, Object>> mapList = VisualUtils.complexImportsDataOnline(listData, visualdevEntity);
        ExcelImportModel excelData = onlineSwapDataUtils.createExcelData(mapList, visualJsonModel, visualdevEntity);
        List<VisualdevModelDataInfoVO> dataInfoList = excelData.getDataInfoList();
        List<String> addIdList = new ArrayList<>();
        List<String> updateIdList = new ArrayList<>();
        for (VisualdevModelDataInfoVO dataInfoVO : dataInfoList) {
            Integer trigger = StringUtil.isEmpty(dataInfoVO.getIntegrateId()) ? 1 : 2;
            if (Objects.equals(trigger, 1)) {
                addIdList.add(dataInfoVO.getId().toString());
            } else {
                updateIdList.add(dataInfoVO.getId().toString());
            }
        }
        List<VisualdevModelDataInfoVO> addData = integrateUtil.dataList(modelId, 1, addIdList);
        integrateUtil.asyncList(addData, UserProvider.getUser());
        List<VisualdevModelDataInfoVO> updateData = integrateUtil.dataList(modelId, 2, updateIdList);
        integrateUtil.asyncList(updateData, UserProvider.getUser());
        // 复杂表头-表头和数据处理
        List<HeaderModel> complexHeaderList = columnDataModel.getComplexHeaderList();
        if (!Objects.equals(columnDataModel.getType(), 3) && !Objects.equals(columnDataModel.getType(), 5)) {
            List<Map<String, Object>> mapList1 = VisualUtils.complexHeaderDataHandel(excelData.getFailResult(),
                    complexHeaderList, false);
            excelData.setFailResult(mapList1);
        }
        excelData.setHeaderRow(headerRow);
        return ActionResult.success(excelData);
    }

    @Operation(summary = "导出")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "paginationModelExport", description = "导出参数"),
    })
    @PostMapping("/{modelId}/Actions/ExportData")
    public ActionResult export(@PathVariable("modelId") String modelId,
            @RequestBody PaginationModelExport paginationModelExport)
            throws ParseException, IOException, SQLException, DataException {
        StpUtil.checkPermission(modelId);

        ModuleEntity menuInfo = moduleService.getInfo(paginationModelExport.getMenuId());
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        if (visualdevEntity == null) {
            ActionResult.fail(MsgCode.FA001.get());
        }
        String excelName = "";
        if (menuInfo != null) {
            excelName = menuInfo.getFullName();
        } else {
            excelName = visualdevEntity.getFullName();
        }

        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(visualdevEntity.getColumnData(),
                ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_DOWNLOAD);
        }

        VisualDevJsonModel visualJsonModel = OnlinePublicUtils.getVisualJsonModel(visualdevEntity);
        // 判断请求客户端来源
        if (!RequestContext.isOrignPc()) {
            visualJsonModel.setColumnData(visualJsonModel.getAppColumnData());
        }

        String[] keys = paginationModelExport.getSelectKey();
        List<String> selectKey = Arrays.asList(paginationModelExport.getSelectKey());
        List<Object> selectIds = Arrays.asList(paginationModelExport.getSelectIds());
        // 关键字过滤
        List<Map<String, Object>> realList;
        DownloadVO vo;

        if (VisualWebTypeEnum.DATA_VIEW.getType().equals(visualdevEntity.getWebType())) {// 视图查询数据
            VisualdevReleaseEntity visualdevREntity = JsonUtil.getJsonToBean(visualdevEntity,
                    VisualdevReleaseEntity.class);
            realList = onlineSwapDataUtils.getInterfaceData(visualdevREntity, paginationModelExport,
                    visualJsonModel.getColumnData());
            if ("2".equals(paginationModelExport.getDataType()) && StringUtil.isBlank(columnDataModel.getViewKey())) {
                ActionResult.fail(MsgCode.VS029.get());
            }
            realList = "2".equals(paginationModelExport.getDataType()) ? realList.stream()
                    .filter(t -> selectIds.contains(t.get(columnDataModel.getViewKey()))).collect(Collectors.toList())
                    : realList;
            vo = VisualUtils.createModelExcelApiData(visualdevEntity.getColumnData(), realList, Arrays.asList(keys),
                    "表单信息", excelName, new ExcelModel());
        } else {
            ExcelModel excelModel = onlineSwapDataUtils.getDefaultValue(visualdevEntity.getFormData(), selectKey);
            realList = visualdevModelDataService.exportData(keys, paginationModelExport, visualJsonModel);
            realList = "2".equals(paginationModelExport.getDataType())
                    ? realList.stream().filter(t -> selectIds.contains(t.get("id"))).collect(Collectors.toList())
                    : realList;
            vo = VisualUtils.createModelExcel(visualdevEntity, realList, Arrays.asList(keys), "表单信息", excelName,
                    excelModel);
        }
        return ActionResult.success(vo);
    }

    @Operation(summary = "功能导出")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
    })
    @PostMapping("/{modelId}/Actions/Export")
    @SaCheckPermission("onlineDev.webDesign")
    public ActionResult exportData(@PathVariable("modelId") String modelId) {
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        BaseDevModelVO vo = JsonUtil.getJsonToBean(visualdevEntity, BaseDevModelVO.class);
        List<VisualAliasEntity> list = aliasService.getList(visualdevEntity.getId());
        vo.setAliasListJson(JsonUtil.getObjectToString(list));
        vo.setModelType(ExportModelTypeEnum.Design.getMessage());
        DownloadVO downloadVO = fileExport.exportFile(vo, configValueUtil.getTemporaryFilePath(),
                visualdevEntity.getFullName(), ModuleTypeEnum.VISUAL_DEV.getTableName());
        return ActionResult.success(downloadVO);
    }

    @Operation(summary = "功能导入")
    @PostMapping(value = "/Actions/Import", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    @SaCheckPermission("onlineDev.webDesign")
    public ActionResult ImportData(@RequestParam("type") Integer type, @RequestPart("file") MultipartFile multipartFile)
            throws WorkFlowException {
        // 判断是否为.json结尾
        if (FileUtil.existsSuffix(multipartFile, ModuleTypeEnum.VISUAL_DEV.getTableName())) {
            return ActionResult.fail(MsgCode.IMP002.get());
        }
        // 获取文件内容
        String fileContent = FileUtil.getFileContent(multipartFile);
        BaseDevModelVO vo = JsonUtil.getJsonToBean(fileContent, BaseDevModelVO.class);

        VisualdevEntity visualdevEntity = JsonUtil.getJsonToBean(vo, VisualdevEntity.class);

        StringJoiner errList = new StringJoiner("、");
        String copyNum = UUID.randomUUID().toString().substring(0, 5);
        if (visualdevService.getInfo(visualdevEntity.getId()) != null) {
            if (Objects.equals(type, 0)) {
                errList.add("ID");
            } else {
                visualdevEntity.setId(RandomUtil.uuId());
            }
        }
        if (visualdevService.getObjByEncode(visualdevEntity.getEnCode(), visualdevEntity.getType()) > 0) {
            if (Objects.equals(type, 0)) {
                errList.add(MsgCode.IMP009.get());
            } else {
                visualdevEntity.setEnCode(visualdevEntity.getEnCode() + copyNum);
            }
        }
        if (visualdevService.getCountByName(visualdevEntity.getFullName(), visualdevEntity.getType()) > 0) {
            if (Objects.equals(type, 0)) {
                errList.add(MsgCode.IMP008.get());
            } else {
                visualdevEntity.setFullName(visualdevEntity.getFullName() + ".副本" + copyNum);
            }
        }
        if (Objects.equals(type, 0) && errList.length() > 0) {
            return ActionResult.fail(errList + MsgCode.IMP007.get());
        }

        if (visualdevEntity.getId() != null) {
            visualdevService.setIgnoreLogicDelete().removeById(visualdevEntity.getId());
            visualdevService.clearIgnoreLogicDelete();
        }
        visualdevEntity.setCreatorTime(DateUtil.getNowDate());
        visualdevEntity.setCreatorUserId(UserProvider.getUser().getUserId());
        visualdevEntity.setLastModifyTime(null);
        visualdevEntity.setLastModifyUserId(null);
        visualdevEntity.setDbLinkId("0");
        visualdevEntity.setState(0);
        visualdevService.save(visualdevEntity);
        if (StringUtil.isNotEmpty(vo.getAliasListJson())) {
            List<VisualAliasEntity> jsonToList = JsonUtil.getJsonToList(vo.getAliasListJson(), VisualAliasEntity.class);
            for (VisualAliasEntity aliasEntity : jsonToList) {
                aliasService.copyEntity(aliasEntity, visualdevEntity.getId());
            }
        }
        return ActionResult.success(MsgCode.IMP001.get());
    }

    @Operation(summary = "模板下载")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "menuId", description = "菜单id"),
    })
    @GetMapping("/{modelId}/TemplateDownload")
    public ActionResult<DownloadVO> templateDownload(@PathVariable("modelId") String modelId,
            @RequestParam(value = "menuId", required = false) String menuId) {
        StpUtil.checkPermission(modelId);

        ModuleEntity menuInfo = moduleService.getInfo(menuId);
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        if (visualdevEntity == null) {
            ActionResult.fail(MsgCode.FA001.get());
        }
        String menuFullName = "";
        if (menuInfo != null) {
            menuFullName = menuInfo.getFullName();
        } else {
            menuFullName = visualdevEntity.getFullName();
        }
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(visualdevEntity.getColumnData(),
                ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_DOWNLOAD);
        }
        UploaderTemplateModel uploaderTemplateModel = JsonUtil.getJsonToBean(columnDataModel.getUploaderTemplateJson(),
                UploaderTemplateModel.class);
        List<String> selectKey = uploaderTemplateModel.getSelectKey();
        ExcelModel excelModel = onlineSwapDataUtils.getDefaultValue(visualdevEntity.getFormData(), selectKey);
        List<Map<String, Object>> dataList = new ArrayList<>();
        dataList.add(excelModel.getDataMap());
        DownloadVO vo = VisualUtils.createModelExcel(visualdevEntity, dataList, selectKey, "导入模板",
                menuFullName + "导入模板", excelModel);
        return ActionResult.success(vo);
    }

    @Operation(summary = "上传文件")
    @PostMapping("/Uploader")
    public ActionResult<Object> Uploader() {
        List<MultipartFile> list = UpUtil.getFileAll();
        MultipartFile file = list.get(0);
        if (file.getOriginalFilename().endsWith(".xlsx") || file.getOriginalFilename().endsWith(".xls")) {
            String filePath = XSSEscape.escape(configValueUtil.getTemporaryFilePath());
            String fileName = XSSEscape.escape(RandomUtil.uuId() + "." + UpUtil.getFileType(file));
            // 上传文件
            FileInfo fileInfo = FileUploadUtils.uploadFile(file, filePath, fileName);
            DownloadVO vo = DownloadVO.builder().build();
            vo.setName(fileInfo.getFilename());
            return ActionResult.success(vo);
        } else {
            return ActionResult.fail(MsgCode.ETD110.get());
        }
    }

    @Operation(summary = "导入预览")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "fileName", description = "文件名"),
    })
    @GetMapping("/{modelId}/ImportPreview")
    public ActionResult<Map<String, Object>> ImportPreview(@PathVariable("modelId") String modelId, String fileName)
            throws Exception {
        StpUtil.checkPermission(modelId);

        Map<String, Object> previewMap = null;
        try {
            VisualdevReleaseEntity entity = visualdevReleaseService.getById(modelId);
            ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(entity.getColumnData(), ColumnDataModel.class);
            if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
                StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_UPLOAD);
            }
            FormDataModel formDataModel = JsonUtil.getJsonToBean(entity.getFormData(), FormDataModel.class);
            UploaderTemplateModel uploaderTemplateModel = JsonUtil
                    .getJsonToBean(columnDataModel.getUploaderTemplateJson(), UploaderTemplateModel.class);
            List<FieLdsModel> fieLdsModels = JsonUtil.getJsonToList(formDataModel.getFields(), FieLdsModel.class);
            List<FieLdsModel> allFields = new ArrayList<>();
            OnlinePublicUtils.recursionFormFields(allFields, fieLdsModels);

            List<String> selectKey = uploaderTemplateModel.getSelectKey();

            // 子表tableField
            Set<String> tablefield1 = selectKey.stream()
                    .filter(s -> s.toLowerCase().startsWith(YunzhupaasKeyConsts.CHILD_TABLE_PREFIX))
                    .map(s -> s.substring(0, s.indexOf("-"))).collect(Collectors.toSet());

            String filePath = FileUploadUtils.getLocalBasePath() + configValueUtil.getTemporaryFilePath();
            FileUploadUtils.downLocal(configValueUtil.getTemporaryFilePath(), filePath, fileName);
            File temporary = new File(XSSEscape.escapePath(filePath + fileName));
            // 判断有无子表
            String tablefield = selectKey.stream()
                    .filter(s -> s.toLowerCase().startsWith(YunzhupaasKeyConsts.CHILD_TABLE_PREFIX)).findFirst()
                    .orElse(null);
            // 判断有没有复杂表头
            boolean hasComplex = false;
            for (HeaderModel item : columnDataModel.getComplexHeaderList()) {
                if (item.getChildColumns() != null && item.getChildColumns().size() > 0) {
                    List<String> childColumns = new ArrayList<>(item.getChildColumns());
                    childColumns.retainAll(selectKey);
                    if (childColumns.size() > 0)
                        hasComplex = true;
                }
            }
            // 有子表需要取第二行的表头
            Integer i = tablefield != null || hasComplex ? 2 : 1;
            // 读取excel中数据
            InputStream inputStream = ExcelUtil.solveOrginTitle(temporary, i);
            List<Map> excelDataList = ExcelUtil.importExcelByInputStream(inputStream, 0, i, Map.class);
            // 数据超过100条
            if (excelDataList != null && excelDataList.size() > 1000) {
                return ActionResult.fail(MsgCode.ETD117.get());
            }
            // todo 备用方案，读取不到时间暂用此方法
            ExcelUtil.imoportExcelToMap(temporary, i, excelDataList);
            // 列表字段
            List<Map<String, Object>> columns = new ArrayList<>();
            List<ImportExcelFieldModel> chiImList = new ArrayList<>();
            List<ImportExcelFieldModel> allImList = new ArrayList<>();
            selectKey.stream().forEach(s -> {
                String requiredStr = "";
                ImportExcelFieldModel importExcel = new ImportExcelFieldModel();
                if (s.toLowerCase().startsWith(YunzhupaasKeyConsts.CHILD_TABLE_PREFIX)) {
                    String table = s.substring(0, s.indexOf("-"));
                    String field = s.substring(s.indexOf("-") + 1);
                    FieLdsModel fieLdsModel = allFields.stream().filter(t -> t.getVModel().equals(table)).findFirst()
                            .orElse(null);
                    List<FieLdsModel> children = fieLdsModel.getConfig().getChildren();
                    FieLdsModel fieLdsModel1 = children.stream().filter(t -> t.getVModel().equals(field)).findFirst()
                            .orElse(null);
                    requiredStr = fieLdsModel1.getConfig().isRequired() ? "*" : "";
                    importExcel.setField(field);
                    importExcel.setTableField(table);
                    importExcel.setFullName(requiredStr + fieLdsModel1.getConfig().getLabel());
                    importExcel.setYunzhupaasKey(fieLdsModel1.getConfig().getYunzhupaasKey());
                    chiImList.add(importExcel);
                } else {
                    FieLdsModel fieLdsModel = allFields.stream().filter(t -> t.getVModel().equals(s)).findFirst()
                            .orElse(null);
                    requiredStr = fieLdsModel.getConfig().isRequired() ? "*" : "";
                    importExcel.setField(s);
                    importExcel.setFullName(requiredStr + fieLdsModel.getConfig().getLabel());
                    importExcel.setYunzhupaasKey(fieLdsModel.getConfig().getYunzhupaasKey());
                    allImList.add(importExcel);
                }
            });
            Map<String, List<ImportExcelFieldModel>> groups = chiImList.stream().collect(Collectors
                    .groupingBy(ImportExcelFieldModel::getTableField, LinkedHashMap::new, Collectors.toList()));

            for (Map.Entry<String, List<ImportExcelFieldModel>> entry : groups.entrySet()) {
                ImportExcelFieldModel importExcel = new ImportExcelFieldModel();

                List<ImportExcelFieldModel> value = entry.getValue();
                ImportExcelFieldModel im = value.get(0);
                FieLdsModel fieLdsModel = allFields.stream().filter(f -> entry.getKey().equals(f.getVModel()))
                        .findFirst().orElse(null);
                String tableName = fieLdsModel.getConfig().getLabel();
                importExcel.setField(entry.getKey());
                importExcel.setFullName(tableName);
                importExcel.setYunzhupaasKey("table");
                // value.stream().forEach(im1->im1.setFullName(im1.getFullName().replace(tableName+"-","")));
                importExcel.setChildren(value);
                allImList.add(importExcel);
            }

            for (ImportExcelFieldModel importExcel : allImList) {
                Map<String, Object> selectMap = new HashMap<>(16);
                selectMap.put("id", importExcel.getField());
                selectMap.put("fullName", importExcel.getFullName());
                selectMap.put("yunzhupaasKey", importExcel.getYunzhupaasKey());
                if (importExcel.getChildren() != null) {
                    List<ImportExcelFieldModel> children = importExcel.getChildren();
                    List<Map<String, Object>> childMapList = new ArrayList<>();
                    for (ImportExcelFieldModel childIm : children) {
                        Map<String, Object> childMap = new HashMap<>(16);
                        childMap.put("id", childIm.getField());
                        childMap.put("fullName", childIm.getFullName());
                        childMap.put("yunzhupaasKey", childIm.getYunzhupaasKey());
                        childMapList.add(childMap);
                    }
                    selectMap.put("children", childMapList);
                }
                columns.add(selectMap);
            }

            List<Map<String, Object>> results = FormExecelUtils.dataMergeChildTable(excelDataList, selectKey);

            previewMap = new HashMap<>();
            // 复杂表头-表头和数据处理
            List<HeaderModel> complexHeaderList = columnDataModel.getComplexHeaderList();
            if (!Objects.equals(columnDataModel.getType(), 3) && !Objects.equals(columnDataModel.getType(), 5)) {
                columns = VisualUtils.complexHeaderHandelOnline(columns, complexHeaderList);
            }
            previewMap.put("dataRow", results);
            previewMap.put("headerRow", columns);
        } catch (Exception e) {
            e.printStackTrace();
            return ActionResult.fail(MsgCode.VS407.get());
        }
        return ActionResult.success(previewMap);
    }

    @Operation(summary = "导出异常报告")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "visualImportModel", description = "导出参数"),
    })
    @PostMapping("/{modelId}/ImportExceptionData")
    public ActionResult<DownloadVO> ImportExceptionData(@PathVariable("modelId") String modelId,
            @RequestBody VisualImportModel visualImportModel) {
        StpUtil.checkPermission(modelId);
        String menuFullName = "";
        if (StringUtil.isNotEmpty(visualImportModel.getMenuId())) {
            ModuleEntity menuInfo = moduleService.getInfo(visualImportModel.getMenuId());
            if (menuInfo != null && StringUtil.isNotEmpty(menuInfo.getFullName())) {
                menuFullName = menuInfo.getFullName();
            }
        }
        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(visualdevEntity.getColumnData(),
                ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + PermissionConst.BTN_DOWNLOAD);
        }
        UploaderTemplateModel uploaderTemplateModel = JsonUtil.getJsonToBean(columnDataModel.getUploaderTemplateJson(),
                UploaderTemplateModel.class);
        List<String> selectKey = uploaderTemplateModel.getSelectKey();
        ExcelModel excelModel = onlineSwapDataUtils.getDefaultValue(visualdevEntity.getFormData(), selectKey);
        DownloadVO vo = VisualUtils.createModelExcel(visualdevEntity, visualImportModel.getList(), selectKey, "错误报告",
                menuFullName + "错误报告", excelModel);
        return ActionResult.success(vo);
    }

    @Operation(summary = "自定义按钮发起审批")
    @Parameters({
            @Parameter(name = "modelId", description = "模板id"),
            @Parameter(name = "visualImportModel", description = "导出参数"),
    })
    @PostMapping("/{modelId}/actionLaunchFlow")
    public ActionResult<DownloadVO> actionLaunchFlow(@PathVariable("modelId") String modelId,
            @RequestBody FlowLaunchModel model) {
        StpUtil.checkPermission(modelId);

        VisualdevEntity visualdevEntity = visualdevService.getReleaseInfo(modelId);
        ColumnDataModel columnDataModel = JsonUtil.getJsonToBean(visualdevEntity.getColumnData(),
                ColumnDataModel.class);
        if (columnDataModel != null && columnDataModel.getUseBtnPermission()) {
            StpUtil.checkPermission(modelId + "::" + model.getBtnCode());
        }
        // 用户列表
        List<String> userList = new ArrayList<>();
        if (Objects.equals(1, model.getCurrentUser())) {
            userList.add(UserProvider.getUser().getUserId());
        }
        if (Objects.equals(1, model.getCustomUser()) && CollectionUtil.isNotEmpty(model.getInitiator())) {
            userList.addAll(userService.getUserIdList(model.getInitiator(), null));
            userList = new ArrayList<>(new HashSet<>(userList));
        }
        // 数据列表
        List<Map<String, Object>> formDataList = new ArrayList<>();
        List<List<TransferModel>> dataList = model.getDataList();
        if (CollectionUtil.isNotEmpty(dataList)) {
            for (List<TransferModel> itemList : dataList) {
                if (CollectionUtil.isNotEmpty(itemList)) {
                    Map<String, Object> map = new HashMap<>();
                    for (TransferModel transferModel : itemList) {
                        map.put(transferModel.getTargetField(), transferModel.getSourceValue());
                    }
                    formDataList.add(map);
                }
            }
        }
        FlowModel flowModel = new FlowModel();
        flowModel.setTemplateId(model.getTemplate());
        flowModel.setUserIds(userList);
        flowModel.setFormDataList(formDataList);
        ActionResult actionResult = taskApi.launchFlow(flowModel);
        if (actionResult == null || !ActionResultCode.Success.getCode().equals(actionResult.getCode())) {
            return ActionResult.fail(actionResult.getMsg());
        }
        return ActionResult.success(actionResult.getMsg());
    }

    @Operation(summary = "根据菜单获取功能配置")
    @Parameters({
            @Parameter(name = "menuId", description = "菜单id"),
    })
    @GetMapping("/Config")
    public ActionResult getConfigByMenu(@RequestParam(value = "menuId", required = false) String menuId,
            @RequestParam(value = "systemId", required = false) String systemId) {
        StpUtil.checkPermissionOr(menuId, "onlineDev.webDesign", "generator.webForm", "generator.flowForm");

        VisualdevReleaseEntity releaseEntity = null;
        ModuleEntity info = moduleService.getInfo(menuId);

        if (info != null && StringUtil.isNotEmpty(info.getPropertyJson())) {
            PropertyJsonModel propertyJsonModel = JsonUtil.getJsonToBean(info.getPropertyJson(),
                    PropertyJsonModel.class);
            String modelId = propertyJsonModel.getModuleId();
            releaseEntity = visualdevReleaseService.getById(modelId);
        }
        if (releaseEntity == null
                || (StringUtil.isNotEmpty(systemId) && !Objects.equals(info.getSystemId(), systemId))) {
            return ActionResult.fail(MsgCode.FA001.get());
        }
        VisualdevEntity entity = JsonUtil.getJsonToBean(releaseEntity, VisualdevEntity.class);

        String s = VisualUtil.checkPublishVisualModel(entity, MsgCode.VS005.get());
        if (s != null) {
            return ActionResult.fail(s);
        }
        DataInfoVO vo = JsonUtil.getJsonToBean(entity, DataInfoVO.class);
        return ActionResult.success(vo);
    }
}
