模块管理

This commit is contained in:
2026-01-09 17:59:45 +08:00
parent 463908dfeb
commit 433830f2a1
15 changed files with 291 additions and 39 deletions

View File

@@ -0,0 +1,40 @@
package com.cczsa.xinghe.codegen.config;
import com.mybatisflex.core.FlexGlobalConfig;
import com.mybatisflex.core.audit.AuditManager;
import com.mybatisflex.core.dialect.DbType;
import com.mybatisflex.spring.boot.MyBatisFlexCustomizer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
/**
* @author xia
* @date 2025/9/11
* @version 0.0.1
*/
@Slf4j
@Configuration
public class MyBatisFlexConfiguration implements MyBatisFlexCustomizer {
@Override
public void customize(FlexGlobalConfig flexGlobalConfig) {
// 逻辑删除字段
flexGlobalConfig.setLogicDeleteColumn("is_delete");
flexGlobalConfig.setDbType(DbType.POSTGRE_SQL);
//开启审计功能
AuditManager.setAuditEnable(true);
//设置 SQL 审计收集器
AuditManager.setMessageCollector(auditMessage ->
{
log.info(" {}" , auditMessage.getFullSql());
log.info("执行时间 {} ms" ,auditMessage.getElapsedTime());
}
);
}
}

View File

@@ -0,0 +1,15 @@
package com.cczsa.xinghe.codegen.constant;
/**
* codegen常量
*/
public class CodegenConstant {
/**
* 操作密码
*/
public static final String OPERATION_PASSWORD = "888";
}

View File

@@ -31,6 +31,7 @@ public class FunItemController {
private final FunItemService funitemService; private final FunItemService funitemService;
@Operation(summary = "获取功能列表", description = "获取功能列表")
@PostMapping("/query") @PostMapping("/query")
public XResult<FunItemQueryRes> query(@RequestBody @Valid FunItemQueryReq req ) { public XResult<FunItemQueryRes> query(@RequestBody @Valid FunItemQueryReq req ) {
return funitemService.query(req); return funitemService.query(req);

View File

@@ -1,6 +1,7 @@
package com.cczsa.xinghe.codegen.controller; package com.cczsa.xinghe.codegen.controller;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleDeleteReq;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleQueryReq; import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleQueryReq;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleSaveUpdateReq; import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleSaveUpdateReq;
import com.cczsa.xinghe.codegen.entity.res.funModule.FunModuleQueryRes; import com.cczsa.xinghe.codegen.entity.res.funModule.FunModuleQueryRes;
@@ -10,12 +11,13 @@ import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/** /**
* 模块管理 控制层。 * 模块管理 控制层。
* *
@@ -32,22 +34,21 @@ public class FunModuleController {
@Operation(summary = "获取模块列表", description = "获取模块列表") @Operation(summary = "获取模块列表", description = "获取模块列表")
@PostMapping("/query") @PostMapping("/query")
public XResult<FunModuleQueryRes> query(@RequestBody @Valid FunModuleQueryReq req ) { public XResult<List<FunModuleQueryRes>> query(@RequestBody @Valid FunModuleQueryReq req) {
return funmoduleService.query(req); return funmoduleService.query(req);
} }
@Operation(summary = "创建/修改模块", description = "创建/修改模块") @Operation(summary = "创建/修改模块", description = "创建/修改模块")
@PostMapping("/save/update") @PostMapping("/save/update")
public XResult<Void> saveUpdate(@RequestBody @Valid FunModuleSaveUpdateReq req ) { public XResult<Void> saveUpdate(@RequestBody @Valid FunModuleSaveUpdateReq req) {
return funmoduleService.saveUpdate(req); return funmoduleService.saveUpdate(req);
} }
@Operation(summary = "删除模块", description = "删除模块") @Operation(summary = "删除模块", description = "删除模块")
@DeleteMapping("/delete") @PostMapping("/delete")
public XResult<Void> delete() { public XResult<Void> delete(@RequestBody @Valid FunModuleDeleteReq req) {
return funmoduleService.delete(); return funmoduleService.delete(req);
} }
} }

View File

@@ -37,7 +37,7 @@ public class FunItemEntity extends BaseEntity implements Serializable {
private Long id; private Long id;
/** /**
* 模块ID * 模块ID(表主键ID)
*/ */
private Long moduleId; private Long moduleId;
@@ -66,4 +66,9 @@ public class FunItemEntity extends BaseEntity implements Serializable {
*/ */
private Integer sortOrder; private Integer sortOrder;
/**
* 功能ID
*/
private Long itemId;
} }

View File

@@ -41,12 +41,12 @@ public class FunOperationEntity extends BaseEntity implements Serializable {
private Long id; private Long id;
/** /**
* 模块ID * 模块ID(表主键ID)
*/ */
private Long moduleId; private Long moduleId;
/** /**
* 功能ID * 功能ID(表主键ID)
*/ */
private Long itemId; private Long itemId;
@@ -97,4 +97,9 @@ public class FunOperationEntity extends BaseEntity implements Serializable {
*/ */
private String describe; private String describe;
/**
* 操作ID
*/
private Integer operationId;
} }

View File

@@ -0,0 +1,31 @@
package com.cczsa.xinghe.codegen.entity.req.funModule;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 删除模块 请求参数
*
* @author my
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "删除模块-参数")
public class FunModuleDeleteReq {
@NotNull(message = "模块id列表不能为空")
@Schema(description = "模块id列表")
private List<Long> moduleIdList;
@NotBlank(message = "操作密码不能为空")
@Schema(description = "操作密码")
private String operationPassword;
}

View File

@@ -19,4 +19,10 @@ public class FunModuleQueryReq implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "模块名称")
private String moduleName;
@Schema(description = "模块编码")
private String moduleCode;
} }

