Ver código fonte

优化代码生成器的展示

YunaiV 4 anos atrás
pai
commit
ba34e3c987

+ 53 - 7
ruoyi-ui/src/views/tool/codegen/index.vue

@@ -77,12 +77,22 @@
     <pagination v-show="total>0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize" @pagination="getList"/>
 
     <!-- 预览界面 -->
-    <el-dialog :title="preview.title" :visible.sync="preview.open" width="80%" top="5vh" append-to-body>
-      <el-tabs tab-position="left" v-model="preview.activeName">
-        <el-tab-pane v-for="item in preview.data" :label="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)" :name="item.filePath" :key="item.filePath">
-          <pre><code class="hljs" v-html="highlightedCode(item)"></code></pre>
-        </el-tab-pane>
-      </el-tabs>
+    <el-dialog :title="preview.title" :visible.sync="preview.open" width="90%" top="5vh" append-to-body>
+
+      <el-row>
+        <el-col :span="7">
+          <el-tree :data="preview.fileTree" :expand-on-click-node="false" default-expand-all
+                   @node-click="handleNodeClick"/>
+        </el-col>
+        <el-col :span="17">
+          <el-tabs v-model="preview.activeName">
+            <el-tab-pane v-for="item in preview.data" :label="item.filePath.substring(item.filePath.lastIndexOf('/') + 1)"
+                         :name="item.filePath" :key="item.filePath">
+              <pre><code class="hljs" v-html="highlightedCode(item)"></code></pre>
+            </el-tab-pane>
+          </el-tabs>
+        </el-col>
+      </el-row>
     </el-dialog>
 
     <!-- 基于 DB 导入 -->
