许鹏程
2024-11-05 2264630f3bc0483fd432cdd8e85e55abd3c4b10f
commit
已添加5个文件
已修改2个文件
1011 ■■■■■ 文件已修改
pom.xml 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/patch/config/ErrorCode.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/patch/controller/PatchExportController.java 81 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/patch/controller/PatchImportController.java 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/patch/service/PatchExportService.java 372 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/patch/service/PatchImportService.java 466 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/patch/service/idel/IPatchImportService.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pom.xml
@@ -30,7 +30,15 @@
        </dependency>
        <dependency>
            <groupId>com.lx</groupId>
            <artifactId>product-server-file</artifactId>
        </dependency>
        <dependency>
            <groupId>com.lx</groupId>
            <artifactId>product-server-tool-table</artifactId>
        </dependency>
        <dependency>
            <groupId>com.lx</groupId>
            <artifactId>product-server-admin</artifactId>
        </dependency>
    </dependencies>
</project>
src/main/java/com/product/patch/config/ErrorCode.java
@@ -31,6 +31,8 @@
    SYNC_DB_FIELD_2_CACHE_TABLE("将数据库表结构字段同步至缓存字段表字段失败", ModuleEnum.PATCH.getValue() + "104"),
    //获取表字段参照失败
    GET_TABLE_FIELD_REFERENCE_FAIL("获取表字段参照失败", ModuleEnum.PATCH.getValue() + "105"),
    ;
    private String text;
src/main/java/com/product/patch/controller/PatchExportController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,81 @@
package com.product.patch.controller;
import com.product.common.utils.StringUtils;
import com.product.core.cache.DataPoolCacheImpl;
import com.product.core.entity.DataTableEntity;
import com.product.core.entity.FieldSetEntity;
import com.product.core.exception.BaseException;
import com.product.module.sys.version.ApiVersion;
import com.product.patch.config.ErrorCode;
import com.product.patch.service.PatchExportService;
import com.product.util.BaseUtil;
import com.product.util.support.AbstractBaseController;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
/**
 * @Author cheng
 * @Date 2024/10/23 10:05
 * @Desc è¡¥ä¸å¯¼å‡º
 */
@RestController
@RequestMapping("/api/patch/export")
public class PatchExportController extends AbstractBaseController {
    @Resource
    private PatchExportService patchExportService;
    @PostMapping("/get-table-field-reference/{version}")
    @ApiVersion(1)
    public String getTableFieldReference(HttpServletRequest request) {
        try {
            FieldSetEntity fse = BaseUtil.getFieldSetEntity(request);
            String tableUuid = fse.getString("table_uuid");
            String[] uuids = tableUuid.split(",");
            DataTableEntity fields = new DataTableEntity();
            for (String uuid : uuids) {
                DataTableEntity f = DataPoolCacheImpl.getInstance().getCacheData("所有字段信息并按表分组", new String[]{uuid});
                BaseUtil.dataTableMerge(fields, f);
            }
            List<String> result = new ArrayList<>();
            for (int i = 0; i < fields.getRows(); i++) {
                if (StringUtils.isEmpty(fields.getString(i, "field_reference"))) {
                    result.add(fields.getString(i, "field_reference"));
                }
            }
            return BaseUtil.success(result);
        } catch (BaseException e) {
            return error(e);
        } catch (Exception e) {
            e.printStackTrace();
            return error(ErrorCode.GET_TABLE_FIELD_REFERENCE_FAIL, e);
        }
    }
    @PostMapping("/execute/{version}")
    @ApiVersion(1)
    public String exportPath(HttpServletRequest request, HttpServletResponse response) {
        try {
            FieldSetEntity fse = BaseUtil.getFieldSetEntity(request);
            patchExportService.export(fse, response);
            return OK();
        } catch (BaseException e) {
            return error(e);
        } catch (Exception e) {
            e.printStackTrace();
            return error(ErrorCode.EXTRACT_FAIL, e);
        }
    }
}
src/main/java/com/product/patch/controller/PatchImportController.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
package com.product.patch.controller;
import com.product.core.config.CoreConst;
import com.product.core.entity.FieldSetEntity;
import com.product.core.entity.RequestParameterEntity;
import com.product.core.exception.BaseException;
import com.product.module.sys.version.ApiVersion;
import com.product.patch.config.ErrorCode;
import com.product.patch.service.idel.IPatchImportService;
import com.product.util.BaseUtil;
import com.product.util.support.AbstractBaseController;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.Map;
/**
 * @Author cheng
 * @Date 2024/10/24 18:22
 * @Desc è¡¥ä¸å¯¼å…¥
 */
