diff --git a/docs/about/change-log.md b/docs/about/change-log.md index 323fab1c..d4c4c261 100644 --- a/docs/about/change-log.md +++ b/docs/about/change-log.md @@ -11,6 +11,7 @@ * 🩰 修改 命令执行日志 UI 修改 * 🌈 新增 命令执行模板配置默认主机 * 🌈 新增 主机终端书签路径 +* 🔨 优化 通用分组模型添加 `userId` * 🔨 优化 退出登录不重定向 * 🔨 优化 动态设置页面标题 * 🔨 优化 终端断开后回车重连 diff --git a/docs/update/v1.0.6.md b/docs/update/v1.0.6.md index c1a85c78..5928668f 100644 --- a/docs/update/v1.0.6.md +++ b/docs/update/v1.0.6.md @@ -3,9 +3,41 @@ > sql 脚本 - DDL ```sql +-- 数据分组添加 userId +ALTER TABLE `data_group` +ADD COLUMN `user_id` bigint(0) NULL COMMENT '用户id' AFTER `type`, +MODIFY COLUMN `name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组名称' AFTER `user_id`, +DROP INDEX `idx_type`, +ADD INDEX `idx_type_user`(`type`, `user_id`) USING BTREE; + +ALTER TABLE `data_group_rel` +MODIFY COLUMN `type` char(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '组类型' AFTER `id`, +ADD COLUMN `user_id` bigint(0) NULL COMMENT '用户id' AFTER `type`, +DROP INDEX `idx_type`, +ADD INDEX `idx_type_user`(`type`, `user_id`) USING BTREE; ``` > sql 脚本 - DML ```sql +-- 设置数据分组 user_id +UPDATE data_group SET user_id = 0; +UPDATE data_group_rel SET user_id = 0; +``` + +> sql 脚本 - 命令分组初始化 + +```sql +-- 插入命令片段分组 +INSERT INTO `data_group` (`parent_id`, `type`, `user_id`, `name`, `sort`, `creator`, `updater`, `deleted`) +SELECT 0, 'COMMAND_SNIPPET', user_id, name, id, creator, updater, deleted +FROM command_snippet_group; + +-- 需要命令分组 groupId +UPDATE command_snippet s +LEFT JOIN data_group g ON g.type = 'COMMAND_SNIPPET' AND g.sort = s.group_id +SET s.group_id = g.id; + +-- 删除命令片段分组表 +DROP TABLE command_snippet_group; ``` diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/CommandSnippetGroupConvert.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/CommandSnippetGroupConvert.java index 660e4350..a926d44f 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/CommandSnippetGroupConvert.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/convert/CommandSnippetGroupConvert.java @@ -1,10 +1,12 @@ package com.orion.ops.module.asset.convert; import com.orion.ops.module.asset.entity.domain.CommandSnippetGroupDO; -import com.orion.ops.module.asset.entity.dto.CommandSnippetGroupCacheDTO; import com.orion.ops.module.asset.entity.request.command.CommandSnippetGroupCreateRequest; import com.orion.ops.module.asset.entity.request.command.CommandSnippetGroupUpdateRequest; import com.orion.ops.module.asset.entity.vo.CommandSnippetGroupVO; +import com.orion.ops.module.infra.entity.dto.data.DataGroupCreateDTO; +import com.orion.ops.module.infra.entity.dto.data.DataGroupDTO; +import com.orion.ops.module.infra.entity.dto.data.DataGroupRenameDTO; import org.mapstruct.Mapper; import org.mapstruct.factory.Mappers; @@ -22,16 +24,12 @@ public interface CommandSnippetGroupConvert { CommandSnippetGroupConvert MAPPER = Mappers.getMapper(CommandSnippetGroupConvert.class); - CommandSnippetGroupDO to(CommandSnippetGroupCreateRequest request); + DataGroupCreateDTO to(CommandSnippetGroupCreateRequest request); - CommandSnippetGroupDO to(CommandSnippetGroupUpdateRequest request); + DataGroupRenameDTO to(CommandSnippetGroupUpdateRequest request); - CommandSnippetGroupVO to(CommandSnippetGroupDO domain); + CommandSnippetGroupVO to(DataGroupDTO domain); List to(List list); - CommandSnippetGroupVO to(CommandSnippetGroupCacheDTO cache); - - CommandSnippetGroupCacheDTO toCache(CommandSnippetGroupDO domain); - } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/CommandSnippetGroupDAO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/CommandSnippetGroupDAO.java deleted file mode 100644 index d8aa7c9f..00000000 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/dao/CommandSnippetGroupDAO.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.orion.ops.module.asset.dao; - -import com.orion.ops.framework.mybatis.core.mapper.IMapper; -import com.orion.ops.module.asset.entity.domain.CommandSnippetGroupDO; -import org.apache.ibatis.annotations.Mapper; - -/** - * 命令片段分组 Mapper 接口 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2024-1-24 12:28 - */ -@Mapper -public interface CommandSnippetGroupDAO extends IMapper { - -} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/cache/CommandSnippetCacheKeyDefine.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/cache/CommandSnippetCacheKeyDefine.java index c9d998ad..764f4d20 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/cache/CommandSnippetCacheKeyDefine.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/define/cache/CommandSnippetCacheKeyDefine.java @@ -25,12 +25,4 @@ public interface CommandSnippetCacheKeyDefine { .timeout(8, TimeUnit.HOURS) .build(); - CacheKeyDefine SNIPPET_GROUP = new CacheKeyBuilder() - .key("command:snippet:group:{}") - .desc("命令片段分组 ${userId}") - .type(CommandSnippetGroupCacheDTO.class) - .struct(RedisCacheStruct.HASH) - .timeout(8, TimeUnit.HOURS) - .build(); - } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/dto/CommandSnippetGroupCacheDTO.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/dto/CommandSnippetGroupCacheDTO.java deleted file mode 100644 index 0475aa43..00000000 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/entity/dto/CommandSnippetGroupCacheDTO.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.orion.ops.module.asset.entity.dto; - -import com.orion.lang.define.cache.key.model.LongCacheIdModel; -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.0 - * @since 2024-1-24 12:28 - */ -@Data -@Builder -@NoArgsConstructor -@AllArgsConstructor -@Schema(name = "CommandSnippetGroupCacheDTO", description = "命令片段分组 缓存对象") -public class CommandSnippetGroupCacheDTO implements LongCacheIdModel, Serializable { - - private static final long serialVersionUID = 1L; - - @Schema(description = "id") - private Long id; - - @Schema(description = "分组名称") - private String name; - -} diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/CommandSnippetGroupServiceImpl.java b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/CommandSnippetGroupServiceImpl.java index a19efd1d..accb02e2 100644 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/CommandSnippetGroupServiceImpl.java +++ b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/java/com/orion/ops/module/asset/service/impl/CommandSnippetGroupServiceImpl.java @@ -1,24 +1,24 @@ package com.orion.ops.module.asset.service.impl; import com.alibaba.fastjson.JSON; -import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.orion.lang.utils.Booleans; +import com.orion.ops.framework.common.constant.Const; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.utils.Valid; -import com.orion.ops.framework.redis.core.utils.RedisMaps; -import com.orion.ops.framework.redis.core.utils.barrier.CacheBarriers; import com.orion.ops.framework.security.core.utils.SecurityUtils; import com.orion.ops.module.asset.convert.CommandSnippetGroupConvert; -import com.orion.ops.module.asset.dao.CommandSnippetGroupDAO; -import com.orion.ops.module.asset.define.cache.CommandSnippetCacheKeyDefine; -import com.orion.ops.module.asset.entity.domain.CommandSnippetGroupDO; -import com.orion.ops.module.asset.entity.dto.CommandSnippetGroupCacheDTO; import com.orion.ops.module.asset.entity.request.command.CommandSnippetGroupCreateRequest; import com.orion.ops.module.asset.entity.request.command.CommandSnippetGroupDeleteRequest; import com.orion.ops.module.asset.entity.request.command.CommandSnippetGroupUpdateRequest; import com.orion.ops.module.asset.entity.vo.CommandSnippetGroupVO; import com.orion.ops.module.asset.service.CommandSnippetGroupService; import com.orion.ops.module.asset.service.CommandSnippetService; +import com.orion.ops.module.infra.api.DataGroupApi; +import com.orion.ops.module.infra.api.DataGroupUserApi; +import com.orion.ops.module.infra.entity.dto.data.DataGroupCreateDTO; +import com.orion.ops.module.infra.entity.dto.data.DataGroupDTO; +import com.orion.ops.module.infra.entity.dto.data.DataGroupRenameDTO; +import com.orion.ops.module.infra.enums.DataGroupTypeEnum; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -40,7 +40,10 @@ import java.util.stream.Collectors; public class CommandSnippetGroupServiceImpl implements CommandSnippetGroupService { @Resource - private CommandSnippetGroupDAO commandSnippetGroupDAO; + private DataGroupApi dataGroupApi; + + @Resource + private DataGroupUserApi dataGroupUserApi; @Resource private CommandSnippetService commandSnippetService; @@ -49,81 +52,40 @@ public class CommandSnippetGroupServiceImpl implements CommandSnippetGroupServic public Long createCommandSnippetGroup(CommandSnippetGroupCreateRequest request) { Long userId = SecurityUtils.getLoginUserId(); log.info("CommandSnippetGroupService-createCommandSnippetGroup request: {}", JSON.toJSONString(request)); - // 转换 - CommandSnippetGroupDO record = CommandSnippetGroupConvert.MAPPER.to(request); - record.setUserId(userId); - // 查询数据是否冲突 - this.checkCommandSnippetGroupPresent(record); - // 插入 - int effect = commandSnippetGroupDAO.insert(record); - Long id = record.getId(); - log.info("CommandSnippetGroupService-createCommandSnippetGroup id: {}, effect: {}", id, effect); - // 删除缓存 - String cacheKey = CommandSnippetCacheKeyDefine.SNIPPET_GROUP.format(userId); - RedisMaps.delete(cacheKey); - return id; + // 创建 + DataGroupCreateDTO create = CommandSnippetGroupConvert.MAPPER.to(request); + create.setParentId(Const.ROOT_PARENT_ID); + return dataGroupUserApi.createDataGroup(DataGroupTypeEnum.COMMAND_SNIPPET, userId, create); } @Override public Integer updateCommandSnippetGroupById(CommandSnippetGroupUpdateRequest request) { Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING); log.info("CommandSnippetGroupService-updateCommandSnippetGroupById id: {}, request: {}", id, JSON.toJSONString(request)); - // 查询 - CommandSnippetGroupDO record = commandSnippetGroupDAO.selectById(id); - Valid.notNull(record, ErrorMessage.DATA_ABSENT); - // 转换 - CommandSnippetGroupDO updateRecord = CommandSnippetGroupConvert.MAPPER.to(request); - updateRecord.setUserId(record.getUserId()); - // 查询数据是否冲突 - this.checkCommandSnippetGroupPresent(updateRecord); - // 更新 - int effect = commandSnippetGroupDAO.updateById(updateRecord); - log.info("CommandSnippetGroupService-updateCommandSnippetGroupById effect: {}", effect); - // 删除缓存 - String cacheKey = CommandSnippetCacheKeyDefine.SNIPPET_GROUP.format(record.getUserId()); - RedisMaps.delete(cacheKey); - return effect; + // 重命名 + DataGroupRenameDTO rename = CommandSnippetGroupConvert.MAPPER.to(request); + return dataGroupApi.renameDataGroup(rename); } @Override public List getCommandSnippetGroupList() { Long userId = SecurityUtils.getLoginUserId(); - // 查询缓存 - String cacheKey = CommandSnippetCacheKeyDefine.SNIPPET_GROUP.format(userId); - List list = RedisMaps.valuesJson(cacheKey, CommandSnippetCacheKeyDefine.SNIPPET_GROUP); - if (list.isEmpty()) { - // 查询数据库 - list = commandSnippetGroupDAO.of() - .createWrapper() - .eq(CommandSnippetGroupDO::getUserId, userId) - .then() - .list(CommandSnippetGroupConvert.MAPPER::toCache); - // 设置屏障 防止穿透 - CacheBarriers.checkBarrier(list, CommandSnippetGroupCacheDTO::new); - // 设置缓存 - RedisMaps.putAllJson(cacheKey, s -> s.getId().toString(), list); - } - // 删除屏障 - CacheBarriers.removeBarrier(list); - // 转换 - return list.stream() + // 查询分组 + return dataGroupUserApi.getDataGroupList(DataGroupTypeEnum.COMMAND_SNIPPET, userId) + .stream() + .sorted(Comparator.comparing(DataGroupDTO::getSort)) .map(CommandSnippetGroupConvert.MAPPER::to) - .sorted(Comparator.comparing(CommandSnippetGroupVO::getId)) .collect(Collectors.toList()); } @Override @Transactional(rollbackFor = Exception.class) public Integer deleteCommandSnippetGroup(CommandSnippetGroupDeleteRequest request) { + Long userId = SecurityUtils.getLoginUserId(); Long id = request.getId(); log.info("CommandSnippetGroupService-deleteCommandSnippetGroupById id: {}", id); - // 检查数据是否存在 - CommandSnippetGroupDO record = commandSnippetGroupDAO.selectById(id); - Valid.notNull(record, ErrorMessage.DATA_ABSENT); - Long userId = record.getUserId(); - // 删除 - int effect = commandSnippetGroupDAO.deleteById(id); - log.info("CommandSnippetGroupService-deleteCommandSnippetGroupById id: {}, effect: {}", id, effect); + // 删除分组 + Integer effect = dataGroupApi.deleteDataGroupById(id); if (Booleans.isTrue(request.getDeleteItem())) { // 删除组内数据 commandSnippetService.deleteByGroupId(userId, id); @@ -131,28 +93,7 @@ public class CommandSnippetGroupServiceImpl implements CommandSnippetGroupServic // 移动到根节点 commandSnippetService.setGroupNull(userId, id); } - // 删除缓存 - String cacheKey = CommandSnippetCacheKeyDefine.SNIPPET_GROUP.format(userId); - RedisMaps.delete(cacheKey, id); return effect; } - /** - * 检查对象是否存在 - * - * @param domain domain - */ - private void checkCommandSnippetGroupPresent(CommandSnippetGroupDO domain) { - // 构造条件 - LambdaQueryWrapper wrapper = commandSnippetGroupDAO.wrapper() - // 更新时忽略当前记录 - .ne(CommandSnippetGroupDO::getId, domain.getId()) - // 用其他字段做重复校验 - .eq(CommandSnippetGroupDO::getUserId, domain.getUserId()) - .eq(CommandSnippetGroupDO::getName, domain.getName()); - // 检查是否存在 - boolean present = commandSnippetGroupDAO.of(wrapper).present(); - Valid.isFalse(present, ErrorMessage.DATA_PRESENT); - } - } diff --git a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/CommandSnippetGroupMapper.xml b/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/CommandSnippetGroupMapper.xml deleted file mode 100644 index 79de6c7d..00000000 --- a/orion-ops-module-asset/orion-ops-module-asset-service/src/main/resources/mapper/CommandSnippetGroupMapper.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - id, user_id, name, create_time, update_time, creator, updater, deleted - - - diff --git a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/DataGroupTypeEnum.java b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/DataGroupTypeEnum.java index 0bd1b49d..219c58d5 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/DataGroupTypeEnum.java +++ b/orion-ops-module-infra/orion-ops-module-infra-provider/src/main/java/com/orion/ops/module/infra/enums/DataGroupTypeEnum.java @@ -19,6 +19,11 @@ public enum DataGroupTypeEnum { */ COMMAND_SNIPPET, + /** + * 路径书签 + */ + PATH_BOOKMARK, + ; public static DataGroupTypeEnum of(String type) { diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataGroupRelServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataGroupRelServiceImpl.java index eb4d1000..f2f41045 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataGroupRelServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/DataGroupRelServiceImpl.java @@ -173,10 +173,13 @@ public class DataGroupRelServiceImpl implements DataGroupRelService { .relId(s.getRelId()) .build())); }); - // 插入 - dataGroupRelDAO.insertBatch(records); - // 删除缓存 - this.deleteCache(type, userId, groupMapping.keySet()); + // 不为空则插入 + if (!records.isEmpty()) { + // 插入 + dataGroupRelDAO.insertBatch(records); + // 删除缓存 + this.deleteCache(type, userId, groupMapping.keySet()); + } } @Override diff --git a/orion-ops-ui/src/views/host/command-snippet/components/command-snippet-list-drawer.vue b/orion-ops-ui/src/views/host/command-snippet/components/command-snippet-list-drawer.vue index 9c63fd91..1fef1ee9 100644 --- a/orion-ops-ui/src/views/host/command-snippet/components/command-snippet-list-drawer.vue +++ b/orion-ops-ui/src/views/host/command-snippet/components/command-snippet-list-drawer.vue @@ -14,12 +14,21 @@
- - + + + + + + + + + { - if (snippet.value) { + const fetchData = async (force: boolean = false) => { + if (snippet.value && !force) { return; } setLoading(true); @@ -298,7 +307,7 @@ } &-input { - width: 220px; + width: 248px; user-select: none; } }