浏览代码

!67 优化 Activiti 的事务、依赖、单元测试等
Merge pull request !67 from 芋道源码/feature/activiti

芋道源码 3 年之前
父节点
当前提交
cd8277cf16
共有 16 个文件被更改,包括 173 次插入100 次删除
  1. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/dept/SysDeptMapper.java
  2. 1 1
      yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/permission/SysMenuMapper.java
  3. 5 3
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java
  4. 33 3
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmFormServiceTest.java
  5. 14 11
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmUserGroupServiceTest.java
  6. 0 1
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dept/SysDeptServiceTest.java
  7. 20 20
      yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/permission/SysMenuServiceTest.java
  8. 0 4
      yudao-admin-server/src/test/resources/logback-spring.xml
  9. 23 0
      yudao-admin-server/src/test/resources/logback.xml
  10. 1 0
      yudao-admin-server/src/test/resources/sql/clean.sql
  11. 22 13
      yudao-admin-server/src/test/resources/sql/create_tables.sql
  12. 32 0
      yudao-dependencies/pom.xml
  13. 4 42
      yudao-framework/yudao-spring-boot-starter-activiti/pom.xml
  14. 15 0
      yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java
  15. 1 1
      yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java
  16. 1 0
      更新日志.md

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/dept/SysDeptMapper.java

