Commit ba34e3c98752acceb8ef18ec8d98a3740be81540

Authored by YunaiV
1 parent 08f64da8

优化代码生成器的展示

ruoyi-ui/src/views/tool/codegen/index.vue
@@ -77,12 +77,22 @@ @@ -77,12 +77,22 @@
77 <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" @pagination="getList"/> 77 <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" @pagination="getList"/>
78 78
79 <!-- 预览界面 --> 79 <!-- 预览界面 -->
80 - <el-dialog :title="preview.title" :visible.sync="preview.open" width="80%" top="5vh" append-to-body>  
81 - <el-tabs tab-position="left" v-model="preview.activeName">  
82 - <el-tab-pane v-for="item in preview.data" :label="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)" :name="item.filePath" :key="item.filePath">  
83 - <pre><code class="hljs" v-html="highlightedCode(item)"></code></pre>  
84 - </el-tab-pane>  
85 - </el-tabs> 80 + <el-dialog :title="preview.title" :visible.sync="preview.open" width="90%" top="5vh" append-to-body>
  81 +
  82 + <el-row>
  83 + <el-col :span="7">
  84 + <el-tree :data="preview.fileTree" :expand-on-click-node="false" default-expand-all
  85 + @node-click="handleNodeClick"/>
  86 + </el-col>
  87 + <el-col :span="17">
  88 + <el-tabs v-model="preview.activeName">
  89 + <el-tab-pane v-for="item in preview.data" :label="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)"
  90 + :name="item.filePath" :key="item.filePath">
  91 + <pre><code class="hljs" v-html="highlightedCode(item)"></code></pre>
  92 + </el-tab-pane>
  93 + </el-tabs>
  94 + </el-col>
  95 + </el-row>
