模板管理

This commit is contained in:
2026-01-14 17:47:36 +08:00
parent fb6ea0bfd2
commit b3a0e377e5
13 changed files with 628 additions and 37 deletions

View File

@@ -0,0 +1,70 @@
package com.cczsa.xinghe.codegen.controller;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateAddReq;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateEditReq;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateQueryReq;
import com.cczsa.xinghe.codegen.entity.res.template.TemplateQueryRes;
import com.cczsa.xinghe.codegen.service.TemplateService;
import com.cczsa.xinghe.codegen.util.XResult;
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.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
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;
import java.util.Map;
/**
* 模板管理 控制层。
*
* @author xia
* @version 0.0.1
*/
@Tag(name = "模板管理")
@RequiredArgsConstructor
@RestController
@RequestMapping("/template")
public class TemplateController {
private final TemplateService templateService;
@Operation(summary = "获取模板列表", description = "获取模板列表")
@PostMapping("/query")
public XResult<List<TemplateQueryRes>> query(@RequestBody @Valid TemplateQueryReq req) {
return templateService.query(req);
}
@Operation(summary = "创建模板", description = "创建模板")
@PutMapping("/add")
public XResult<Void> add(@RequestBody @Valid TemplateAddReq req) {
return templateService.add(req);
}
@Operation(summary = "修改模板", description = "修改模板")
@PostMapping("/edit")
public XResult<Void> edit(@RequestBody @Valid TemplateEditReq req) {
return templateService.edit(req);
}
@Operation(summary = "删除模板", description = "删除模板")
@DeleteMapping("/delete/{id}")
public XResult<Void> delete(@PathVariable Long id) {
return templateService.delete(id);
}
@Operation(summary = "模板类型列表", description = "模板类型列表")
@GetMapping("/templateType")
public XResult<List<Map<Integer, String>>> getTemplateTypeList() {
return templateService.getTemplateTypeList();
}
}

View File

@@ -0,0 +1,60 @@
package com.cczsa.xinghe.codegen.entity;
import com.cczsa.xinghe.codegen.entity.enums.TemplateTypeEnum;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.annotation.Table;
import java.io.Serializable;
import java.io.Serial;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.EqualsAndHashCode;
/**
* 实体类。
*
* @author My
* @since 0.0.1
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Table("cg_template")
public class TemplateEntity extends BaseEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@Id(keyType = KeyType.Auto)
private Long id;
/**
* 是否使用
*/
private Boolean isUse;
/**
* 模板名称
*/
private String templateName;
/**
* 模板类型
*/
private TemplateTypeEnum templateType;
/**
* 正文
*/
private String content;
}

View File

@@ -0,0 +1,56 @@
package com.cczsa.xinghe.codegen.entity.enums;
import com.fasterxml.jackson.annotation.JsonValue;
import com.mybatisflex.annotation.EnumValue;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 模板类型枚举
*
* @author My
*/
@Schema(description = "模板类型",
example = "0",
allowableValues = {"0: controller", "1: service", "2: mapper"})
@Getter
public enum TemplateTypeEnum {
CONTROLLER(0, "controller"),
SERVICE(1, "service"),
MAPPER(2, "mapper");
private final int code;
private final String desc;
TemplateTypeEnum(int code, String desc) {
this.code = code;
this.desc = desc;
}
@JsonValue
@EnumValue
public int getCode() {
return code;
}
/**
* 获取枚举值列表
*/
public static List<Map<Integer, String>> getEnumList() {
return Arrays.stream(values())
.map(enumValue -> {
Map<Integer, String> map = new HashMap<>();
map.put(enumValue.getCode(), enumValue.getDesc());
return map;
})
.collect(Collectors.toList());
}
}

View File

@@ -7,6 +7,7 @@ import lombok.Setter;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* 菜单绑定权限 请求参数 * 菜单绑定权限 请求参数
@@ -28,6 +29,6 @@ public class MenuBindFunReq implements Serializable {
@NotNull(message = "功能ID不能为空") @NotNull(message = "功能ID不能为空")
@Schema(description = "功能ID") @Schema(description = "功能ID")
private Long funId; private List<Long> funIdList;
} }

View File