@@ -23,7 +23,7 @@ public interface SysDeptMapper extends BaseMapperX<SysDeptDO> {
 
     default SysDeptDO selectByParentIdAndName(Long parentId, String name) {
         return selectOne(new LambdaQueryWrapper<SysDeptDO>().eq(SysDeptDO::getParentId, parentId)
-                .eq(SysDeptDO::getParentId, name));
+                .eq(SysDeptDO::getName, name));
     }
 
     default Integer selectCountByParentId(Long parentId) {

+ 1 - 1
yudao-admin-server/src/main/java/cn/iocoder/yudao/adminserver/modules/system/dal/mysql/permission/SysMenuMapper.java

@@ -24,7 +24,7 @@ public interface SysMenuMapper extends BaseMapperX<SysMenuDO> {
     }
 
     default List<SysMenuDO> selectList(SysMenuListReqVO reqVO) {
-        return selectList(new LambdaQueryWrapperX<SysMenuDO>().likeIfPresent(SysMenuDO::getParentId, reqVO.getName())
+        return selectList(new LambdaQueryWrapperX<SysMenuDO>().likeIfPresent(SysMenuDO::getName, reqVO.getName())
                 .eqIfPresent(SysMenuDO::getStatus, reqVO.getStatus()));
     }
 

+ 5 - 3
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/framework/activiti/core/behavior/BpmUserTaskActivitiBehaviorTest.java

@@ -17,6 +17,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
 import org.activiti.engine.impl.persistence.entity.TaskEntity;
+import org.activiti.engine.impl.persistence.entity.TaskEntityImpl;
 import org.junit.jupiter.api.Test;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
@@ -70,7 +71,7 @@ public class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest {
         // mock 方法
         List<SysUserDO> users = CollectionUtils.convertList(asSet(11L, 22L),
                 id -> new SysUserDO().setId(id));
-        when(userService.getUsersByPostIds(eq(rule.getOptions()))).thenReturn(users);
+        when(userService.getUsersByDeptIds(eq(rule.getOptions()))).thenReturn(users);
         mockGetUserMap(asSet(11L, 22L));
 
         // 调用
@@ -185,10 +186,11 @@ public class BpmUserTaskActivitiBehaviorTest extends BaseMockitoUnitTest {
 
     @Test
     public void testRemoveDisableUsers() {
-        // 准备参数
+        // 准备参数. 1L 可以找到;2L 是禁用的;3L 找不到
         Set<Long> assigneeUserIds = asSet(1L, 2L, 3L);
         // mock 方法
-        SysUserDO user1 = randomPojo(SysUserDO.class, o -> o.setId(1L));
+        SysUserDO user1 = randomPojo(SysUserDO.class, o -> o.setId(1L)
+                .setStatus(CommonStatusEnum.ENABLE.getStatus()));
         SysUserDO user2 = randomPojo(SysUserDO.class, o -> o.setId(2L)
                 .setStatus(CommonStatusEnum.DISABLE.getStatus()));
         Map<Long, SysUserDO> userMap = MapUtil.builder(user1.getId(), user1)

+ 33 - 3
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmFormServiceTest.java

@@ -1,18 +1,30 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
 
+import cn.hutool.core.util.RandomUtil;
 import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormCreateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormPageReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.form.BpmFormUpdateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmFormDO;
 import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmFormMapper;
+import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.dto.BpmFormFieldRespDTO;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl.BpmFormServiceImpl;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import org.junit.jupiter.api.Test;
 import org.springframework.context.annotation.Import;
 
 import javax.annotation.Resource;
 
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
 import static cn.iocoder.yudao.adminserver.modules.bpm.enums.BpmErrorCodeConstants.FORM_NOT_EXISTS;
 import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
@@ -38,7 +50,10 @@ public class BpmFormServiceTest extends BaseDbUnitTest {
     @Test
     public void testCreateForm_success() {
         // 准备参数
-        BpmFormCreateReqVO reqVO = randomPojo(BpmFormCreateReqVO.class);
+        BpmFormCreateReqVO reqVO = randomPojo(BpmFormCreateReqVO.class, o -> {
+            o.setConf("{}");
+            o.setFields(randomFields());
+        });
 
         // 调用
         Long formId = formService.createForm(reqVO);
@@ -52,11 +67,16 @@ public class BpmFormServiceTest extends BaseDbUnitTest {
     @Test
     public void testUpdateForm_success() {
         // mock 数据
-        BpmFormDO dbForm = randomPojo(BpmFormDO.class);
+        BpmFormDO dbForm = randomPojo(BpmFormDO.class, o -> {
+            o.setConf("{}");
+            o.setFields(randomFields());
+        });
         formMapper.insert(dbForm);// @Sql: 先插入出一条存在的数据
         // 准备参数
         BpmFormUpdateReqVO reqVO = randomPojo(BpmFormUpdateReqVO.class, o -> {
             o.setId(dbForm.getId()); // 设置更新的 ID
+            o.setConf("{'yudao': 'yuanma'}");
+            o.setFields(randomFields());
         });
 
         // 调用
@@ -69,7 +89,10 @@ public class BpmFormServiceTest extends BaseDbUnitTest {
     @Test
     public void testUpdateForm_notExists() {
         // 准备参数
-        BpmFormUpdateReqVO reqVO = randomPojo(BpmFormUpdateReqVO.class);
+        BpmFormUpdateReqVO reqVO = randomPojo(BpmFormUpdateReqVO.class, o -> {
+            o.setConf("{'yudao': 'yuanma'}");
+            o.setFields(randomFields());
+        });
 
         // 调用, 并断言异常
         assertServiceException(() -> formService.updateForm(reqVO), FORM_NOT_EXISTS);
@@ -119,4 +142,11 @@ public class BpmFormServiceTest extends BaseDbUnitTest {
         assertPojoEquals(dbForm, pageResult.getList().get(0));
     }
 
+    private List<String> randomFields() {
+        int size = RandomUtil.randomInt(1, 3);
+        return Stream.iterate(0, i -> i).limit(size)
+                .map(i -> JsonUtils.toJsonString(randomPojo(BpmFormFieldRespDTO.class)))
+                .collect(Collectors.toList());
+    }
+
 }

+ 14 - 11
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/bpm/service/definition/BpmUserGroupServiceTest.java

@@ -1,5 +1,6 @@
 package cn.iocoder.yudao.adminserver.modules.bpm.service.definition;
 
+import cn.hutool.core.date.DateUtil;
 import cn.iocoder.yudao.adminserver.BaseDbUnitTest;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupCreateReqVO;
 import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.BpmUserGroupPageReqVO;
@@ -7,7 +8,9 @@ import cn.iocoder.yudao.adminserver.modules.bpm.controller.definition.vo.group.B
 import cn.iocoder.yudao.adminserver.modules.bpm.dal.dataobject.definition.BpmUserGroupDO;
 import cn.iocoder.yudao.adminserver.modules.bpm.dal.mysql.definition.BpmUserGroupMapper;
 import cn.iocoder.yudao.adminserver.modules.bpm.service.definition.impl.BpmUserGroupServiceImpl;
+import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.common.util.date.DateUtils;
 import org.junit.jupiter.api.Test;
 import org.springframework.context.annotation.Import;
 
@@ -98,27 +101,27 @@ public class BpmUserGroupServiceTest extends BaseDbUnitTest {
         assertServiceException(() -> userGroupService.deleteUserGroup(id), USER_GROUP_NOT_EXISTS);
     }
 
-    @Test // TODO 请修改 null 为需要的值
+    @Test
     public void testGetUserGroupPage() {
        // mock 数据
        BpmUserGroupDO dbUserGroup = randomPojo(BpmUserGroupDO.class, o -> { // 等会查询到
-           o.setName(null);
-           o.setStatus(null);
-           o.setCreateTime(null);
+           o.setName("芋道源码");
+           o.setStatus(CommonStatusEnum.ENABLE.getStatus());
+           o.setCreateTime(DateUtils.buildTime(2021, 11, 11));
        });
        userGroupMapper.insert(dbUserGroup);
        // 测试 name 不匹配
-       userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setName(null)));
+       userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setName("芋道")));
        // 测试 status 不匹配
-       userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setStatus(null)));
+       userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
        // 测试 createTime 不匹配
-       userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setCreateTime(null)));
+       userGroupMapper.insert(cloneIgnoreId(dbUserGroup, o -> o.setCreateTime(DateUtils.buildTime(2021, 12, 12))));
        // 准备参数
        BpmUserGroupPageReqVO reqVO = new BpmUserGroupPageReqVO();
-       reqVO.setName(null);
-       reqVO.setStatus(null);
-       reqVO.setBeginCreateTime(null);
-       reqVO.setEndCreateTime(null);
+       reqVO.setName("源码");
+       reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
+       reqVO.setBeginCreateTime(DateUtils.buildTime(2021, 11, 10));
+       reqVO.setEndCreateTime(DateUtils.buildTime(2021, 11, 12));
 
        // 调用
        PageResult<BpmUserGroupDO> pageResult = userGroupService.getUserGroupPage(reqVO);

+ 0 - 1
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/dept/SysDeptServiceTest.java

@@ -172,7 +172,6 @@ class SysDeptServiceTest extends BaseDbUnitTest {
             });
         // 调用, 并断言异常
         assertServiceException(() -> deptService.updateDept(reqVO), DEPT_NAME_DUPLICATE);
-
     }
 
     @Test

+ 20 - 20
yudao-admin-server/src/test/java/cn/iocoder/yudao/adminserver/modules/system/service/permission/SysMenuServiceTest.java

@@ -28,7 +28,7 @@ import static cn.iocoder.yudao.adminserver.modules.system.enums.SysErrorCodeCons
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
 import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
 import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
-import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.*;
 import static org.mockito.Mockito.verify;
 
 @Import(SysMenuServiceImpl.class)
@@ -146,12 +146,12 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
         SysMenuDO sonMenuDO = initParentAndSonMenuDO();
         Long sonId = sonMenuDO.getId();
 
-        //调用
+        // 调用
         sysMenuService.deleteMenu(sonId);
 
-        //断言
+        // 断言
         SysMenuDO menuDO = menuMapper.selectById(sonId);
-        Assert.isNull(menuDO);
+        assertNull(menuDO);
         verify(sysPermissionService).processMenuDeleted(sonId);
         verify(sysMenuProducer).sendMenuRefreshMessage();
     }