@RestController
@RequestMapping("/api/patch/import")
public class PatchImportController extends AbstractBaseController {
    @Resource
    public IPatchImportService patchImportService;
    @PostMapping("/upload/{version}")
    @ApiVersion(1)
    public String upload(HttpServletRequest request) {
        try {
            RequestParameterEntity rpe = null;
            Object bean = request.getAttribute(CoreConst.API_POST_REQUEST_DATA);
            if (bean != null) {
                rpe = (RequestParameterEntity) bean;
            }
            FieldSetEntity fse = rpe.getFormData();
            String fileName = fse.getString("patchFile");
            if (rpe == null || rpe.getFormData() == null || rpe.getFiles() == null || rpe.getFiles().isEmpty() || rpe.getFiles().get(fileName) == null) {
                throw new BaseException(ErrorCode.SYSTEM_FORM_COUNT);
            }
            File patchFile = rpe.getFiles().get(fileName);
            IPatchImportService service = (IPatchImportService) getProxyInstance(patchImportService);
            Map<String, Object> result = service.uploadPatchFile(patchFile);
            return BaseUtil.success(result);
        } catch (BaseException e) {
            e.printStackTrace();
            return error(e);
        } catch (Exception e) {
            e.printStackTrace();
            return error(ErrorCode.EXTRACT_FAIL, e);
        }
    }
}
src/main/java/com/product/patch/service/PatchExportService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,372 @@
package com.product.patch.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.product.core.cache.DataPoolCacheImpl;
import com.product.core.config.CoreConst;
import com.product.core.config.Global;
import com.product.core.entity.DataTableEntity;
import com.product.core.entity.FieldSetEntity;
import com.product.core.service.support.AbstractBaseService;
import com.product.file.service.FileManagerService;
import com.product.patch.config.CmnConst;
import com.product.patch.config.ErrorCode;
import com.product.tool.table.enums.FieldType;
import com.product.util.BaseUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.*;
/**
 * @Author cheng
 * @Date 2024/10/23 10:07
 * @Desc è¡¥ä¸å¯¼å‡º
 */