@@ -0,0 +1,43 @@
package com.cczsa.xinghe.codegen.entity.req.template;
import com.cczsa.xinghe.codegen.entity.enums.TemplateTypeEnum;
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.io.Serial;
import java.io.Serializable;
/**
* 创建模板 请求参数
*
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "创建模板-参数")
public class TemplateAddReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull(message = "是否使用不能为空")
@Schema(description = "是否使用")
private Boolean isUse;
@NotBlank(message = "模板名称不能为空")
@Schema(description = "模板名称")
private String templateName;
@NotNull(message = "模板类型不能为空")
@Schema(description = "模板类型")
private TemplateTypeEnum templateType;
@NotBlank(message = "正文不能为空")
@Schema(description = "正文")
private String content;
}

View File

@@ -0,0 +1,45 @@
package com.cczsa.xinghe.codegen.entity.req.template;
import com.cczsa.xinghe.codegen.entity.enums.TemplateTypeEnum;
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.io.Serial;
import java.io.Serializable;
/**
* 修改模板 请求参数
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "修改模板-参数")
public class TemplateEditReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@NotNull(message = "id不能为空")
@Schema(description = "id")
private Long id;
@NotNull(message = "是否使用不能为空")
@Schema(description = "是否使用")
private Boolean isUse;
@NotBlank(message = "模板名称不能为空")
@Schema(description = "模板名称")
private String templateName;
@NotNull(message = "模板类型不能为空")
@Schema(description = "模板类型")
private TemplateTypeEnum templateType;
@NotBlank(message = "正文不能为空")
@Schema(description = "正文")
private String content;
}

View File

@@ -0,0 +1,32 @@
package com.cczsa.xinghe.codegen.entity.req.template;
import com.cczsa.xinghe.codegen.entity.enums.TemplateTypeEnum;
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
*/
@Getter
@Setter
@Schema(description = "获取模板列表-参数")
public class TemplateQueryReq implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "是否使用")
private Boolean isUse;
@Schema(description = "模板名称")
private String templateName;
@Schema(description = "模板类型")
private TemplateTypeEnum templateType;
}

View File

@@ -0,0 +1,40 @@
package com.cczsa.xinghe.codegen.entity.res.template;
import com.cczsa.xinghe.codegen.entity.enums.TemplateTypeEnum;
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.io.Serial;
import java.io.Serializable;
/**
* 获取模板列表 响应参数
* @author xia
* @version 0.0.1
*/
@Getter
@Setter
@Schema(description = "获取模板列表-响应")
public class TemplateQueryRes implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@Schema(description = "id")
private Long id;
@Schema(description = "是否使用")
private Boolean isUse;
@Schema(description = "模板名称")
private String templateName;
@Schema(description = "模板类型")
private TemplateTypeEnum templateType;
@Schema(description = "正文")
private String content;
}

View File

@@ -0,0 +1,16 @@
package com.cczsa.xinghe.codegen.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.mybatisflex.core.BaseMapper;
import com.cczsa.xinghe.codegen.entity.TemplateEntity;
/**
* 映射层。
*
* @author My
* @since 0.0.1
*/
@Mapper
public interface TemplateMapper extends BaseMapper<TemplateEntity> {
}

View File

@@ -0,0 +1,72 @@
package com.cczsa.xinghe.codegen.mapper.def;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.table.TableDef;
import java.io.Serial;
/**
* 表定义层。
*
* @author My
* @since 0.0.1
*/
public class TemplateDef extends TableDef {
@Serial
private static final long serialVersionUID = 1L;
/**
*
*/
public static final TemplateDef TEMPLATE_ENTITY = new TemplateDef();
/**
* 主键ID
*/
public final QueryColumn ID = new QueryColumn(this, "id");
/**
* 是否使用
*/
public final QueryColumn IS_USE = new QueryColumn(this, "is_use");
/**
* 正文
*/
public final QueryColumn CONTENT = new QueryColumn(this, "content");
/**
* 模板名称
*/
public final QueryColumn TEMPLATE_NAME = new QueryColumn(this, "template_name");
/**
* 模板类型
*/
public final QueryColumn TEMPLATE_TYPE = new QueryColumn(this, "template_type");
/**
* 所有字段。
*/
public final QueryColumn ALL_COLUMNS = new QueryColumn(this, "*");
/**
* 默认字段,不包含逻辑删除或者 large 等字段。
*/
public final QueryColumn[] DEFAULT_COLUMNS = new QueryColumn[]{ID, IS_USE, TEMPLATE_NAME, TEMPLATE_TYPE, CONTENT};
public TemplateDef() {
super("", "cg_template");
}
private TemplateDef(String schema, String name, String alisa) {
super(schema, name, alisa);
}
public TemplateDef as(String alias) {
String key = getNameWithSchema() + "." + alias;
return getCache(key, k -> new TemplateDef("", "cg_template", alias));
}
}