@@ -182,18 +182,18 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
         menuMapper.insert(sonMenu);
         idMenuMap.put(sonMenu.getId(), sonMenu);
 
-        //调用
+        // 调用
         List<SysMenuDO> menuDOS = sysMenuService.getMenus();
 
-        //断言
-        Assert.isTrue(menuDOS.size() == idMenuMap.size());
+        // 断言
+        assertEquals(menuDOS.size(), idMenuMap.size());
         menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
     }
 
     @Test
     public void testGetMenusReqVo_success() {
         Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
-        //用于验证可以模糊搜索名称包含"name",状态为1的menu
+        // 用于验证可以模糊搜索名称包含"name",状态为1的menu
         SysMenuDO menu = createMenuDO(MenuTypeEnum.MENU, "name2", 0L, 1);
         menuMapper.insert(menu);
         idMenuMap.put(menu.getId(), menu);
@@ -206,32 +206,32 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
         menuMapper.insert(menu);
         idMenuMap.put(menu.getId(), menu);
 
-        //以下是不符合搜索条件的的menu
+        // 以下是不符合搜索条件的的menu
         menu = createMenuDO(MenuTypeEnum.MENU, "xxxxxx", 0L, 1);
         menuMapper.insert(menu);
         menu = createMenuDO(MenuTypeEnum.MENU, "name", 0L, 2);
         menuMapper.insert(menu);
 
-        //调用
+        // 调用
         SysMenuListReqVO reqVO = new SysMenuListReqVO();
         reqVO.setStatus(1);
         reqVO.setName("name");
         List<SysMenuDO> menuDOS = sysMenuService.getMenus(reqVO);
 
-        //断言
-        Assert.isTrue(menuDOS.size() == idMenuMap.size());
+        // 断言
+        assertEquals(menuDOS.size(), idMenuMap.size());
         menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
     }
 
     @Test
     public void testListMenusFromCache_success() throws Exception {
         Map<Long, SysMenuDO> mockCacheMap = new HashMap<>();
-        //获取代理对象
+        // 获取代理对象
         SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
 
         Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
-        //用于验证搜索类型为MENU,状态为1的menu
+        // 用于验证搜索类型为MENU,状态为1的menu
         SysMenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1);
         mockCacheMap.put(menuDO.getId(), menuDO);
         idMenuMap.put(menuDO.getId(), menuDO);
