fix: 代码生成器 自定义模板 新增删除

This commit is contained in:
cuijiawang
2025-09-27 17:15:32 +08:00
parent e512fc29e0
commit 685cc3d92c
4 changed files with 81 additions and 63 deletions

View File

@@ -128,9 +128,19 @@ public class UserTemplateController {
public R<Void> removeBatch(@RequestBody Map<String, Object> params) {
try {
@SuppressWarnings("unchecked")
List<Integer> idsInt = (List<Integer>) params.get("ids");
Long[] ids = idsInt.stream()
.map(Integer::longValue)
List<Object> idsObj = (List<Object>) params.get("ids");
Long[] ids = idsObj.stream()
.map(obj -> {
if (obj instanceof Integer) {
return ((Integer) obj).longValue();
} else if (obj instanceof Long) {
return (Long) obj;
} else if (obj instanceof String) {
return Long.parseLong((String) obj);
} else {
throw new RuntimeException("不支持的ID类型: " + obj.getClass());
}
})
.toArray(Long[]::new);
boolean success = userTemplateService.deleteUserTemplateByIds(ids);
return success ? R.ok() : R.fail("批量删除模板失败");

View File

@@ -2,9 +2,6 @@ package com.agileboot.codegen.mapper;
import com.agileboot.codegen.entity.UserTemplate;
import com.agileboot.common.mybatis.mapper.BaseMapperDelete;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
@@ -14,30 +11,20 @@ import java.util.List;
/**
* 用户模板 Mapper接口
*
*
* @author system
* @date 2025-09-26
*/
@Mapper
public interface UserTemplateMapper extends BaseMapperDelete<UserTemplate> {
/**
* 分页查询用户模板列表
*
* @param page 页码对象
* @param queryWrapper 查询条件
* @return 用户模板列表
*/
@Select("SELECT * FROM user_template ${ew.customSqlSegment}")
Page<UserTemplate> selectUserTemplateList(Page<UserTemplate> page, @Param(Constants.WRAPPER) Wrapper<UserTemplate> queryWrapper);
/**
* 查询公开模板列表
*
* @param templateGroup 模板分组(可选)
* @return 公开模板列表
*/
@Select("SELECT * FROM user_template WHERE is_public = 1 AND status = 1 ORDER BY use_count DESC, create_time DESC")
@Select("SELECT * FROM user_template WHERE is_public = 1 AND status = 1 AND deleted = 0 ORDER BY use_count DESC, create_time DESC")
List<UserTemplate> selectPublicTemplates(@Param("templateGroup") String templateGroup);
/**
@@ -48,10 +35,10 @@ public interface UserTemplateMapper extends BaseMapperDelete<UserTemplate> {
* @param excludeId 排除的模板ID更新时使用
* @return 存在的数量
*/
@Select("SELECT COUNT(*) FROM user_template WHERE user_id = #{userId} AND template_name = #{templateName}")
int checkTemplateNameExists(@Param("userId") Long userId,
@Param("templateName") String templateName,
@Param("excludeId") Long excludeId);
@Select("SELECT COUNT(*) FROM user_template WHERE user_id = #{userId} AND template_name = #{templateName} AND deleted = 0 AND (#{excludeId} IS NULL OR id != #{excludeId})")
int checkTemplateNameExists(@Param("userId") Long userId,
@Param("templateName") String templateName,
@Param("excludeId") Long excludeId);
/**
* 增加模板使用次数
@@ -69,6 +56,6 @@ public interface UserTemplateMapper extends BaseMapperDelete<UserTemplate> {
* @param status 状态
* @return 模板数量
*/
@Select("SELECT COUNT(*) FROM user_template WHERE user_id = #{userId} AND status = #{status}")
@Select("SELECT COUNT(*) FROM user_template WHERE user_id = #{userId} AND status = #{status} AND deleted = 0")
int countByUserIdAndStatus(@Param("userId") Long userId, @Param("status") Integer status);
}

View File

@@ -9,6 +9,7 @@ import cn.hutool.core.bean.BeanUtil;
import com.agileboot.common.satoken.utils.LoginHelper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import java.util.Arrays;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.RequiredArgsConstructor;
@@ -25,7 +26,7 @@ import java.util.stream.Collectors;
/**
* 用户模板 Service实现类
*
*
* @author system
* @date 2025-09-26
*/
@@ -43,16 +44,16 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
.eq(StringUtils.isNotBlank(templateGroup), UserTemplate::getTemplateGroup, templateGroup)
.eq(isPublic != null, UserTemplate::getIsPublic, isPublic)
.orderByDesc(UserTemplate::getCreateTime);
Page<UserTemplate> templatePage = userTemplateMapper.selectUserTemplateList(page, wrapper);
Page<UserTemplate> templatePage = userTemplateMapper.selectPage(page, wrapper);
// 转换为VO
Page<UserTemplateVO> voPage = new Page<>(templatePage.getCurrent(), templatePage.getSize(), templatePage.getTotal());
List<UserTemplateVO> voList = templatePage.getRecords().stream()
.map(this::convertToVO)
.collect(Collectors.toList());
voPage.setRecords(voList);
return voPage;
}
@@ -78,19 +79,19 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
@Transactional
public boolean insertUserTemplate(UserTemplateDTO dto) {
Long currentUserId = LoginHelper.getUserId();
// 检查模板名称是否存在
if (checkTemplateNameExists(currentUserId, dto.getTemplateName(), null)) {
throw new RuntimeException("模板名称已存在");
}
UserTemplate template = new UserTemplate();
BeanUtil.copyProperties(dto, template);
template.setUserId(currentUserId);
template.setUseCount(0);
template.setStatus(dto.getStatus() != null ? dto.getStatus() : 1);
template.setVersion(StringUtils.isNotBlank(dto.getVersion()) ? dto.getVersion() : "1.0.0");
return userTemplateMapper.insert(template) > 0;
}
@@ -100,46 +101,55 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
if (dto.getId() == null) {
throw new RuntimeException("模板ID不能为空");
}
UserTemplate existTemplate = userTemplateMapper.selectById(dto.getId());
if (existTemplate == null) {
throw new RuntimeException("模板不存在");
}
Long currentUserId = LoginHelper.getUserId();
// 只能修改自己的模板
if (!currentUserId.equals(existTemplate.getUserId())) {
throw new RuntimeException("无权限修改此模板");
}
// 检查模板名称是否存在(只在名称发生变化时才检查)
if (!existTemplate.getTemplateName().equals(dto.getTemplateName()) &&
if (!existTemplate.getTemplateName().equals(dto.getTemplateName()) &&
checkTemplateNameExists(currentUserId, dto.getTemplateName(), dto.getId())) {
throw new RuntimeException("模板名称已存在");
}
UserTemplate template = new UserTemplate();
BeanUtil.copyProperties(dto, template);
template.setUserId(currentUserId);
return userTemplateMapper.updateById(template) > 0;
}
@Override
@Transactional
public boolean deleteUserTemplateById(Long id) {
if (id == null) {
throw new RuntimeException("模板ID不能为空");
}
UserTemplate template = userTemplateMapper.selectById(id);
if (template == null) {
return false;
throw new RuntimeException("模板不存在或已被删除");
}
Long currentUserId = LoginHelper.getUserId();
// 只能删除自己的模板
if (!currentUserId.equals(template.getUserId())) {
throw new RuntimeException("无权限删除此模板");
}
return userTemplateMapper.deleteById(id) > 0;
int result = userTemplateMapper.deleteById(id);
if (result <= 0) {
throw new RuntimeException("删除操作失败");
}
return true;
}
@Override
@@ -148,9 +158,9 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
if (ids == null || ids.length == 0) {
return false;
}
Long currentUserId = LoginHelper.getUserId();
// 检查所有模板是否属于当前用户
for (Long id : ids) {
UserTemplate template = userTemplateMapper.selectById(id);
@@ -158,13 +168,8 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
throw new RuntimeException("无权限删除模板ID: " + id);
}
}
// 批量删除
for (Long id : ids) {
userTemplateMapper.deleteById(id);
}
return true;
return userTemplateMapper.deleteByIds(Arrays.asList(ids)) > 0;
}
@Override
@@ -174,19 +179,19 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
if (sourceTemplate == null) {
throw new RuntimeException("源模板不存在");
}
// 只能复制公开模板
if (sourceTemplate.getIsPublic() != 1) {
throw new RuntimeException("该模板不是公开模板,无法复制");
}
Long currentUserId = LoginHelper.getUserId();
// 检查新模板名称是否存在
if (checkTemplateNameExists(currentUserId, newName, null)) {
throw new RuntimeException("模板名称已存在");
}
UserTemplate newTemplate = new UserTemplate();
BeanUtil.copyProperties(sourceTemplate, newTemplate);
newTemplate.setId(null);
@@ -194,7 +199,7 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
newTemplate.setTemplateName(newName);
newTemplate.setIsPublic(0); // 复制的模板默认为私有
newTemplate.setUseCount(0);
return userTemplateMapper.insert(newTemplate) > 0;
}
@@ -203,18 +208,18 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
try {
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
cfg.setDefaultEncoding("UTF-8");
// 创建模板对象
Template template = new Template("validate", new StringReader(templateContent), cfg);
// 使用测试数据验证模板
StringWriter writer = new StringWriter();
HashMap<String, Object> testData = new HashMap<>();
testData.put("className", "TestClass");
testData.put("tableName", "test_table");
template.process(testData, writer);
return "模板语法验证通过";
} catch (Exception e) {
return "模板语法错误: " + e.getMessage();
@@ -238,10 +243,10 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
private UserTemplateVO convertToVO(UserTemplate template) {
UserTemplateVO vo = new UserTemplateVO();
BeanUtil.copyProperties(template, vo);
// 设置文本描述
vo.setIsPublicText(template.getIsPublic() == 1 ? "公开" : "私有");
String statusText;
switch (template.getStatus()) {
case 0:
@@ -257,11 +262,11 @@ public class UserTemplateServiceImpl implements IUserTemplateService {
statusText = "未知";
}
vo.setStatusText(statusText);
// 判断是否为当前用户创建
Long currentUserId = LoginHelper.getUserId();
vo.setIsOwner(currentUserId != null && currentUserId.equals(template.getUserId()));
return vo;
}
}

View File

@@ -0,0 +1,16 @@
-- 修复用户模板表的唯一约束问题
-- 解决逻辑删除与唯一约束的冲突
-- 1. 删除原有的唯一约束
ALTER TABLE `user_template` DROP INDEX `uk_user_template_name`;
-- 2. 创建条件唯一索引,只对未删除的记录生效
-- MySQL 5.7+ 支持函数索引,但为了兼容性,我们使用另一种方案
-- 创建一个复合索引,对于已删除的记录,使用 NULL 值来避免唯一约束
ALTER TABLE `user_template` ADD UNIQUE INDEX `uk_user_template_name_active` (`user_id`, `template_name`, (CASE WHEN deleted = 0 THEN 0 ELSE NULL END));
-- 注意:这个索引允许以下情况:
-- - 用户A有模板"test1"deleted=0正常- 唯一
-- - 用户A有多个模板"test1"deleted=1已删除- 允许多个
-- 但不允许:
-- - 用户A有两个模板"test1"都是deleted=0