refactor: 添加菜单feign客户端,提供代码生成新增菜单

This commit is contained in:
Ray.Hao 2024-09-07 19:52:33 +08:00
parent 02f2c8e640
commit daec9f8542
17 changed files with 126 additions and 38 deletions

View File

@ -13,7 +13,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
* @since 0.0.1
*/
@SpringBootApplication
@EnableDiscoveryClient()
@EnableDiscoveryClient
@EnableFeignClients(basePackageClasses = {SkuFeignClient.class})
public class MemberApplication {
public static void main(String[] args) {

View File

@ -72,6 +72,11 @@
<artifactId>velocity-engine-core</artifactId>
</dependency>
<dependency>
<groupId>com.youlai</groupId>
<artifactId>system-api</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,15 +1,20 @@
package com.youlai.codegen;
import com.youlai.system.api.MenuFeignClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* 系统服务启动类
* 代码生成器启动类
*
* @author Ray
* @since 0.0.1
* @since 4.0.0
*/
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackageClasses = {MenuFeignClient.class})
public class CodegenApplication {
public static void main(String[] args) {
SpringApplication.run(CodegenApplication.class, args);

View File

@ -7,7 +7,7 @@ import com.youlai.common.result.Result;
import com.youlai.codegen.config.CodegenProperties;
import com.youlai.codegen.model.form.GenConfigForm;
import com.youlai.codegen.model.query.TablePageQuery;
import com.youlai.codegen.model.vo.CodePreviewVO;
import com.youlai.codegen.model.vo.CodegenPreviewVO;
import com.youlai.codegen.model.vo.TablePageVO;
import com.youlai.codegen.service.GenConfigService;
import com.youlai.codegen.service.CodegenService;
@ -91,14 +91,14 @@ public class CodegenController {
@Operation(summary = "获取预览生成代码")
@GetMapping("/{tableName}/preview")
public Result<List<CodePreviewVO>> getCodePreviewData(@PathVariable String tableName) {
List<CodePreviewVO> list = codegenService.getCodePreviewData(tableName);
public Result<List<CodegenPreviewVO>> getCodePreviewData(@PathVariable String tableName) {
List<CodegenPreviewVO> list = codegenService.getCodePreviewData(tableName);
return Result.success(list);
}
@Operation(summary = "下载代码")
@GetMapping("/{tableName}/download")
public void downloadZip(HttpServletResponse response, @PathVariable String tableName) throws IOException {
public void downloadZip(HttpServletResponse response, @PathVariable String tableName) {
String[] tableNames = tableName.split(",");
byte[] data = codegenService.downloadCode(tableNames);

View File

@ -3,6 +3,7 @@ package com.youlai.codegen.converter;
import com.youlai.codegen.model.entity.GenConfig;
import com.youlai.codegen.model.entity.GenFieldConfig;
import com.youlai.codegen.model.form.GenConfigForm;
import com.youlai.system.dto.CodegenMenuDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@ -36,4 +37,8 @@ public interface CodegenConverter {
GenFieldConfig toGenFieldConfig(GenConfigForm.FieldConfig fieldConfig);
@Mapping(source = "parentMenuId", target = "parentMenuId")
CodegenMenuDTO toCodegenMenuDTO(Long parentMenuId, GenConfig genConfig);
}

View File

@ -5,7 +5,7 @@ import lombok.Data;
@Schema(description = "代码生成代码预览VO")
@Data
public class CodePreviewVO {
public class CodegenPreviewVO {
@Schema(description = "生成文件路径")
private String path;

View File

@ -2,7 +2,7 @@ package com.youlai.codegen.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.youlai.codegen.model.query.TablePageQuery;
import com.youlai.codegen.model.vo.CodePreviewVO;
import com.youlai.codegen.model.vo.CodegenPreviewVO;
import com.youlai.codegen.model.vo.TablePageVO;
import java.util.List;
@ -29,7 +29,7 @@ public interface CodegenService {
* @param tableName 表名
* @return 包含代码预览信息的列表
*/
List<CodePreviewVO> getCodePreviewData(String tableName);
List<CodegenPreviewVO> getCodePreviewData(String tableName);
/**
* 下载代码

View File

@ -12,7 +12,6 @@ import com.youlai.codegen.model.form.GenConfigForm;
*/
public interface GenConfigService extends IService<GenConfig> {
/**
* 获取代码生成配置
*

View File

@ -17,7 +17,7 @@ import com.youlai.codegen.enums.JavaTypeEnum;
import com.youlai.codegen.model.entity.GenConfig;
import com.youlai.codegen.model.entity.GenFieldConfig;
import com.youlai.codegen.model.query.TablePageQuery;
import com.youlai.codegen.model.vo.CodePreviewVO;
import com.youlai.codegen.model.vo.CodegenPreviewVO;
import com.youlai.codegen.model.vo.TablePageVO;
import com.youlai.codegen.service.DatabaseService;
import com.youlai.codegen.service.GenConfigService;
@ -93,9 +93,9 @@ public class CodegenServiceImpl implements CodegenService {
* @return 预览数据
*/
@Override
public List<CodePreviewVO> getCodePreviewData(String tableName) {
public List<CodegenPreviewVO> getCodePreviewData(String tableName) {
List<CodePreviewVO> list = new ArrayList<>();
List<CodegenPreviewVO> list = new ArrayList<>();
GenConfig genConfig = genConfigService.getOne(new LambdaQueryWrapper<GenConfig>()
.eq(GenConfig::getTableName, tableName)
@ -116,7 +116,7 @@ public class CodegenServiceImpl implements CodegenService {
// 遍历模板配置
Map<String, CodegenProperties.TemplateConfig> templateConfigs = codegenProperties.getTemplateConfigs();
for (Map.Entry<String, CodegenProperties.TemplateConfig> templateConfigEntry : templateConfigs.entrySet()) {
CodePreviewVO previewVO = new CodePreviewVO();
CodegenPreviewVO previewVO = new CodegenPreviewVO();
CodegenProperties.TemplateConfig templateConfig = templateConfigEntry.getValue();
@ -308,9 +308,9 @@ public class CodegenServiceImpl implements CodegenService {
* @param zip 压缩文件输出流
*/
private void generateAndZipCode(String tableName, ZipOutputStream zip) {
List<CodePreviewVO> codePreviewList = getCodePreviewData(tableName);
List<CodegenPreviewVO> codePreviewList = getCodePreviewData(tableName);
for (CodePreviewVO codePreview : codePreviewList) {
for (CodegenPreviewVO codePreview : codePreviewList) {
String fileName = codePreview.getFileName();
String content = codePreview.getContent();
String path = codePreview.getPath();

View File

@ -21,6 +21,8 @@ import com.youlai.codegen.model.entity.GenFieldConfig;
import com.youlai.codegen.model.form.GenConfigForm;
import com.youlai.codegen.service.GenConfigService;
import com.youlai.codegen.service.GenFieldConfigService;
import com.youlai.system.api.MenuFeignClient;
import com.youlai.system.dto.CodegenMenuDTO;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@ -41,7 +43,7 @@ public class GenConfigServiceImpl extends ServiceImpl<GenConfigMapper, GenConfig
private final CodegenProperties codegenProperties;
private final GenFieldConfigService genFieldConfigService;
private final CodegenConverter codegenConverter;
/* private final MenuService menuService;*/
private final MenuFeignClient menuFeignClient;
@Value("${spring.profiles.active}")
private String springProfilesActive;
@ -174,10 +176,11 @@ public class GenConfigServiceImpl extends ServiceImpl<GenConfigMapper, GenConfig
GenConfig genConfig = codegenConverter.toGenConfig(formData);
this.saveOrUpdate(genConfig);
// 如果选择上级菜单
// 如果选择上级菜单且当前环境不是生产环境则新增菜单
Long parentMenuId = formData.getParentMenuId();
if (parentMenuId != null && EnvEnum.DEV.getValue().equals(springProfilesActive) ) {
// menuService.saveMenu(parentMenuId, genConfig);
if (parentMenuId != null && EnvEnum.PROD.getValue().equals(springProfilesActive)) {
CodegenMenuDTO codegenMenuDTO = codegenConverter.toCodegenMenuDTO(parentMenuId, genConfig);
menuFeignClient.addMenuForCodegen(codegenMenuDTO);
}
List<GenFieldConfig> genFieldConfigs = codegenConverter.toGenFieldConfig(formData.getFieldConfigs());

View File

@ -3,12 +3,12 @@ server:
spring:
application:
name: youlai-generator
name: youlai-codegen
profiles:
active: dev
# 代码生成器配置
generator:
codegen:
# 下载代码文件名称
downloadFileName: youlai-mall-code.zip
# 后端项目名称

View File

@ -12,8 +12,8 @@ import lombok.Getter;
@Getter
public enum EnvEnum implements IBaseEnum<String> {
DEV("dev", "开发"),
PROD("prod", "生产");
DEV("dev", "开发环境"),
PROD("prod", "生产环境");
private final String value;

View File

@ -0,0 +1,14 @@
package com.youlai.system.api;
import com.youlai.common.core.config.FeignDecoderConfig;
import com.youlai.system.dto.CodegenMenuDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@FeignClient(value = "youlai-system", contextId = "menu", configuration = {FeignDecoderConfig.class})
public interface MenuFeignClient {
@PostMapping("/api/v1/menus/codegen")
void addMenuForCodegen( @RequestBody CodegenMenuDTO data);
}

View File

@ -7,7 +7,7 @@ import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
@FeignClient(value = "youlai-system", fallback = UserFeignFallbackClient.class, configuration = {FeignDecoderConfig.class})
@FeignClient(value = "youlai-system", contextId = "user", fallback = UserFeignFallbackClient.class, configuration = {FeignDecoderConfig.class})
public interface UserFeignClient {
@GetMapping("/api/v1/users/{username}/authInfo")

View File

@ -113,16 +113,14 @@ public class MenuController {
return Result.judge(result);
}
/**
* 代码生成器生成代码新增菜单
*/
@PostMapping("/codegen")
public Result<Void> createCodegenMenu(
public Result<Void> addMenuForCodegen(
@RequestBody @Valid CodegenMenuDTO data
) {
boolean result = menuService.createCodegenMenu(data);
boolean result = menuService.addMenuForCodegen(data);
return Result.judge(result);
}

View File

@ -64,5 +64,5 @@ public interface MenuService extends IService<Menu> {
/**
* 保存生成代码菜单
*/
boolean createCodegenMenu(@Valid CodegenMenuDTO data);
boolean addMenuForCodegen(@Valid CodegenMenuDTO data);
}

View File

@ -338,15 +338,74 @@ public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements Me
}
/**
* 保存生成代码菜单
* 代码生成时添加菜单
*
* @param data
* @return
* @param data {@link CodegenMenuDTO} 代码生成菜单数据传输对象
* @return 是否成功
*/
@Override
public boolean createCodegenMenu(CodegenMenuDTO data) {
return false;
public boolean addMenuForCodegen(CodegenMenuDTO data) {
Long parentMenuId = data.getParentMenuId();
Menu parentMenu = this.getById(parentMenuId);
Assert.notNull(parentMenu, "上级菜单不存在");
String entityName =data.getEntityName();
long count = this.count(new LambdaQueryWrapper<Menu>().eq(Menu::getRouteName, entityName));
if (count > 0) {
throw new RuntimeException("菜单已存在");
}
// 业务名称 e.g. 用户管理
String businessName = data.getBusinessName();
// 模块名称 e.g. system
String moduleName = data.getModuleName();
// 获取父级菜单子菜单最带的排序
Menu maxSortMenu = this.getOne(new LambdaQueryWrapper<Menu>().eq(Menu::getParentId, parentMenuId)
.orderByDesc(Menu::getSort)
.last("limit 1")
);
int sort = 1;
if (maxSortMenu != null) {
sort = maxSortMenu.getSort() + 1;
}
Menu menu = new Menu();
menu.setParentId(parentMenuId);
menu.setName(businessName);
menu.setRouteName(entityName);
menu.setRoutePath(StrUtil.toSymbolCase(entityName, '-'));
menu.setComponent(data.getModuleName() + "/" + StrUtil.toSymbolCase(entityName, '-') + "/index");
menu.setType(MenuTypeEnum.MENU);
menu.setSort(sort);
menu.setVisible(1);
boolean result = this.save(menu);
if (result) {
// 生成treePath
String treePath = generateMenuTreePath(parentMenuId);
menu.setTreePath(treePath);
this.updateById(menu);
// 生成CURD按钮权限
String permPrefix = data.getModuleName() + ":" + StrUtil.lowerFirst(entityName) + ":";
String[] actions = {"查询", "新增", "编辑", "删除"};
String[] perms = {"query", "add", "edit", "delete"};
for (int i = 0; i < actions.length; i++) {
Menu button = new Menu();
button.setParentId(menu.getId());
button.setType(MenuTypeEnum.BUTTON);
button.setName(actions[i]);
button.setPerm(permPrefix + perms[i]);
button.setSort(i + 1);
this.save(button);
// 生成 treepath
button.setTreePath(treePath + "," + button.getId());
this.updateById(button);
}
}
return result;
}
}