@Service
public class PatchExportService extends AbstractBaseService {
    @Resource
    private FileManagerService fileManagerService;
    public void export(FieldSetEntity fse, HttpServletResponse response) throws IOException {
        Set<String> promptNameSet = new HashSet<>();
        Set<String> dictNameSet = new HashSet<>();
        String checkedTable = fse.getString("checkedTable");
        JSONArray tables = null;
        if (!StringUtils.isEmpty(checkedTable)) {
            tables = JSONArray.parseArray(checkedTable);
        }
        String exportData = fse.getString("exportData");
        JSONObject exportDataObj = null;
        if (!StringUtils.isEmpty(exportData)) {
            exportDataObj = JSONArray.parseObject(exportData);
        }
        String exportFunction = fse.getString("exportFunction");
        JSONArray exportFunctionArr = null;
        if (!StringUtils.isEmpty(exportFunction)) {
            exportFunctionArr = JSONArray.parseArray(exportFunction);
        }
        String exportFace = fse.getString("exportFace");
        JSONArray exportFaceArr = null;
        if (!StringUtils.isEmpty(exportFace)) {
            exportFaceArr = JSONArray.parseArray(exportFace);
        }
        String exportFlow = fse.getString("exportFlow");
        JSONArray exportFlowArr = null;
        if (!StringUtils.isEmpty(exportFlow)) {
            exportFlowArr = JSONArray.parseArray(exportFlow);
        }
        String exportReference = fse.getString("exportReference");
        JSONObject exportReferenceObj = null;
        if (!StringUtils.isEmpty(exportReference)) {
            exportReferenceObj = JSONArray.parseObject(exportReference);
        }
        String tempDir = Global.getSystemConfig("temp.dir", "./attachment/file/temp");
        //生成本次补丁文件夹 æ‰€æœ‰äº§ç”Ÿçš„临时文件放入该文件夹下 æ–¹ä¾¿åˆ é™¤
        File currentDir = new File(tempDir + "/" + getDateTime());
        File tableStructureFile = exportTable(currentDir, tables, promptNameSet, dictNameSet);
        DataTableEntity attachments = new DataTableEntity();
        File dataZipFile = exportBusinessData(currentDir, exportDataObj, attachments);
        File functionFile = exportFunction(currentDir, exportFunctionArr);
        File faceFile = exportFace(currentDir, exportFaceArr, promptNameSet, dictNameSet);
        File flowFile = exportFlow(currentDir, exportFlowArr, attachments);
        File referenceFile = exportReference(currentDir, exportReferenceObj);
        String zipFileName = currentDir + "/lx_" + getDateTime() + ".patch";
        List<File> fileList = new ArrayList<>();
        if (tableStructureFile != null) {
            fileList.add(tableStructureFile);
        }
        if (dataZipFile != null) {
            fileList.add(dataZipFile);
        }
        if (functionFile != null) {
            fileList.add(functionFile);
        }
        if (faceFile != null) {
            fileList.add(faceFile);
        }
        if (flowFile != null) {
            fileList.add(flowFile);
        }
        if (referenceFile != null) {
            fileList.add(referenceFile);
        }
        File attachment = exportAttachment(currentDir, attachments);
        if (attachment != null) {
            fileList.add(attachment);
        }
        File zip = ZipUtil.zip(new File(zipFileName), Charset.defaultCharset(), false, fileList.toArray(new File[0]));
        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setHeader("Content-Disposition", "attachment; filename=" + zip.getName());
        response.setContentType("application/octet-stream");
        response.setContentLengthLong(zip.length());
        OutputStream out = response.getOutputStream();
        try {
            FileUtil.writeToStream(zip, out);
        } catch (Exception e) {
            e.printStackTrace();
            //异常时输出类型改为json
            response.setContentType("application/json");
            Map<String, Object> result = new HashMap<>();
            result.put("code", ErrorCode.EXTRACT_FAIL.getValue());
            result.put("msg", ErrorCode.EXTRACT_FAIL.getText());
            result.put("status", "fail");
            IoUtil.write(out, Charset.defaultCharset(), false, JSONObject.toJSONString(result));
            logger.error("导出补丁文件异常", e);
        }
        out.flush();
        out.close();
        FileUtil.del(currentDir);
    }
    private File writeString(DataTableEntity dte, String fileName, File dir) {
        if (DataTableEntity.isEmpty(dte) || StringUtils.isEmpty(fileName)) {
            return null;
        }
        if (!fileName.startsWith("/") && !fileName.startsWith("\\")) {
            fileName = "/" + fileName;
        }
        JSONArray objects = BaseUtil.dataTableEntityToJson(dte);
        //将数据导出到文件
        String data = objects.toJSONString();
        File touch = FileUtil.touch(dir, fileName);
        FileUtil.writeString(data, touch, "UTF-8");
        return touch;
    }
    public File exportReference(File dir, JSONObject exportReferenceObj) {
        if (exportReferenceObj == null) {
            return null;
        }
        //创建文件夹
        File referenceDir = new File(dir.getPath() + File.separator + "reference");
        if (!referenceDir.exists()) {
            referenceDir.mkdirs();
        }
        JSONArray prompt = exportReferenceObj.getJSONArray("prompt");
        JSONArray dict = exportReferenceObj.getJSONArray("dict");
        if (prompt != null && prompt.size() > 0) {
            DataTableEntity dte = getBaseDao().listTable("product_sys_prompt", BaseUtil.buildQuestionMarkFilter("prompt_name", prompt.size(), true), prompt.toArray());
            writeString(dte, "prompt_" + getDateTime(), referenceDir);
        }
        if (dict != null && dict.size() > 0) {
            DataTableEntity dte = getBaseDao().listTable("product_sys_dict", BaseUtil.buildQuestionMarkFilter("dict_name", dict.size(), true), dict.toArray());
            writeString(dte, "dict_" + getDateTime(), referenceDir);
        }
        if (referenceDir.list().length > 0) {
            return ZipUtil.zip(referenceDir);
        }
        return null;
    }
    /**
     * å¯¼å‡ºè¡¨ç»“æž„ åŒ…含索引
     * @param dir
     * @param tableInfoArr
     * @return
     */
    public File exportTable(File dir, JSONArray tableInfoArr, Set<String> promptNameSet, Set<String> dictNameSet) {
        DataTableEntity tableDte = getBaseDao().listTable(CoreConst.PRODUCT_SYS_DATAMODEL_TABLE, BaseUtil.buildQuestionMarkFilter("table_name", tableInfoArr.size(), true), tableInfoArr.stream().toArray(),
                new Object[]{}, null, Integer.MAX_VALUE, 1, true);
        return writeString(tableDte, "table_" + getDateTime(), dir);
    }
    /**
     * å¯¼å‡ºä¸šåŠ¡æ•°æ®
     * @param dir
     * @param exportDataObj
     * @return
     */
    public File exportBusinessData(File dir, JSONObject exportDataObj, DataTableEntity attachments) {
        if (exportDataObj == null) {
            return null;
        }
        Set<String> tableNameSet = exportDataObj.keySet();
        if (CollectionUtil.isEmpty(tableNameSet)) {
            return null;
        }
        List<File> fileList = new ArrayList<>();
        for (String tableName : tableNameSet) {
            JSONObject conf = exportDataObj.getJSONObject(tableName);
            // 0 å¿½ç•¥æ•°æ® 1 å¯¼å‡ºå…¨éƒ¨æ•°æ® 2 å¯¼å‡ºæŒ‡å®šæ•°æ®
            String dataExportType = conf.getString("dataExportType");
            if ("0".equals(dataExportType)) {
                continue;
            }
            String filter = null;
            Object[] params = null;
            if ("2".equals(dataExportType)) {
                JSONArray selectionData = conf.getJSONArray("selectionData");
                if (selectionData == null || selectionData.isEmpty()) {
                    continue;
                }
                filter = BaseUtil.buildQuestionMarkFilter("uuid", selectionData.size(), true);
                params = selectionData.stream().toArray();
            }
            DataTableEntity dte = getBaseDao().listTable(tableName, filter, params);
            if (DataTableEntity.isEmpty(dte)) {
                continue;
            }
            DataTableEntity dt = getAttachmentData(dte);
            if (!DataTableEntity.isEmpty(dt)) {
                BaseUtil.dataTableMerge(attachments, dt);
            }
            File file = writeString(dte, "data_" + tableName + "_" + getDateTime(), dir);
            fileList.add(file);
        }
        //压缩文件
        File[] array = fileList.toArray(new File[]{});
        File zip = new File(dir.getPath() + "/table_data" + getDateTime() + ".zip");
        ZipUtil.zip(zip, Charset.defaultCharset(), false, array);
        return zip;
    }
    /**
     * å¯¼å‡ºåŠŸèƒ½
     * @param dir
     * @param exportFunctionArr
     * @return
     */
    public File exportFunction(File dir, JSONArray exportFunctionArr) {
        if (exportFunctionArr == null || exportFunctionArr.isEmpty()) {
            return null;
        }
        DataTableEntity functionDte = getBaseDao().listTable(CoreConst.PRODUCT_SYS_FUNCTIONS, BaseUtil.buildQuestionMarkFilter("uuid", exportFunctionArr.size(), true), exportFunctionArr.stream().toArray(),
                new Object[]{}, null, Integer.MAX_VALUE, 1, true);
        return writeString(functionDte, "function_" + getDateTime(), dir);
    }
    public File exportFlow(File dir, JSONArray exportFlowArr, DataTableEntity attachments) {
        if (exportFlowArr == null || exportFlowArr.isEmpty()) {
            return null;
        }
        DataTableEntity flowDte = getBaseDao().listTable(CmnConst.TABLE_PRODUCT_SYS_FLOW_MODEL, BaseUtil.buildQuestionMarkFilter("type_code", exportFlowArr.size(), true), exportFlowArr.stream().toArray(),
                new Object[]{}, null, Integer.MAX_VALUE, 1, true);
        return writeString(flowDte, "flow_" + getDateTime(), dir);
    }
    public File exportFace(File dir, JSONArray exportFaceArr, Set<String> promptNameSet, Set<String> dictNameSet) {
        if (exportFaceArr == null || exportFaceArr.isEmpty()) {
            return null;
        }
        DataTableEntity faceDte = getBaseDao().listTable("product_sys_face", BaseUtil.buildQuestionMarkFilter("face_number", exportFaceArr.size(), true), exportFaceArr.stream().toArray(),
                new Object[]{}, null, Integer.MAX_VALUE, 1, true);
        return writeString(faceDte, "face_" + getDateTime(), dir);
    }
    public File exportAttachment(File dir, DataTableEntity attachments) {
        if (DataTableEntity.isEmpty(attachments)) {
            return null;
        }
        File attachmentDir = new File(dir.getPath() + File.separator + "/attachment");
        for (int i = 0; i < attachments.getRows(); i++) {
            FieldSetEntity fieldSetEntity = attachments.getFieldSetEntity(i);
            try {
                File file = fileManagerService.getFile(fieldSetEntity);
                if (file != null && file.isFile()) {
                    File tempFile = new File(attachmentDir.getPath() + File.separator + fieldSetEntity.getString("attachment_title"));
                    if (!tempFile.getParentFile().exists()) {
                        tempFile.getParentFile().mkdirs();
                    }
                    if (!tempFile.exists()) {
                        tempFile.createNewFile();
                    }
                    FileUtil.copy(file, tempFile, true);
                    FileUtil.del(file);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        JSONArray objects = BaseUtil.dataTableEntityToJson(attachments);
        String data = objects.toJSONString();
        File touch = FileUtil.touch(dir, "/attachment_data" + getDateTime());
        FileUtil.writeString(data, touch, "UTF-8");
        File zip = ZipUtil.zip(new File(dir.getPath() + "/attachment" + getDateTime() + ".zip"), Charset.defaultCharset(), true, touch, attachmentDir);
        return zip;
    }
    private DataTableEntity getAttachmentData(DataTableEntity dte) {
        if (DataTableEntity.isEmpty(dte)) {
            return null;
        }
        String tableName = dte.getTableName().toString();
        FieldSetEntity tableInfo = BaseUtil.getSingleInfoByCache("所有表信息", new String[]{tableName});
        if (FieldSetEntity.isEmpty(tableInfo)) {
            return null;
        }
        String tableUuid = tableInfo.getString("uuid");
        DataTableEntity fieldDte = DataPoolCacheImpl.getInstance().getCacheData("所有字段信息并按表分组", new String[]{tableUuid});
        //获取所有附件字段
        Set<String> attachmentField = new HashSet<>();
        for (int i = 0; i < fieldDte.getRows(); i++) {
            String fieldType = fieldDte.getString(i, "field_type");
            if (FieldType.FILE.equals(FieldType.getByDictValue(fieldType))) {
                attachmentField.add(fieldDte.getString(i, "field_name"));
            }
        }
        if (CollectionUtil.isEmpty(attachmentField)) {
            return null;
        }
        Set<String> fileUuidSet = new HashSet<>();
        for (int i = 0; i < dte.getRows(); i++) {
            for (String field : attachmentField) {
                String fileUuid = dte.getString(i, field);
                if (StringUtils.isEmpty(fileUuid)) {
                    continue;
                }
                fileUuidSet.add(fileUuid);
            }
        }
        if (CollectionUtil.isEmpty(fileUuidSet)) {
            return null;
        }
        return getBaseDao().listTable("product_sys_attachments", BaseUtil.buildQuestionMarkFilter("uuid", fileUuidSet.size(), true), fileUuidSet.toArray());
    }
    private String getDateTime() {
        return DateTime.now().toString("yyyyMMddHHmmss");
    }
}
src/main/java/com/product/patch/service/PatchImportService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,466 @@
package com.product.patch.service;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Sets;
import com.product.admin.service.PublicService;
import com.product.common.utils.StringUtils;
import com.product.core.config.CoreConst;
import com.product.core.config.Global;
import com.product.core.entity.DataTableEntity;
import com.product.core.entity.FieldSetEntity;
import com.product.core.exception.BaseException;
import com.product.core.service.support.AbstractBaseService;
import com.product.core.transfer.Transactional;
import com.product.core.util.JsonUtil;
import com.product.patch.config.CmnConst;
import com.product.patch.service.idel.IPatchImportService;
import com.product.tool.table.service.DataModelService;
import com.product.util.BaseUtil;
import com.sun.xml.internal.bind.v2.TODO;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.StandardCopyOption;
import java.util.*;
/**
 * @Author cheng
 * @Date 2024/10/23 10:07
 * @Desc è¡¥ä¸å¯¼å‡º
 */
@Service
public class PatchImportService extends AbstractBaseService implements IPatchImportService {
    @Resource
    private PublicService publicService;
    @Resource
    private DataModelService dataModelService;
    @Override
    @Transactional
    public Map<String, Object> uploadPatchFile(File patchFile) throws Exception {
        Map<String, Object> result = new HashMap<>();
        File patchDir = ZipUtil.unzip(patchFile);
        //获取文件夹下的所有文件
        File[] files = patchDir.listFiles();
        //文件排序将zip排到最后
        Arrays.sort(files, (a, v) -> {
            if (a.getName().endsWith(".zip")) {
                return 1;
            } else {
                return -1;
            }
        });
        for (File file : files) {
            if (!file.isFile()) {
                continue;
            }
            String fileName = file.getName();
            if (fileName.startsWith("face_")) {
                //表单
                readFaceData(file);
            } else if (fileName.startsWith("flow_")) {
                //流程
                readFlowData(file);
            } else if (fileName.startsWith("function_")) {
                //功能
                readFunctionData(file);
            } else if (fileName.startsWith("structure_")) {
                //数据表
                readTableStructure(file);
            } else if (fileName.startsWith("attachment") && fileName.endsWith(".zip")) {
                //附件
                readAttachment(file);
            } else if (fileName.startsWith("table_data") && fileName.endsWith(".zip")) {
                //数据
                readTableData(file);
            } else if (fileName.startsWith("reference") && fileName.endsWith(".zip")) {
                //参照
                readReference(file);
            }
        }
        return result;
    }
    /**
     * è¯»å–参照
     */
    private Integer readReference(File file) throws Exception {
        if (!file.isFile()) {
            return 0;
        }
        File unzip = ZipUtil.unzip(file);
        //解压的文件下 æœ‰ prompt æ–‡ä»¶ å’Œ dict æ–‡ä»¶ åœ¨ç›®å½•下找到这两个文件
        File dict = new File(unzip.getPath() + File.separator + "dict");
        File prompt = new File(unzip.getPath() + File.separator + "prompt");
        DataTableEntity dictDte = readFileData(dict, "product_sys_dict");
        DataTableEntity promptDte = readFileData(prompt, "product_sys_prompt");
        return addOrUpdate(dictDte) + addOrUpdate(promptDte);
    }
    private Integer addOrUpdate(DataTableEntity dte) {
        if (DataTableEntity.isEmpty(dte)) {
            return 0;
        }
        String tableName = dte.getTableName().toString();
        //获取uuid
        Object[] uuids = dte.getUuids();
        DataTableEntity dte1 = getBaseDao().listTable(tableName, BaseUtil.buildQuestionMarkFilter("uuid", uuids.length, true), uuids);
        Set<String> subTableNames = Sets.newHashSet();
        for (int i = 0; i < dte.getRows(); i++) {
            String uuid = dte1.getString(i, CoreConst.UUID);
            FieldSetEntity ff = dte1.getFieldSetEntity(i);
            if (ff.getSubData() != null) {
                subTableNames.addAll(ff.getSubData().keySet());
            }
            List<FieldSetEntity> fieldSetEntity = dte1.getFieldSetEntity(uuid);
            if (!CollectionUtil.isEmpty(fieldSetEntity)) {
                continue;
            }
            FieldSetEntity fse = fieldSetEntity.get(0);
            fse.setValue(CoreConst.SYSTEM_DATA_OPERATE_TYPE, CoreConst.SYSTEM_DATA_OPERATE_ADD);
        }
        for (String subTableName : subTableNames) {
            FieldSetEntity info = BaseUtil.getSingleInfoByCache("所有表信息", new String[]{subTableName});
            if (info == null) {
                continue;
            }
            FieldSetEntity info1 = BaseUtil.getSingleInfoByCache("所有表关联信息", new String[]{info.getUUID()});
            if (FieldSetEntity.isEmpty(info1)) {
                continue;
            }
            getBaseDao().delete(subTableName, BaseUtil.buildQuestionMarkFilter(info1.getString("field_name"), dte1.getRows(), true), uuids);
        }
        getBaseDao().update(dte);
        return dte.getRows();
    }
    /**
     * è¯»å–表结构数据
     * @param file
     * @return
     * @throws Exception
     */
    private DataTableEntity readTableStructure(File file) throws Exception {
        DataTableEntity dte = readFileData(file, "product_sys_datamodel_table");
        DataTableEntity old = getBaseDao().listTable("product_sys_datamodel_table", BaseUtil.buildQuestionMarkFilter("uuid", dte.getUuids().length, true), dte.getUuids(), null, null, Integer.MAX_VALUE, 1, true);
        for (int i = 0; i < dte.getRows(); i++) {
            FieldSetEntity fse = dte.getFieldSetEntity(i);
            //查询出不存在的索引和字段
            if (old != null && old.getRows() > 0) {
                List<FieldSetEntity> oldf = old.getFieldSetEntity(fse.getString("uuid"));
                if (CollectionUtil.isEmpty(oldf)) {
                    //记录不存在 ã€æ–°è¡¨
                    continue;
                }
                FieldSetEntity oldFse = oldf.get(0);
                //对比索引和字段
                String[] table = {"product_sys_datamodel_field", "product_sys_datamodel_index"};
                for (String t : table) {
                    DataTableEntity sub = fse.getSubDataTable(t);
                    DataTableEntity oldSub = oldFse.getSubDataTable(t);
                    if (DataTableEntity.isEmpty(oldSub)) {
                        continue;
                    }
                    // è¡¥ä¸ä¸­å­è¡¨ä¸ºç©º åˆ™å…¨åˆ é™¤
                    if (DataTableEntity.isEmpty(sub)) {
                        sub = old.clones();
                        //设置为删除
                        for (int i1 = 0; i1 < sub.getRows(); i1++) {
                            sub.setFieldValue(i1, CoreConst.SYSTEM_DATA_OPERATE_TYPE, CoreConst.SYSTEM_DATA_OPERATE_DEL);
                        }
                        continue;
                    }
                    //删除当前已存在的字段但补丁中没有的
                    for (int i1 = 0; i1 < oldSub.getRows(); i1++) {
                        FieldSetEntity oldFse1 = oldSub.getFieldSetEntity(i1);
                        List<FieldSetEntity> fieldSetEntity = sub.getFieldSetEntity(oldFse1.getString("uuid"));
                        if (CollectionUtil.isEmpty(fieldSetEntity)) {
                            //不存在
                            FieldSetEntity clones = oldFse1.clones();
                            clones.setValue(CoreConst.SYSTEM_DATA_OPERATE_TYPE, CoreConst.SYSTEM_DATA_OPERATE_DEL);
                            sub.addFieldSetEntity(clones);
                        }
                    }
                }
            }
            //调用数据建模统一操作方法
            dataModelService.dataModelOperation(fse);
        }
        return null;
    }
    /**
     * è¯»å–流程配置
     * @param file
     * @return
     * @throws Exception
     */
    private Integer readFlowData(File file) throws Exception {
        DataTableEntity dataTableEntity = readFileData(file, "product_sys_flow");
        return addOrUpdate(dataTableEntity);
    }
    /**
     * è¯»å–功能配置
     * @param file
     * @return
     * @throws Exception
     */
    private int readFunctionData(File file) throws Exception {
        DataTableEntity dte = readFileData(file, "product_sys_functions");
        //判断是否已经存在 ä¸” tricode ä¸ä¸€è‡´
        if (DataTableEntity.isEmpty(dte)) {
            return 0;
        }
        String tableName = dte.getTableName().toString();
        //获取uuid
        Object[] uuids = dte.getUuids();
        DataTableEntity dte1 = getBaseDao().listTable(tableName, BaseUtil.buildQuestionMarkFilter("uuid", uuids.length, true), uuids);
        Set<String> subTableNames = Sets.newHashSet();
        for (int i = 0; i < dte.getRows(); i++) {
            String uuid = dte1.getString(i, CoreConst.UUID);
            FieldSetEntity ff = dte1.getFieldSetEntity(i);
            if (ff.getSubData() != null) {
                subTableNames.addAll(ff.getSubData().keySet());
            }
            List<FieldSetEntity> fieldSetEntity = dte1.getFieldSetEntity(uuid);
            if (!CollectionUtil.isEmpty(fieldSetEntity)) {
                //判断tricode æ˜¯å¦ä¸€è‡´
                FieldSetEntity fieldSetEntity1 = fieldSetEntity.get(0);
                String tricode = fieldSetEntity1.getString("tricode");
                String tricode1 = dte.getString(i, "tricode");
                if (StringUtils.isNotEmpty(tricode) && !tricode.equals(tricode1)) {
                    //不一致
                    String triCodeParent = fieldSetEntity1.getString("tricode_parent");
                    String triCodeParent1 = dte.getString(i, "tricode_parent");
                    if (StringUtils.isNotEmpty(triCodeParent) && !triCodeParent.equals(triCodeParent1)) {
                        //拿到已存在的tricode æ›¿æ¢
                        dte.setFieldValue(i, "tricode", tricode);
                        dte.setFieldValue(i, "tricode_parent", triCodeParent);
                        continue;
                    } else {
                        //重新生成
                        dte.setFieldValue(i, "tricode", null);
                        publicService.createdCode(dte.getFieldSetEntity(i), "product_sys_functions", "tricode", "tricode_parent");
                    }
                    continue;
                }
                continue;
            }
            for (String subTableName : subTableNames) {
                FieldSetEntity info = BaseUtil.getSingleInfoByCache("所有表信息", new String[]{subTableName});
                if (info == null) {
                    continue;
                }
                FieldSetEntity info1 = BaseUtil.getSingleInfoByCache("所有表关联信息", new String[]{info.getUUID()});
                if (FieldSetEntity.isEmpty(info1)) {
                    continue;
                }
                getBaseDao().delete(subTableName, BaseUtil.buildQuestionMarkFilter(info1.getString("field_name"), dte1.getRows(), true), uuids);
            }
            FieldSetEntity fse = fieldSetEntity.get(0);
            fse.setValue(CoreConst.SYSTEM_DATA_OPERATE_TYPE, CoreConst.SYSTEM_DATA_OPERATE_ADD);
        }
        getBaseDao().update(dte);
        return dte.getRows();
    }
    /**
     * è¯»å–表单配置
     * @param file
     * @return
     * @throws Exception
     */
    private int readFaceData(File file) throws Exception {
        DataTableEntity dte = readFileData(file, "product_sys_form");
        return addOrUpdate(dte);
    }
    /**
     * æ•°æ®ä¸šåŠ¡è¡¨æ•°æ®
     * @param file
     * @return
     * @throws Exception
     */
    private int readTableData(File file) throws Exception {
        if (!file.isFile()) {
            return 0;
        }
        File fileDir = ZipUtil.unzip(file);
        int result = 0;
        for (File file1 : fileDir.listFiles()) {
            if (!file1.isFile()) {
                continue;
            }
            String fileName = file1.getName();
            //判断文件名是否以data_开头 ä¸­é—´ä»»æ„å­—母+下划线 ç»“尾是 _ + 16位数字
            String regex = "^data_.*_[0-9]{14}$";
            if (!fileName.matches(regex)) {
                continue;
            }
            String tableName = fileName.substring(5, fileName.length() - 15);
            DataTableEntity res = readFileData(file1, tableName);
            if (DataTableEntity.isEmpty(res)) {
                continue;
            }
            result += addOrUpdate(res);
        }
        return result;
    }
    /**
     * è¯»å–附件数据并保存
     * @param file
     * @throws Exception
     */
    private void readAttachment(File file) throws Exception {
        File unzip = ZipUtil.unzip(file);
        //去读文件夹中的文件
        File[] files = unzip.listFiles((v) -> v.isFile());
        if (files.length == 0) {
            return;
        }
        File attachmentFile = files[0];
        String fileName = attachmentFile.getName();
        JSONArray data = null;
        if (fileName.startsWith("attachment_data")) {
            //附件数据
            data = readFileString(attachmentFile);
        } else {
            return;
        }
        if (data == null || data.isEmpty()) {
            return;
        }
        DataTableEntity attachmentDte = toDataTable(data, "product_sys_attachments");
        //去读附件文件
        File attachmentDir = new File(unzip.getPath() + File.separator + "attachment");
        Object[] uuids = attachmentDte.getUuids();
        DataTableEntity dte = getBaseDao().listTable("product_sys_attachments", BaseUtil.buildQuestionMarkFilter("uuid", uuids.length, true), uuids);
        for (int i = 0; i < attachmentDte.getRows(); i++) {
            FieldSetEntity fse = attachmentDte.getFieldSetEntity(i);
            //获取数据对应的附件
            String attachmentTitle = fse.getString("attachment_title");
            File file1 = new File(attachmentDir + File.separator + attachmentTitle);
            if (!file1.isFile()) {
                continue;
            }
            //移动到附件对应的目录
            String path = fse.getString("attachment_url");
            String dir = Global.getSystemConfig("local.dir", "./attachment/file");
            File targetDir = new File(dir + File.separator + path);
            if (!targetDir.exists()) {
                targetDir.mkdirs();
            }
            //复制文件到直接文件夹 å­˜åœ¨æ›¿æ¢
            FileUtil.copyFile(file1, targetDir, StandardCopyOption.REPLACE_EXISTING);
            List<FieldSetEntity> fieldSetEntity = dte.getFieldSetEntity(fse.getUUID());
            if (fieldSetEntity == null || fieldSetEntity.isEmpty()) {
                //新数据
                fse.setValue(CoreConst.SYSTEM_DATA_OPERATE_TYPE, CoreConst.SYSTEM_DATA_OPERATE_ADD);
            }
        }
        getBaseDao().update(attachmentDte);
    }
    /**
     * è¯»å–文件中的数据并转为DataTable
     * @param file
     * @param tableName
     * @return
     * @throws Exception
     */
    private DataTableEntity readFileData(File file, String tableName) throws Exception {
        if (!file.isFile()) {
            return null;
        }
        JSONArray objects = readFileString(file);
        if (objects == null || objects.isEmpty()) {
            return null;
        }
        return toDataTable(objects, tableName);
    }
    /**
     * json数组转DataTable
     * @param arr
     * @param tableName
     * @return
     */
    private DataTableEntity toDataTable(JSONArray arr, String tableName) throws BaseException {
        if (arr == null || arr.isEmpty()) {
            return null;
        }
        DataTableEntity result = new DataTableEntity();
        //遍历json数组
        for (int i = 0; i < arr.size(); i++) {
            FieldSetEntity fse = new FieldSetEntity(tableName);
            JSONObject jsonObject = arr.getJSONObject(i);
            fse.setValues((Map) jsonObject.clone());
            //将json中装载的json对象转成DataTableEntity,遍历json中的内容
            for (String key : jsonObject.keySet()) {
                Object o = jsonObject.get(key);
                if (o instanceof JSONArray) {
                    fse.remove(key);
                    fse.addSubDataTable(toDataTable(jsonObject.getJSONArray(key), key));
                }
            }
            result.addFieldSetEntity(fse);
        }
        return result;
    }
    /**
     * è¯»å–文件中的内容
     * @param file
     * @return
     */
    private JSONArray readFileString(File file) throws Exception {
        if (!file.isFile()) {
            return null;
        }
        try (InputStream in = new FileInputStream(file)) {
            String str = IoUtil.read(in, "UTF-8");
            if (StringUtils.isEmpty(str)) {
                return null;
            }
            return JSONArray.parseArray(str);
        }
    }
    private String getDateTime() {
        return DateTime.now().toString("yyyyMMddHHmmss");
    }
}
src/main/java/com/product/patch/service/idel/IPatchImportService.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,17 @@
package com.product.patch.service.idel;
import java.io.File;
import java.util.Map;
/**
 * @Author cheng
 * @Date 2024/10/23 10:07
 * @Desc è¡¥ä¸å¯¼å‡º
 */
public interface IPatchImportService {
    Map<String, Object> uploadPatchFile(File patchFile) throws Exception;
}