mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 02:08:43 +08:00 
			
		
		
		
	多模块重构 11:代码生成器,优化展示
This commit is contained in:
		| @@ -229,7 +229,8 @@ public class CodegenEngine { | ||||
|     } | ||||
|  | ||||
|     private static String vueFilePath(String path) { | ||||
|         return "vue/" + path; | ||||
|         return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录 | ||||
|                 "src/" + path; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -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)); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -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++) { | ||||
|           // 已经添加大奥 files 中,则跳过 | ||||
|             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 中,则跳过 | ||||
|           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
									
								
								更新日志.md
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								更新日志.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 | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 YunaiV
					YunaiV