From 4b17d7b4abfff9a3a47b99f7c01f2d1c26346713 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Mon, 13 May 2024 12:22:26 +0800 Subject: [PATCH 1/8] =?UTF-8?q?:bookmark:=20=E5=8D=87=E7=BA=A7=E7=89=88?= =?UTF-8?q?=E6=9C=AC.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- docker-compose.yml | 4 ++-- docker/mysql/build.sh | 2 +- docker/orion-ops-pro/build.sh | 2 +- docs/README.md | 2 +- docs/_coverpage.md | 2 +- docs/about/change-log.md | 8 ++++++++ docs/about/roadmap.md | 2 -- docs/update/v2.0.0.md | 11 +++++++++++ orion-ops-dependencies/pom.xml | 2 +- .../orion/ops/framework/common/constant/AppConst.java | 2 +- pom.xml | 2 +- 12 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 docs/update/v2.0.0.md diff --git a/README.md b/README.md index 61df4063..327ef10c 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@

-当前版本: **1.0.7** +当前版本: **1.0.8** **github:** https://github.com/lijiahangmax/orion-ops-pro **gitee:** https://gitee.com/lijiahangmax/orion-ops-pro diff --git a/docker-compose.yml b/docker-compose.yml index 6f8f21f0..3b204e2b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: '3.3' services: orion-ops-pro: - image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-ops-pro:1.0.7 + image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-ops-pro:1.0.8 ports: - 1081:80 environment: @@ -19,7 +19,7 @@ services: - orion-ops-pro-db - orion-ops-pro-redis orion-ops-pro-db: - image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-ops-pro-mysql:1.0.7 + image: registry.cn-hangzhou.aliyuncs.com/lijiahangmax/orion-ops-pro-mysql:1.0.8 privileged: true ports: - 3307:3306 diff --git a/docker/mysql/build.sh b/docker/mysql/build.sh index 597372e8..4b3100c9 100644 --- a/docker/mysql/build.sh +++ b/docker/mysql/build.sh @@ -1,5 +1,5 @@ #/bin/bash -version=1.0.7 +version=1.0.8 cp -r ../../sql ./sql docker build -t orion-ops-pro-mysql:${version} . rm -rf ./sql diff --git a/docker/orion-ops-pro/build.sh b/docker/orion-ops-pro/build.sh index 29f79d71..012efdb4 100644 --- a/docker/orion-ops-pro/build.sh +++ b/docker/orion-ops-pro/build.sh @@ -1,5 +1,5 @@ #/bin/bash -version=1.0.7 +version=1.0.8 mv ../../orion-ops-launch/target/orion-ops-launch.jar ./orion-ops-launch.jar mv ../../orion-ops-ui/dist ./dist docker build -t orion-ops-pro:${version} . diff --git a/docs/README.md b/docs/README.md index 12e7f642..78db4771 100644 --- a/docs/README.md +++ b/docs/README.md @@ -26,7 +26,7 @@

