Sfoglia il codice sorgente

多模块重构 11:代码生成器,优化展示

YunaiV 3 anni fa
parent
commit
db9bae05b0

+ 2 - 1
yudao-module-tool/yudao-module-tool-impl/src/main/java/cn/iocoder/yudao/module/tool/service/codegen/inner/CodegenEngine.java

@@ -229,7 +229,8 @@ public class CodegenEngine {
     }
 
     private static String vueFilePath(String path) {
-        return "vue/" + path;
+        return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录
+                "src/" + path;
     }
 
 }

+ 0 - 187
yudao-module-tool/yudao-module-tool-impl/src/test/java/cn/iocoder/yudao/module/tool/service/test/TestDemoServiceImplTest.java

@@ -1,187 +0,0 @@
-package cn.iocoder.yudao.module.tool.service.test;
-
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.mock.mockito.MockBean;
-
-import javax.annotation.Resource;
-
-import cn.iocoder.yudao.module.tool.test.BaseDbUnitTest;
-import cn.iocoder.yudao.module.tool.controller.app.test.vo.*;
-import cn.iocoder.yudao.module.tool.dal.dataobject.test.TestDemoDO;
-import cn.iocoder.yudao.module.tool.dal.mysql.test.TestDemoMapper;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import javax.annotation.Resource;
-import org.springframework.context.annotation.Import;
-import java.util.*;
-
-import static cn.hutool.core.util.RandomUtil.*;
-import static cn.iocoder.yudao.module.tool.enums.ErrorCodeConstants.*;
-import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.*;
-import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.*;
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.*;
-import static org.junit.jupiter.api.Assertions.*;
-import static org.mockito.Mockito.*;
-
-/**
-* {@link TestDemoServiceImpl} 的单元测试类
-*
-* @author 芋道源码
-*/
-@Import(TestDemoServiceImpl.class)
-public class TestDemoServiceImplTest extends BaseDbUnitTest {
-
-    @Resource
-    private TestDemoServiceImpl testDemoService;
-
-    @Resource
-    private TestDemoMapper testDemoMapper;
-
-    @Test
-    public void testCreateTestDemo_success() {
-        // 准备参数
-        AppTestDemoCreateReqVO reqVO = randomPojo(AppTestDemoCreateReqVO.class);
-
-        // 调用
-        Long testDemoId = testDemoService.createTestDemo(reqVO);
-        // 断言
-        assertNotNull(testDemoId);
-        // 校验记录的属性是否正确
-        TestDemoDO testDemo = testDemoMapper.selectById(testDemoId);
-        assertPojoEquals(reqVO, testDemo);
-    }
-
-    @Test
-    public void testUpdateTestDemo_success() {
-        // mock 数据
-        TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class);
-        testDemoMapper.insert(dbTestDemo);// @Sql: 先插入出一条存在的数据
-        // 准备参数
-        AppTestDemoUpdateReqVO reqVO = randomPojo(AppTestDemoUpdateReqVO.class, o -> {
-            o.setId(dbTestDemo.getId()); // 设置更新的 ID
-        });
-
-        // 调用
-        testDemoService.updateTestDemo(reqVO);
-        // 校验是否更新正确
-        TestDemoDO testDemo = testDemoMapper.selectById(reqVO.getId()); // 获取最新的
-        assertPojoEquals(reqVO, testDemo);
-    }
-
-    @Test
-    public void testUpdateTestDemo_notExists() {
-        // 准备参数
-        AppTestDemoUpdateReqVO reqVO = randomPojo(AppTestDemoUpdateReqVO.class);
-
-        // 调用, 并断言异常
-        assertServiceException(() -> testDemoService.updateTestDemo(reqVO), TEST_DEMO_NOT_EXISTS);
-    }
-
-    @Test
-    public void testDeleteTestDemo_success() {
-        // mock 数据
-        TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class);
-        testDemoMapper.insert(dbTestDemo);// @Sql: 先插入出一条存在的数据
-        // 准备参数
-        Long id = dbTestDemo.getId();
-
-        // 调用
-        testDemoService.deleteTestDemo(id);
-       // 校验数据不存在了
-       assertNull(testDemoMapper.selectById(id));
-    }
-
-    @Test
-    public void testDeleteTestDemo_notExists() {
-        // 准备参数
-        Long id = randomLongId();
-
-        // 调用, 并断言异常
-        assertServiceException(() -> testDemoService.deleteTestDemo(id), TEST_DEMO_NOT_EXISTS);
-    }
-
-    @Test // TODO 请修改 null 为需要的值
-    public void testGetTestDemoPage() {
-       // mock 数据
-       TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class, o -> { // 等会查询到
-           o.setName(null);
-           o.setStatus(null);
-           o.setType(null);
-           o.setCategory(null);
-           o.setRemark(null);
-           o.setCreateTime(null);
-       });
-       testDemoMapper.insert(dbTestDemo);
-       // 测试 name 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setName(null)));
-       // 测试 status 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setStatus(null)));
-       // 测试 type 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setType(null)));
-       // 测试 category 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCategory(null)));
-       // 测试 remark 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setRemark(null)));
-       // 测试 createTime 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCreateTime(null)));
-       // 准备参数
-       AppTestDemoPageReqVO reqVO = new AppTestDemoPageReqVO();
-       reqVO.setName(null);
-       reqVO.setStatus(null);
-       reqVO.setType(null);
-       reqVO.setCategory(null);
-       reqVO.setRemark(null);
-       reqVO.setBeginCreateTime(null);
-       reqVO.setEndCreateTime(null);
-
-       // 调用
-       PageResult<TestDemoDO> pageResult = testDemoService.getTestDemoPage(reqVO);
-       // 断言
-       assertEquals(1, pageResult.getTotal());
-       assertEquals(1, pageResult.getList().size());
-       assertPojoEquals(dbTestDemo, pageResult.getList().get(0));
-    }
-
-    @Test // TODO 请修改 null 为需要的值
-    public void testGetTestDemoList() {
-       // mock 数据
-       TestDemoDO dbTestDemo = randomPojo(TestDemoDO.class, o -> { // 等会查询到
-           o.setName(null);
-           o.setStatus(null);
-           o.setType(null);
-           o.setCategory(null);
-           o.setRemark(null);
-           o.setCreateTime(null);
-       });
-       testDemoMapper.insert(dbTestDemo);
-       // 测试 name 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setName(null)));
-       // 测试 status 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setStatus(null)));
-       // 测试 type 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setType(null)));
-       // 测试 category 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCategory(null)));
-       // 测试 remark 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setRemark(null)));
-       // 测试 createTime 不匹配
-       testDemoMapper.insert(cloneIgnoreId(dbTestDemo, o -> o.setCreateTime(null)));
-       // 准备参数
-       AppTestDemoExportReqVO reqVO = new AppTestDemoExportReqVO();
-       reqVO.setName(null);
-       reqVO.setStatus(null);
-       reqVO.setType(null);
-       reqVO.setCategory(null);
-       reqVO.setRemark(null);
-       reqVO.setBeginCreateTime(null);
-       reqVO.setEndCreateTime(null);
-
-       // 调用
-       List<TestDemoDO> list = testDemoService.getTestDemoList(reqVO);
-       // 断言
-       assertEquals(1, list.size());
-       assertPojoEquals(dbTestDemo, list.get(0));
-    }
-
-}