View File

@@ -1,6 +1,11 @@
package com.cczsa.xinghe.codegen.entity.req.funModule; package com.cczsa.xinghe.codegen.entity.req.funModule;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.io.Serial; import java.io.Serial;
@@ -19,4 +24,33 @@ public class FunModuleSaveUpdateReq implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@NotNull(message = "id不能为空")
@Schema(description = "id")
@Min(value = 10, message = "id必须大于等于10")
@Max(value = 99, message = "id必须小于等于99")
private Long id;
@NotBlank(message = "模块名称不能为空")
@Schema(description = "模块名称")
private String moduleName;
@NotBlank(message = "模块编码不能为空")
@Pattern(regexp = "^[a-z]+$", message = "模块编码只能包含英文小写字母")
@Schema(description = "模块编码")
private String moduleCode;
@Schema(description = "描述")
private String describe;
@NotBlank(message = "包名称不能为空")
@Schema(description = "包名称")
private String packageName;
@NotBlank(message = "参数包名不能为空")
@Schema(description = "参数包名")
private String apiPackageName;
@Schema(description = "排序")
private Integer sortOrder;
} }

View File

@@ -3,11 +3,13 @@ package com.cczsa.xinghe.codegen.entity.res.funModule;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
/** /**
* 获取模块列表 响应参数 * 获取模块列表 响应参数
*
* @author xia * @author xia
* @version 0.0.1 * @version 0.0.1
*/ */
@@ -19,4 +21,25 @@ public class FunModuleQueryRes implements Serializable {
@Serial @Serial
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@Schema(description = "id")
private Long id;
@Schema(description = "模块名称")
private String moduleName;
@Schema(description = "模块编码")
private String moduleCode;
@Schema(description = "描述")
private String describe;
@Schema(description = "包名称")
private String packageName;
@Schema(description = "参数包名")
private String apiPackageName;
@Schema(description = "排序")
private Integer sortOrder;
} }

View File

@@ -0,0 +1,26 @@
package com.cczsa.xinghe.codegen.handler;
import com.cczsa.xinghe.codegen.util.XResult;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* 全局异常处理
*
* @author My
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public XResult<Void> handleValidationException(MethodArgumentNotValidException ex) {
// 只获取第一个错误信息
if (!ex.getBindingResult().getFieldErrors().isEmpty()) {
var firstError = ex.getBindingResult().getFieldErrors().get(0);
return XResult.failed(firstError.getDefaultMessage());
}
return XResult.failed("参数校验失败");
}
}

View File