-当前版本: **1.0.7** +当前版本: **1.0.8** **github:** https://github.com/lijiahangmax/orion-ops-pro **gitee:** https://gitee.com/lijiahangmax/orion-ops-pro diff --git a/docs/_coverpage.md b/docs/_coverpage.md index 34ea5f45..f1676b7e 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,4 +1,4 @@ -# orion-ops-pro 1.0.7 +# orion-ops-pro 1.0.8 > 一款开箱即用的运维平台。 diff --git a/docs/about/change-log.md b/docs/about/change-log.md index f08e64e2..ba930ca5 100644 --- a/docs/about/change-log.md +++ b/docs/about/change-log.md @@ -7,6 +7,14 @@ * 执行完成菜单 sql 后请刷新缓存 `系统设置` > `系统菜单` > `刷新缓存` * 执行完成字典 sql 后请刷新缓存 `系统设置` > `数据字典项` > `刷新缓存` +### v1.0.8 + +`2024-05-15` `release` + +* 🌈 新增 站内信模块 + +[如何升级](/update/v1.0.8.md) + ### v1.0.7 `2024-05-13` `release` diff --git a/docs/about/roadmap.md b/docs/about/roadmap.md index 066aede7..f6f04cce 100644 --- a/docs/about/roadmap.md +++ b/docs/about/roadmap.md @@ -1,7 +1,5 @@ ## 功能排期 -* 批量上传 -* 站内消息 * 终端背景图片 * 资产授权 UI 改版 * RDP 远程桌面 diff --git a/docs/update/v2.0.0.md b/docs/update/v2.0.0.md new file mode 100644 index 00000000..712bfab8 --- /dev/null +++ b/docs/update/v2.0.0.md @@ -0,0 +1,11 @@ +## v2.0.0 + +> sql 脚本 - DDL + +```sql +``` + +> sql 脚本 - DML + +```sql +``` diff --git a/orion-ops-dependencies/pom.xml b/orion-ops-dependencies/pom.xml index f27115f1..c75a58c9 100644 --- a/orion-ops-dependencies/pom.xml +++ b/orion-ops-dependencies/pom.xml @@ -14,7 +14,7 @@ https://github.com/lijiahangmax/orion-ops-pro - 1.0.7 + 1.0.8 2.7.17 2.7.15 1.5.0 diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/AppConst.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/AppConst.java index a93b5cb9..6a9c1740 100644 --- a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/AppConst.java +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/AppConst.java @@ -14,7 +14,7 @@ public interface AppConst extends OrionConst { /** * 同 ${orion.version} 迭代时候需要手动更改 */ - String VERSION = "1.0.7"; + String VERSION = "1.0.8"; String ORION_OPS_PRO = "orion-ops-pro"; diff --git a/pom.xml b/pom.xml index 133c19de..60d9252c 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ - 1.0.7 + 1.0.8 8 8 3.0.0-M5 From 1ae47f8ab9a7164b3e08378e1eaf924784cc6220 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Tue, 14 May 2024 11:32:17 +0800 Subject: [PATCH 2/8] =?UTF-8?q?:sparkles:=20=E7=AB=99=E5=86=85=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=9C=8D=E5=8A=A1.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/generator/CodeGenerators.java | 32 ++-- .../core/generator/template/DictTemplate.java | 11 ++ .../module/infra/api/SystemMessageApi.java | 24 +++ .../dto/message/SystemMessageCreateDTO.java | 56 ++++++ .../infra/enums/MessageClassifyEnum.java | 24 +++ .../infra/api/impl/SystemMessageApiImpl.java | 41 +++++ .../controller/SystemMessageController.http | 39 +++++ .../controller/SystemMessageController.java | 90 ++++++++++ .../infra/convert/SystemMessageConvert.java | 32 ++++ .../convert/SystemMessageProviderConvert.java | 22 +++ .../module/infra/dao/SystemMessageDAO.java | 31 ++++ .../infra/entity/domain/SystemMessageDO.java | 73 ++++++++ .../entity/dto/SystemMessageCountDTO.java | 33 ++++ .../message/SystemMessageCreateRequest.java | 62 +++++++ .../message/SystemMessageQueryRequest.java | 35 ++++ .../infra/entity/vo/SystemMessageVO.java | 52 ++++++ .../module/infra/enums/MessageStatusEnum.java | 31 ++++ .../infra/service/SystemMessageService.java | 82 +++++++++ .../impl/SystemMessageServiceImpl.java | 165 ++++++++++++++++++ .../resources/mapper/SystemMessageMapper.xml | 43 +++++ orion-ops-ui/.env.development | 2 +- orion-ops-ui/.env.production | 2 +- orion-ops-ui/package.json | 2 +- 23 files changed, 964 insertions(+), 20 deletions(-) create mode 100644 orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/MessageClassifyEnum.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.http create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageConvert.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageProviderConvert.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemMessageDAO.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/SystemMessageDO.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/dto/SystemMessageCountDTO.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageCreateRequest.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageQueryRequest.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/SystemMessageVO.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/enums/MessageStatusEnum.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemMessageService.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/SystemMessageMapper.xml diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java index 2811e166..e8ff942a 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/CodeGenerators.java @@ -26,7 +26,7 @@ public class CodeGenerators { // 作者 String author = Const.ORION_AUTHOR; // 模块 - String module = "asset"; + String module = "infra"; // 生成的表 Table[] tables = { // Template.create("dict_key", "字典配置项", "dict") @@ -49,24 +49,22 @@ public class CodeGenerators { // .disableUnitTest() // .vue("exec", "exec-template-host") // .build(), - Template.create("upload_task", "上传任务", "upload") + Template.create("system_message", "系统消息", "message") .disableUnitTest() - .vue("exec", "upload-task") - .enableRowSelection() - .dict("uploadTaskStatus", "status") - .comment("上传任务状态") - .fields("WAITING", "UPLOADING", "FINISHED", "FAILED", "CANCELED") - .labels("等待中", "上传中", "已完成", "已失败", "已取消") + .enableProviderApi() + .vue("system", "message") + .dict("messageClassify", "classify", "messageClassify") + .comment("消息分类") + .fields("NOTICE", "TODO") + .labels("通知", "待办") .valueUseFields() - .build(), - Template.create("upload_task_file", "上传任务文件", "upload") - .disableUnitTest() - .vue("exec", "upload-task-file") - .enableRowSelection() - .dict("uploadTaskFileStatus", "status") - .comment("上传任务文件状态") - .fields("WAITING", "UPLOADING", "FINISHED", "FAILED", "CANCELED") - .labels("等待中", "上传中", "已完成", "已失败", "已取消") + .dict("messageType", "type", "messageType") + .comment("消息类型") + .fields("EXEC_FAILED", "UPLOAD_FAILED") + .labels("执行失败", "上传失败") + .extra("tagLabel", "执行失败", "上传失败") + .extra("tagVisible", true, true) + .extra("tagColor", "red", "red") .valueUseFields() .build(), }; diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/template/DictTemplate.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/template/DictTemplate.java index 4760400a..214a46aa 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/template/DictTemplate.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/core/generator/template/DictTemplate.java @@ -14,6 +14,17 @@ import java.util.LinkedHashMap; */ public class DictTemplate extends Template { + // // $comment + // export const $field = { + // // labels[0] + // fields[0]: 'values[0]', + // // labels[1] + // fields[0]: 'values[1]', + // }; + // + // // $comment 字典项 + // export const $keyField = '$keyName'; + private final DictMeta dictMeta; public DictTemplate(Table table, String keyName, String variable) { diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java new file mode 100644 index 00000000..17a5c01c --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java @@ -0,0 +1,24 @@ +package com.orion.ops.module.infra.api; + +import com.orion.ops.module.infra.entity.dto.message.SystemMessageCreateDTO; +import com.orion.ops.module.infra.enums.MessageClassifyEnum; + +/** + * 系统消息 对外服务类 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +public interface SystemMessageApi { + + /** + * 创建系统消息 + * + * @param classify classify + * @param dto dto + * @return id + */ + Long createSystemMessage(MessageClassifyEnum classify, SystemMessageCreateDTO dto); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java new file mode 100644 index 00000000..9ab2c708 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java @@ -0,0 +1,56 @@ +package com.orion.ops.module.infra.entity.dto.message; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; + +/** + * 系统消息 创建请求业务对象 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "SystemMessageCreateDTO", description = "系统消息 创建请求业务对象") +public class SystemMessageCreateDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @NotBlank + @Size(max = 32) + @Schema(description = "消息类型") + private String type; + + @NotBlank + @Size(max = 64) + @Schema(description = "消息关联") + private String relKey; + + @NotBlank + @Size(max = 128) + @Schema(description = "标题") + private String title; + + @NotBlank + @Schema(description = "消息内容") + private String content; + + @NotNull + @Schema(description = "接收人id") + private Long receiverId; + + @Schema(description = "接收人用户名") + private String receiverUsername; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/MessageClassifyEnum.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/MessageClassifyEnum.java new file mode 100644 index 00000000..5bb3fe2a --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/MessageClassifyEnum.java @@ -0,0 +1,24 @@ +package com.orion.ops.module.infra.enums; + +/** + * 消息分类 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024/5/11 16:38 + */ +public enum MessageClassifyEnum { + + /** + * 通知 + */ + NOTICE, + + /** + * 待办 + */ + TODO, + + ; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java new file mode 100644 index 00000000..8c427d85 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java @@ -0,0 +1,41 @@ +package com.orion.ops.module.infra.api.impl; + +import com.alibaba.fastjson.JSON; +import com.orion.ops.framework.common.utils.Valid; +import com.orion.ops.module.infra.api.SystemMessageApi; +import com.orion.ops.module.infra.convert.SystemMessageProviderConvert; +import com.orion.ops.module.infra.entity.dto.message.SystemMessageCreateDTO; +import com.orion.ops.module.infra.entity.request.message.SystemMessageCreateRequest; +import com.orion.ops.module.infra.enums.MessageClassifyEnum; +import com.orion.ops.module.infra.service.SystemMessageService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 系统消息 对外服务实现类 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Slf4j +@Service +public class SystemMessageApiImpl implements SystemMessageApi { + + @Resource + private SystemMessageService systemMessageService; + + @Override + public Long createSystemMessage(MessageClassifyEnum classify, SystemMessageCreateDTO dto) { + log.info("SystemMessageApi.createSystemMessage dto: {}", JSON.toJSONString(dto)); + Valid.valid(dto); + // 转换 + SystemMessageCreateRequest request = SystemMessageProviderConvert.MAPPER.toRequest(dto); + request.setClassify(classify.name()); + // 创建 + return systemMessageService.createSystemMessage(request); + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.http b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.http new file mode 100644 index 00000000..0d0df1fa --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.http @@ -0,0 +1,39 @@ +### 查询系统消息列表 +POST {{baseUrl}}/infra/system-message/list +Content-Type: application/json +Authorization: {{token}} + +{ + "limit": 10, + "maxId": null, + "classify": "NOTICE", + "queryCount": true, + "queryUnread": true +} + + +### 查询是否有未读消息 +GET {{baseUrl}}/infra/system-message/has-unread +Authorization: {{token}} + + +### 查询是否有未读消息 +PUT {{baseUrl}}/infra/system-message/read?id=1 +Authorization: {{token}} + + +### 更新全部系统消息为已读 +PUT {{baseUrl}}/infra/system-message/read-all?classify=NOTICE +Authorization: {{token}} + + +### 删除系统消息 +DELETE {{baseUrl}}/infra/system-message/delete?id=1 +Authorization: {{token}} + + +### 清理已读的系统消息 +DELETE {{baseUrl}}/infra/system-message/clear?classify=NOTICE +Authorization: {{token}} + +### diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.java new file mode 100644 index 00000000..fca4e08f --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/controller/SystemMessageController.java @@ -0,0 +1,90 @@ +package com.orion.ops.module.infra.controller; + +import com.orion.ops.framework.log.core.annotation.IgnoreLog; +import com.orion.ops.framework.log.core.enums.IgnoreLogMode; +import com.orion.ops.framework.web.core.annotation.RestWrapper; +import com.orion.ops.module.infra.entity.request.message.SystemMessageQueryRequest; +import com.orion.ops.module.infra.entity.vo.SystemMessageVO; +import com.orion.ops.module.infra.service.SystemMessageService; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.extern.slf4j.Slf4j; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +/** + * 系统消息 api + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Tag(name = "infra - 系统消息服务") +@Slf4j +@Validated +@RestWrapper +@RestController +@RequestMapping("/infra/system-message") +@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"}) +public class SystemMessageController { + + @Resource + private SystemMessageService systemMessageService; + + @IgnoreLog(IgnoreLogMode.ALL) + @PostMapping("/list") + @Operation(summary = "查询系统消息列表") + public List getSystemMessageList(@RequestBody SystemMessageQueryRequest request) { + return systemMessageService.getSystemMessageList(request); + } + + @IgnoreLog(IgnoreLogMode.ALL) + @GetMapping("/count") + @Operation(summary = "查询系统消息数量") + @Parameter(name = "queryUnread", description = "queryUnread", required = true) + public Map getSystemMessageCount(@RequestParam("queryUnread") Boolean queryUnread) { + return systemMessageService.getSystemMessageCount(queryUnread); + } + + @IgnoreLog(IgnoreLogMode.ALL) + @GetMapping("/has-unread") + @Operation(summary = "查询是否有未读消息") + public Boolean checkHasUnreadMessage() { + return systemMessageService.checkHasUnreadMessage(); + } + + @PutMapping("/read") + @Operation(summary = "更新系统消息为已读") + @Parameter(name = "id", description = "id", required = true) + public Integer readSystemMessage(@RequestParam("id") Long id) { + return systemMessageService.readSystemMessage(id); + } + + @PutMapping("/read-all") + @Operation(summary = "更新全部系统消息为已读") + @Parameter(name = "classify", description = "classify", required = true) + public Integer readAllSystemMessage(@RequestParam("classify") String classify) { + return systemMessageService.readAllSystemMessage(classify); + } + + @DeleteMapping("/delete") + @Operation(summary = "删除系统消息") + @Parameter(name = "id", description = "id", required = true) + public Integer deleteSystemMessage(@RequestParam("id") Long id) { + return systemMessageService.deleteSystemMessageById(id); + } + + @DeleteMapping("/clear") + @Operation(summary = "清理已读的系统消息") + @Parameter(name = "classify", description = "classify", required = true) + public Integer clearSystemMessage(@RequestParam("classify") String classify) { + return systemMessageService.clearSystemMessage(classify); + } + +} + diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageConvert.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageConvert.java new file mode 100644 index 00000000..64b79551 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageConvert.java @@ -0,0 +1,32 @@ +package com.orion.ops.module.infra.convert; + +import com.orion.ops.module.infra.entity.domain.SystemMessageDO; +import com.orion.ops.module.infra.entity.request.message.SystemMessageCreateRequest; +import com.orion.ops.module.infra.entity.request.message.SystemMessageQueryRequest; +import com.orion.ops.module.infra.entity.vo.SystemMessageVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +import java.util.List; + +/** + * 系统消息 内部对象转换器 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Mapper +public interface SystemMessageConvert { + + SystemMessageConvert MAPPER = Mappers.getMapper(SystemMessageConvert.class); + + SystemMessageDO to(SystemMessageCreateRequest request); + + SystemMessageDO to(SystemMessageQueryRequest request); + + SystemMessageVO to(SystemMessageDO domain); + + List to(List list); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageProviderConvert.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageProviderConvert.java new file mode 100644 index 00000000..7dfc71f2 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/convert/SystemMessageProviderConvert.java @@ -0,0 +1,22 @@ +package com.orion.ops.module.infra.convert; + +import com.orion.ops.module.infra.entity.dto.message.SystemMessageCreateDTO; +import com.orion.ops.module.infra.entity.request.message.SystemMessageCreateRequest; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 系统消息 对外服务对象转换器 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Mapper +public interface SystemMessageProviderConvert { + + SystemMessageProviderConvert MAPPER = Mappers.getMapper(SystemMessageProviderConvert.class); + + SystemMessageCreateRequest toRequest(SystemMessageCreateDTO request); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemMessageDAO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemMessageDAO.java new file mode 100644 index 00000000..2c9b1dca --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/dao/SystemMessageDAO.java @@ -0,0 +1,31 @@ +package com.orion.ops.module.infra.dao; + +import com.orion.ops.framework.mybatis.core.mapper.IMapper; +import com.orion.ops.module.infra.entity.domain.SystemMessageDO; +import com.orion.ops.module.infra.entity.dto.SystemMessageCountDTO; +import org.apache.ibatis.annotations.Mapper; +import org.apache.ibatis.annotations.Param; + +import java.util.List; + +/** + * 系统消息 Mapper 接口 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Mapper +public interface SystemMessageDAO extends IMapper { + + /** + * 查询消息数量 + * + * @param receiverId receiverId + * @param status status + * @return count + */ + List selectSystemMessageCount(@Param("receiverId") Long receiverId, + @Param("status") Integer status); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/SystemMessageDO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/SystemMessageDO.java new file mode 100644 index 00000000..b016fffc --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/domain/SystemMessageDO.java @@ -0,0 +1,73 @@ +package com.orion.ops.module.infra.entity.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.orion.ops.framework.mybatis.core.domain.BaseDO; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +/** + * 系统消息 实体对象 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(callSuper = true) +@TableName(value = "system_message", autoResultMap = true) +@Schema(name = "SystemMessageDO", description = "系统消息 实体对象") +public class SystemMessageDO extends BaseDO { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + @Schema(description = "消息分类") + @TableField("classify") + private String classify; + + @Schema(description = "消息类型") + @TableField("type") + private String type; + + @Schema(description = "消息状态") + @TableField("status") + private Integer status; + + @Schema(description = "消息关联") + @TableField("rel_key") + private String relKey; + + @Schema(description = "标题") + @TableField("title") + private String title; + + @Schema(description = "消息内容") + @TableField("content") + private String content; + + @Schema(description = "接收人id") + @TableField("receiver_id") + private Long receiverId; + + @Schema(description = "接收人用户名") + @TableField("receiver_username") + private String receiverUsername; + + @Schema(description = "创建人") + @TableField(exist = false) + private String creator; + + @Schema(description = "修改人") + @TableField(exist = false) + private String updater; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/dto/SystemMessageCountDTO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/dto/SystemMessageCountDTO.java new file mode 100644 index 00000000..05980814 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/dto/SystemMessageCountDTO.java @@ -0,0 +1,33 @@ +package com.orion.ops.module.infra.entity.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 系统消息数量对象 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024/5/11 18:15 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "SystemMessageCountDTO", description = "系统消息数量对象") +public class SystemMessageCountDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "消息分类") + private String classify; + + @Schema(description = "数量") + private Integer count; + +} \ No newline at end of file diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageCreateRequest.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageCreateRequest.java new file mode 100644 index 00000000..1dfcf24c --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageCreateRequest.java @@ -0,0 +1,62 @@ +package com.orion.ops.module.infra.entity.request.message; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; + +/** + * 系统消息 创建请求对象 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "SystemMessageCreateRequest", description = "系统消息 创建请求对象") +public class SystemMessageCreateRequest implements Serializable { + + private static final long serialVersionUID = 1L; + + @NotBlank + @Size(max = 10) + @Schema(description = "消息分类") + private String classify; + + @NotBlank + @Size(max = 32) + @Schema(description = "消息类型") + private String type; + + @NotBlank + @Size(max = 64) + @Schema(description = "消息关联") + private String relKey; + + @NotBlank + @Size(max = 128) + @Schema(description = "标题") + private String title; + + @NotBlank + @Schema(description = "消息内容") + private String content; + + @NotNull + @Schema(description = "接收人id") + private Long receiverId; + + @Size(max = 32) + @Schema(description = "接收人用户名") + private String receiverUsername; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageQueryRequest.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageQueryRequest.java new file mode 100644 index 00000000..ad6e2cc1 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/request/message/SystemMessageQueryRequest.java @@ -0,0 +1,35 @@ +package com.orion.ops.module.infra.entity.request.message; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 系统消息 查询请求对象 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "SystemMessageQueryRequest", description = "系统消息 查询请求对象") +public class SystemMessageQueryRequest { + + @Schema(description = "大小") + private Integer limit; + + @Schema(description = "maxId") + private Long maxId; + + @Schema(description = "消息分类") + private String classify; + + @Schema(description = "是否查询未读消息") + private Boolean queryUnread; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/SystemMessageVO.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/SystemMessageVO.java new file mode 100644 index 00000000..fdbc1b00 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/entity/vo/SystemMessageVO.java @@ -0,0 +1,52 @@ +package com.orion.ops.module.infra.entity.vo; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.Date; + +/** + * 系统消息 视图响应对象 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "SystemMessageVO", description = "系统消息 视图响应对象") +public class SystemMessageVO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + private Long id; + + @Schema(description = "消息分类") + private String classify; + + @Schema(description = "消息类型") + private String type; + + @Schema(description = "消息状态") + private Integer status; + + @Schema(description = "消息关联") + private String relKey; + + @Schema(description = "标题") + private String title; + + @Schema(description = "消息内容") + private String content; + + @Schema(description = "创建时间") + private Date createTime; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/enums/MessageStatusEnum.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/enums/MessageStatusEnum.java new file mode 100644 index 00000000..bdb6f10f --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/enums/MessageStatusEnum.java @@ -0,0 +1,31 @@ +package com.orion.ops.module.infra.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 消息状态 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024/5/11 16:35 + */ +@Getter +@AllArgsConstructor +public enum MessageStatusEnum { + + /** + * 未读 + */ + UNREAD(0), + + /** + * 已读 + */ + READ(1), + + ; + + private final Integer status; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemMessageService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemMessageService.java new file mode 100644 index 00000000..6a0389d7 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemMessageService.java @@ -0,0 +1,82 @@ +package com.orion.ops.module.infra.service; + +import com.orion.ops.module.infra.entity.request.message.SystemMessageCreateRequest; +import com.orion.ops.module.infra.entity.request.message.SystemMessageQueryRequest; +import com.orion.ops.module.infra.entity.vo.SystemMessageVO; + +import java.util.List; +import java.util.Map; + +/** + * 系统消息 服务类 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +public interface SystemMessageService { + + /** + * 创建系统消息 + * + * @param request request + * @return id + */ + Long createSystemMessage(SystemMessageCreateRequest request); + + /** + * 查询系统消息列表 + * + * @param request request + * @return rows + */ + List getSystemMessageList(SystemMessageQueryRequest request); + + /** + * 查询系统消息数量 + * + * @param queryUnread queryUnread + * @return rows + */ + Map getSystemMessageCount(Boolean queryUnread); + + /** + * 查询是否有未读消息 + * + * @return has + */ + Boolean checkHasUnreadMessage(); + + /** + * 更新系统消息为已读 + * + * @param id id + * @return effect + */ + Integer readSystemMessage(Long id); + + /** + * 更新全部系统消息为已读 + * + * @param classify classify + * @return effect + */ + Integer readAllSystemMessage(String classify); + + /** + * 删除系统消息 + * + * @param id id + * @return effect + */ + Integer deleteSystemMessageById(Long id); + + /** + * 清理已读的系统消息 + * + * @param classify classify + * @return effect + */ + Integer clearSystemMessage(String classify); + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java new file mode 100644 index 00000000..d1fa51c4 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java @@ -0,0 +1,165 @@ +package com.orion.ops.module.infra.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.orion.lang.function.Functions; +import com.orion.lang.utils.Booleans; +import com.orion.ops.framework.common.constant.Const; +import com.orion.ops.framework.security.core.utils.SecurityUtils; +import com.orion.ops.module.infra.convert.SystemMessageConvert; +import com.orion.ops.module.infra.dao.SystemMessageDAO; +import com.orion.ops.module.infra.dao.SystemUserDAO; +import com.orion.ops.module.infra.entity.domain.SystemMessageDO; +import com.orion.ops.module.infra.entity.domain.SystemUserDO; +import com.orion.ops.module.infra.entity.dto.SystemMessageCountDTO; +import com.orion.ops.module.infra.entity.request.message.SystemMessageCreateRequest; +import com.orion.ops.module.infra.entity.request.message.SystemMessageQueryRequest; +import com.orion.ops.module.infra.entity.vo.SystemMessageVO; +import com.orion.ops.module.infra.enums.MessageStatusEnum; +import com.orion.ops.module.infra.service.SystemMessageService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 系统消息 服务实现类 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Slf4j +@Service +public class SystemMessageServiceImpl implements SystemMessageService { + + @Resource + private SystemMessageDAO systemMessageDAO; + + @Resource + private SystemUserDAO systemUserDAO; + + @Override + public Long createSystemMessage(SystemMessageCreateRequest request) { + // 设置接收人用户名 + if (request.getReceiverUsername() == null) { + Optional.ofNullable(request.getReceiverId()) + .map(systemUserDAO::selectById) + .map(SystemUserDO::getUsername) + .ifPresent(request::setReceiverUsername); + } + // 转换 + SystemMessageDO record = SystemMessageConvert.MAPPER.to(request); + record.setStatus(MessageStatusEnum.UNREAD.getStatus()); + // 插入 + int effect = systemMessageDAO.insert(record); + Long id = record.getId(); + log.info("SystemMessageService-createSystemMessage id: {}, effect: {}", id, effect); + return id; + } + + @Override + public List getSystemMessageList(SystemMessageQueryRequest request) { + Long userId = SecurityUtils.getLoginUserId(); + Integer status = Booleans.isTrue(request.getQueryUnread()) ? MessageStatusEnum.UNREAD.getStatus() : null; + // 查询列表 + return systemMessageDAO.of() + .createValidateWrapper() + .eq(SystemMessageDO::getReceiverId, userId) + .eq(SystemMessageDO::getClassify, request.getClassify()) + .lt(SystemMessageDO::getId, request.getMaxId()) + .eq(SystemMessageDO::getStatus, status) + .last(Const.LIMIT + Const.SPACE + request.getLimit()) + .orderByDesc(SystemMessageDO::getId) + .then() + .list(SystemMessageConvert.MAPPER::to); + } + + @Override + public Map getSystemMessageCount(Boolean queryUnread) { + Long userId = SecurityUtils.getLoginUserId(); + Integer status = queryUnread ? MessageStatusEnum.UNREAD.getStatus() : null; + // 查询数量 + List countList = systemMessageDAO.selectSystemMessageCount(userId, status); + // 返回 + return countList.stream() + .collect(Collectors.toMap(SystemMessageCountDTO::getClassify, + SystemMessageCountDTO::getCount, + Functions.right())); + } + + @Override + public Boolean checkHasUnreadMessage() { + // 查询 + return systemMessageDAO.of() + .createWrapper() + .select(SystemMessageDO::getId) + .eq(SystemMessageDO::getReceiverId, SecurityUtils.getLoginUserId()) + .eq(SystemMessageDO::getStatus, MessageStatusEnum.UNREAD.getStatus()) + .then() + .only() + .optional() + .isPresent(); + } + + @Override + public Integer readSystemMessage(Long id) { + Long userId = SecurityUtils.getLoginUserId(); + log.info("SystemMessageService-readSystemMessage id: {}, userId: {}", id, userId); + // 修改状态 + SystemMessageDO update = new SystemMessageDO(); + update.setStatus(MessageStatusEnum.READ.getStatus()); + LambdaQueryWrapper wrapper = systemMessageDAO.wrapper() + .eq(SystemMessageDO::getId, id) + .eq(SystemMessageDO::getReceiverId, userId); + int effect = systemMessageDAO.update(update, wrapper); + log.info("SystemMessageService-readSystemMessage id: {}, effect: {}", id, effect); + return effect; + } + + @Override + public Integer readAllSystemMessage(String classify) { + Long userId = SecurityUtils.getLoginUserId(); + log.info("SystemMessageService-readAllSystemMessage classify: {}, userId: {}", classify, userId); + // 修改状态 + SystemMessageDO update = new SystemMessageDO(); + update.setStatus(MessageStatusEnum.READ.getStatus()); + LambdaQueryWrapper wrapper = systemMessageDAO.wrapper() + .eq(SystemMessageDO::getReceiverId, userId) + .eq(SystemMessageDO::getClassify, classify) + .eq(SystemMessageDO::getStatus, MessageStatusEnum.UNREAD.getStatus()); + int effect = systemMessageDAO.update(update, wrapper); + log.info("SystemMessageService-readAllSystemMessage classify: {}, effect: {}", classify, effect); + return effect; + } + + @Override + public Integer deleteSystemMessageById(Long id) { + log.info("SystemMessageService-deleteSystemMessageById id: {}", id); + // 删除 + LambdaQueryWrapper wrapper = systemMessageDAO.wrapper() + .eq(SystemMessageDO::getId, id) + .eq(SystemMessageDO::getReceiverId, SecurityUtils.getLoginUserId()); + int effect = systemMessageDAO.delete(wrapper); + log.info("SystemMessageService-deleteSystemMessageById id: {}, effect: {}", id, effect); + return effect; + } + + @Override + public Integer clearSystemMessage(String classify) { + Long userId = SecurityUtils.getLoginUserId(); + log.info("SystemMessageService-clearSystemMessage classify: {}, userId: {}", classify, userId); + // 删除 + LambdaQueryWrapper wrapper = systemMessageDAO.wrapper() + .eq(SystemMessageDO::getReceiverId, userId) + .eq(SystemMessageDO::getClassify, classify) + .eq(SystemMessageDO::getStatus, MessageStatusEnum.READ.getStatus()); + int effect = systemMessageDAO.delete(wrapper); + log.info("SystemMessageService-clearSystemMessage classify: {}, effect: {}", classify, effect); + return effect; + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/SystemMessageMapper.xml b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/SystemMessageMapper.xml new file mode 100644 index 00000000..2c3e9098 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/resources/mapper/SystemMessageMapper.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + id, classify, type, status, rel_key, title, content, receiver_id, receiver_username, create_time, update_time, deleted + + + + + + diff --git a/orion-ops-ui/.env.development b/orion-ops-ui/.env.development index 01433b12..8baf6503 100644 --- a/orion-ops-ui/.env.development +++ b/orion-ops-ui/.env.development @@ -1,4 +1,4 @@ VITE_API_BASE_URL= 'http://127.0.0.1:9200/orion/api' VITE_WS_BASE_URL= 'ws://127.0.0.1:9200/orion/keep-alive' -VITE_APP_VERSION= '1.0.7' +VITE_APP_VERSION= '1.0.8' VITE_SFTP_PREVIEW_MB= 2 diff --git a/orion-ops-ui/.env.production b/orion-ops-ui/.env.production index d324128c..58105ca7 100644 --- a/orion-ops-ui/.env.production +++ b/orion-ops-ui/.env.production @@ -1,4 +1,4 @@ VITE_API_BASE_URL= '/orion/api' VITE_WS_BASE_URL= '/orion/keep-alive' -VITE_APP_VERSION= '1.0.7' +VITE_APP_VERSION= '1.0.8' VITE_SFTP_PREVIEW_MB= 2 diff --git a/orion-ops-ui/package.json b/orion-ops-ui/package.json index b908221b..7f16e257 100644 --- a/orion-ops-ui/package.json +++ b/orion-ops-ui/package.json @@ -1,7 +1,7 @@ { "name": "orion-ops-pro-ui", "description": "Orion Ops Pro for Vue", - "version": "1.0.7", + "version": "1.0.8", "private": true, "author": "Jiahang Li", "license": "Apache 2.0", From e86bf3f19d373dff193dc1068c02e5ee51a7c409 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Tue, 14 May 2024 11:34:51 +0800 Subject: [PATCH 3/8] =?UTF-8?q?:zap:=20=E4=BF=AE=E6=94=B9=E5=8F=98?= =?UTF-8?q?=E9=87=8F=E8=A7=84=E8=8C=83.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orion-ops-ui/src/api/system/message.ts | 82 ++++++++++---- .../src/components/exec/log/panel/index.vue | 10 +- orion-ops-ui/src/utils/setup-mock.ts | 4 +- .../src/views/dashboard/workplace/mock.ts | 101 ++---------------- .../batch-upload/components/upload-panel.vue | 6 +- .../components/exec-command-log-table.vue | 8 +- .../components/upload-task-table.vue | 8 +- .../terminal/handler/sftp-transfer-manager.ts | 6 +- .../handler/terminal-session-manager.ts | 9 +- .../components/exec-job-log-table.vue | 8 +- 10 files changed, 96 insertions(+), 146 deletions(-) diff --git a/orion-ops-ui/src/api/system/message.ts b/orion-ops-ui/src/api/system/message.ts index e2d60eee..80aa48d6 100644 --- a/orion-ops-ui/src/api/system/message.ts +++ b/orion-ops-ui/src/api/system/message.ts @@ -1,38 +1,74 @@ import axios from 'axios'; -export interface MessageRecord { +/** + * 系统消息查询请求 + */ +export interface MessageQueryRequest { + limit?: number; + maxId?: number; + classify?: string; + queryUnread?: boolean; +} + +/** + * 系统消息查询响应 + */ +export interface MessageRecordResponse { id: number; + classify: string; type: string; + status: number; + relKey: string; title: string; - subTitle: string; - avatar?: string; content: string; - time: string; - status: 0 | 1; - messageType?: number; -} -export type MessageListType = MessageRecord[]; - -export function queryMessageList() { - return axios.post('/api/message/list'); + createTime: number; } -interface MessageStatus { - ids: number[]; +/** + * 查询系统消息列表 + */ +export function getMessageList(request: MessageQueryRequest) { + return axios.post>('/infra/system-message/list', request); } -export function setMessageStatus(data: MessageStatus) { - return axios.post('/api/message/read', data); +/** + * 查询系统消息数量 + */ +export function getMessageCount(queryUnread: boolean) { + return axios.get>('/infra/system-message/count', { params: { queryUnread } }); } -export interface ChatRecord { - id: number; - username: string; - content: string; - time: string; - isCollect: boolean; +/** + * 查询是否有未读消息 + */ +export function checkHasUnreadMessage() { + return axios.get('/infra/system-message/has-unread'); } -export function queryChatList() { - return axios.post('/api/chat/list'); +/** + * 更新系统消息为已读 + */ +export function updateMessageRead(id: number) { + return axios.put('/infra/system-message/read', undefined, { params: { id } }); +} + +/** + * 更新全部系统消息为已读 + */ +export function updateMessageReadAll(classify: string) { + return axios.put('/infra/system-message/read-all', undefined, { params: { classify } }); +} + +/** + * 删除系统消息 + */ +export function deleteMessage(id: number) { + return axios.delete('/infra/system-message/delete', { params: { id } }); +} + +/** + * 清理已读的系统消息 + */ +export function clearMessage(classify: string) { + return axios.delete('/infra/system-message/clear', { params: { classify } }); } diff --git a/orion-ops-ui/src/components/exec/log/panel/index.vue b/orion-ops-ui/src/components/exec/log/panel/index.vue index e869873f..0953a709 100644 --- a/orion-ops-ui/src/components/exec/log/panel/index.vue +++ b/orion-ops-ui/src/components/exec/log/panel/index.vue @@ -44,7 +44,7 @@ const logViewRef = ref(); const currentHostExecId = ref(); - const statusIntervalId = ref(); + const pullIntervalId = ref(); const execLog = ref(); const appender = ref(); @@ -57,9 +57,9 @@ if (record.status === execStatus.WAITING || record.status === execStatus.RUNNING) { // 等待一秒后先查询一下状态 - setTimeout(fetchTaskStatus, 1000); + setTimeout(pullExecStatus, 1000); // 注册状态轮询 - statusIntervalId.value = setInterval(fetchTaskStatus, 5000); + pullIntervalId.value = setInterval(pullExecStatus, 5000); } // 打开日志 nextTick(() => { @@ -68,7 +68,7 @@ }; // 加载状态 - const fetchTaskStatus = async () => { + const pullExecStatus = async () => { if (!execLog.value) { return; } @@ -150,7 +150,7 @@ // 清理轮询 const clearAllInterval = () => { // 关闭状态轮询 - clearInterval(statusIntervalId.value); + clearInterval(pullIntervalId.value); }; // 加载字典值 diff --git a/orion-ops-ui/src/utils/setup-mock.ts b/orion-ops-ui/src/utils/setup-mock.ts index 816ec285..feaafea9 100644 --- a/orion-ops-ui/src/utils/setup-mock.ts +++ b/orion-ops-ui/src/utils/setup-mock.ts @@ -7,12 +7,12 @@ export default ({ mock, setup }: { mock?: boolean; setup: () => void }) => { export const successResponseWrap = (data: unknown) => { return { data, - msg: '请求成功', + msg: 'success', code: 200, }; }; -export const failResponseWrap = (data: unknown, msg: string, code = 5000) => { +export const failResponseWrap = (data: unknown, msg: string, code = 500) => { return { data, msg, diff --git a/orion-ops-ui/src/views/dashboard/workplace/mock.ts b/orion-ops-ui/src/views/dashboard/workplace/mock.ts index ef436f41..e037190f 100644 --- a/orion-ops-ui/src/views/dashboard/workplace/mock.ts +++ b/orion-ops-ui/src/views/dashboard/workplace/mock.ts @@ -7,99 +7,18 @@ import setupMock, { successResponseWrap } from '@/utils/setup-mock'; const textList = [ { key: 1, - clickNumber: '346.3w+', - title: '经济日报:财政政策要精准提升…', + clickNumber: '1w+', + title: 'text...', increases: 35, }, { key: 2, - clickNumber: '324.2w+', - title: '双12遇冷,消费者厌倦了电商平…', + clickNumber: '2w+', + title: 'text...', increases: 22, }, - { - key: 3, - clickNumber: '318.9w+', - title: '致敬坚守战“疫”一线的社区工作…', - increases: 9, - }, - { - key: 4, - clickNumber: '257.9w+', - title: '普高还是职高?家长们陷入选择…', - increases: 17, - }, - { - key: 5, - clickNumber: '124.2w+', - title: '人民快评:没想到“浓眉大眼”的…', - increases: 37, - }, -]; -const imageList = [ - { - key: 1, - clickNumber: '15.3w+', - title: '杨涛接替陆慷出任外交部美大司…', - increases: 15, - }, - { - key: 2, - clickNumber: '12.2w+', - title: '图集:龙卷风袭击美国多州房屋…', - increases: 26, - }, - { - key: 3, - clickNumber: '18.9w+', - title: '52岁大姐贴钱照顾自闭症儿童八…', - increases: 9, - }, - { - key: 4, - clickNumber: '7.9w+', - title: '杭州一家三口公园宿营取暖中毒', - increases: 0, - }, - { - key: 5, - clickNumber: '5.2w+', - title: '派出所副所长威胁市民?警方调…', - increases: 4, - }, -]; -const videoList = [ - { - key: 1, - clickNumber: '367.6w+', - title: '这是今日10点的南京', - increases: 5, - }, - { - key: 2, - clickNumber: '352.2w+', - title: '立陶宛不断挑衅致经济受损民众…', - increases: 17, - }, - { - key: 3, - clickNumber: '348.9w+', - title: '韩国艺人刘在石确诊新冠', - increases: 30, - }, - { - key: 4, - clickNumber: '346.3w+', - title: '关于北京冬奥会,文在寅表态', - increases: 12, - }, - { - key: 5, - clickNumber: '271.2w+', - title: '95后现役军人荣立一等功', - increases: 2, - }, ]; + setupMock({ setup() { Mock.mock(new RegExp('/api/content-data'), () => { @@ -117,13 +36,11 @@ setupMock({ }); Mock.mock(new RegExp('/api/popular/list'), (params: GetParams) => { const { type = 'text' } = qs.parseUrl(params.url).query; - if (type === 'image') { - return successResponseWrap([...videoList]); + if (type === 'text') { + return successResponseWrap([...textList]); + } else { + return successResponseWrap([]); } - if (type === 'video') { - return successResponseWrap([...imageList]); - } - return successResponseWrap([...textList]); }); }, }); diff --git a/orion-ops-ui/src/views/exec/batch-upload/components/upload-panel.vue b/orion-ops-ui/src/views/exec/batch-upload/components/upload-panel.vue index 733a1ec0..e4c81fa9 100644 --- a/orion-ops-ui/src/views/exec/batch-upload/components/upload-panel.vue +++ b/orion-ops-ui/src/views/exec/batch-upload/components/upload-panel.vue @@ -76,7 +76,7 @@ const { loading, setLoading } = useLoading(); - const pullStatusId = ref(); + const pullIntervalId = ref(); const taskId = ref(); const task = ref({} as UploadTaskQueryResponse); const selectedHost = ref(); @@ -266,12 +266,12 @@ // 设置轮询状态 onMounted(() => { - pullStatusId.value = setInterval(pullTaskStatus, 5000); + pullIntervalId.value = setInterval(pullTaskStatus, 5000); }); // 卸载状态查询 onUnmounted(() => { - clearInterval(pullStatusId.value); + clearInterval(pullIntervalId.value); }); diff --git a/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue b/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue index 85cafa0f..3036d1a1 100644 --- a/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue +++ b/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue @@ -236,7 +236,7 @@ const { loading, setLoading } = useLoading(); const { toOptions, getDictValue } = useDictStore(); - const intervalId = ref(); + const pullIntervalId = ref(); const tableRef = ref(); const selectedKeys = ref([]); const tableRenderData = ref([]); @@ -343,7 +343,7 @@ }; // 加载状态 - const fetchTaskStatus = async () => { + const pullExecStatus = async () => { const unCompleteIdList = tableRenderData.value .filter(s => s.status === execStatus.WAITING || s.status === execStatus.RUNNING) .map(s => s.id); @@ -409,12 +409,12 @@ // 加载数据 fetchTableData(); // 注册状态轮询 - intervalId.value = setInterval(fetchTaskStatus, 10000); + pullIntervalId.value = setInterval(pullExecStatus, 10000); }); onUnmounted(() => { // 卸载状态轮询 - clearInterval(intervalId.value); + clearInterval(pullIntervalId.value); }); diff --git a/orion-ops-ui/src/views/exec/upload-task/components/upload-task-table.vue b/orion-ops-ui/src/views/exec/upload-task/components/upload-task-table.vue index 8bda1598..13b6abb6 100644 --- a/orion-ops-ui/src/views/exec/upload-task/components/upload-task-table.vue +++ b/orion-ops-ui/src/views/exec/upload-task/components/upload-task-table.vue @@ -199,7 +199,7 @@ const { loading, setLoading } = useLoading(); const { toOptions, getDictValue } = useDictStore(); - const intervalId = ref(); + const pullIntervalId = ref(); const selectedKeys = ref([]); const tableRenderData = ref([]); const formModel = reactive({ @@ -264,7 +264,7 @@ }; // 加载状态 - const fetchTaskStatus = async () => { + const pullTaskStatus = async () => { const unCompleteIdList = tableRenderData.value .filter(s => s.status === UploadTaskStatus.WAITING || s.status === UploadTaskStatus.UPLOADING) .map(s => s.id); @@ -311,12 +311,12 @@ // 加载数据 fetchTableData(); // 注册状态轮询 - intervalId.value = setInterval(fetchTaskStatus, 10000); + pullIntervalId.value = setInterval(pullTaskStatus, 10000); }); onUnmounted(() => { // 卸载状态轮询 - clearInterval(intervalId.value); + clearInterval(pullIntervalId.value); }); diff --git a/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts index 611746e4..ee2f9349 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/sftp-transfer-manager.ts @@ -14,7 +14,7 @@ export default class SftpTransferManager implements ISftpTransferManager { private run: boolean; - private progressId?: number; + private progressIntervalId?: number; private currentItem?: SftpTransferItem; @@ -136,7 +136,7 @@ export default class SftpTransferManager implements ISftpTransferManager { // 处理消息 this.client.onmessage = this.resolveMessage.bind(this); // 计算传输进度 - this.progressId = setInterval(this.calcProgress.bind(this), 500); + this.progressIntervalId = setInterval(this.calcProgress.bind(this), 500); // 打开后自动传输下一个任务 this.transferNextItem(); } @@ -275,7 +275,7 @@ export default class SftpTransferManager implements ISftpTransferManager { // 重置 run this.run = false; // 关闭传输进度 - clearInterval(this.progressId); + clearInterval(this.progressIntervalId); } } diff --git a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts index 5463b139..52309f4d 100644 --- a/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts +++ b/orion-ops-ui/src/views/host/terminal/handler/terminal-session-manager.ts @@ -23,7 +23,7 @@ export default class TerminalSessionManager implements ITerminalSessionManager { private sessions: Record; - private keepAliveTask?: any; + private keepAliveTaskId?: any; private readonly dispatchResizeFn: () => {}; @@ -136,7 +136,7 @@ export default class TerminalSessionManager implements ITerminalSessionManager { // 注册 resize 事件 addEventListen(window, 'resize', this.dispatchResizeFn); // 注册 ping 事件 - this.keepAliveTask = setInterval(() => { + this.keepAliveTaskId = setInterval(() => { this.channel.send(InputProtocol.PING, {}); }, 15000); } @@ -158,10 +158,7 @@ export default class TerminalSessionManager implements ITerminalSessionManager { // 关闭 channel this.channel.close(); // 清除 ping 事件 - if (this.keepAliveTask) { - clearInterval(this.keepAliveTask); - this.keepAliveTask = undefined; - } + clearInterval(this.keepAliveTaskId); // 移除 resize 事件 removeEventListen(window, 'resize', this.dispatchResizeFn); } catch (e) { diff --git a/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue b/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue index 4ea5746c..84dcfcfb 100644 --- a/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue +++ b/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue @@ -217,7 +217,7 @@ const { loading, setLoading } = useLoading(); const { toOptions, getDictValue } = useDictStore(); - const intervalId = ref(); + const pullIntervalId = ref(); const tableRef = ref(); const selectedKeys = ref([]); const tableRenderData = ref([]); @@ -308,7 +308,7 @@ }; // 加载状态 - const fetchTaskStatus = async () => { + const pullJobStatus = async () => { const unCompleteIdList = tableRenderData.value .filter(s => s.status === execStatus.WAITING || s.status === execStatus.RUNNING) .map(s => s.id); @@ -374,12 +374,12 @@ // 加载数据 fetchTableData(); // 注册状态轮询 - intervalId.value = setInterval(fetchTaskStatus, 10000); + pullIntervalId.value = setInterval(pullJobStatus, 10000); }); onUnmounted(() => { // 卸载状态轮询 - clearInterval(intervalId.value); + clearInterval(pullIntervalId.value); }); From a0717c3338da78fbf84296d75a8db9b4f048fe9c Mon Sep 17 00:00:00 2001 From: lijiahang Date: Tue, 14 May 2024 15:37:50 +0800 Subject: [PATCH 4/8] =?UTF-8?q?:sparkles:=20=E7=AB=99=E5=86=85=E6=B6=88?= =?UTF-8?q?=E6=81=AF.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- orion-ops-ui/src/api/system/message.ts | 13 +- .../src/components/app/navbar/index.vue | 46 ++- .../components/system/message-box/const.ts | 20 ++ .../components/system/message-box/index.vue | 331 +++++++++++++----- .../components/system/message-box/list.vue | 317 ++++++++++------- .../components/system/message-box/modal.vue | 49 +++ .../src/views/exec/batch-upload/index.vue | 4 + .../src/views/exec/exec-command/index.vue | 21 ++ 8 files changed, 567 insertions(+), 234 deletions(-) create mode 100644 orion-ops-ui/src/components/system/message-box/const.ts create mode 100644 orion-ops-ui/src/components/system/message-box/modal.vue diff --git a/orion-ops-ui/src/api/system/message.ts b/orion-ops-ui/src/api/system/message.ts index 80aa48d6..c58e9ff0 100644 --- a/orion-ops-ui/src/api/system/message.ts +++ b/orion-ops-ui/src/api/system/message.ts @@ -21,20 +21,21 @@ export interface MessageRecordResponse { relKey: string; title: string; content: string; + contentHtml: string; createTime: number; } /** * 查询系统消息列表 */ -export function getMessageList(request: MessageQueryRequest) { +export function getSystemMessageList(request: MessageQueryRequest) { return axios.post>('/infra/system-message/list', request); } /** * 查询系统消息数量 */ -export function getMessageCount(queryUnread: boolean) { +export function getSystemMessageCount(queryUnread: boolean) { return axios.get>('/infra/system-message/count', { params: { queryUnread } }); } @@ -48,27 +49,27 @@ export function checkHasUnreadMessage() { /** * 更新系统消息为已读 */ -export function updateMessageRead(id: number) { +export function updateSystemMessageRead(id: number) { return axios.put('/infra/system-message/read', undefined, { params: { id } }); } /** * 更新全部系统消息为已读 */ -export function updateMessageReadAll(classify: string) { +export function updateSystemMessageReadAll(classify: string) { return axios.put('/infra/system-message/read-all', undefined, { params: { classify } }); } /** * 删除系统消息 */ -export function deleteMessage(id: number) { +export function deleteSystemMessage(id: number) { return axios.delete('/infra/system-message/delete', { params: { id } }); } /** * 清理已读的系统消息 */ -export function clearMessage(classify: string) { +export function clearSystemMessage(classify: string) { return axios.delete('/infra/system-message/clear', { params: { classify } }); } diff --git a/orion-ops-ui/src/components/app/navbar/index.vue b/orion-ops-ui/src/components/app/navbar/index.vue index 42fecadd..7ed5b09d 100644 --- a/orion-ops-ui/src/components/app/navbar/index.vue +++ b/orion-ops-ui/src/components/app/navbar/index.vue @@ -80,11 +80,11 @@ - -
  • - + +
  • +
    - + + content-class="message-popover" + position="br" + :show-arrow="false" + :popup-style="{ marginLeft: '198px' }" + :content-style="{ padding: 0, width: '498px' }">
    diff --git a/orion-ops-ui/src/components/system/message-box/list.vue b/orion-ops-ui/src/components/system/message-box/list.vue index a661c331..85e84da4 100644 --- a/orion-ops-ui/src/components/system/message-box/list.vue +++ b/orion-ops-ui/src/components/system/message-box/list.vue @@ -1,149 +1,216 @@ + + diff --git a/orion-ops-ui/src/components/system/message-box/modal.vue b/orion-ops-ui/src/components/system/message-box/modal.vue new file mode 100644 index 00000000..17909f5a --- /dev/null +++ b/orion-ops-ui/src/components/system/message-box/modal.vue @@ -0,0 +1,49 @@ + + + + + + + diff --git a/orion-ops-ui/src/views/exec/batch-upload/index.vue b/orion-ops-ui/src/views/exec/batch-upload/index.vue index ec372558..7c67d048 100644 --- a/orion-ops-ui/src/views/exec/batch-upload/index.vue +++ b/orion-ops-ui/src/views/exec/batch-upload/index.vue @@ -28,10 +28,14 @@ await dictStore.loadKeys(dictKeys); }); + // 跳转日志 onMounted(async () => { const idParam = route.query.id; + const keyParam = route.query.key; if (idParam) { await panel.value?.openLog(Number.parseInt(idParam as string)); + } else if (keyParam) { + await panel.value?.openLog(Number.parseInt(keyParam as string)); } }); diff --git a/orion-ops-ui/src/views/exec/exec-command/index.vue b/orion-ops-ui/src/views/exec/exec-command/index.vue index 2af0d7d3..d1329e65 100644 --- a/orion-ops-ui/src/views/exec/exec-command/index.vue +++ b/orion-ops-ui/src/views/exec/exec-command/index.vue @@ -26,10 +26,13 @@ import useVisible from '@/hooks/visible'; import { useDictStore } from '@/store'; import { dictKeys } from '@/components/exec/log/const'; + import { useRoute } from 'vue-router'; + import { getExecCommandLog } from '@/api/exec/exec-command-log'; import ExecCommandPanel from './components/exec-command-panel.vue'; import ExecLogPanel from '@/components/exec/log/panel/index.vue'; const { visible: logVisible, setVisible: setLogVisible } = useVisible(); + const route = useRoute(); const log = ref(); @@ -41,12 +44,30 @@ }); }; + // 打开日志 + const openLogWithId = async (id: number) => { + setLogVisible(true); + // 查询日志 + const { data } = await getExecCommandLog(id); + openLog(data); + }; + // 加载字典值 onMounted(async () => { const dictStore = useDictStore(); await dictStore.loadKeys(dictKeys); }); + // 跳转日志 + onMounted(async () => { + const idParam = route.query.id; + const keyParam = route.query.key; + if (idParam) { + await openLogWithId(Number.parseInt(idParam as string)); + } else if (keyParam) { + await openLogWithId(Number.parseInt(keyParam as string)); + } + }); diff --git a/orion-ops-ui/src/views/exec/exec-command-log/index.vue b/orion-ops-ui/src/views/exec/exec-command-log/index.vue index 1c305a02..6869de2e 100644 --- a/orion-ops-ui/src/views/exec/exec-command-log/index.vue +++ b/orion-ops-ui/src/views/exec/exec-command-log/index.vue @@ -69,7 +69,7 @@ if (newWindow) { // 跳转新页面 openNewRoute({ - name: 'execCommandLogView', + name: 'execCommand', query: { id } From 4fe6208d0e81fd0c52d76f4072ad24cfb623e306 Mon Sep 17 00:00:00 2001 From: lijiahang Date: Tue, 14 May 2024 19:17:12 +0800 Subject: [PATCH 6/8] =?UTF-8?q?:sparkles:=20=E7=AB=99=E5=86=85=E6=B6=88?= =?UTF-8?q?=E6=81=AF.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/about/change-log.md | 2 + .../framework/common/constant/FieldConst.java | 4 ++ .../define/message/ExecMessageDefine.java | 53 ++++++++++++++++ .../define/message/UploadMessageDefine.java | 53 ++++++++++++++++ .../host/exec/command/dto/ExecCommandDTO.java | 2 +- .../handler/BaseExecCommandHandler.java | 4 ++ .../exec/command/handler/ExecTaskHandler.java | 60 ++++++++++++++++--- .../command/handler/IExecCommandHandler.java | 7 +++ .../host/upload/task/FileUploadTask.java | 43 +++++++++++-- .../module/infra/api/SystemMessageApi.java | 13 +++- .../infra/define/SystemMessageDefine.java | 47 +++++++++++++++ .../dto/message/SystemMessageCreateDTO.java | 5 ++ .../entity/dto/message/SystemMessageDTO.java | 46 ++++++++++++++ .../infra/api/impl/SystemMessageApiImpl.java | 25 ++++++-- .../impl/SystemMessageServiceImpl.java | 2 + .../src/components/app/navbar/index.vue | 7 +-- .../components/system/message-box/index.vue | 14 ++--- .../components/system/message-box/list.vue | 46 ++++++++------ .../components/system/message-box/modal.vue | 4 +- 19 files changed, 385 insertions(+), 52 deletions(-) create mode 100644 orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/ExecMessageDefine.java create mode 100644 orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/UploadMessageDefine.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/define/SystemMessageDefine.java create mode 100644 orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageDTO.java diff --git a/docs/about/change-log.md b/docs/about/change-log.md index ba930ca5..e400c15b 100644 --- a/docs/about/change-log.md +++ b/docs/about/change-log.md @@ -12,6 +12,8 @@ `2024-05-15` `release` * 🌈 新增 站内信模块 +* 🔨 优化 执行命令日志跳转逻辑 +* 🔨 修改 `exitStatus` 改为 `exitCode` [如何升级](/update/v1.0.8.md) diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/FieldConst.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/FieldConst.java index 5c48f978..505b777f 100644 --- a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/FieldConst.java +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/constant/FieldConst.java @@ -55,6 +55,10 @@ public interface FieldConst { String COUNT = "count"; + String DATE = "date"; + + String TIME = "time"; + String LOCATION = "location"; String USER_AGENT = "userAgent"; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/ExecMessageDefine.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/ExecMessageDefine.java new file mode 100644 index 00000000..b850f79d --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/ExecMessageDefine.java @@ -0,0 +1,53 @@ +package com.orion.ops.module.asset.define.message; + +import com.orion.ops.module.infra.define.SystemMessageDefine; +import com.orion.ops.module.infra.enums.MessageClassifyEnum; +import lombok.Getter; + +/** + * 命令执行 系统消息定义 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/5/14 17:23 + */ +@Getter +public enum ExecMessageDefine implements SystemMessageDefine { + + /** + * 命令执行部分失败 + */ + EXEC_FAILED(MessageClassifyEnum.NOTICE, + "命令执行失败", + "您在 ${time} 执行的命令部分失败, 或者返回了非零的 exitCode。点击查看详情 #${id} >>>"), + + ; + + ExecMessageDefine(MessageClassifyEnum classify, String title, String content) { + this.classify = classify; + this.type = this.name(); + this.title = title; + this.content = content; + } + + /** + * 消息分类 + */ + private final MessageClassifyEnum classify; + + /** + * 消息类型 + */ + private final String type; + + /** + * 标题 + */ + private final String title; + + /** + * 内容 + */ + private final String content; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/UploadMessageDefine.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/UploadMessageDefine.java new file mode 100644 index 00000000..bd02296c --- /dev/null +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/message/UploadMessageDefine.java @@ -0,0 +1,53 @@ +package com.orion.ops.module.asset.define.message; + +import com.orion.ops.module.infra.define.SystemMessageDefine; +import com.orion.ops.module.infra.enums.MessageClassifyEnum; +import lombok.Getter; + +/** + * 上传任务 系统消息定义 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/5/14 17:23 + */ +@Getter +public enum UploadMessageDefine implements SystemMessageDefine { + + /** + * 上传任务部分失败 + */ + UPLOAD_FAILED(MessageClassifyEnum.NOTICE, + "批量上传失败", + "您在 ${time} 提交的上传任务中, 有部分主机文件上传失败。点击查看详情 #${id} >>>"), + + ; + + UploadMessageDefine(MessageClassifyEnum classify, String title, String content) { + this.classify = classify; + this.type = this.name(); + this.title = title; + this.content = content; + } + + /** + * 消息分类 + */ + private final MessageClassifyEnum classify; + + /** + * 消息类型 + */ + private final String type; + + /** + * 标题 + */ + private final String title; + + /** + * 内容 + */ + private final String content; + +} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/dto/ExecCommandDTO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/dto/ExecCommandDTO.java index 909c9dd1..6a239c13 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/dto/ExecCommandDTO.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/dto/ExecCommandDTO.java @@ -22,7 +22,7 @@ import java.util.List; @Schema(name = "ExecCommandDTO", description = "批量执行启动对象") public class ExecCommandDTO { - @Schema(description = "hostId") + @Schema(description = "logId") private Long logId; @Schema(description = "用户id") diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java index dde24a38..78c3c1da 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java @@ -67,6 +67,9 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler { private CommandExecutor executor; + @Getter + private Integer exitCode; + private volatile boolean closed; private volatile boolean interrupted; @@ -228,6 +231,7 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler { // 完成 updateRecord.setFinishTime(new Date()); updateRecord.setExitStatus(executor.getExitCode()); + this.exitCode = executor.getExitCode(); } else if (ExecHostStatusEnum.FAILED.equals(status)) { // 失败 updateRecord.setFinishTime(new Date()); diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecTaskHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecTaskHandler.java index 93d8ed93..53f58d58 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecTaskHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecTaskHandler.java @@ -7,20 +7,29 @@ import com.orion.lang.utils.Booleans; import com.orion.lang.utils.Threads; import com.orion.lang.utils.collect.Lists; import com.orion.lang.utils.io.Streams; +import com.orion.lang.utils.time.Dates; +import com.orion.net.host.ssh.ExitCode; +import com.orion.ops.framework.common.constant.ExtraFieldConst; import com.orion.ops.module.asset.dao.ExecLogDAO; import com.orion.ops.module.asset.define.AssetThreadPools; import com.orion.ops.module.asset.define.config.AppExecLogConfig; +import com.orion.ops.module.asset.define.message.ExecMessageDefine; import com.orion.ops.module.asset.entity.domain.ExecLogDO; +import com.orion.ops.module.asset.enums.ExecHostStatusEnum; import com.orion.ops.module.asset.enums.ExecStatusEnum; import com.orion.ops.module.asset.handler.host.exec.command.dto.ExecCommandDTO; import com.orion.ops.module.asset.handler.host.exec.command.dto.ExecCommandHostDTO; import com.orion.ops.module.asset.handler.host.exec.command.manager.ExecTaskManager; +import com.orion.ops.module.infra.api.SystemMessageApi; +import com.orion.ops.module.infra.entity.dto.message.SystemMessageDTO; import com.orion.spring.SpringHolder; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 命令执行任务 @@ -38,6 +47,8 @@ public class ExecTaskHandler implements IExecTaskHandler { private static final AppExecLogConfig appExecLogConfig = SpringHolder.getBean(AppExecLogConfig.class); + private static final SystemMessageApi systemMessageApi = SpringHolder.getBean(SystemMessageApi.class); + private final ExecCommandDTO execCommand; private TimeoutChecker timeoutChecker; @@ -45,6 +56,8 @@ public class ExecTaskHandler implements IExecTaskHandler { @Getter private final List handlers; + private Date startTime; + public ExecTaskHandler(ExecCommandDTO execCommand) { this.execCommand = execCommand; this.handlers = Lists.newList(); @@ -56,9 +69,9 @@ public class ExecTaskHandler implements IExecTaskHandler { // 添加任务 execTaskManager.addTask(id, this); log.info("ExecTaskHandler.run start id: {}", id); - // 更新状态 - this.updateStatus(ExecStatusEnum.RUNNING); try { + // 更新状态 + this.updateStatus(ExecStatusEnum.RUNNING); // 执行命令 this.runHostCommand(); // 更新状态-执行完成 @@ -69,10 +82,12 @@ public class ExecTaskHandler implements IExecTaskHandler { this.updateStatus(ExecStatusEnum.FAILED); log.error("ExecTaskHandler.run error id: {}", id, e); } finally { - // 释放资源 - Streams.close(this); + // 检查是否发送消息 + this.checkSendMessage(); // 移除任务 execTaskManager.removeTask(id); + // 释放资源 + this.close(); } } @@ -82,6 +97,13 @@ public class ExecTaskHandler implements IExecTaskHandler { handlers.forEach(IExecCommandHandler::interrupt); } + @Override + public void close() { + log.info("ExecTaskHandler-close id: {}", execCommand.getLogId()); + Streams.close(timeoutChecker); + this.handlers.forEach(Streams::close); + } + /** * 执行主机命令 * @@ -139,6 +161,7 @@ public class ExecTaskHandler implements IExecTaskHandler { update.setStatus(statusName); if (ExecStatusEnum.RUNNING.equals(status)) { // 执行中 + this.startTime = new Date(); update.setStartTime(new Date()); } else if (ExecStatusEnum.COMPLETED.equals(status)) { // 执行完成 @@ -151,11 +174,30 @@ public class ExecTaskHandler implements IExecTaskHandler { log.info("ExecTaskHandler-updateStatus finish id: {}, effect: {}", id, effect); } - @Override - public void close() { - log.info("ExecTaskHandler-close id: {}", execCommand.getLogId()); - Streams.close(timeoutChecker); - this.handlers.forEach(Streams::close); + /** + * 检查是否发送消息 + */ + private void checkSendMessage() { + // 检查是否执行失败/exitCode + boolean hasError = handlers.stream().anyMatch(s -> + ExecHostStatusEnum.FAILED.equals(s.getStatus()) + || ExecHostStatusEnum.TIMEOUT.equals(s.getStatus()) + || !ExitCode.isSuccess(s.getExitCode())); + if (!hasError) { + return; + } + // 参数 + Map params = new HashMap<>(); + params.put(ExtraFieldConst.ID, execCommand.getLogId()); + params.put(ExtraFieldConst.TIME, Dates.format(this.startTime, Dates.MD_HM)); + SystemMessageDTO message = SystemMessageDTO.builder() + .receiverId(execCommand.getUserId()) + .receiverUsername(execCommand.getUsername()) + .relKey(String.valueOf(execCommand.getLogId())) + .params(params) + .build(); + // 发送 + systemMessageApi.create(ExecMessageDefine.EXEC_FAILED, message); } } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/IExecCommandHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/IExecCommandHandler.java index 79f2c579..6e6ae93c 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/IExecCommandHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/IExecCommandHandler.java @@ -31,6 +31,13 @@ public interface IExecCommandHandler extends Runnable, SafeCloseable { */ ExecHostStatusEnum getStatus(); + /** + * 获取退出码 + * + * @return exit code + */ + Integer getExitCode(); + /** * 获取主机 id * diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java index 504e5d66..a893e422 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/upload/task/FileUploadTask.java @@ -3,10 +3,13 @@ package com.orion.ops.module.asset.handler.host.upload.task; import com.orion.lang.utils.Threads; import com.orion.lang.utils.io.Files1; import com.orion.lang.utils.io.Streams; +import com.orion.lang.utils.time.Dates; import com.orion.ops.framework.common.constant.Const; +import com.orion.ops.framework.common.constant.ExtraFieldConst; import com.orion.ops.module.asset.dao.UploadTaskDAO; import com.orion.ops.module.asset.dao.UploadTaskFileDAO; import com.orion.ops.module.asset.define.AssetThreadPools; +import com.orion.ops.module.asset.define.message.UploadMessageDefine; import com.orion.ops.module.asset.entity.domain.UploadTaskDO; import com.orion.ops.module.asset.entity.domain.UploadTaskFileDO; import com.orion.ops.module.asset.enums.UploadTaskFileStatusEnum; @@ -16,14 +19,13 @@ import com.orion.ops.module.asset.handler.host.upload.manager.FileUploadTaskMana import com.orion.ops.module.asset.handler.host.upload.uploader.FileUploader; import com.orion.ops.module.asset.handler.host.upload.uploader.IFileUploader; import com.orion.ops.module.asset.service.UploadTaskService; +import com.orion.ops.module.infra.api.SystemMessageApi; +import com.orion.ops.module.infra.entity.dto.message.SystemMessageDTO; import com.orion.spring.SpringHolder; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; /** @@ -42,6 +44,8 @@ public class FileUploadTask implements IFileUploadTask { private static final UploadTaskService uploadTaskService = SpringHolder.getBean(UploadTaskService.class); + private static final SystemMessageApi systemMessageApi = SpringHolder.getBean(SystemMessageApi.class); + private static final FileUploadTaskManager fileUploadTaskManager = SpringHolder.getBean(FileUploadTaskManager.class); private final Long id; @@ -91,6 +95,8 @@ public class FileUploadTask implements IFileUploadTask { } else { this.updateStatus(UploadTaskStatusEnum.FINISHED); } + // 检查是否发送消息 + this.checkSendMessage(); // 移除任务 fileUploadTaskManager.removeTask(id); // 释放资源 @@ -187,4 +193,33 @@ public class FileUploadTask implements IFileUploadTask { uploadTaskDAO.updateById(update); } + /** + * 检查是否发送消息 + */ + private void checkSendMessage() { + if (canceled) { + return; + } + // 检查是否上传失败 + boolean hasError = uploaderList.stream() + .map(IFileUploader::getFiles) + .flatMap(Collection::stream) + .anyMatch(s -> UploadTaskFileStatusEnum.FAILED.name().equals(s.getStatus())); + if (!hasError) { + return; + } + // 参数 + Map params = new HashMap<>(); + params.put(ExtraFieldConst.ID, record.getId()); + params.put(ExtraFieldConst.TIME, Dates.format(record.getCreateTime(), Dates.MD_HM)); + SystemMessageDTO message = SystemMessageDTO.builder() + .receiverId(record.getUserId()) + .receiverUsername(record.getUsername()) + .relKey(String.valueOf(record.getId())) + .params(params) + .build(); + // 发送 + systemMessageApi.create(UploadMessageDefine.UPLOAD_FAILED, message); + } + } diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java index 17a5c01c..0ecd4add 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/api/SystemMessageApi.java @@ -1,6 +1,8 @@ package com.orion.ops.module.infra.api; +import com.orion.ops.module.infra.define.SystemMessageDefine; import com.orion.ops.module.infra.entity.dto.message.SystemMessageCreateDTO; +import com.orion.ops.module.infra.entity.dto.message.SystemMessageDTO; import com.orion.ops.module.infra.enums.MessageClassifyEnum; /** @@ -12,6 +14,15 @@ import com.orion.ops.module.infra.enums.MessageClassifyEnum; */ public interface SystemMessageApi { + /** + * 创建系统消息 + * + * @param define define + * @param dto dto + * @return id + */ + Long create(SystemMessageDefine define, SystemMessageDTO dto); + /** * 创建系统消息 * @@ -19,6 +30,6 @@ public interface SystemMessageApi { * @param dto dto * @return id */ - Long createSystemMessage(MessageClassifyEnum classify, SystemMessageCreateDTO dto); + Long create(MessageClassifyEnum classify, SystemMessageCreateDTO dto); } diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/define/SystemMessageDefine.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/define/SystemMessageDefine.java new file mode 100644 index 00000000..b2e836a9 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/define/SystemMessageDefine.java @@ -0,0 +1,47 @@ +package com.orion.ops.module.infra.define; + +import com.orion.lang.utils.Strings; +import com.orion.ops.module.infra.enums.MessageClassifyEnum; + +import java.util.Map; + +/** + * 系统消息定义 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/5/14 17:06 + */ +public interface SystemMessageDefine { + + /** + * @return 消息分类 + */ + MessageClassifyEnum getClassify(); + + /** + * @return 消息类型 + */ + String getType(); + + /** + * @return 标题 + */ + String getTitle(); + + /** + * @return 内容 + */ + String getContent(); + + /** + * 格式化内容 + * + * @param params params + * @return content + */ + default String formatContent(Map params) { + return Strings.format(this.getContent(), params); + } + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java index 9ab2c708..c3ea71e9 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageCreateDTO.java @@ -27,6 +27,11 @@ public class SystemMessageCreateDTO implements Serializable { private static final long serialVersionUID = 1L; + @NotBlank + @Size(max = 10) + @Schema(description = "消息分类") + private String classify; + @NotBlank @Size(max = 32) @Schema(description = "消息类型") diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageDTO.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageDTO.java new file mode 100644 index 00000000..c11e05a1 --- /dev/null +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/entity/dto/message/SystemMessageDTO.java @@ -0,0 +1,46 @@ +package com.orion.ops.module.infra.entity.dto.message; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import java.io.Serializable; +import java.util.Map; + +/** + * 系统消息 请求业务对象 + * + * @author Jiahang Li + * @version 1.0.8 + * @since 2024-5-11 16:29 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "SystemMessageDTO", description = "系统消息 请求业务对象") +public class SystemMessageDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @NotBlank + @Size(max = 64) + @Schema(description = "消息关联") + private String relKey; + + @NotNull + @Schema(description = "接收人id") + private Long receiverId; + + @Schema(description = "接收人用户名") + private String receiverUsername; + + @Schema(description = "参数") + private Map params; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java index 8c427d85..b839b23b 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/api/impl/SystemMessageApiImpl.java @@ -1,10 +1,11 @@ package com.orion.ops.module.infra.api.impl; -import com.alibaba.fastjson.JSON; import com.orion.ops.framework.common.utils.Valid; import com.orion.ops.module.infra.api.SystemMessageApi; import com.orion.ops.module.infra.convert.SystemMessageProviderConvert; +import com.orion.ops.module.infra.define.SystemMessageDefine; import com.orion.ops.module.infra.entity.dto.message.SystemMessageCreateDTO; +import com.orion.ops.module.infra.entity.dto.message.SystemMessageDTO; import com.orion.ops.module.infra.entity.request.message.SystemMessageCreateRequest; import com.orion.ops.module.infra.enums.MessageClassifyEnum; import com.orion.ops.module.infra.service.SystemMessageService; @@ -28,12 +29,28 @@ public class SystemMessageApiImpl implements SystemMessageApi { private SystemMessageService systemMessageService; @Override - public Long createSystemMessage(MessageClassifyEnum classify, SystemMessageCreateDTO dto) { - log.info("SystemMessageApi.createSystemMessage dto: {}", JSON.toJSONString(dto)); + public Long create(SystemMessageDefine define, SystemMessageDTO dto) { + Valid.valid(dto); + // 转换 + SystemMessageCreateRequest request = SystemMessageCreateRequest.builder() + .classify(define.getClassify().name()) + .type(define.getType()) + .title(define.getTitle()) + .content(define.formatContent(dto.getParams())) + .relKey(dto.getRelKey()) + .receiverId(dto.getReceiverId()) + .receiverUsername(dto.getReceiverUsername()) + .build(); + // 创建 + return systemMessageService.createSystemMessage(request); + } + + @Override + public Long create(MessageClassifyEnum classify, SystemMessageCreateDTO dto) { + dto.setClassify(classify.name()); Valid.valid(dto); // 转换 SystemMessageCreateRequest request = SystemMessageProviderConvert.MAPPER.toRequest(dto); - request.setClassify(classify.name()); // 创建 return systemMessageService.createSystemMessage(request); } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java index d1fa51c4..0fb367b4 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemMessageServiceImpl.java @@ -1,5 +1,6 @@ package com.orion.ops.module.infra.service.impl; +import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.orion.lang.function.Functions; import com.orion.lang.utils.Booleans; @@ -44,6 +45,7 @@ public class SystemMessageServiceImpl implements SystemMessageService { @Override public Long createSystemMessage(SystemMessageCreateRequest request) { + log.info("SystemMessageService.createSystemMessage request: {}", JSON.toJSONString(request)); // 设置接收人用户名 if (request.getReceiverUsername() == null) { Optional.ofNullable(request.getReceiverId()) diff --git a/orion-ops-ui/src/components/app/navbar/index.vue b/orion-ops-ui/src/components/app/navbar/index.vue index 7ed5b09d..b40813dd 100644 --- a/orion-ops-ui/src/components/app/navbar/index.vue +++ b/orion-ops-ui/src/components/app/navbar/index.vue @@ -99,7 +99,8 @@ position="br" :show-arrow="false" :popup-style="{ marginLeft: '198px' }" - :content-style="{ padding: 0, width: '498px' }"> + :content-style="{ padding: 0, width: '428px' }" + @hide="pullHasUnreadMessage">
    diff --git a/orion-ops-ui/src/components/system/message-box/list.vue b/orion-ops-ui/src/components/system/message-box/list.vue index f1ac3ce1..815e2250 100644 --- a/orion-ops-ui/src/components/system/message-box/list.vue +++ b/orion-ops-ui/src/components/system/message-box/list.vue @@ -6,7 +6,7 @@
    @@ -56,17 +56,21 @@
    - +
    + +
    + {{ dateFormat(new Date(message.createTime))}} +
    @@ -92,6 +96,7 @@ import type { MessageRecordResponse } from '@/api/system/message'; import { MessageStatus, messageTypeKey } from './const'; import { useDictStore } from '@/store'; + import { dateFormat } from '@/utils'; const emits = defineEmits(['load', 'click', 'view', 'delete']); const props = defineProps<{ @@ -107,7 +112,6 @@ diff --git a/orion-ops-ui/src/components/system/message-box/modal.vue b/orion-ops-ui/src/components/system/message-box/modal.vue index 17909f5a..0a787900 100644 --- a/orion-ops-ui/src/components/system/message-box/modal.vue +++ b/orion-ops-ui/src/components/system/message-box/modal.vue @@ -3,12 +3,11 @@ title-align="start" :title="record.title" :top="80" - :width="720" :align-center="false" :unmount-on-close="true" ok-text="删除" :hide-cancel="true" - :ok-button-props="{ status: 'danger' }" + :ok-button-props="{ status: 'danger', size: 'small' }" :body-style="{ padding: '20px' }" @ok="emits('delete', record)">
    @@ -45,5 +44,6 @@ From a6209751de4dbe58c655566f2afb35e7b1ce3597 Mon Sep 17 00:00:00 2001 From: lijiahangmax Date: Wed, 15 May 2024 00:20:38 +0800 Subject: [PATCH 7/8] =?UTF-8?q?:construction:=20=E4=BF=AE=E6=94=B9=20exitC?= =?UTF-8?q?ode.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/update/v1.0.8.md | 44 +++++++++++++++++ .../asset/entity/domain/ExecHostLogDO.java | 4 +- .../module/asset/entity/vo/ExecHostLogVO.java | 2 +- .../handler/BaseExecCommandHandler.java | 2 +- .../handler/ExecCommandAnsiHandler.java | 10 ++-- .../service/impl/ExecLogServiceImpl.java | 2 +- .../resources/mapper/ExecHostLogMapper.xml | 4 +- orion-ops-ui/src/api/exec/exec-log.ts | 2 +- .../src/components/exec/log/panel/index.vue | 2 +- .../components/exec/log/panel/log-item.vue | 12 ++--- .../components/system/message-box/index.vue | 32 ++---------- .../components/system/message-box/list.vue | 17 ++----- .../components/system/message-box/modal.vue | 49 ------------------- .../components/exec-command-log-table.vue | 2 +- .../types/host-table.columns.ts | 6 +-- .../components/exec-job-log-table.vue | 2 +- 16 files changed, 76 insertions(+), 116 deletions(-) delete mode 100644 orion-ops-ui/src/components/system/message-box/modal.vue diff --git a/docs/update/v1.0.8.md b/docs/update/v1.0.8.md index 50b325e0..64d79312 100644 --- a/docs/update/v1.0.8.md +++ b/docs/update/v1.0.8.md @@ -3,9 +3,53 @@ > sql 脚本 - DDL ```sql +-- 修改字段名称 +ALTER TABLE `exec_host_log` +CHANGE COLUMN `exit_status` `exit_code` int(0) NULL DEFAULT NULL COMMENT '退出码' AFTER `parameter`; + +-- 系统消息 +DROP TABLE IF EXISTS `system_message`; +CREATE TABLE `system_message` +( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT 'id', + `classify` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '消息分类', + `type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '消息类型', + `status` tinyint(0) NULL DEFAULT NULL COMMENT '消息状态', + `rel_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '消息关联', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标题', + `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '消息内容', + `receiver_id` bigint(0) NULL DEFAULT NULL COMMENT '接收人id', + `receiver_username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '接收人用户名', + `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间', + `deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除 0未删除 1已删除', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_receiver_classify` (`receiver_id`, `classify`) USING BTREE +) ENGINE = InnoDB + AUTO_INCREMENT = 1 + CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_general_ci COMMENT = '系统消息' + ROW_FORMAT = Dynamic; ``` > sql 脚本 - DML ```sql +-- 菜单 +DELETE FROM system_menu WHERE id IN (161, 175, 197, 198) OR id > 202; +INSERT INTO `system_menu` VALUES (161, 176, '执行模板', NULL, 2, 50, 1, 1, 1, 0, 'IconBookmark', NULL, 'execTemplate', '2024-03-07 18:32:41', '2024-05-14 15:58:51', '1', '1', 0); +INSERT INTO `system_menu` VALUES (197, 176, '批量上传', NULL, 2, 30, 1, 1, 1, 0, 'IconUpload', NULL, 'batchUpload', '2024-05-08 22:12:23', '2024-05-14 15:58:44', '1', '1', 0); +INSERT INTO `system_menu` VALUES (198, 176, '上传任务', NULL, 2, 40, 1, 1, 1, 0, 'IconCloud', NULL, 'uploadTask', '2024-05-08 22:16:05', '2024-05-14 15:58:46', '1', '1', 0); + +-- 字典项 +DELETE FROM dict_key WHERE id >= 43; +INSERT INTO `dict_key` VALUES (43, 'messageType', 'STRING', '[{\"name\": \"tagLabel\", \"type\": \"STRING\"}, {\"name\": \"tagVisible\", \"type\": \"STRING\"}, {\"name\": \"tagColor\", \"type\": \"STRING\"}, {\"name\": \"redirectComponent\", \"type\": \"STRING\"}]', '消息类型', '2024-05-13 12:07:56', '2024-05-14 14:48:28', '1', '1', 0); +INSERT INTO `dict_key` VALUES (44, 'messageClassify', 'STRING', '[]', '消息分类', '2024-05-13 15:06:27', '2024-05-13 15:06:27', '1', '1', 0); + +-- 字典值 +DELETE FROM dict_value WHERE id >= 295; +INSERT INTO `dict_value` VALUES (295, 43, 'messageType', 'EXEC_FAILED', '执行失败', '{\"tagColor\": \"red\", \"tagLabel\": \"部分失败\", \"tagVisible\": \"true\", \"redirectComponent\": \"execCommand\"}', 10, '2024-05-13 12:07:56', '2024-05-14 15:19:19', '1', '1', 0); +INSERT INTO `dict_value` VALUES (296, 43, 'messageType', 'UPLOAD_FAILED', '上传失败', '{\"tagColor\": \"red\", \"tagLabel\": \"部分失败\", \"tagVisible\": \"true\", \"redirectComponent\": \"batchUpload\"}', 20, '2024-05-13 12:07:56', '2024-05-14 15:11:21', '1', '1', 0); +INSERT INTO `dict_value` VALUES (297, 44, 'messageClassify', 'NOTICE', '通知', '{}', 10, '2024-05-13 15:06:27', '2024-05-13 15:06:27', '1', '1', 0); +INSERT INTO `dict_value` VALUES (298, 44, 'messageClassify', 'TODO', '待办', '{}', 20, '2024-05-13 15:06:27', '2024-05-13 15:06:27', '1', '1', 0); ``` diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/ExecHostLogDO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/ExecHostLogDO.java index e6e950c5..3c9e1fee 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/ExecHostLogDO.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/domain/ExecHostLogDO.java @@ -61,8 +61,8 @@ public class ExecHostLogDO extends BaseDO { private String parameter; @Schema(description = "退出码") - @TableField("exit_status") - private Integer exitStatus; + @TableField("exit_code") + private Integer exitCode; @Schema(description = "日志路径") @TableField("log_path") diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecHostLogVO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecHostLogVO.java index 5260a96f..6824aaf0 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecHostLogVO.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/vo/ExecHostLogVO.java @@ -50,7 +50,7 @@ public class ExecHostLogVO implements Serializable { private String parameter; @Schema(description = "退出码") - private Integer exitStatus; + private Integer exitCode; @Schema(description = "错误信息") private String errorMessage; diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java index 78c3c1da..b8a2aecd 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/BaseExecCommandHandler.java @@ -230,7 +230,7 @@ public abstract class BaseExecCommandHandler implements IExecCommandHandler { } else if (ExecHostStatusEnum.COMPLETED.equals(status)) { // 完成 updateRecord.setFinishTime(new Date()); - updateRecord.setExitStatus(executor.getExitCode()); + updateRecord.setExitCode(executor.getExitCode()); this.exitCode = executor.getExitCode(); } else if (ExecHostStatusEnum.FAILED.equals(status)) { // 失败 diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandAnsiHandler.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandAnsiHandler.java index 744bd2e5..b313457f 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandAnsiHandler.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/handler/host/exec/command/handler/ExecCommandAnsiHandler.java @@ -149,17 +149,17 @@ public class ExecCommandAnsiHandler extends BaseExecCommandHandler { .append(Dates.current()) .newLine(); } else { - long ms = this.updateRecord.getFinishTime().getTime() - this.updateRecord.getStartTime().getTime(); - Integer exitStatus = this.updateRecord.getExitStatus(); + long ms = updateRecord.getFinishTime().getTime() - updateRecord.getStartTime().getTime(); + Integer exitCode = updateRecord.getExitCode(); // 执行完成 appender.append(AnsiForeground.BRIGHT_GREEN, "< 命令执行完成 ") .append(Dates.current()) .newLine() .append(AnsiForeground.BRIGHT_BLUE, "exit: "); - if (ExitCode.isSuccess(exitStatus)) { - appender.append(AnsiForeground.BRIGHT_GREEN, exitStatus); + if (ExitCode.isSuccess(exitCode)) { + appender.append(AnsiForeground.BRIGHT_GREEN, exitCode); } else { - appender.append(AnsiForeground.BRIGHT_RED, exitStatus); + appender.append(AnsiForeground.BRIGHT_RED, exitCode); } appender.newLine() .append(AnsiForeground.BRIGHT_BLUE, "used: ") diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java index 110d33af..a11cb412 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/ExecLogServiceImpl.java @@ -156,7 +156,7 @@ public class ExecLogServiceImpl implements ExecLogService { ExecHostLogDO::getStatus, ExecHostLogDO::getStartTime, ExecHostLogDO::getFinishTime, - ExecHostLogDO::getExitStatus, + ExecHostLogDO::getExitCode, ExecHostLogDO::getErrorMessage) .in(ExecHostLogDO::getLogId, idList) .then() diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/ExecHostLogMapper.xml b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/ExecHostLogMapper.xml index 98177313..1f4b1991 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/ExecHostLogMapper.xml +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/ExecHostLogMapper.xml @@ -12,7 +12,7 @@ - + @@ -27,7 +27,7 @@ - id, log_id, host_id, host_name, host_address, status, command, parameter, exit_status, log_path, script_path, error_message, start_time, finish_time, create_time, update_time, creator, updater, deleted + id, log_id, host_id, host_name, host_address, status, command, parameter, exit_code, log_path, script_path, error_message, start_time, finish_time, create_time, update_time, creator, updater, deleted diff --git a/orion-ops-ui/src/api/exec/exec-log.ts b/orion-ops-ui/src/api/exec/exec-log.ts index 1a3f4245..bd15063b 100644 --- a/orion-ops-ui/src/api/exec/exec-log.ts +++ b/orion-ops-ui/src/api/exec/exec-log.ts @@ -54,7 +54,7 @@ export interface ExecHostLogQueryResponse extends TableData { status: string; command: string; parameter: string; - exitStatus: number; + exitCode: number; errorMessage: string; startTime: number; finishTime: number; diff --git a/orion-ops-ui/src/components/exec/log/panel/index.vue b/orion-ops-ui/src/components/exec/log/panel/index.vue index 0953a709..8221497c 100644 --- a/orion-ops-ui/src/components/exec/log/panel/index.vue +++ b/orion-ops-ui/src/components/exec/log/panel/index.vue @@ -95,7 +95,7 @@ host.startTime = hostStatus.startTime; // 结束时间绑定了使用时间 如果未完成则使用当前时间 host.finishTime = hostStatus.finishTime || Date.now(); - host.exitStatus = hostStatus.exitStatus; + host.exitCode = hostStatus.exitCode; host.errorMessage = hostStatus.errorMessage; } } diff --git a/orion-ops-ui/src/components/exec/log/panel/log-item.vue b/orion-ops-ui/src/components/exec/log/panel/log-item.vue index 228832b9..1082a4e7 100644 --- a/orion-ops-ui/src/components/exec/log/panel/log-item.vue +++ b/orion-ops-ui/src/components/exec/log/panel/log-item.vue @@ -12,15 +12,15 @@ {{ getDictValue(execHostStatusKey, host.status) }} - - + + - {{ host.exitStatus }} + {{ host.exitCode }} + :key="item.value as string"> @@ -51,11 +51,7 @@ :message-list="messageList" @load="loadMessage" @click="clickMessage" - @view="viewMessage" @delete="deleteMessage" /> - -
    @@ -78,11 +74,10 @@ } from '@/api/system/message'; import useLoading from '@/hooks/loading'; import { useRouter } from 'vue-router'; + import { clearHtmlTag, replaceHtmlTag } from '@/utils'; import { useDictStore } from '@/store'; import { dictKeys, messageClassifyKey, messageTypeKey, defaultClassify, MESSAGE_CONFIG_KEY, messageLimit, MessageStatus } from './const'; import List from './list.vue'; - import Modal from './modal.vue'; - import { clearHtmlTag, replaceHtmlTag } from '@/utils'; const { loading: fetchLoading, setLoading: setFetchLoading } = useLoading(); const { loading: messageLoading, setLoading: setMessageLoading } = useLoading(); @@ -94,7 +89,6 @@ const classifyCount = ref>({}); const messageList = ref>([]); const hasMore = ref(true); - const modalRef = ref(); // 重新加载消息 const reloadAllMessage = async () => { @@ -193,26 +187,6 @@ if (redirectComponent && redirectComponent !== '0') { // 跳转组件 router.push({ name: redirectComponent, query: { key: message.relKey } }); - } else { - // 打开消息模态框 - modalRef.value.open(message); - } - }; - - // 查看消息 - const viewMessage = async (message: MessageRecordResponse) => { - setMessageLoading(true); - try { - // 设置为已读 - if (message.status === MessageStatus.UNREAD) { - await updateSystemMessageRead(message.id); - message.status = MessageStatus.READ; - } - // 打开消息模态框 - modalRef.value.open(message); - } catch (ex) { - } finally { - setMessageLoading(false); } }; diff --git a/orion-ops-ui/src/components/system/message-box/list.vue b/orion-ops-ui/src/components/system/message-box/list.vue index 815e2250..1920a21d 100644 --- a/orion-ops-ui/src/components/system/message-box/list.vue +++ b/orion-ops-ui/src/components/system/message-box/list.vue @@ -33,20 +33,13 @@
    - - - 查看 -
    -
    +
    - {{ dateFormat(new Date(message.createTime))}} + {{ dateFormat(new Date(message.createTime)) }}
    @@ -98,7 +89,7 @@ import { useDictStore } from '@/store'; import { dateFormat } from '@/utils'; - const emits = defineEmits(['load', 'click', 'view', 'delete']); + const emits = defineEmits(['load', 'click', 'delete']); const props = defineProps<{ fetchLoading: boolean; messageLoading: boolean; diff --git a/orion-ops-ui/src/components/system/message-box/modal.vue b/orion-ops-ui/src/components/system/message-box/modal.vue deleted file mode 100644 index 0a787900..00000000 --- a/orion-ops-ui/src/components/system/message-box/modal.vue +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - diff --git a/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue b/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue index 3036d1a1..0ac7e2cf 100644 --- a/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue +++ b/orion-ops-ui/src/views/exec/exec-command-log/components/exec-command-log-table.vue @@ -374,7 +374,7 @@ host.status = s.status; host.startTime = s.startTime; host.finishTime = s.finishTime; - host.exitStatus = s.exitStatus; + host.exitCode = s.exitCode; host.errorMessage = s.errorMessage; }); }; diff --git a/orion-ops-ui/src/views/exec/exec-command-log/types/host-table.columns.ts b/orion-ops-ui/src/views/exec/exec-command-log/types/host-table.columns.ts index cb18fd99..04997dc3 100644 --- a/orion-ops-ui/src/views/exec/exec-command-log/types/host-table.columns.ts +++ b/orion-ops-ui/src/views/exec/exec-command-log/types/host-table.columns.ts @@ -18,12 +18,12 @@ const columns = [ tooltip: true, }, { title: '退出码', - dataIndex: 'exitStatus', - slotName: 'exitStatus', + dataIndex: 'exitCode', + slotName: 'exitCode', align: 'left', width: 118, render: ({ record }) => { - return isNumber(record.exitStatus) ? record.exitStatus : '-'; + return isNumber(record.exitCode) ? record.exitCode : '-'; }, }, { title: '执行状态', diff --git a/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue b/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue index 84dcfcfb..89a1350f 100644 --- a/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue +++ b/orion-ops-ui/src/views/job/exec-job-log/components/exec-job-log-table.vue @@ -339,7 +339,7 @@ host.status = s.status; host.startTime = s.startTime; host.finishTime = s.finishTime; - host.exitStatus = s.exitStatus; + host.exitCode = s.exitCode; host.errorMessage = s.errorMessage; }); }; From 81b7c7d5927d6b680d0c5e405b179312e9100633 Mon Sep 17 00:00:00 2001 From: lijiahangmax Date: Wed, 15 May 2024 00:21:16 +0800 Subject: [PATCH 8/8] =?UTF-8?q?:pencil:=20=E4=BF=AE=E6=94=B9=E6=96=87?= =?UTF-8?q?=E6=A1=A3.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sql/init-2-schema-tables.sql | 28 +++++++++++++++++++++++++++- sql/init-4-data.sql | 13 +++++++++---- 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/sql/init-2-schema-tables.sql b/sql/init-2-schema-tables.sql index 3b4851df..411548dc 100644 --- a/sql/init-2-schema-tables.sql +++ b/sql/init-2-schema-tables.sql @@ -211,7 +211,7 @@ CREATE TABLE `exec_host_log` `status` char(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '执行状态', `command` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '执行命令', `parameter` json NULL COMMENT '执行参数', - `exit_status` int(0) NULL DEFAULT NULL COMMENT '退出码', + `exit_code` int(0) NULL DEFAULT NULL COMMENT '退出码', `log_path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '日志路径', `script_path` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '脚本路径', `error_message` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '错误信息', @@ -644,6 +644,32 @@ CREATE TABLE `system_menu` COLLATE = utf8mb4_unicode_ci COMMENT = '菜单表' ROW_FORMAT = Dynamic; +-- ---------------------------- +-- Table structure for system_message +-- ---------------------------- +DROP TABLE IF EXISTS `system_message`; +CREATE TABLE `system_message` +( + `id` bigint(0) NOT NULL AUTO_INCREMENT COMMENT 'id', + `classify` char(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '消息分类', + `type` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '消息类型', + `status` tinyint(0) NULL DEFAULT NULL COMMENT '消息状态', + `rel_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '消息关联', + `title` varchar(128) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '标题', + `content` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL COMMENT '消息内容', + `receiver_id` bigint(0) NULL DEFAULT NULL COMMENT '接收人id', + `receiver_username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '接收人用户名', + `create_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', + `update_time` datetime(0) NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间', + `deleted` tinyint(1) NULL DEFAULT 0 COMMENT '是否删除 0未删除 1已删除', + PRIMARY KEY (`id`) USING BTREE, + INDEX `idx_receiver_classify` (`receiver_id`, `classify`) USING BTREE +) ENGINE = InnoDB + AUTO_INCREMENT = 1 + CHARACTER SET = utf8mb4 + COLLATE = utf8mb4_general_ci COMMENT = '系统消息' + ROW_FORMAT = Dynamic; + -- ---------------------------- -- Table structure for system_role -- ---------------------------- diff --git a/sql/init-4-data.sql b/sql/init-4-data.sql index 7be2941c..7c0d8a01 100644 --- a/sql/init-4-data.sql +++ b/sql/init-4-data.sql @@ -90,7 +90,7 @@ INSERT INTO `system_menu` VALUES (157, 122, '清空操作日志', 'infra:operato INSERT INTO `system_menu` VALUES (158, 152, '文件操作日志', NULL, 2, 30, 1, 1, 1, 0, 'IconFile', NULL, 'sftpLog', '2024-03-05 15:30:13', '2024-05-07 11:11:24', '1', '1', 0); INSERT INTO `system_menu` VALUES (159, 158, '查询文件操作日志', 'asset:host-sftp-log:management:query', 3, 10, 1, 1, 1, 0, NULL, NULL, NULL, '2024-03-05 15:31:02', '2024-04-12 14:49:18', '1', '1', 0); INSERT INTO `system_menu` VALUES (160, 158, '删除文件操作日志', 'asset:host-sftp-log:management:delete', 3, 20, 1, 1, 1, 0, NULL, NULL, NULL, '2024-03-05 15:31:17', '2024-04-12 14:49:21', '1', '1', 0); -INSERT INTO `system_menu` VALUES (161, 176, '执行模板', NULL, 2, 60, 1, 1, 1, 0, 'IconBookmark', NULL, 'execTemplate', '2024-03-07 18:32:41', '2024-04-28 17:14:30', '1', '1', 0); +INSERT INTO `system_menu` VALUES (161, 176, '执行模板', NULL, 2, 50, 1, 1, 1, 0, 'IconBookmark', NULL, 'execTemplate', '2024-03-07 18:32:41', '2024-05-14 15:58:51', '1', '1', 0); INSERT INTO `system_menu` VALUES (162, 161, '查询执行模板', 'asset:exec-template:query', 3, 10, 1, 1, 1, 0, NULL, NULL, NULL, '2024-03-07 18:32:41', '2024-03-07 18:32:41', '1', '1', 0); INSERT INTO `system_menu` VALUES (163, 161, '创建执行模板', 'asset:exec-template:create', 3, 20, 1, 1, 1, 0, NULL, NULL, NULL, '2024-03-07 18:32:41', '2024-03-07 18:32:41', '1', '1', 0); INSERT INTO `system_menu` VALUES (164, 161, '修改执行模板', 'asset:exec-template:update', 3, 30, 1, 1, 1, 0, NULL, NULL, NULL, '2024-03-07 18:32:41', '2024-03-07 18:32:41', '1', '1', 0); @@ -102,7 +102,6 @@ INSERT INTO `system_menu` VALUES (171, 167, '清理执行日志', 'asset:exec-co INSERT INTO `system_menu` VALUES (172, 176, '命令执行', NULL, 2, 10, 1, 1, 1, 0, 'icon-thunderbolt', NULL, 'execCommand', '2024-03-13 15:08:23', '2024-05-08 21:58:24', '1', '1', 0); INSERT INTO `system_menu` VALUES (173, 172, '执行命令', 'asset:exec-command:exec', 3, 10, 1, 1, 1, 0, NULL, NULL, NULL, '2024-03-13 15:08:23', '2024-04-10 22:04:32', '1', '1', 0); INSERT INTO `system_menu` VALUES (174, 167, '中断批量执行', 'asset:exec-command-log:interrupt', 3, 40, 1, 1, 1, 0, NULL, NULL, NULL, '2024-03-13 15:25:36', '2024-04-12 12:48:36', '1', '1', 0); -INSERT INTO `system_menu` VALUES (175, 176, '批量执行日志新页面', NULL, 2, 30, 0, 1, 0, 1, '', NULL, 'execCommandLogView', '2024-03-21 14:03:10', '2024-04-11 23:45:08', '1', '1', 0); INSERT INTO `system_menu` VALUES (176, 0, '批量执行', NULL, 1, 420, 1, 1, 1, 0, 'icon-relation', NULL, 'execModule', '2024-04-10 16:13:27', '2024-04-28 15:30:31', '1', '1', 0); INSERT INTO `system_menu` VALUES (177, 193, '任务列表', NULL, 2, 10, 1, 1, 1, 0, 'IconUnorderedList', NULL, 'execJob', '2024-04-10 16:13:27', '2024-04-28 15:36:10', '1', '1', 0); INSERT INTO `system_menu` VALUES (178, 177, '查询计划任务', 'asset:exec-job:query', 3, 10, 1, 1, 1, 0, NULL, NULL, NULL, '2024-04-10 16:13:27', '2024-04-10 16:13:27', '1', '1', 0); @@ -123,8 +122,8 @@ INSERT INTO `system_menu` VALUES (193, 0, '计划任务', NULL, 1, 430, 1, 1, 1, INSERT INTO `system_menu` VALUES (194, 152, '在线会话', NULL, 2, 20, 1, 1, 1, 0, 'IconUserGroup', NULL, 'connectSession', '2024-05-07 11:12:17', '2024-05-07 11:12:35', '1', '1', 0); INSERT INTO `system_menu` VALUES (195, 194, '查询在线会话', 'asset:host-connect-session:management:query', 3, 10, 1, 1, 1, 0, NULL, NULL, NULL, '2024-05-07 11:13:16', '2024-05-07 11:13:16', '1', '1', 0); INSERT INTO `system_menu` VALUES (196, 194, '强制断开连接', 'asset:host-connect-session:management:force-offline', 3, 20, 1, 1, 1, 0, NULL, NULL, NULL, '2024-05-07 11:13:37', '2024-05-07 11:13:37', '1', '1', 0); -INSERT INTO `system_menu` VALUES (197, 176, '批量上传', NULL, 2, 40, 1, 1, 1, 0, 'IconUpload', NULL, 'batchUpload', '2024-05-08 22:12:23', '2024-05-08 22:12:23', '1', '1', 0); -INSERT INTO `system_menu` VALUES (198, 176, '上传任务', NULL, 2, 50, 1, 1, 1, 0, 'IconCloud', NULL, 'uploadTask', '2024-05-08 22:16:05', '2024-05-10 23:09:58', '1', '1', 0); +INSERT INTO `system_menu` VALUES (197, 176, '批量上传', NULL, 2, 30, 1, 1, 1, 0, 'IconUpload', NULL, 'batchUpload', '2024-05-08 22:12:23', '2024-05-14 15:58:44', '1', '1', 0); +INSERT INTO `system_menu` VALUES (198, 176, '上传任务', NULL, 2, 40, 1, 1, 1, 0, 'IconCloud', NULL, 'uploadTask', '2024-05-08 22:16:05', '2024-05-14 15:58:46', '1', '1', 0); INSERT INTO `system_menu` VALUES (199, 197, '上传文件', 'asset:upload-task:upload', 3, 10, 1, 1, 1, 0, NULL, NULL, NULL, '2024-05-08 22:19:35', '2024-05-08 22:19:35', '1', '1', 0); INSERT INTO `system_menu` VALUES (200, 198, '查询上传日志', 'asset:upload-task:query', 3, 10, 1, 1, 1, 0, NULL, NULL, NULL, '2024-05-08 22:20:01', '2024-05-08 22:20:01', '1', '1', 0); INSERT INTO `system_menu` VALUES (201, 198, '删除上传日志', 'asset:upload-task:delete', 3, 20, 1, 1, 1, 0, NULL, NULL, NULL, '2024-05-08 22:20:26', '2024-05-08 22:20:26', '1', '1', 0); @@ -165,6 +164,8 @@ INSERT INTO `dict_key` VALUES (39, 'pathBookmarkType', 'STRING', '[]', '路径 INSERT INTO `dict_key` VALUES (40, 'sftpTransferStatus', 'STRING', '[{\"name\": \"status\", \"type\": \"STRING\"}, {\"name\": \"color\", \"type\": \"COLOR\"}, {\"name\": \"icon\", \"type\": \"STRING\"}]', 'SFTP 传输状态', '2024-05-06 11:54:49', '2024-05-06 11:54:49', '1', '1', 0); INSERT INTO `dict_key` VALUES (41, 'uploadTaskStatus', 'STRING', '[{\"name\": \"color\", \"type\": \"COLOR\"}]', '上传任务状态', '2024-05-07 22:18:48', '2024-05-08 22:06:23', '1', '1', 0); INSERT INTO `dict_key` VALUES (42, 'uploadTaskFileStatus', 'STRING', '[{\"name\": \"status\", \"type\": \"STRING\"}]', '上传任务文件状态', '2024-05-08 10:30:29', '2024-05-10 17:34:13', '1', '1', 0); +INSERT INTO `dict_key` VALUES (43, 'messageType', 'STRING', '[{\"name\": \"tagLabel\", \"type\": \"STRING\"}, {\"name\": \"tagVisible\", \"type\": \"STRING\"}, {\"name\": \"tagColor\", \"type\": \"STRING\"}, {\"name\": \"redirectComponent\", \"type\": \"STRING\"}]', '消息类型', '2024-05-13 12:07:56', '2024-05-14 14:48:28', '1', '1', 0); +INSERT INTO `dict_key` VALUES (44, 'messageClassify', 'STRING', '[]', '消息分类', '2024-05-13 15:06:27', '2024-05-13 15:06:27', '1', '1', 0); -- 字典值 INSERT INTO `dict_value` VALUES (3, 4, 'systemMenuType', '1', '父菜单', '{}', 10, '2023-10-26 15:58:59', '2023-10-26 15:58:59', '1', '1', 0); @@ -405,3 +406,7 @@ INSERT INTO `dict_value` VALUES (291, 2, 'operatorLogType', 'upload-task:cancel' INSERT INTO `dict_value` VALUES (292, 2, 'operatorLogType', 'upload-task:delete', '删除上传记录', '{}', 30, '2024-05-08 22:23:44', '2024-05-08 22:23:44', '1', '1', 0); INSERT INTO `dict_value` VALUES (293, 2, 'operatorLogType', 'upload-task:clear', '清理上传记录', '{}', 40, '2024-05-08 22:23:59', '2024-05-08 22:23:59', '1', '1', 0); INSERT INTO `dict_value` VALUES (294, 41, 'uploadTaskStatus', 'FAILED', '已失败', '{\"color\": \"red\"}', 40, '2024-05-10 11:29:17', '2024-05-10 11:29:17', '1', '1', 0); +INSERT INTO `dict_value` VALUES (295, 43, 'messageType', 'EXEC_FAILED', '执行失败', '{\"tagColor\": \"red\", \"tagLabel\": \"部分失败\", \"tagVisible\": \"true\", \"redirectComponent\": \"execCommand\"}', 10, '2024-05-13 12:07:56', '2024-05-14 15:19:19', '1', '1', 0); +INSERT INTO `dict_value` VALUES (296, 43, 'messageType', 'UPLOAD_FAILED', '上传失败', '{\"tagColor\": \"red\", \"tagLabel\": \"部分失败\", \"tagVisible\": \"true\", \"redirectComponent\": \"batchUpload\"}', 20, '2024-05-13 12:07:56', '2024-05-14 15:11:21', '1', '1', 0); +INSERT INTO `dict_value` VALUES (297, 44, 'messageClassify', 'NOTICE', '通知', '{}', 10, '2024-05-13 15:06:27', '2024-05-13 15:06:27', '1', '1', 0); +INSERT INTO `dict_value` VALUES (298, 44, 'messageClassify', 'TODO', '待办', '{}', 20, '2024-05-13 15:06:27', '2024-05-13 15:06:27', '1', '1', 0);