模块管理

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;
@Operation(summary = "获取功能列表", description = "获取功能列表")
@PostMapping("/query")
public XResult<FunItemQueryRes> query(@RequestBody @Valid FunItemQueryReq req ) {
return funitemService.query(req);

View File

@@ -1,6 +1,7 @@
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.FunModuleSaveUpdateReq;
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 jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* 模块管理 控制层。
*
@@ -32,7 +34,7 @@ public class FunModuleController {
@Operation(summary = "获取模块列表", description = "获取模块列表")
@PostMapping("/query")
public XResult<FunModuleQueryRes> query(@RequestBody @Valid FunModuleQueryReq req ) {
public XResult<List<FunModuleQueryRes>> query(@RequestBody @Valid FunModuleQueryReq req) {
return funmoduleService.query(req);
}
@@ -43,11 +45,10 @@ public class FunModuleController {
}
@Operation(summary = "删除模块", description = "删除模块")
@DeleteMapping("/delete")
public XResult<Void> delete() {
return funmoduleService.delete();
@PostMapping("/delete")
public XResult<Void> delete(@RequestBody @Valid FunModuleDeleteReq req) {
return funmoduleService.delete(req);
}
}

View File

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

View File

@@ -41,12 +41,12 @@ public class FunOperationEntity extends BaseEntity implements Serializable {
private Long id;
/**
* 模块ID
* 模块ID(表主键ID)
*/
private Long moduleId;
/**
* 功能ID
* 功能ID(表主键ID)
*/
private Long itemId;
@@ -97,4 +97,9 @@ public class FunOperationEntity extends BaseEntity implements Serializable {
*/
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
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;
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.Setter;
import java.io.Serial;
@@ -19,4 +24,33 @@ public class FunModuleSaveUpdateReq implements Serializable {
@Serial
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 lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
/**
* 获取模块列表 响应参数
*
* @author xia
* @version 0.0.1
*/
@@ -19,4 +21,25 @@ public class FunModuleQueryRes implements Serializable {
@Serial
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");
/**
* 功能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");
/**
* 模块ID
* 模块ID(表主键ID)
*/
public final QueryColumn MODULE_ID = new QueryColumn(this, "module_id");
@@ -64,7 +69,7 @@ public class FunItemDef extends TableDef {
/**
* 默认字段,不包含逻辑删除或者 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() {
super("", "cg_fun_item");

View File

@@ -27,7 +27,7 @@ public class FunOperationDef extends TableDef {
public final QueryColumn ID = new QueryColumn(this, "id");
/**
* 功能ID
* 功能ID(表主键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");
/**
* 模块ID
* 模块ID(表主键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");
/**
* 操作ID
*/
public final QueryColumn OPERATION_ID = new QueryColumn(this, "operation_id");
/**
* 请求类型
*/
@@ -89,7 +94,7 @@ public class FunOperationDef extends TableDef {
/**
* 默认字段,不包含逻辑删除或者 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() {
super("", "cg_fun_operation");

View File

@@ -1,10 +1,13 @@
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.FunModuleSaveUpdateReq;
import com.cczsa.xinghe.codegen.entity.res.funModule.FunModuleQueryRes;
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,12 +1,27 @@
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.FunModuleSaveUpdateReq;
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.util.XResult;
import com.github.xiaoymin.knife4j.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 模块管理 服务层实现。
@@ -18,14 +33,23 @@ import org.springframework.stereotype.Service;
@RequiredArgsConstructor
public class FunModuleServiceImpl implements FunModuleService {
private final FunModuleMapper funModuleMapper;
private final FunItemMapper funItemMapper;
private final FunOperationMapper funOperationMapper;
/**
* 获取模块列表
*/
@Override
public XResult<FunModuleQueryRes> query(FunModuleQueryReq req) {
// TODO 实现 获取模块列表 业务逻辑
return null;
public XResult<List<FunModuleQueryRes>> query(FunModuleQueryReq req) {
QueryWrapper queryWrapper = new QueryWrapper();
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);
}
/**
@@ -33,17 +57,45 @@ public class FunModuleServiceImpl implements FunModuleService {
*/
@Override
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();
}
/**
* 删除模块
*/
@Transactional
@Override
public XResult<Void> delete() {
// TODO 实现 删除模块 业务逻辑
return null;
public XResult<Void> delete(FunModuleDeleteReq req) {
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();
}
}