diff --git a/orion-ops-service/src/main/java/com/orion/ops/consts/export/ExportConst.java b/orion-ops-service/src/main/java/com/orion/ops/consts/export/ExportConst.java new file mode 100644 index 00000000..51b72c6d --- /dev/null +++ b/orion-ops-service/src/main/java/com/orion/ops/consts/export/ExportConst.java @@ -0,0 +1,31 @@ +package com.orion.ops.consts.export; + +import com.orion.utils.Strings; +import com.orion.utils.time.Dates; + +/** + * 导出常量 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/5/26 16:14 + */ +public class ExportConst { + + private ExportConst() { + } + + public static final String MACHINE_EXPORT_NAME = "机器导出信息{}.xlsx"; + + + /** + * 格式导出文件名 + * + * @param name name + * @return name + */ + public static String getFileName(String name) { + return Strings.format(name, Dates.current(Dates.YMD_HM2)); + } + +} diff --git a/orion-ops-service/src/main/java/com/orion/ops/consts/export/ExportType.java b/orion-ops-service/src/main/java/com/orion/ops/consts/export/ExportType.java new file mode 100644 index 00000000..26491278 --- /dev/null +++ b/orion-ops-service/src/main/java/com/orion/ops/consts/export/ExportType.java @@ -0,0 +1,39 @@ +package com.orion.ops.consts.export; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 导出类型 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/5/27 17:17 + */ +@AllArgsConstructor +@Getter +public enum ExportType { + + /** + * 导出机器 + */ + MACHINE(10), + + ; + + private final Integer type; + + + public static ExportType of(Integer type) { + if (type == null) { + return null; + } + for (ExportType value : values()) { + if (value.type.equals(type)) { + return value; + } + } + return null; + } + +} diff --git a/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageClassify.java b/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageClassify.java index ba8943a1..97ddf722 100644 --- a/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageClassify.java +++ b/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageClassify.java @@ -19,6 +19,11 @@ public enum MessageClassify { */ SYSTEM(10), + /** + * 数据导入 + */ + IMPORT(20), + ; private final Integer classify; diff --git a/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageType.java b/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageType.java index 644c9ec9..d7f95bf7 100644 --- a/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageType.java +++ b/orion-ops-service/src/main/java/com/orion/ops/consts/message/MessageType.java @@ -14,6 +14,8 @@ import lombok.Getter; @Getter public enum MessageType { + // -------------------- 系统消息 -------------------- + /** * 命令执行完成 */ @@ -84,6 +86,18 @@ public enum MessageType { */ PIPELINE_EXEC_FAILURE(1140, MessageClassify.SYSTEM, "应用流水线 ${name} ${title} 执行失败"), + // -------------------- 导入通知 -------------------- + + /** + * 导入机器成功 + */ + MACHINE_IMPORT_SUCCESS(2010, MessageClassify.IMPORT, "您在 ${time} 进行的机器导入操作执行完成"), + + /** + * 导入机器失败 + */ + MACHINE_IMPORT_FAILURE(2020, MessageClassify.IMPORT, "您在 ${time} 进行的机器导入操作执行失败"), + ; private final Integer type; diff --git a/orion-ops-service/src/main/java/com/orion/ops/controller/DataExportController.java b/orion-ops-service/src/main/java/com/orion/ops/controller/DataExportController.java new file mode 100644 index 00000000..93b30e95 --- /dev/null +++ b/orion-ops-service/src/main/java/com/orion/ops/controller/DataExportController.java @@ -0,0 +1,41 @@ +package com.orion.ops.controller; + +import com.orion.ops.annotation.EventLog; +import com.orion.ops.consts.event.EventType; +import com.orion.ops.consts.export.ExportConst; +import com.orion.ops.entity.request.DataExportRequest; +import com.orion.ops.service.api.DataExportService; +import com.orion.servlet.web.Servlets; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 数据导出 controller + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/5/26 14:02 + */ +@RestController +@RequestMapping("/orion/api/data-export") +public class DataExportController { + + @Resource + private DataExportService dataExportService; + + /** + * 导出机器 + */ + @RequestMapping("/machine") + @EventLog(EventType.DATA_EXPORT_MACHINE) + public void exportMachine(@RequestBody DataExportRequest request, HttpServletResponse response) throws IOException { + Servlets.setDownloadHeader(response, ExportConst.getFileName(ExportConst.MACHINE_EXPORT_NAME)); + dataExportService.exportMachine(request, response); + } + +} diff --git a/orion-ops-service/src/main/java/com/orion/ops/entity/dto/MachineInfoExportDTO.java b/orion-ops-service/src/main/java/com/orion/ops/entity/dto/MachineInfoExportDTO.java new file mode 100644 index 00000000..f622cb9f --- /dev/null +++ b/orion-ops-service/src/main/java/com/orion/ops/entity/dto/MachineInfoExportDTO.java @@ -0,0 +1,87 @@ +package com.orion.ops.entity.dto; + +import com.orion.office.excel.annotation.ExportField; +import com.orion.office.excel.annotation.ExportSheet; +import com.orion.office.excel.annotation.ExportTitle; +import com.orion.ops.consts.machine.MachineAuthType; +import com.orion.ops.entity.domain.MachineInfoDO; +import com.orion.utils.convert.TypeStore; +import lombok.Data; + +/** + * 机器信息导出 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/5/26 14:01 + */ +@Data +@ExportTitle(title = "机器信息导出") +@ExportSheet(name = "机器信息", height = 22, freezeHeader = true, filterHeader = true) +public class MachineInfoExportDTO { + + /** + * 机器名称 + */ + @ExportField(index = 0, header = "机器名称", width = 30) + private String name; + + /** + * 机器标签 + */ + @ExportField(index = 1, header = "唯一标识", width = 25) + private String tag; + + /** + * 机器主机 + */ + @ExportField(index = 2, header = "机器主机", width = 30) + private String host; + + /** + * ssh 端口 + */ + @ExportField(index = 3, header = "ssh 端口", width = 10) + private Integer port; + + /** + * 用户名 + */ + @ExportField(index = 4, header = "用户名", width = 20) + private String username; + + /** + * 密码 (密文) + */ + @ExportField(index = 5, header = "导出密码 (密文)", width = 20, wrapText = true) + private String encryptPassword; + + /** + * 导入密码 (明文) + */ + @ExportField(index = 6, header = "导入密码 (明文)", width = 20, wrapText = true) + private String importPassword; + + /** + * 描述 + */ + @ExportField(index = 7, header = "描述", width = 25, wrapText = true) + private String description; + + static { + TypeStore.STORE.register(MachineInfoDO.class, MachineInfoExportDTO.class, p -> { + MachineInfoExportDTO dto = new MachineInfoExportDTO(); + dto.setName(p.getMachineName()); + dto.setTag(p.getMachineTag()); + dto.setHost(p.getMachineHost()); + dto.setPort(p.getSshPort()); + dto.setUsername(p.getUsername()); + if (MachineAuthType.PASSWORD.getType().equals(p.getAuthType())) { + dto.setEncryptPassword(p.getPassword()); + } + dto.setDescription(p.getDescription()); + return dto; + }); + } + +} diff --git a/orion-ops-service/src/main/java/com/orion/ops/entity/request/DataExportRequest.java b/orion-ops-service/src/main/java/com/orion/ops/entity/request/DataExportRequest.java new file mode 100644 index 00000000..bfaddb2e --- /dev/null +++ b/orion-ops-service/src/main/java/com/orion/ops/entity/request/DataExportRequest.java @@ -0,0 +1,28 @@ +package com.orion.ops.entity.request; + +import lombok.Data; + +/** + * 数据导出请求 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/5/26 16:10 + */ +@Data +public class DataExportRequest { + + /** + * 是否导出密码 + * + * @see com.orion.ops.consts.Const#ENABLE + * @see com.orion.ops.consts.Const#DISABLE + */ + private Integer exportPassword; + + /** + * 保护密码 + */ + private String protectPassword; + +} diff --git a/orion-ops-service/src/main/java/com/orion/ops/service/api/DataExportService.java b/orion-ops-service/src/main/java/com/orion/ops/service/api/DataExportService.java new file mode 100644 index 00000000..0d9c5a59 --- /dev/null +++ b/orion-ops-service/src/main/java/com/orion/ops/service/api/DataExportService.java @@ -0,0 +1,26 @@ +package com.orion.ops.service.api; + +import com.orion.ops.entity.request.DataExportRequest; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * 数据导出服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/5/26 16:18 + */ +public interface DataExportService { + + /** + * 导出机器 + * + * @param request request + * @param response response + * @throws IOException IOException + */ + void exportMachine(DataExportRequest request, HttpServletResponse response) throws IOException; + +} diff --git a/orion-ops-service/src/main/java/com/orion/ops/service/impl/DataExportServiceImpl.java b/orion-ops-service/src/main/java/com/orion/ops/service/impl/DataExportServiceImpl.java new file mode 100644 index 00000000..b49a8daa --- /dev/null +++ b/orion-ops-service/src/main/java/com/orion/ops/service/impl/DataExportServiceImpl.java @@ -0,0 +1,82 @@ +package com.orion.ops.service.impl; + +import com.orion.office.excel.writer.exporting.ExcelExport; +import com.orion.ops.consts.Const; +import com.orion.ops.consts.export.ExportType; +import com.orion.ops.consts.system.SystemEnvAttr; +import com.orion.ops.dao.MachineInfoDAO; +import com.orion.ops.entity.domain.MachineInfoDO; +import com.orion.ops.entity.dto.MachineInfoExportDTO; +import com.orion.ops.entity.request.DataExportRequest; +import com.orion.ops.service.api.DataExportService; +import com.orion.ops.utils.Currents; +import com.orion.ops.utils.PathBuilders; +import com.orion.utils.Strings; +import com.orion.utils.convert.Converts; +import com.orion.utils.io.FileWriters; +import com.orion.utils.io.Files1; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.List; + +/** + * 数据导出服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2022/5/26 16:18 + */ +@Service("dataExportService") +public class DataExportServiceImpl implements DataExportService { + + @Resource + private MachineInfoDAO machineInfoDAO; + + @Override + public void exportMachine(DataExportRequest request, HttpServletResponse response) throws IOException { + // 查询数据 + List machineList = machineInfoDAO.selectList(null); + List exportList = Converts.toList(machineList, MachineInfoExportDTO.class); + if (!Const.ENABLE.equals(request.getExportPassword())) { + exportList.forEach(s -> s.setEncryptPassword(null)); + } + // 导出 + ExcelExport exporter = new ExcelExport<>(MachineInfoExportDTO.class).init(); + exporter.addRows(exportList); + // 写入 + this.writeWorkbook(request, response, exporter, ExportType.MACHINE); + } + + /** + * 写入 workbook + * + * @param request request + * @param response response + * @param exporter exporter + * @param type type + * @throws IOException IOException + */ + private void writeWorkbook(DataExportRequest request, HttpServletResponse response, + ExcelExport exporter, ExportType type) throws IOException { + // 写入 workbook 到 byte + ByteArrayOutputStream store = new ByteArrayOutputStream(); + String password = request.getProtectPassword(); + if (!Strings.isBlank(password)) { + exporter.write(store, password); + } else { + exporter.write(store); + } + // 设置 http 返回 + byte[] excelData = store.toByteArray(); + response.getOutputStream().write(excelData); + // 保存至本地 + String exportPath = PathBuilders.getExportDataJsonPath(Currents.getUserId(), type.getType(), Strings.def(password)); + String path = Files1.getPath(SystemEnvAttr.LOG_PATH.getValue(), exportPath); + FileWriters.write(path, excelData); + } + +} diff --git a/orion-ops-service/src/main/java/com/orion/ops/utils/PathBuilders.java b/orion-ops-service/src/main/java/com/orion/ops/utils/PathBuilders.java index e135e8d5..2f14e190 100644 --- a/orion-ops-service/src/main/java/com/orion/ops/utils/PathBuilders.java +++ b/orion-ops-service/src/main/java/com/orion/ops/utils/PathBuilders.java @@ -177,6 +177,39 @@ public class PathBuilders { return Const.PACKAGE_DIR + "/" + fileToken + "." + Const.SUFFIX_ZIP; } + /** + * 获取导出数据 xlsx 文件路径 + * + * @param userId userId + * @param type type + * @return path + */ + public static String getExportDataJsonPath(Long userId, Integer type, String password) { + return Const.EXPORT_DIR + + "/" + type + + "/" + Dates.current(Dates.YMD_HMS2) + + "-" + userId + + "-" + password + + "." + Const.SUFFIX_XLSX; + } + + /** + * 获取导入数据 json 文件路径 + * + * @param userId userId + * @param type type + * @param token token + * @return path + */ + public static String getImportDataJsonPath(Long userId, Integer type, String token) { + return Const.IMPORT_DIR + + "/" + type + + "/" + Dates.current(Dates.YMD_HMS2) + + "-" + userId + + "-" + token + + "." + Const.SUFFIX_JSON; + } + /** * 获取用户根目录 *