@@ -154,8 +164,9 @@ export default {
       preview: {
         open: false,
         title: "代码预览",
+        fileTree: [],
         data: {},
-        activeName: "domain.java"
+        activeName: "",
       },
       // 基于 SQL 导入
       importSQL: {
@@ -243,6 +254,11 @@ export default {
     handlePreview(row) {
       previewCodegen(row.id).then(response => {
         this.preview.data = response.data;
+        let files = this.handleFiles(response.data);
+        console.log(files)
+        this.preview.fileTree = this.handleTree(files, "id", "parentId", "children",
+            "/"); // "/" 为根节点
+        console.log(this.preview.fileTree)
         this.preview.activeName = response.data[0].filePath;
         this.preview.open = true;
       });
@@ -255,6 +271,36 @@ export default {
       const result = hljs.highlight(language, item.code || "", true);
       return result.value || '&nbsp;';
     },
+    /** 生成 files 目录 **/
+    handleFiles(datas) {
+      let exists = {}; // key:file 的 id;value:true
+      let files = [];
+      // 遍历每个元素
+      for (const data of datas) {
+        let paths = data.filePath.split('/');
+        let fullPath = ''; // 从头开始的路径,用于生成 id
+        for (let i = 0; i < paths.length; i++) {
+          // 已经添加大奥 files 中,则跳过
+          let oldFullPath = fullPath;
+          fullPath = fullPath.length === 0 ? paths[i] : fullPath + '/' + paths[i];
+          if (exists[fullPath]) {
+            continue;
+          }
+          // 添加到 files 中
+          exists[fullPath] = true;
+          files.push({
+            id: fullPath,
+            label: paths[i],
+            parentId: oldFullPath || '/'  // "/" 为根节点
+          });
+        }
+      }
+      return files;
+    },
+    /** 节点单击事件 **/
+    handleNodeClick(data) {
+      this.preview.activeName = data.id;
+    },
     /** 修改按钮操作 */
     handleEditTable(row) {
       const tableId = row.id;

+ 2 - 0
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;
 import cn.iocoder.dashboard.framework.mybatis.core.dataobject.BaseDO;
 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
@@ -22,6 +23,7 @@ public class InfConfigDO extends BaseDO {
     /**
      * 参数主键
      */
+    @TableId
     private Long id;
     /**
      * 参数分组

+ 44 - 11
src/test/java/cn/iocoder/dashboard/modules/infra/service/config/InfConfigServiceImplTest.java

@@ -3,21 +3,22 @@ package cn.iocoder.dashboard.modules.infra.service.config;
 import cn.iocoder.dashboard.BaseSpringBootUnitTest;
 import cn.iocoder.dashboard.common.exception.ServiceException;
 import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigCreateReqVO;
+import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigUpdateReqVO;
 import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO;
 import cn.iocoder.dashboard.modules.infra.dal.mysql.config.InfConfigMapper;
 import cn.iocoder.dashboard.modules.infra.enums.config.InfConfigTypeEnum;
 import cn.iocoder.dashboard.modules.infra.mq.producer.config.InfConfigProducer;
 import cn.iocoder.dashboard.modules.infra.service.config.impl.InfConfigServiceImpl;
-import cn.iocoder.dashboard.util.AssertUtils;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.mock.mockito.MockBean;
 
 import javax.annotation.Resource;
+import java.util.function.Consumer;
 
 import static cn.hutool.core.util.RandomUtil.randomEle;
 import static cn.iocoder.dashboard.modules.infra.enums.InfErrorCodeConstants.CONFIG_KEY_DUPLICATE;
-import static cn.iocoder.dashboard.util.RandomUtils.randomInfConfigCreateReqVO;
-import static cn.iocoder.dashboard.util.RandomUtils.randomInfConfigDO;
+import static cn.iocoder.dashboard.util.AssertUtils.assertPojoEquals;
+import static cn.iocoder.dashboard.util.RandomUtils.randomPojo;
 import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -35,17 +36,17 @@ public class InfConfigServiceImplTest extends BaseSpringBootUnitTest {
 
     @Test
     public void testCreateConfig_success() {
-        // 入参
+        // 准备参数
         InfConfigCreateReqVO reqVO = randomInfConfigCreateReqVO();
         // mock
 
         // 调用
         Long configId = configService.createConfig(reqVO);
-        // 校验
+        // 断言
         assertNotNull(configId);
         // 校验记录的属性是否正确
         InfConfigDO config = configMapper.selectById(configId);
-        AssertUtils.assertEquals(reqVO, config);
+        assertPojoEquals(reqVO, config);
         assertEquals(InfConfigTypeEnum.CUSTOM.getType(), config.getType());
         // 校验调用
         verify(configProducer, times(1)).sendConfigRefreshMessage();
@@ -53,18 +54,50 @@ public class InfConfigServiceImplTest extends BaseSpringBootUnitTest {
 
     @Test
     public void testCreateConfig_keyDuplicate() {
-        // 入参
+        // 准备参数
         InfConfigCreateReqVO reqVO = randomInfConfigCreateReqVO();
         // mock 数据
-        configMapper.insert(randomInfConfigDO(o -> {
-            o.setKey(reqVO.getKey()); // @Sql:插入一条重复的 key
-            o.setType(randomEle(InfConfigTypeEnum.values()).getType());
+        configMapper.insert(randomInfConfigDO(o -> { // @Sql
+            o.setKey(reqVO.getKey()); // 模拟 key 重复
         }));
 
         // 调用
         ServiceException serviceException = assertThrows(ServiceException.class, () -> configService.createConfig(reqVO));
         // 断言
-        AssertUtils.assertEquals(CONFIG_KEY_DUPLICATE, serviceException);
+        assertPojoEquals(CONFIG_KEY_DUPLICATE, serviceException);
+    }
+
+    @Test
+    public void testUpdateConfig_success() {
+        // 准备参数
+        InfConfigUpdateReqVO reqVO = randomInfConfigUpdateReqVO();
+        // mock 数据
+        configMapper.insert(randomInfConfigDO(o -> o.setId(reqVO.getId())));// @Sql: 先插入出一条存在的数据
+
+        // 调用
+        configService.updateConfig(reqVO);
+        // 校验是否更新正确
+        InfConfigDO config = configMapper.selectById(reqVO.getId()); // 获取最新的
+        assertPojoEquals(reqVO, config);
+        // 校验调用
+        verify(configProducer, times(1)).sendConfigRefreshMessage();
+    }
+
+    // ========== 随机对象 ==========
+
+    @SafeVarargs
+    private static InfConfigDO randomInfConfigDO(Consumer<InfConfigDO>... consumers) {
+        InfConfigDO config = randomPojo(InfConfigDO.class, consumers);
+        config.setType(randomEle(InfConfigTypeEnum.values()).getType());
+        return config;
+    }
+
+    private static InfConfigCreateReqVO randomInfConfigCreateReqVO() {
+        return randomPojo(InfConfigCreateReqVO.class);
+    }
+
+    private static InfConfigUpdateReqVO randomInfConfigUpdateReqVO() {
+        return randomPojo(InfConfigUpdateReqVO.class);
     }
 
 }

+ 2 - 2
src/test/java/cn/iocoder/dashboard/modules/system/service/auth/SysAuthServiceImplTest.java

@@ -42,7 +42,7 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
         // 调用
         LoginUser loginUser = (LoginUser) authService.loadUserByUsername(username);
         // 校验
-        AssertUtils.assertEquals(user, loginUser, "updateTime");
+        AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
         assertNull(loginUser.getRoleIds()); // 此时不会加载角色,所以是空的
     }
 
@@ -73,7 +73,7 @@ public class SysAuthServiceImplTest extends BaseSpringBootUnitTest {
         // 调用
         LoginUser loginUser = authService.mockLogin(userId);
         // 断言
-        AssertUtils.assertEquals(user, loginUser, "updateTime");
+        AssertUtils.assertPojoEquals(user, loginUser, "updateTime");
         assertEquals(roleIds, loginUser.getRoleIds());
     }
 

+ 2 - 2
src/test/java/cn/iocoder/dashboard/util/AssertUtils.java

@@ -25,7 +25,7 @@ public class AssertUtils {
      * @param actual 实际对象
      * @param ignoreFields 忽略的属性数组
      */
-    public static void assertEquals(Object expected, Object actual, String... ignoreFields) {
+    public static void assertPojoEquals(Object expected, Object actual, String... ignoreFields) {
         Field[] expectedFields = ReflectUtil.getFields(expected.getClass());
         Arrays.stream(expectedFields).forEach(expectedField -> {
             // 如果是忽略的属性,则不进行比对
@@ -52,7 +52,7 @@ public class AssertUtils {
      * @param errorCode 错误码对象
      * @param serviceException 业务异常
      */
-    public static void assertEquals(ErrorCode errorCode, ServiceException serviceException) {
+    public static void assertPojoEquals(ErrorCode errorCode, ServiceException serviceException) {
         Assertions.assertEquals(errorCode.getCode(), serviceException.getCode(), "错误码不匹配");
         Assertions.assertEquals(errorCode.getMessage(), serviceException.getMessage(), "错误提示不匹配");
     }

+ 1 - 13
src/test/java/cn/iocoder/dashboard/util/RandomUtils.java

@@ -2,8 +2,6 @@ package cn.iocoder.dashboard.util;
 
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.RandomUtil;
-import cn.iocoder.dashboard.modules.infra.controller.config.vo.InfConfigCreateReqVO;
-import cn.iocoder.dashboard.modules.infra.dal.dataobject.config.InfConfigDO;
 import cn.iocoder.dashboard.modules.system.dal.dataobject.user.SysUserDO;
 import uk.co.jemos.podam.api.PodamFactory;
 import uk.co.jemos.podam.api.PodamFactoryImpl;
@@ -75,17 +73,7 @@ public class RandomUtils {
     }
 
     @SafeVarargs
-    public static InfConfigCreateReqVO randomInfConfigCreateReqVO(Consumer<InfConfigCreateReqVO>... consumers) {
-        return randomPojo(InfConfigCreateReqVO.class, consumers);
-    }
-
-    @SafeVarargs
-    public static InfConfigDO randomInfConfigDO(Consumer<InfConfigDO>... consumers) {
-        return randomPojo(InfConfigDO.class, consumers);
-    }
-
-    @SafeVarargs
-    private static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
+    public static <T> T randomPojo(Class<T> clazz, Consumer<T>... consumers) {
         T pojo = PODAM_FACTORY.manufacturePojo(clazz);
         // 非空时,回调逻辑。通过它,可以实现 Pojo 的进一步处理
         if (ArrayUtil.isNotEmpty(consumers)) {