@@ -240,7 +240,7 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
         mockCacheMap.put(menuDO.getId(), menuDO);
         idMenuMap.put(menuDO.getId(), menuDO);
 
-        //以下是不符合搜索条件的menu
+        // 以下是不符合搜索条件的menu
         menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1);
         mockCacheMap.put(menuDO.getId(), menuDO);
         menuDO = createMenuDO(4L, MenuTypeEnum.MENU, "name", 0L, 2);
@@ -248,24 +248,24 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
 
         List<SysMenuDO> menuDOS = sysMenuService.listMenusFromCache(Collections.singletonList(MenuTypeEnum.MENU.getType()),
                 Collections.singletonList(CommonStatusEnum.DISABLE.getStatus()));
-        Assert.isTrue(menuDOS.size() == idMenuMap.size());
+        assertEquals(menuDOS.size(), idMenuMap.size());
         menuDOS.forEach(m -> assertPojoEquals(idMenuMap.get(m.getId()), m));
     }
 
     @Test
     public void testListMenusFromCache2_success() throws Exception {
         Map<Long, SysMenuDO> mockCacheMap = new HashMap<>();
-        //获取代理对象
+        // 获取代理对象
         SysMenuServiceImpl target = (SysMenuServiceImpl) SpringAopUtils.getTarget(sysMenuService);
         BeanUtil.setFieldValue(target, "menuCache", mockCacheMap);
 
         Map<Long, SysMenuDO> idMenuMap = new HashMap<>();
-        //验证搜索id为1, 类型为MENU, 状态为1 的menu
+        // 验证搜索id为1, 类型为MENU, 状态为1 的menu
         SysMenuDO menuDO = createMenuDO(1L, MenuTypeEnum.MENU, "name", 0L, 1);
         mockCacheMap.put(menuDO.getId(), menuDO);
         idMenuMap.put(menuDO.getId(), menuDO);
 
-        //以下是不符合搜索条件的menu
+        // 以下是不符合搜索条件的menu
         menuDO = createMenuDO(2L, MenuTypeEnum.MENU, "name", 0L, 1);
         mockCacheMap.put(menuDO.getId(), menuDO);
         menuDO = createMenuDO(3L, MenuTypeEnum.BUTTON, "name", 0L, 1);
@@ -275,7 +275,7 @@ public class SysMenuServiceTest extends BaseDbUnitTest {
 
         List<SysMenuDO> menuDOS = sysMenuService.listMenusFromCache(Collections.singletonList(1L),
                 Collections.singletonList(MenuTypeEnum.MENU.getType()), Collections.singletonList(1));
-        Assert.isTrue(menuDOS.size() == idMenuMap.size());
+        assertEquals(menuDOS.size(), idMenuMap.size());
         menuDOS.forEach(menu -> assertPojoEquals(idMenuMap.get(menu.getId()), menu));
     }
 

+ 0 - 4
yudao-admin-server/src/test/resources/logback-spring.xml

@@ -1,4 +0,0 @@
-<configuration>
-    <!-- 引用 Spring Boot 的 logback 基础配置 -->
-    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
-</configuration>

+ 23 - 0
yudao-admin-server/src/test/resources/logback.xml

@@ -0,0 +1,23 @@
+<configuration>
+    <!-- 由于单元测试未开启 Spring Boot 的上下文,所以只能使用 logback.xml 文件 -->
+
+    <!-- 引用 Spring Boot 的 logback 基础配置 -->
+    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
+
+    <!-- 格式化输出:%d 表示日期,%X{tid} SkWalking 链路追踪编号,%thread 表示线程名,%-5level:级别从左显示 5 个字符宽度,%msg:日志消息,%n是换行符 -->
+    <property name="PATTERN_DEFAULT" value="%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%thread] [%tid] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
+
+    <!-- 控制台 Appender -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">     
+        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
+            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
+                <pattern>${PATTERN_DEFAULT}</pattern>
+            </layout>
+        </encoder>
+    </appender>
+
+    <root level="INFO">
+        <appender-ref ref="STDOUT"/>
+    </root>
+
+</configuration>

+ 1 - 0
yudao-admin-server/src/test/resources/sql/clean.sql

@@ -35,3 +35,4 @@ DELETE FROM pay_refund;
 
 -- bpm 开头的 DB
 DELETE FROM "bpm_form";
+DELETE FROM "bpm_user_group";

+ 22 - 13
yudao-admin-server/src/test/resources/sql/create_tables.sql

@@ -74,7 +74,7 @@ CREATE TABLE IF NOT EXISTS "sys_dept" (
     "name" varchar(30) NOT NULL DEFAULT '',
     "parent_id" bigint NOT NULL DEFAULT '0',
     "sort" int NOT NULL DEFAULT '0',
-    "leader" varchar(20) DEFAULT NULL,
+    "leader_user_id" bigint DEFAULT NULL,
     "phone" varchar(11) DEFAULT NULL,
     "email" varchar(50) DEFAULT NULL,
     "status" tinyint NOT NULL,
@@ -490,8 +490,9 @@ CREATE TABLE IF NOT EXISTS "pay_merchant"
     PRIMARY KEY ("id")
 ) COMMENT '支付商户信息';
 
-CREATE TABLE IF NOT EXISTS "pay_app"
-(
+-- bpm 开头的 DB
+
+CREATE TABLE IF NOT EXISTS "pay_app" (
     "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     "name"              varchar(64)   NOT NULL,
     "status"            tinyint       NOT NULL,
@@ -507,8 +508,7 @@ CREATE TABLE IF NOT EXISTS "pay_app"
     PRIMARY KEY ("id")
 ) COMMENT = '支付应用信息';
 
-CREATE TABLE IF NOT EXISTS "pay_channel"
-(
+CREATE TABLE IF NOT EXISTS "pay_channel" (
     "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     "code"        varchar(32)    NOT NULL,
     "status"      tinyint(4)     NOT NULL,
@@ -525,8 +525,7 @@ CREATE TABLE IF NOT EXISTS "pay_channel"
     PRIMARY KEY ("id")
 ) COMMENT = '支付渠道';
 
-CREATE TABLE IF NOT EXISTS `pay_order`
-(
+CREATE TABLE IF NOT EXISTS `pay_order` (
     "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
     `merchant_id`          bigint(20)    NOT NULL,
     `app_id`               bigint(20)    NOT NULL,
@@ -559,12 +558,8 @@ CREATE TABLE IF NOT EXISTS `pay_order`
     PRIMARY KEY ("id")
 ) COMMENT = '支付订单';
 
-
-
-CREATE TABLE IF NOT EXISTS `pay_refund`
-(
+CREATE TABLE IF NOT EXISTS `pay_refund` (
     "id" number NOT NULL GENERATED BY DEFAULT AS IDENTITY,
-    `req_no`             varchar(64)   NOT NULL,
     `merchant_id`        bigint(20)    NOT NULL,
     `app_id`             bigint(20)    NOT NULL,
     `channel_id`         bigint(20)    NOT NULL,
@@ -597,7 +592,7 @@ CREATE TABLE IF NOT EXISTS `pay_refund`
     PRIMARY KEY ("id")
 ) COMMENT = '退款订单';
 
-
+-- bpm 开头的 DB
 
 CREATE TABLE IF NOT EXISTS "bpm_form" (
     "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
@@ -613,3 +608,17 @@ CREATE TABLE IF NOT EXISTS "bpm_form" (
     "deleted" bit NOT NULL DEFAULT FALSE,
     PRIMARY KEY ("id")
 ) COMMENT '动态表单';
+
+CREATE TABLE IF NOT EXISTS "bpm_user_group" (
+    "id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
+    "name" varchar(63) NOT NULL,
+    "description" varchar(255) NOT NULL,
+    "status" tinyint NOT NULL,
+    "member_user_ids" varchar(255) NOT NULL,
+    "creator" varchar(64) DEFAULT '',
+    "create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "updater" varchar(64) DEFAULT '',
+    "update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+    "deleted" bit NOT NULL DEFAULT FALSE,
+    PRIMARY KEY ("id")
+    ) COMMENT '用户组';

+ 32 - 0
yudao-dependencies/pom.xml

@@ -41,6 +41,8 @@
         <podam.version>7.2.6.RELEASE</podam.version>
         <jedis-mock.version>0.1.16</jedis-mock.version>
         <mockito-inline.version>3.6.28</mockito-inline.version>
+        <!-- Bpm 工作流相关 -->
+        <activiti.version>7.1.0.M6</activiti.version>
         <!-- 工具类相关 -->
         <lombok.version>1.18.20</lombok.version>
         <mapstruct.version>1.4.1.Final</mapstruct.version>
@@ -365,6 +367,36 @@
                 <version>${podam.version}</version>
             </dependency>
 
+            <!-- 工作流相关 -->
+            <dependency>
+                <groupId>org.activiti</groupId>
+                <artifactId>activiti-spring-boot-starter</artifactId>
+                <version>${activiti.version}</version>
+                <exclusions>
+                    <exclusion>
+                        <groupId>de.odysseus.juel</groupId>
+                        <artifactId>juel-api</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>de.odysseus.juel</groupId>
+                        <artifactId>juel-spi</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <groupId>org.mybatis</groupId>
+                        <artifactId>mybatis</artifactId>
+                    </exclusion>
+                    <exclusion>
+                        <artifactId>el-api</artifactId>
+                        <groupId>javax.el</groupId>
+                    </exclusion>
+                </exclusions>
+            </dependency>
+            <dependency>
+                <groupId>org.activiti</groupId>
+                <artifactId>activiti-image-generator</artifactId>
+                <version>${activiti.version}</version>
+            </dependency>
+
             <!-- 工具类相关 -->
             <dependency>
                 <groupId>cn.iocoder.boot</groupId>

+ 4 - 42
yudao-framework/yudao-spring-boot-starter-activiti/pom.xml

@@ -15,22 +15,6 @@
     <description>Activiti 拓展</description>
     <url>https://github.com/YunaiV/ruoyi-vue-pro</url>
 
-
-    <properties>
-        <activiti.version>7.1.0.M6</activiti.version>
-    </properties>
-    <!-- TODO @jason:后续弄到 yudao-dependencies 里 -->
-    <dependencyManagement>
-        <dependencies>
-            <dependency>
-                <groupId>org.activiti.dependencies</groupId>
-                <artifactId>activiti-dependencies</artifactId>
-                <version>${activiti.version}</version>
-                <scope>import</scope>
-                <type>pom</type>
-            </dependency>
-        </dependencies>
-    </dependencyManagement>
     <dependencies>
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
@@ -43,42 +27,20 @@
             <artifactId>yudao-spring-boot-starter-security</artifactId>
         </dependency>
 
-
-
+        <!-- DB 相关 -->
         <dependency>
-            <groupId>org.mybatis</groupId>
-            <artifactId>mybatis</artifactId>
-            <optional>true</optional>
+            <groupId>cn.iocoder.boot</groupId>
+            <artifactId>yudao-spring-boot-starter-mybatis</artifactId>
         </dependency>
 
-        <!--使用mybatis plus需排除掉mybatis-->
+        <!-- 工作流相关 -->
         <dependency>
             <groupId>org.activiti</groupId>
             <artifactId>activiti-spring-boot-starter</artifactId>
-            <version>${activiti.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>de.odysseus.juel</groupId>
-                    <artifactId>juel-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>de.odysseus.juel</groupId>
-                    <artifactId>juel-spi</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.mybatis</groupId>
-                    <artifactId>mybatis</artifactId>
-                </exclusion>
-                <exclusion>
-                    <artifactId>el-api</artifactId>
-                    <groupId>javax.el</groupId>
-                </exclusion>
-            </exclusions>
         </dependency>
         <dependency>
             <groupId>org.activiti</groupId>
             <artifactId>activiti-image-generator</artifactId>
-            <version>${activiti.version}</version>
         </dependency>
 
     </dependencies>

+ 15 - 0
yudao-framework/yudao-spring-boot-starter-activiti/src/main/java/cn/iocoder/yudao/framework/activiti/config/YudaoActivitiConfiguration.java

@@ -4,9 +4,15 @@ import cn.iocoder.yudao.framework.activiti.core.web.ActivitiWebFilter;
 import cn.iocoder.yudao.framework.common.enums.WebFilterOrderEnum;
 import org.activiti.image.ProcessDiagramGenerator;
 import org.activiti.image.impl.DefaultProcessDiagramGenerator;
+import org.activiti.spring.SpringProcessEngineConfiguration;
+import org.activiti.spring.boot.ProcessEngineConfigurationConfigurer;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.apache.ibatis.transaction.TransactionFactory;
+import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
 import org.springframework.boot.web.servlet.FilterRegistrationBean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.transaction.PlatformTransactionManager;
 
 @Configuration
 public class YudaoActivitiConfiguration {
@@ -27,4 +33,13 @@ public class YudaoActivitiConfiguration {
         return registrationBean;
     }
 
+    /**
+     * ProcessEngineConfigurationConfigurer 实现类,设置事务管理器,保证 ACT_ 表和自己的表的事务一致性
+     */
+    @Bean
+    public ProcessEngineConfigurationConfigurer processEngineConfigurationConfigurer(
+            PlatformTransactionManager platformTransactionManager) {
+        return processEngineConfiguration -> processEngineConfiguration.setTransactionManager(platformTransactionManager);
+    }
+
 }

+ 1 - 1
yudao-framework/yudao-spring-boot-starter-test/src/main/java/cn/iocoder/yudao/framework/test/core/util/RandomUtils.java

@@ -70,7 +70,7 @@ public class RandomUtils {
     }
 
     public static <T> Set<T> randomSet(Class<T> clazz) {
-        return Stream.iterate(0, i -> i).limit(RandomUtil.randomInt(0, RANDOM_DATE_MAX))
+        return Stream.iterate(0, i -> i).limit(RandomUtil.randomInt(1, RANDOM_COLLECTION_LENGTH))
                 .map(i -> randomPojo(clazz)).collect(Collectors.toSet());
     }
 

+ 1 - 0
更新日志.md

@@ -39,6 +39,7 @@
 * 总代码行数:61594
 * 源码代码行数:37931
 * 注释行数:14225
+* 单元测试用例数:278
 
 ### ⭐ New Features