View File

@@ -0,0 +1,45 @@
package com.cczsa.xinghe.codegen.service;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateAddReq;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateEditReq;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateQueryReq;
import com.cczsa.xinghe.codegen.entity.res.template.TemplateQueryRes;
import com.cczsa.xinghe.codegen.util.XResult;
import java.util.List;
import java.util.Map;
/**
* 模板管理 服务层接口。
*
* @author xia
* @version 0.0.1
*/
public interface TemplateService {
/**
* 获取模板列表
*/
XResult<List<TemplateQueryRes>> query(TemplateQueryReq req);
/**
* 创建模板
*/
XResult<Void> add(TemplateAddReq req);
/**
* 修改模板
*/
XResult<Void> edit(TemplateEditReq req);
/**
* 删除模板
*/
XResult<Void> delete(Long id);
/**
* 获取模板类型列表
*/
XResult<List<Map<Integer, String>>> getTemplateTypeList();
}

View File

@@ -194,47 +194,49 @@ public class MenuServiceImpl implements MenuService {
return XResult.failed("菜单不存在"); return XResult.failed("菜单不存在");
} }
// 获取操作 // 获取操作
QueryWrapper queryFun = new QueryWrapper(); List<Long> funIdList = req.getFunIdList();
queryFun.eq(FunOperationEntity::getId, req.getFunId());
FunOperationEntity funOperationEntity = funOperationMapper.selectOneByQuery(queryFun);
if (funOperationEntity == null) {
return XResult.failed("权限不存在");
}
// 获取功能
QueryWrapper queryItem = new QueryWrapper();
queryItem.eq(FunItemEntity::getId, funOperationEntity.getItemId());
FunItemEntity funItemEntity = funItemMapper.selectOneByQuery(queryItem);
if (funItemEntity == null) {
return XResult.failed("功能不存在");
}
Boolean menuIsTenant = menuEntity.getIsTenant();
Boolean itemIsTenant = funItemEntity.getIsTenant();
if (!menuIsTenant.equals(itemIsTenant)) {
return XResult.failed("菜单和权限是否租户不一致");
}
// 删除旧绑定 // 删除旧绑定
QueryWrapper deleteMenuBindFun = new QueryWrapper(); QueryWrapper deleteMenuBindFun = new QueryWrapper();
deleteMenuBindFun.eq(MenuBindFunEntity::getMenuId, req.getMenuId()); deleteMenuBindFun.eq(MenuBindFunEntity::getMenuId, req.getMenuId());
deleteMenuBindFun.eq(MenuBindFunEntity::getFunId, req.getFunId());
menuBindFunMapper.deleteByQuery(deleteMenuBindFun); menuBindFunMapper.deleteByQuery(deleteMenuBindFun);
// 获取最大ID for (Long funId : funIdList) {
MenuBindFunDef menuBindFunDef = MenuBindFunDef.MENU_BIND_FUN_ENTITY; QueryWrapper queryFun = new QueryWrapper();
QueryWrapper queryId = new QueryWrapper(); queryFun.eq(FunOperationEntity::getId, funId);
queryId.select(menuBindFunDef.ID) FunOperationEntity funOperationEntity = funOperationMapper.selectOneByQuery(queryFun);
.from(menuBindFunDef) if (funOperationEntity == null) {
.orderBy(MenuBindFunEntity::getId, false); return XResult.failed("权限不存在:" + funId);
Long maxId = menuBindFunMapper.selectOneByQueryAs(queryId, Long.class); }
if (maxId == null) { // 获取功能
maxId = 10000L; QueryWrapper queryItem = new QueryWrapper();
} else { queryItem.eq(FunItemEntity::getId, funOperationEntity.getItemId());
maxId++; FunItemEntity funItemEntity = funItemMapper.selectOneByQuery(queryItem);
if (funItemEntity == null) {
return XResult.failed("功能不存在:" + funId);
}
Boolean menuIsTenant = menuEntity.getIsTenant();
Boolean itemIsTenant = funItemEntity.getIsTenant();
if (!menuIsTenant.equals(itemIsTenant)) {
return XResult.failed("菜单和权限是否租户不一致:" + funId);
}
// 获取最大ID
MenuBindFunDef menuBindFunDef = MenuBindFunDef.MENU_BIND_FUN_ENTITY;
QueryWrapper queryId = new QueryWrapper();
queryId.select(menuBindFunDef.ID)
.from(menuBindFunDef)
.orderBy(MenuBindFunEntity::getId, false);
Long maxId = menuBindFunMapper.selectOneByQueryAs(queryId, Long.class);
if (maxId == null) {
maxId = 10000L;
} else {
maxId++;
}
// 新增绑定
MenuBindFunEntity menuBindFunEntity = new MenuBindFunEntity();
menuBindFunEntity.setId(maxId);
menuBindFunEntity.setMenuId(req.getMenuId());
menuBindFunEntity.setFunId(funId);
menuBindFunMapper.insertSelective(menuBindFunEntity);
} }
// 新增绑定
MenuBindFunEntity menuBindFunEntity = new MenuBindFunEntity();
menuBindFunEntity.setId(maxId);
menuBindFunEntity.setMenuId(req.getMenuId());
menuBindFunEntity.setFunId(req.getFunId());
menuBindFunMapper.insertSelective(menuBindFunEntity);
return XResult.ok(); return XResult.ok();
} }