86 </el-dialog> 96 </el-dialog>
87 97
88 <!-- 基于 DB 导入 --> 98 <!-- 基于 DB 导入 -->
@@ -154,8 +164,9 @@ export default { @@ -154,8 +164,9 @@ export default {
154 preview: { 164 preview: {
155 open: false, 165 open: false,
156 title: "代码预览", 166 title: "代码预览",
  167 + fileTree: [],
157 data: {}, 168 data: {},
158 - activeName: "domain.java" 169 + activeName: "",
159 }, 170 },
160 // 基于 SQL 导入 171 // 基于 SQL 导入
161 importSQL: { 172 importSQL: {
@@ -243,6 +254,11 @@ export default { @@ -243,6 +254,11 @@ export default {
243 handlePreview(row) { 254 handlePreview(row) {
244 previewCodegen(row.id).then(response => { 255 previewCodegen(row.id).then(response => {
245 this.preview.data = response.data; 256 this.preview.data = response.data;
  257 + let files = this.handleFiles(response.data);
  258 + console.log(files)
  259 + this.preview.fileTree = this.handleTree(files, "id", "parentId", "children",
  260 + "/"); // "/" 为根节点
  261 + console.log(this.preview.fileTree)
246 this.preview.activeName = response.data[0].filePath; 262 this.preview.activeName = response.data[0].filePath;
247 this.preview.open = true; 263 this.preview.open = true;
248 }); 264 });
@@ -255,6 +271,36 @@ export default { @@ -255,6 +271,36 @@ export default {
255 const result = hljs.highlight(language, item.code || "", true); 271 const result = hljs.highlight(language, item.code || "", true);
256 return result.value || '&nbsp;'; 272 return result.value || '&nbsp;';
257 }, 273 },
  274 + /** 生成 files 目录 **/
  275 + handleFiles(datas) {
  276 + let exists = {}; // key:file 的 id;value:true
  277 + let files = [];
  278 + // 遍历每个元素
  279 + for (const data of datas) {
  280 + let paths = data.filePath.split('/');
  281 + let fullPath = ''; // 从头开始的路径,用于生成 id
  282 + for (let i = 0; i < paths.length; i++) {
  283 + // 已经添加大奥 files 中,则跳过
  284 + let oldFullPath = fullPath;
  285 + fullPath = fullPath.length === 0 ? paths[i] : fullPath + '/' + paths[i];
  286 + if (exists[fullPath]) {
  287 + continue;
  288 + }
  289 + // 添加到 files 中
  290 + exists[fullPath] = true;
  291 + files.push({
  292 + id: fullPath,
  293 + label: paths[i],
  294 + parentId: oldFullPath || '/' // "/" 为根节点
  295 + });
  296 + }
  297 + }
  298 + return files;
  299 + },
  300 + /** 节点单击事件 **/
  301 + handleNodeClick(data) {
  302 + this.preview.activeName = data.id;
  303 + },
258 /** 修改按钮操作 */ 304 /** 修改按钮操作 */
259 handleEditTable(row) { 305 handleEditTable(row) {
260 const tableId = row.id; 306 const tableId = row.id;
src/main/java/cn/iocoder/dashboard/modules/infra/dal/dataobject/config/InfConfigDO.java
@@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.infra.dal.dataobject.config; @@ -3,6 +3,7 @@ package cn.iocoder.dashboard.modules.infra.dal.dataobject.config;
3 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO; 3 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
4 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum; 4 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
5 import com.baomidou.mybatisplus.annotation.TableField; 5 import com.baomidou.mybatisplus.annotation.TableField;
  6 +import com.baomidou.mybatisplus.annotation.TableId;
6 import com.baomidou.mybatisplus.annotation.TableName; 7 import com.baomidou.mybatisplus.annotation.TableName;
7 import lombok.Data; 8 import lombok.Data;
8 import lombok.EqualsAndHashCode; 9 import lombok.EqualsAndHashCode;
@@ -22,6 +23,7 @@ public class InfConfigDO extends BaseDO { @@ -22,6 +23,7 @@ public class InfConfigDO extends BaseDO {
22 /** 23 /**
23 * 参数主键 24 * 参数主键
24 */ 25 */
  26 + @TableId
25 private Long id; 27 private Long id;
26 /** 28 /**
27 * 参数分组 29 * 参数分组
src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceImplTest.java
@@ -3,21 +3,22 @@ package cn.iocoder.dashboard.modules.infra.service.config; @@ -3,21 +3,22 @@ package cn.iocoder.dashboard.modules.infra.service.config;
3 import cn.iocoder.dashboard.BaseSpringBootUnitTest; 3 import cn.iocoder.dashboard.BaseSpringBootUnitTest;
4 import cn.iocoder.dashboard.common.exception.ServiceException; 4 import cn.iocoder.dashboard.common.exception.ServiceException;
5 import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigCreateReqVO; 5 import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigCreateReqVO;
  6 +import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigUpdateReqVO;
6 import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO; 7 import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO;
7 import cn.iocoder.dashboard.modules.infra.dal.mysql.config.InfConfigMapper; 8 import cn.iocoder.dashboard.modules.infra.dal.mysql.config.InfConfigMapper;
8 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum; 9 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
9 import cn.iocoder.dashboard.modules.infra.mq.producer.config.InfConfigProducer; 10 import cn.iocoder.dashboard.modules.infra.mq.producer.config.InfConfigProducer;
10 import cn.iocoder.dashboard.modules.infra.service.config.impl.InfConfigServiceImpl; 11 import cn.iocoder.dashboard.modules.infra.service.config.impl.InfConfigServiceImpl;
11 -import cn.iocoder.dashboard.util.AssertUtils;  
12 import org.junit.jupiter.api.Test; 12 import org.junit.jupiter.api.Test;
13 import org.springframework.boot.test.mock.mockito.MockBean; 13 import org.springframework.boot.test.mock.mockito.MockBean;
14 14
15 import javax.annotation.Resource; 15 import javax.annotation.Resource;
  16 +import java.util.function.Consumer;
16 17
17 import static cn.hutool.core.util.RandomUtil.randomEle; 18 import static cn.hutool.core.util.RandomUtil.randomEle;
18 import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.CONFIG_KEY_DUPLICATE; 19 import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.CONFIG_KEY_DUPLICATE;
19 -import static cn.iocoder.dashboard.util.RandomUtils.randomInfConfigCreateReqVO;  
20 -import static cn.iocoder.dashboard.util.RandomUtils.randomInfConfigDO; 20 +import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
  21 +import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
21 import static org.junit.jupiter.api.Assertions.*; 22 import static org.junit.jupiter.api.Assertions.*;
22 import static org.mockito.Mockito.times; 23 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify; 24 import static org.mockito.Mockito.verify;
@@ -35,17 +36,17 @@ public class InfConfigServiceImplTest extends BaseSpringBootUnitTest { @@ -35,17 +36,17 @@ public class InfConfigServiceImplTest extends BaseSpringBootUnitTest {
35 36
36 @Test 37 @Test
37 public void testCreateConfig_success() { 38 public void testCreateConfig_success() {
38 - // 入参 39 + // 准备参数
39 InfConfigCreateReqVO reqVO = randomInfConfigCreateReqVO(); 40 InfConfigCreateReqVO reqVO = randomInfConfigCreateReqVO();
40 // mock 41 // mock
41 42
42 // 调用 43 // 调用
43 Long configId = configService.createConfig(reqVO); 44 Long configId = configService.createConfig(reqVO);
44 - // 校验 45 + // 断言
45 assertNotNull(configId); 46 assertNotNull(configId);
46 // 校验记录的属性是否正确 47 // 校验记录的属性是否正确
47 InfConfigDO config = configMapper.selectById(configId); 48 InfConfigDO config = configMapper.selectById(configId);
48 - AssertUtils.assertEquals(reqVO, config); 49 + assertPojoEquals(reqVO, config);
49 assertEquals(InfConfigTypeEnum.CUSTOM.getType(), config.getType()); 50 assertEquals(InfConfigTypeEnum.CUSTOM.getType(), config.getType());
50 // 校验调用 51 // 校验调用
51 verify(configProducer, times(1)).sendConfigRefreshMessage(); 52 verify(configProducer, times(1)).sendConfigRefreshMessage();
@@ -53,18 +54,50 @@ public class InfConfigServiceImplTest extends BaseSpringBootUnitTest { @@ -53,18 +54,50 @@ public class InfConfigServiceImplTest extends BaseSpringBootUnitTest {
53 54
54 @Test 55 @Test
55 public void testCreateConfig_keyDuplicate() { 56 public void testCreateConfig_keyDuplicate() {
56 - // 入参 57 + // 准备参数
57 InfConfigCreateReqVO reqVO = randomInfConfigCreateReqVO(); 58 InfConfigCreateReqVO reqVO = randomInfConfigCreateReqVO();
58 // mock 数据 59 // mock 数据
59 - configMapper.insert(randomInfConfigDO(o -> {  
60 - o.setKey(reqVO.getKey()); // @Sql:插入一条重复的 key  
61 - o.setType(randomEle(InfConfigTypeEnum.values()).getType()); 60 + configMapper.insert(randomInfConfigDO(o -> { // @Sql
  61 + o.setKey(reqVO.getKey()); // 模拟 key 重复
62 })); 62 }));
63 63
64 // 调用 64 // 调用
65 ServiceException serviceException = assertThrows(ServiceException.class, () -> configService.createConfig(reqVO)); 65 ServiceException serviceException = assertThrows(ServiceException.class, () -> configService.createConfig(reqVO));
66 // 断言 66 // 断言
67 - AssertUtils.assertEquals(CONFIG_KEY_DUPLICATE, serviceException); 67 + assertPojoEquals(CONFIG_KEY_DUPLICATE, serviceException);
  68 + }
  69 +
  70 + @Test
  71 + public void testUpdateConfig_success() {
  72 + // 准备参数
  73 + InfConfigUpdateReqVO reqVO = randomInfConfigUpdateReqVO();
  74 + // mock 数据
  75 + configMapper.insert(randomInfConfigDO(o -> o.setId(reqVO.getId())));// @Sql: 先插入出一条存在的数据
  76 +
  77 + // 调用
  78 + configService.updateConfig(reqVO);
  79 + // 校验是否更新正确
  80 + InfConfigDO config = configMapper.selectById(reqVO.getId()); // 获取最新的
  81 + assertPojoEquals(reqVO, config);
  82 + // 校验调用
  83 + verify(configProducer, times(1)).sendConfigRefreshMessage();
  84 + }
  85 +
  86 + // ========== 随机对象 ==========
  87 +
  88 + @SafeVarargs
  89 + private static InfConfigDO randomInfConfigDO(Consumer<InfConfigDO>... consumers) {
  90 + InfConfigDO config = randomPojo(InfConfigDO.class, consumers);
  91 + config.setType(randomEle(InfConfigTypeEnum.values()).getType());
  92 + return config;
  93 + }
  94 +
  95 + private static InfConfigCreateReqVO randomInfConfigCreateReqVO() {
  96 + return randomPojo(InfConfigCreateReqVO.class);
  97 + }
  98 +
  99 + private static InfConfigUpdateReqVO randomInfConfigUpdateReqVO() {
  100 + return randomPojo(InfConfigUpdateReqVO.class);
68 } 101 }
69 102
70 } 103 }
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java
@@ -42,7 +42,7 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest { @@ -42,7 +42,7 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
42 // 调用 42 // 调用
43 LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username); 43 LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
44 // 校验 44 // 校验
45 - AssertUtils.assertEquals(user, loginUser, "updateTime"); 45 + AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
46 assertNull(loginUser.getRoleIds()); // 此时不会加载角色,所以是空的 46 assertNull(loginUser.getRoleIds()); // 此时不会加载角色,所以是空的
47 } 47 }
48 48
@@ -73,7 +73,7 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest { @@ -73,7 +73,7 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
73 // 调用 73 // 调用
74 LoginUser loginUser = authService.mockLogin(userId); 74 LoginUser loginUser = authService.mockLogin(userId);
75 // 断言 75 // 断言
76 - AssertUtils.assertEquals(user, loginUser, "updateTime"); 76 + AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
77 assertEquals(roleIds, loginUser.getRoleIds()); 77 assertEquals(roleIds, loginUser.getRoleIds());
78 } 78 }
79 79
src/test/java/cn/iocoder/dashboard/util/AssertUtils.java
@@ -25,7 +25,7 @@ public class AssertUtils { @@ -25,7 +25,7 @@ public class AssertUtils {
25 * @param actual 实际对象 25 * @param actual 实际对象
26 * @param ignoreFields 忽略的属性数组 26 * @param ignoreFields 忽略的属性数组
27 */ 27 */
28 - public static void assertEquals(Object expected, Object actual, String... ignoreFields) { 28 + public static void assertPojoEquals(Object expected, Object actual, String... ignoreFields) {
29 Field[] expectedFields = ReflectUtil.getFields(expected.getClass()); 29 Field[] expectedFields = ReflectUtil.getFields(expected.getClass());
30 Arrays.stream(expectedFields).forEach(expectedField -> { 30 Arrays.stream(expectedFields).forEach(expectedField -> {
31 // 如果是忽略的属性,则不进行比对 31 // 如果是忽略的属性,则不进行比对
@@ -52,7 +52,7 @@ public class AssertUtils { @@ -52,7 +52,7 @@ public class AssertUtils {
52 * @param errorCode 错误码对象 52 * @param errorCode 错误码对象
53 * @param serviceException 业务异常 53 * @param serviceException 业务异常
54 */ 54 */
55 - public static void assertEquals(ErrorCode errorCode, ServiceException serviceException) { 55 + public static void assertPojoEquals(ErrorCode errorCode, ServiceException serviceException) {
56 Assertions.assertEquals(errorCode.getCode(), serviceException.getCode(), "错误码不匹配"); 56 Assertions.assertEquals(errorCode.getCode(), serviceException.getCode(), "错误码不匹配");
57 Assertions.assertEquals(errorCode.getMessage(), serviceException.getMessage(), "错误提示不匹配"); 57 Assertions.assertEquals(errorCode.getMessage(), serviceException.getMessage(), "错误提示不匹配");
58 } 58 }
src/test/java/cn/iocoder/dashboard/util/RandomUtils.java
@@ -2,8 +2,6 @@ package cn.iocoder.dashboard.util; @@ -2,8 +2,6 @@ package cn.iocoder.dashboard.util;
2 2
3 import cn.hutool.core.util.ArrayUtil; 3 import cn.hutool.core.util.ArrayUtil;
4 import cn.hutool.core.util.RandomUtil; 4 import cn.hutool.core.util.RandomUtil;
5 -import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigCreateReqVO;  
6 -import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO;  
7 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO; 5 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
8 import uk.co.jemos.podam.api.PodamFactory; 6 import uk.co.jemos.podam.api.PodamFactory;
9 import uk.co.jemos.podam.api.PodamFactoryImpl; 7 import uk.co.jemos.podam.api.PodamFactoryImpl;
@@ -75,17 +73,7 @@ public class RandomUtils { @@ -75,17 +73,7 @@ public class RandomUtils {
75 } 73 }
76 74
77 @SafeVarargs 75 @SafeVarargs
78 - public static InfConfigCreateReqVO randomInfConfigCreateReqVO(Consumer<InfConfigCreateReqVO>... consumers) {  
79 - return randomPojo(InfConfigCreateReqVO.class, consumers);  
80 - }  
81 -  
82 - @SafeVarargs  
83 - public static InfConfigDO randomInfConfigDO(Consumer<InfConfigDO>... consumers) {  
84 - return randomPojo(InfConfigDO.class, consumers);  
85 - }  
86 -  
87 - @SafeVarargs  
88 - private static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) { 76 + public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
89 T pojo = PODAM_FACTORY.manufacturePojo(clazz); 77 T pojo = PODAM_FACTORY.manufacturePojo(clazz);
90 // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理 78 // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
91 if (ArrayUtil.isNotEmpty(consumers)) { 79 if (ArrayUtil.isNotEmpty(consumers)) {