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");
|
}
|
}
|