From e3d34c3ca6cf876346dbd5ac69f4229a5fb0f6ed Mon Sep 17 00:00:00 2001 From: zhuangdashia Date: Wed, 25 Jun 2025 13:37:42 +0800 Subject: [PATCH] =?UTF-8?q?=E5=B7=A5=E4=BD=9C=E6=B5=81=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=96=87=E6=98=AF=E5=90=8C=E5=8F=98=E9=87=8F=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/SystemVariableMapper.java | 9 + .../persistence/po/SystemVariable.java | 36 +++ .../controller/SystemVariableController.java | 92 +++++++ .../model/request/SystemVariableQueryVO.java | 13 + .../request/SystemVariableRequestVO.java | 30 +++ .../response/SystemVariableResponseVO.java | 30 +++ .../web/service/SystemVariableService.java | 26 ++ .../impl/SystemVariableServiceImpl.java | 249 ++++++++++++++++++ 8 files changed, 485 insertions(+) create mode 100644 snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/mapper/SystemVariableMapper.java create mode 100644 snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/po/SystemVariable.java create mode 100644 snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/SystemVariableController.java create mode 100644 snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableQueryVO.java create mode 100644 snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableRequestVO.java create mode 100644 snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/response/SystemVariableResponseVO.java create mode 100644 snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/SystemVariableService.java create mode 100644 snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/SystemVariableServiceImpl.java diff --git a/snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/mapper/SystemVariableMapper.java b/snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/mapper/SystemVariableMapper.java new file mode 100644 index 00000000..3afa1066 --- /dev/null +++ b/snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/mapper/SystemVariableMapper.java @@ -0,0 +1,9 @@ +package com.aizuda.snailjob.template.datasource.persistence.mapper; + +import com.aizuda.snailjob.template.datasource.persistence.po.SystemVariable; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import org.apache.ibatis.annotations.Mapper; + +@Mapper +public interface SystemVariableMapper extends BaseMapper { +} diff --git a/snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/po/SystemVariable.java b/snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/po/SystemVariable.java new file mode 100644 index 00000000..b73a916f --- /dev/null +++ b/snail-job-datasource/snail-job-datasource-template/src/main/java/com/aizuda/snailjob/template/datasource/persistence/po/SystemVariable.java @@ -0,0 +1,36 @@ +package com.aizuda.snailjob.template.datasource.persistence.po; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +@TableName("sj_system_variable") +public class SystemVariable { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String variableKey; + + private String variableName; + + private String variableValue; + + private Integer variableType; + + private Long systemUserId; + + private String namespaceId; + + private String groupNames; + + private String description; + + private LocalDateTime createDt; + + private LocalDateTime updateDt; +} \ No newline at end of file diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/SystemVariableController.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/SystemVariableController.java new file mode 100644 index 00000000..dc4e07a5 --- /dev/null +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/controller/SystemVariableController.java @@ -0,0 +1,92 @@ +package com.aizuda.snailjob.server.web.controller; + +import com.aizuda.snailjob.server.web.annotation.LoginRequired; +import com.aizuda.snailjob.server.web.model.base.PageResult; +import com.aizuda.snailjob.server.web.model.request.SystemVariableQueryVO; +import com.aizuda.snailjob.server.web.model.request.SystemVariableRequestVO; +import com.aizuda.snailjob.server.web.model.response.SystemVariableResponseVO; +import com.aizuda.snailjob.server.web.service.SystemVariableService; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * 系统变量管理 前端控制器 + * + * @author opensnail + * @since 2024-01-01 + */ +@RestController +@RequestMapping("/system-variable") +@RequiredArgsConstructor +public class SystemVariableController { + + private final SystemVariableService systemVariableService; + + /** + * 分页查询系统变量列表 + */ + @GetMapping("/page/list") + @LoginRequired + public PageResult> getVariablePageList(SystemVariableQueryVO queryVO) { + return systemVariableService.getVariablePageList(queryVO); + } + /** + * 查询系统变量列表 + */ + @GetMapping("/list") + @LoginRequired + public List getVariableList() { + return systemVariableService.getVariableList(); + } + + /** + * 根据ID获取系统变量详情 + */ + @GetMapping("/{id}") + @LoginRequired + public SystemVariableResponseVO getVariableById(@PathVariable("id") Long id) { + return systemVariableService.getVariableById(id); + } + + /** + * 新增系统变量 + */ + @PostMapping + @LoginRequired + public void addVariable(@RequestBody @Valid SystemVariableRequestVO requestVO) { + systemVariableService.addVariable(requestVO); + } + + /** + * 更新系统变量 + */ + @PutMapping + @LoginRequired + public void updateVariable(@RequestBody @Valid SystemVariableRequestVO requestVO) { + systemVariableService.updateVariable(requestVO); + } + + /** + * 删除系统变量 + */ + @DeleteMapping("/{id}") + @LoginRequired + public void deleteVariable(@PathVariable("id") Long id) { + systemVariableService.deleteVariable(id); + } + + /** + * 批量删除系统变量 + */ + @DeleteMapping("/batch") + @LoginRequired + public void deleteVariables(@RequestBody @NotEmpty(message = "删除ID列表不能为空") Set ids) { + ids.forEach(systemVariableService::deleteVariable); + } +} \ No newline at end of file diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableQueryVO.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableQueryVO.java new file mode 100644 index 00000000..23bc3e4e --- /dev/null +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableQueryVO.java @@ -0,0 +1,13 @@ +package com.aizuda.snailjob.server.web.model.request; + +import lombok.Data; +import lombok.EqualsAndHashCode; +import com.aizuda.snailjob.server.common.vo.base.BaseQueryVO; +@Data +@EqualsAndHashCode(callSuper = true) +public class SystemVariableQueryVO extends BaseQueryVO { + + private String variableName; + + private Integer variableType; +} \ No newline at end of file diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableRequestVO.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableRequestVO.java new file mode 100644 index 00000000..68719891 --- /dev/null +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/request/SystemVariableRequestVO.java @@ -0,0 +1,30 @@ +package com.aizuda.snailjob.server.web.model.request; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; +import lombok.Data; + +@Data +public class SystemVariableRequestVO { + + private Long id; + + @NotBlank(message = "变量不能为空") + @Size(max = 64, message = "变量长度不能超过64个字符") + private String variableKey; + + @NotBlank(message = "变量名不能为空") + @Size(max = 64, message = "变量名长度不能超过64个字符") + private String variableName; + + @NotBlank(message = "变量值不能为空") + @Size(max = 512, message = "变量值长度不能超过512个字符") + private String variableValue; + + @NotNull(message = "变量类型不能为空") + private Integer variableType; + + @Size(max = 256, message = "描述长度不能超过256个字符") + private String description; +} diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/response/SystemVariableResponseVO.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/response/SystemVariableResponseVO.java new file mode 100644 index 00000000..534c055e --- /dev/null +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/model/response/SystemVariableResponseVO.java @@ -0,0 +1,30 @@ +package com.aizuda.snailjob.server.web.model.response; + +import lombok.Data; +import java.time.LocalDateTime; + +@Data +public class SystemVariableResponseVO { + + private Long id; + + private String variableKey; + + private String variableName; + + private String variableValue; + + private Integer variableType; + + private Long systemUserId; + + private String namespaceId; + + private String groupNames; + + private String description; + + private LocalDateTime createDt; + + private LocalDateTime updateDt; +} \ No newline at end of file diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/SystemVariableService.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/SystemVariableService.java new file mode 100644 index 00000000..d4abba46 --- /dev/null +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/SystemVariableService.java @@ -0,0 +1,26 @@ +package com.aizuda.snailjob.server.web.service; + +import com.aizuda.snailjob.server.web.model.base.PageResult; +import com.aizuda.snailjob.server.web.model.request.SystemVariableQueryVO; +import com.aizuda.snailjob.server.web.model.request.SystemVariableRequestVO; +import com.aizuda.snailjob.server.web.model.response.SystemVariableResponseVO; + +import java.util.List; +import java.util.Map; + +public interface SystemVariableService { + + void addVariable(SystemVariableRequestVO requestVO); + + void updateVariable(SystemVariableRequestVO requestVO); + + void deleteVariable(Long id); + + PageResult> getVariablePageList(SystemVariableQueryVO queryVO); + + SystemVariableResponseVO getVariableById(Long id); + + Map getUserVariables(Long userId, String namespaceId); + + List getVariableList(); +} \ No newline at end of file diff --git a/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/SystemVariableServiceImpl.java b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/SystemVariableServiceImpl.java new file mode 100644 index 00000000..4a300aef --- /dev/null +++ b/snail-job-server/snail-job-server-web/src/main/java/com/aizuda/snailjob/server/web/service/impl/SystemVariableServiceImpl.java @@ -0,0 +1,249 @@ +package com.aizuda.snailjob.server.web.service.impl; + +import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; +import cn.hutool.core.util.StrUtil; +import com.aizuda.snailjob.common.core.util.StreamUtils; +import com.aizuda.snailjob.server.common.exception.SnailJobServerException; +import com.aizuda.snailjob.server.web.model.base.PageResult; +import com.aizuda.snailjob.server.web.model.request.SystemVariableQueryVO; +import com.aizuda.snailjob.server.web.model.request.SystemVariableRequestVO; +import com.aizuda.snailjob.server.web.model.request.UserSessionVO; +import com.aizuda.snailjob.server.web.model.response.SystemVariableResponseVO; +import com.aizuda.snailjob.server.web.service.SystemVariableService; +import com.aizuda.snailjob.server.web.util.UserSessionUtils; +import com.aizuda.snailjob.template.datasource.persistence.mapper.SystemVariableMapper; +import com.aizuda.snailjob.template.datasource.persistence.po.SystemVariable; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +@Service +@RequiredArgsConstructor +public class SystemVariableServiceImpl implements SystemVariableService { + + private final SystemVariableMapper systemVariableMapper; + + @Override + @Transactional + public void addVariable(SystemVariableRequestVO requestVO) { + UserSessionVO userSession = UserSessionUtils.currentUserSession(); + + // 检查变量名是否已存在 + long count = systemVariableMapper.selectCount( + new LambdaQueryWrapper() + .eq(SystemVariable::getSystemUserId, userSession.getId()) + .eq(SystemVariable::getNamespaceId, userSession.getNamespaceId()) + .eq(SystemVariable::getGroupNames, userSession.getGroupNames()) + .eq(SystemVariable::getVariableName, requestVO.getVariableName())); + + if (count > 0) { + throw new SnailJobServerException("变量名已存在"); + } + + SystemVariable systemVariable = new SystemVariable(); + BeanUtils.copyProperties(requestVO, systemVariable); + systemVariable.setSystemUserId(userSession.getId()); + systemVariable.setNamespaceId(userSession.getNamespaceId()); + // 设置 groupNames + if (userSession.isAdmin()) { + // admin用户创建的变量,设置为空或特殊标识,表示所有组都可见 + systemVariable.setGroupNames(""); + } else { + // 普通用户创建的变量,存储用户所属的组名 + List userGroupNames = userSession.getGroupNames(); + systemVariable.setGroupNames(String.join(",", userGroupNames)); + } + + Assert.isTrue(1 == systemVariableMapper.insert(systemVariable), + () -> new SnailJobServerException("添加系统变量失败")); + } + + @Override + @Transactional + public void updateVariable(SystemVariableRequestVO requestVO) { + UserSessionVO userSession = UserSessionUtils.currentUserSession(); + + SystemVariable existingVariable = systemVariableMapper.selectOne( + new LambdaQueryWrapper() + .eq(SystemVariable::getId, requestVO.getId()) + .eq(SystemVariable::getSystemUserId, userSession.getId()) + .eq(SystemVariable::getNamespaceId, userSession.getNamespaceId())); + + if (Objects.isNull(existingVariable)) { + throw new SnailJobServerException("系统变量不存在或无权限修改"); + } + + // 检查变量名是否与其他变量冲突 + if (!existingVariable.getVariableName().equals(requestVO.getVariableName())) { + long count = systemVariableMapper.selectCount( + new LambdaQueryWrapper() + .eq(SystemVariable::getSystemUserId, userSession.getId()) + .eq(SystemVariable::getNamespaceId, userSession.getNamespaceId()) + .eq(SystemVariable::getVariableName, requestVO.getVariableName()) + .ne(SystemVariable::getId, requestVO.getId())); + + if (count > 0) { + throw new SnailJobServerException("变量名已存在"); + } + } + + BeanUtils.copyProperties(requestVO, existingVariable); + Assert.isTrue(1 == systemVariableMapper.updateById(existingVariable), + () -> new SnailJobServerException("更新系统变量失败")); + } + + @Override + @Transactional + public void deleteVariable(Long id) { + UserSessionVO userSession = UserSessionUtils.currentUserSession(); + + SystemVariable existingVariable = systemVariableMapper.selectOne( + new LambdaQueryWrapper() + .eq(SystemVariable::getId, id) + .eq(SystemVariable::getSystemUserId, userSession.getId()) + .eq(SystemVariable::getNamespaceId, userSession.getNamespaceId())); + + if (Objects.isNull(existingVariable)) { + throw new SnailJobServerException("系统变量不存在或无权限删除"); + } + + Assert.isTrue(1 == systemVariableMapper.deleteById(id), + () -> new SnailJobServerException("删除系统变量失败")); + } + + @Override + public PageResult> getVariablePageList(SystemVariableQueryVO queryVO) { + UserSessionVO userSession = UserSessionUtils.currentUserSession(); + + PageDTO pageDTO = new PageDTO<>(queryVO.getPage(), queryVO.getSize()); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper() + .eq(SystemVariable::getNamespaceId, userSession.getNamespaceId()) + .like(StrUtil.isNotBlank(queryVO.getVariableName()), + SystemVariable::getVariableName, queryVO.getVariableName()) + .eq(Objects.nonNull(queryVO.getVariableType()), + SystemVariable::getVariableType, queryVO.getVariableType()) + .orderByDesc(SystemVariable::getId); + + // 根据用户权限过滤 + if (userSession.isUser()) { + // 普通用户:只能看到自己有权限的组的变量 + admin创建的变量 + List groupNames = userSession.getGroupNames(); + if (CollUtil.isEmpty(groupNames)) { + return new PageResult<>(pageDTO, Collections.emptyList()); + } + + wrapper.and(w -> { + // 用户有权限的组的变量 + for (String groupName : groupNames) { + w.or().like(SystemVariable::getGroupNames, groupName); + } + // admin创建的变量(通过查询admin用户ID) + w.or().exists("SELECT 1 FROM sj_system_user su WHERE su.id = sj_system_variable.system_user_id AND su.role = 2"); +// return w; + }); + } + // admin用户可以看到所有变量,不需要额外过滤 + + PageDTO selectPage = systemVariableMapper.selectPage(pageDTO, wrapper); + + List responseList = selectPage.getRecords().stream() + .map(this::convertToResponseVO) + .toList(); + + return new PageResult<>(pageDTO, responseList); + } + + @Override + public SystemVariableResponseVO getVariableById(Long id) { + UserSessionVO userSession = UserSessionUtils.currentUserSession(); + + SystemVariable systemVariable = systemVariableMapper.selectOne( + new LambdaQueryWrapper() + .eq(SystemVariable::getId, id) + .eq(SystemVariable::getSystemUserId, userSession.getId()) + .eq(SystemVariable::getNamespaceId, userSession.getNamespaceId())); + + if (Objects.isNull(systemVariable)) { + throw new SnailJobServerException("系统变量不存在或无权限访问"); + } + + return convertToResponseVO(systemVariable); + } + + @Override + public Map getUserVariables(Long userId, String namespaceId) { + UserSessionVO userSession = UserSessionUtils.currentUserSession(); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper() + .eq(SystemVariable::getNamespaceId, namespaceId); + + // 根据用户权限过滤 + if (userSession.isUser()) { + List userGroupNames = userSession.getGroupNames(); + if (CollUtil.isNotEmpty(userGroupNames)) { + wrapper.and(w -> { + // 用户有权限的组的变量 + for (String groupName : userGroupNames) { + w.or().like(SystemVariable::getGroupNames, groupName); + } + // admin创建的变量 + w.or().exists("SELECT 1 FROM sj_system_user su WHERE su.id = sj_system_variable.system_user_id AND su.role = 2"); +// return w; + }); + } + } + // admin用户可以获取所有变量 + + List variables = systemVariableMapper.selectList(wrapper); + + return StreamUtils.toMap(variables, SystemVariable::getVariableName, SystemVariable::getVariableValue); + } + + @Override + public List getVariableList() { + UserSessionVO userSession = UserSessionUtils.currentUserSession(); + + LambdaQueryWrapper wrapper = new LambdaQueryWrapper() + .eq(SystemVariable::getNamespaceId, userSession.getNamespaceId()) + .orderByDesc(SystemVariable::getId); + + // 根据用户权限过滤 + if (userSession.isUser()) { + List groupNames = userSession.getGroupNames(); + if (CollUtil.isNotEmpty(groupNames)) { + wrapper.and(w -> { + // 用户有权限的组的变量 + for (String groupName : groupNames) { + w.or().like(SystemVariable::getGroupNames, groupName); + } + // admin创建的变量 + w.or().exists("SELECT 1 FROM sj_system_user su WHERE su.id = sj_system_variable.system_user_id AND su.role = 2"); +// return w; + }); + } + } + // admin用户可以看到所有变量 + + List variables = systemVariableMapper.selectList(wrapper); + + return variables.stream() + .map(this::convertToResponseVO) + .toList(); + } + + private SystemVariableResponseVO convertToResponseVO(SystemVariable systemVariable) { + SystemVariableResponseVO responseVO = new SystemVariableResponseVO(); + BeanUtils.copyProperties(systemVariable, responseVO); + return responseVO; + } +} \ No newline at end of file