View File

@@ -0,0 +1,109 @@
package com.cczsa.xinghe.codegen.service.impl;
import com.cczsa.xinghe.codegen.entity.TemplateEntity;
import com.cczsa.xinghe.codegen.entity.enums.TemplateTypeEnum;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateAddReq;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateEditReq;
import com.cczsa.xinghe.codegen.entity.req.template.TemplateQueryReq;
import com.cczsa.xinghe.codegen.entity.res.template.TemplateQueryRes;
import com.cczsa.xinghe.codegen.mapper.TemplateMapper;
import com.cczsa.xinghe.codegen.mapper.def.TemplateDef;
import com.cczsa.xinghe.codegen.service.TemplateService;
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 java.util.List;
import java.util.Map;
/**
* 模板管理 服务层实现。
*
* @author xia
* @version 0.0.1
*/
@Service
@RequiredArgsConstructor
public class TemplateServiceImpl implements TemplateService {
private final TemplateMapper templateMapper;
/**
* 获取模板列表
*/
@Override
public XResult<List<TemplateQueryRes>> query(TemplateQueryReq req) {
TemplateDef templateDef = TemplateDef.TEMPLATE_ENTITY;
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.select(templateDef.ALL_COLUMNS)
.from(templateDef)
.like(TemplateEntity::getTemplateName, req.getTemplateName(), StrUtil.isNotBlank(req.getTemplateName()))
.eq(TemplateEntity::getTemplateType, req.getTemplateType(), req.getTemplateType() != null)
.eq(TemplateEntity::getIsUse, req.getIsUse(), req.getIsUse() != null);
List<TemplateQueryRes> templateQueryRes = templateMapper.selectListByQueryAs(queryWrapper, TemplateQueryRes.class);
return XResult.ok(templateQueryRes);
}
/**
* 创建模板
*/
@Override
public XResult<Void> add(TemplateAddReq req) {
// 模板名称是否存在
QueryWrapper queryName = new QueryWrapper();
queryName.eq(TemplateEntity::getTemplateName, req.getTemplateName());
long count = templateMapper.selectCountByQuery(queryName);
if (count > 0) {
return XResult.failed("模板名称已存在");
}
TemplateEntity templateEntity = new TemplateEntity();
BeanUtils.copyProperties(req, templateEntity);
templateMapper.insert(templateEntity);
return XResult.ok();
}
/**
* 修改模板
*/
@Override
public XResult<Void> edit(TemplateEditReq req) {
// 获取模板
TemplateEntity templateEntity = templateMapper.selectOneById(req.getId());
if (templateEntity == null) {
return XResult.failed("模板不存在");
}
// 模板名称是否存在
QueryWrapper queryName = new QueryWrapper();
queryName.eq(TemplateEntity::getTemplateName, req.getTemplateName());
queryName.ne(TemplateEntity::getId, req.getId());
long count = templateMapper.selectCountByQuery(queryName);
if (count > 0) {
return XResult.failed("模板名称已存在");
}
BeanUtils.copyProperties(req, templateEntity);
templateMapper.update(templateEntity);
return XResult.ok();
}
/**
* 删除模板
*/
@Override
public XResult<Void> delete(Long id) {
templateMapper.deleteById(id);
return XResult.ok();
}
/**
* 获取模板类型列表
*/
@Override
public XResult<List<Map<Integer, String>>> getTemplateTypeList() {
return XResult.ok(TemplateTypeEnum.getEnumList());
}
}