@@ -26,6 +26,11 @@ public class FunItemDef extends TableDef {
*/ */
public final QueryColumn ID = new QueryColumn(this, "id"); public final QueryColumn ID = new QueryColumn(this, "id");
/**
* 功能ID
*/
public final QueryColumn ITEM_ID = new QueryColumn(this, "item_id");
/** /**
* 说明 * 说明
*/ */
@@ -47,7 +52,7 @@ public class FunItemDef extends TableDef {
public final QueryColumn ITEM_NAME = new QueryColumn(this, "item_name"); public final QueryColumn ITEM_NAME = new QueryColumn(this, "item_name");
/** /**
* 模块ID * 模块ID(表主键ID)
*/ */
public final QueryColumn MODULE_ID = new QueryColumn(this, "module_id"); public final QueryColumn MODULE_ID = new QueryColumn(this, "module_id");
@@ -64,7 +69,7 @@ public class FunItemDef extends TableDef {
/** /**
* 默认字段,不包含逻辑删除或者 large 等字段。 * 默认字段,不包含逻辑删除或者 large 等字段。
*/ */
public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, MODULE_ID, ITEM_NAME, ITEM_CODE, IS_TENANT, DESCRIBE, SORT_ORDER}; public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, MODULE_ID, ITEM_NAME, ITEM_CODE, IS_TENANT, DESCRIBE, SORT_ORDER, ITEM_ID};
public FunItemDef() { public FunItemDef() {
super("", "cg_fun_item"); super("", "cg_fun_item");

View File

@@ -27,7 +27,7 @@ public class FunOperationDef extends TableDef {
public final QueryColumn ID = new QueryColumn(this, "id"); public final QueryColumn ID = new QueryColumn(this, "id");
/** /**
* 功能ID * 功能ID(表主键ID)
*/ */
public final QueryColumn ITEM_ID = new QueryColumn(this, "item_id"); public final QueryColumn ITEM_ID = new QueryColumn(this, "item_id");
@@ -47,7 +47,7 @@ public class FunOperationDef extends TableDef {
public final QueryColumn DESCRIBE = new QueryColumn(this, "describe"); public final QueryColumn DESCRIBE = new QueryColumn(this, "describe");
/** /**
* 模块ID * 模块ID(表主键ID)
*/ */
public final QueryColumn MODULE_ID = new QueryColumn(this, "module_id"); public final QueryColumn MODULE_ID = new QueryColumn(this, "module_id");
@@ -61,6 +61,11 @@ public class FunOperationDef extends TableDef {
*/ */
public final QueryColumn FIELD_COFNIG = new QueryColumn(this, "field_cofnig"); public final QueryColumn FIELD_COFNIG = new QueryColumn(this, "field_cofnig");
/**
* 操作ID
*/
public final QueryColumn OPERATION_ID = new QueryColumn(this, "operation_id");
/** /**
* 请求类型 * 请求类型
*/ */
@@ -89,7 +94,7 @@ public class FunOperationDef extends TableDef {
/** /**
* 默认字段,不包含逻辑删除或者 large 等字段。 * 默认字段,不包含逻辑删除或者 large 等字段。
*/ */
public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, MODULE_ID, ITEM_ID, IS_GREEN_LIGHT, FUN_NAME, OPERATION_CODE, FUN_TYPE, REQUEST_TYPE, USABLE_CONFIG, FIELD_COFNIG, SORT_ORDER, DESCRIBE}; public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, MODULE_ID, ITEM_ID, IS_GREEN_LIGHT, FUN_NAME, OPERATION_CODE, FUN_TYPE, REQUEST_TYPE, USABLE_CONFIG, FIELD_COFNIG, SORT_ORDER, DESCRIBE, OPERATION_ID};
public FunOperationDef() { public FunOperationDef() {
super("", "cg_fun_operation"); super("", "cg_fun_operation");

View File

@@ -1,10 +1,13 @@
package com.cczsa.xinghe.codegen.service; package com.cczsa.xinghe.codegen.service;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleDeleteReq;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleQueryReq; import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleQueryReq;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleSaveUpdateReq; import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleSaveUpdateReq;
import com.cczsa.xinghe.codegen.entity.res.funModule.FunModuleQueryRes; import com.cczsa.xinghe.codegen.entity.res.funModule.FunModuleQueryRes;
import com.cczsa.xinghe.codegen.util.XResult; import com.cczsa.xinghe.codegen.util.XResult;
import java.util.List;
/** /**
* 模块管理 服务层接口。 * 模块管理 服务层接口。
* *
@@ -16,7 +19,7 @@ public interface FunModuleService {
/** /**
* 获取模块列表 * 获取模块列表
*/ */
XResult<FunModuleQueryRes> query(FunModuleQueryReq req); XResult<List<FunModuleQueryRes>> query(FunModuleQueryReq req);
/** /**
* 创建/修改模块 * 创建/修改模块
@@ -26,7 +29,7 @@ public interface FunModuleService {
/** /**
* 删除模块 * 删除模块
*/ */
XResult<Void> delete(); XResult<Void> delete(FunModuleDeleteReq req);
} }

View File

@@ -1,49 +1,101 @@
package com.cczsa.xinghe.codegen.service.impl; package com.cczsa.xinghe.codegen.service.impl;
import com.cczsa.xinghe.codegen.constant.CodegenConstant;
import com.cczsa.xinghe.codegen.entity.FunItemEntity;
import com.cczsa.xinghe.codegen.entity.FunModuleEntity;
import com.cczsa.xinghe.codegen.entity.FunOperationEntity;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleDeleteReq;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleQueryReq; import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleQueryReq;
import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleSaveUpdateReq; import com.cczsa.xinghe.codegen.entity.req.funModule.FunModuleSaveUpdateReq;
import com.cczsa.xinghe.codegen.entity.res.funModule.FunModuleQueryRes; import com.cczsa.xinghe.codegen.entity.res.funModule.FunModuleQueryRes;
import com.cczsa.xinghe.codegen.mapper.FunItemMapper;
import com.cczsa.xinghe.codegen.mapper.FunModuleMapper;
import com.cczsa.xinghe.codegen.mapper.FunOperationMapper;
import com.cczsa.xinghe.codegen.mapper.def.FunModuleDef;
import com.cczsa.xinghe.codegen.service.FunModuleService; import com.cczsa.xinghe.codegen.service.FunModuleService;
import com.cczsa.xinghe.codegen.util.XResult; import com.cczsa.xinghe.codegen.util.XResult;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/** /**
* 模块管理 服务层实现。 * 模块管理 服务层实现。
* *
* @author xia * @author xia
* @version 0.0.1 * @version 0.0.1
*/ */
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
public class FunModuleServiceImpl implements FunModuleService { public class FunModuleServiceImpl implements FunModuleService {
private final FunModuleMapper funModuleMapper;
private final FunItemMapper funItemMapper;
private final FunOperationMapper funOperationMapper;
/** /**
* 获取模块列表 * 获取模块列表
*/ */
@Override @Override
public XResult<FunModuleQueryRes> query(FunModuleQueryReq req) { public XResult<List<FunModuleQueryRes>> query(FunModuleQueryReq req) {
// TODO 实现 获取模块列表 业务逻辑 QueryWrapper queryWrapper = new QueryWrapper();
return null; queryWrapper.select(FunModuleDef.FUN_MODULE_ENTITY.ALL_COLUMNS)
} .like(FunModuleEntity::getModuleName, req.getModuleName(), StrUtil.isNotBlank(req.getModuleName()))
.like(FunModuleEntity::getModuleCode, req.getModuleCode(), StrUtil.isNotBlank(req.getModuleCode()))
.orderBy(FunModuleEntity::getSortOrder, true);
List<FunModuleQueryRes> funModuleQueryRes = funModuleMapper.selectListByQueryAs(queryWrapper, FunModuleQueryRes.class);
return XResult.ok(funModuleQueryRes);
}
/** /**
* 创建/修改模块 * 创建/修改模块
*/ */
@Override @Override
public XResult<Void> saveUpdate(FunModuleSaveUpdateReq req) { public XResult<Void> saveUpdate(FunModuleSaveUpdateReq req) {
// TODO 实现 创建/修改模块 业务逻辑 // 模块编码不能重复
return null; QueryWrapper queryWrapper = new QueryWrapper();
} queryWrapper.eq(FunModuleEntity::getModuleCode, req.getModuleCode());
queryWrapper.ne(FunModuleEntity::getId, req.getId());
if (funModuleMapper.selectCountByQuery(queryWrapper) > 0) {
return XResult.failed("模块编码不能重复");
}
FunModuleEntity funModuleEntity = new FunModuleEntity();
BeanUtils.copyProperties(req, funModuleEntity);
int update = funModuleMapper.update(funModuleEntity);
if (update <= 0) {
funModuleMapper.insert(funModuleEntity);
}
return XResult.ok();
}
/** /**
* 删除模块 * 删除模块
*/ */
@Override @Transactional
public XResult<Void> delete() { @Override
// TODO 实现 删除模块 业务逻辑 public XResult<Void> delete(FunModuleDeleteReq req) {
return null; List<Long> ids = req.getModuleIdList();
} if (!req.getOperationPassword().equals(CodegenConstant.OPERATION_PASSWORD)) {
return XResult.failed("操作密码错误");
}
// 删除模块
QueryWrapper deleteModule = new QueryWrapper();
deleteModule.in(FunModuleEntity::getId, ids);
funModuleMapper.deleteByQuery(deleteModule);
// 删除功能
QueryWrapper deleteFun = new QueryWrapper();
deleteFun.in(FunItemEntity::getModuleId, ids);
funItemMapper.deleteByQuery(deleteFun);
// 删除操作
QueryWrapper deleteOperation = new QueryWrapper();
deleteOperation.in(FunOperationEntity::getModuleId, ids);
funOperationMapper.deleteByQuery(deleteOperation);
return XResult.ok();
}
} }