+ 44 - 5
yudao-ui-admin/src/views/tool/codegen/index.vue

@@ -61,11 +61,11 @@
     <!-- 预览界面 -->
     <el-dialog :title="preview.title" :visible.sync="preview.open" width="90%" top="5vh" append-to-body>
       <el-row>
-        <el-col :span="9">
+        <el-col :span="7">
           <el-tree :data="preview.fileTree" :expand-on-click-node="false" default-expand-all highlight-current
                    @node-click="handleNodeClick"/>
         </el-col>
-        <el-col :span="15">
+        <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">
@@ -257,10 +257,45 @@ export default {
       for (const data of datas) {
         let paths = data.filePath.split('/');
         let fullPath = ''; // 从头开始的路径,用于生成 id
+        // 特殊处理 java 文件
+        if (paths[paths.length - 1].indexOf('.java') >= 0) {
+          let newPaths = [];
+          for (let i = 0; i < paths.length; i++) {
+            let path = paths[i];
+            if (path !== 'java') {
+              newPaths.push(path);
+              continue;
+            }
+            newPaths.push(path);
+            // 特殊处理中间的 package,进行合并
+            let tmp = undefined;
+            while (i < paths.length) {
+              path = paths[i + 1];
+              if (path === 'controller'
+                || path === 'convert'
+                || path === 'dal'
+                || path === 'enums'
+                || path === 'service'
+                || path === 'vo' // 下面三个,主要是兜底。可能考虑到有人改了包结构
+                || path === 'mysql'
+                || path === 'dataobject') {
+                break;
+              }
+              tmp = tmp ? tmp + '.' + path : path;
+              i++;
+            }
+            if (tmp) {
+              newPaths.push(tmp);
+            }
+          }
+          paths = newPaths;
+        }
+        // 遍历每个 path, 拼接成树
         for (let i = 0; i < paths.length; i++) {
-          // 已经添加大奥 files 中,则跳过
+          // 已经添加 files 中,则跳过
           let oldFullPath = fullPath;
-          fullPath = fullPath.length === 0 ? paths[i] : fullPath + '/' + paths[i];
+          // 下面的 replaceAll 的原因,是因为上面包处理了,导致和 tabs 不匹配,所以 replaceAll 下
+          fullPath = fullPath.length === 0 ? paths[i] : fullPath.replaceAll('.', '/') + '/' + paths[i];
           if (exists[fullPath]) {
             continue;
           }
@@ -276,7 +311,11 @@ export default {
       return files;
     },
     /** 节点单击事件 **/
-    handleNodeClick(data) {
+    handleNodeClick(data, node) {
+      if (node && !node.isLeaf) {
+        return false;
+      }
+      // 判断,如果非子节点,不允许选中
       this.preview.activeName = data.id;
     },
     /** 修改按钮操作 */

+ 3 - 0
更新日志.md

@@ -20,12 +20,15 @@
 
 ### 📈 Statistic
 
+TODO 待统计
+
 ### ⭐ New Features
 
 *【重构】大模块按照多 Maven Module 的方式拆分,提升可维护性,为后续重构 onemall 提供基础
 *【新增】Spring Security 支持读取多种用户类型,从不同的数据库表,从而实现单项目提供管理后台、用户 APP 的不同 RESTful API 接口
 *【新增】代码生成器支持多 Maven Module 的方式生成代码,支持管理后台、用户 APP 两种场景的 RESTful API 的生成,支持 H2 SQL 脚本的生成
 *【重构】将数据库文档调整到 tool 模块,更加明确
+*【优化】代码生成器的前端展示效果,例如说 Java 包路径合并
 
 ### 🐞 Bug Fixes