feat(dept): 科室管理——flw_dept/flw_dept_member 组+成员模型取代单用户映射行(议题3,拍板D1选B)
build / build-push (push) Successful in 54s
build / build-push (push) Successful in 54s
- deptKey=本地自增 id;source_group_id 幂等(一键拉取=初始化/刷新语义,不重复建组);不做存量迁移 - 四处读源全部切新表:AssigneeResolver(宽容口径:deptKey 不存在/停用返回空,图示/轨迹不炸)、 enabledDeptKeys 发布校验白名单、DeptLabelSupport 唯一出口(图示科室视图+轨迹富化)、编辑器 deptList 聚合 - /admin/dept/* 全套端点(CRUD/成员/拉取预览导入);旧 /map/* 映射 CRUD 端点删除 (保留 /map/lookupUser 选人检索与 /user/teacherTree);flw_assignee_map 实体/表保留不删 - IT 种子切源(FlowTestSupport tag→deptKey 注册表,用例主体零改动);全量 191 绿;E2E 22/22 (local-debug/four-topics-e-e2e.py,含切源后果验证与生产盘点 SQL)
This commit is contained in:
@@ -228,7 +228,7 @@ class FlowEngineIT extends FlowTestSupport {
|
||||
assertEquals(2, trace.get(3).get("round"));
|
||||
// 科室口径富化(DEPT_KEY 节点):deptName 取映射里的科室名,前端"按科室"据此换掉人名
|
||||
assertEquals("DEPT_KEY", trace.get(3).get("assigneeType"));
|
||||
assertEquals("ybb", trace.get(3).get("deptKey"));
|
||||
assertEquals(dk("ybb"), trace.get(3).get("deptKey"));
|
||||
assertEquals("ybb科", trace.get(3).get("deptName"));
|
||||
|
||||
// ② 已办去重:同一办件一行,结果是最后一次(同意),次数=2
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yunhai.flowcenter.engine.FlowEngine;
|
||||
import com.yunhai.flowcenter.entity.FlwDef;
|
||||
import com.yunhai.flowcenter.enums.FlwEnums;
|
||||
import com.yunhai.flowcenter.repository.FlwAssigneeMapRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDefRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwRouterRepository;
|
||||
import com.yunhai.platform.apistd.BizException;
|
||||
@@ -45,10 +44,10 @@ class FlowDefAdminServiceSaveTest {
|
||||
defRepository = mock(FlwDefRepository.class);
|
||||
appRepository = mock(com.yunhai.flowcenter.repository.FlwAppRepository.class);
|
||||
service = new FlowDefAdminService(defRepository,
|
||||
mock(FlwAssigneeMapRepository.class),
|
||||
mock(FlwRouterRepository.class),
|
||||
mock(com.yunhai.flowcenter.repository.FlwCallbackRegRepository.class),
|
||||
appRepository,
|
||||
mock(com.yunhai.flowcenter.service.FlowDeptAdminService.class),
|
||||
mock(FlowEngine.class),
|
||||
new ObjectMapper());
|
||||
when(defRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yunhai.flowcenter.engine.FlowEngine;
|
||||
import com.yunhai.flowcenter.entity.FlwDef;
|
||||
import com.yunhai.flowcenter.repository.FlwAppRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwAssigneeMapRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDefRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwRouterRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -38,10 +37,10 @@ class FlowDefAdminServiceUpdateMetaTest {
|
||||
defRepository = mock(FlwDefRepository.class);
|
||||
appRepository = mock(FlwAppRepository.class);
|
||||
service = new FlowDefAdminService(defRepository,
|
||||
mock(FlwAssigneeMapRepository.class),
|
||||
mock(FlwRouterRepository.class),
|
||||
mock(com.yunhai.flowcenter.repository.FlwCallbackRegRepository.class),
|
||||
appRepository,
|
||||
mock(com.yunhai.flowcenter.service.FlowDeptAdminService.class),
|
||||
mock(FlowEngine.class),
|
||||
new ObjectMapper());
|
||||
when(defRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
|
||||
@@ -0,0 +1,209 @@
|
||||
package com.yunhai.flowcenter.service;
|
||||
|
||||
import com.yunhai.flowcenter.entity.FlwDept;
|
||||
import com.yunhai.flowcenter.entity.FlwDeptMember;
|
||||
import com.yunhai.flowcenter.repository.FlwDeptMemberRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDeptRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* 科室管理单测(2026-10-10 四议题·议题3,拍板 D1):CRUD 守卫、enabledDeptKeys 白名单口径、
|
||||
* 解析宽容口径(deptKey 不存在/科室停用返回空,示意图/轨迹不炸)、一键拉取幂等
|
||||
* (source_group_id 命中刷新组名+成员集对齐,删不在集内旧成员)。
|
||||
*/
|
||||
class FlowDeptAdminServiceTest {
|
||||
|
||||
private static final Long SCH = 990001L;
|
||||
|
||||
private FlwDeptRepository deptRepository;
|
||||
private FlwDeptMemberRepository memberRepository;
|
||||
private FlowMapAdminService mapAdminService;
|
||||
private FlowDeptAdminService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
deptRepository = mock(FlwDeptRepository.class);
|
||||
memberRepository = mock(FlwDeptMemberRepository.class);
|
||||
mapAdminService = mock(FlowMapAdminService.class);
|
||||
service = new FlowDeptAdminService(deptRepository, memberRepository, mapAdminService);
|
||||
when(deptRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
when(memberRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||
}
|
||||
|
||||
private FlwDept dept(long id, String name, int status, Integer sourceGroupId) {
|
||||
FlwDept d = new FlwDept();
|
||||
d.setId(id);
|
||||
d.setSchId(SCH);
|
||||
d.setDeptName(name);
|
||||
d.setStatus(status);
|
||||
d.setSourceGroupId(sourceGroupId);
|
||||
return d;
|
||||
}
|
||||
|
||||
private FlwDeptMember member(long deptId, int userId, String name) {
|
||||
FlwDeptMember m = new FlwDeptMember();
|
||||
m.setDeptId(deptId);
|
||||
m.setUserId(userId);
|
||||
m.setUserName(name);
|
||||
m.setStatus(0);
|
||||
return m;
|
||||
}
|
||||
|
||||
private FlowMapAdminService.GroupDeptVo groupVo(int groupId, String name, FlowMapAdminService.MemberVo... users) {
|
||||
FlowMapAdminService.GroupDeptVo vo = new FlowMapAdminService.GroupDeptVo();
|
||||
vo.setDeptKey(String.valueOf(groupId));
|
||||
vo.setDeptName(name);
|
||||
vo.setUsers(Arrays.asList(users));
|
||||
return vo;
|
||||
}
|
||||
|
||||
private FlowMapAdminService.MemberVo userVo(int userId, String name) {
|
||||
return new FlowMapAdminService.MemberVo(userId, name);
|
||||
}
|
||||
|
||||
@Test
|
||||
void list_启用户口count_停用科室恒0() {
|
||||
FlwDept on = dept(1L, "人事处", 0, null);
|
||||
FlwDept off = dept(2L, "教务处", 1, null);
|
||||
when(deptRepository.findBySchIdOrderByIdAsc(SCH)).thenReturn(Arrays.asList(on, off));
|
||||
when(memberRepository.countByDeptIdAndStatus(1L, 0)).thenReturn(3L);
|
||||
when(memberRepository.countByDeptIdAndStatus(2L, 0)).thenReturn(5L);
|
||||
|
||||
List<FlowDeptAdminService.DeptVo> rows = service.list(SCH);
|
||||
|
||||
assertEquals(2, rows.size());
|
||||
assertEquals("1", rows.get(0).getDeptKey());
|
||||
assertEquals(3, rows.get(0).getCount());
|
||||
assertEquals(0, rows.get(1).getCount(), "停用科室 count 恒 0(编辑器提示'无启用人员')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void enabledDeptKeys_仅含有启用成员的启用科室() {
|
||||
FlwDept with = dept(1L, "人事处", 0, null);
|
||||
FlwDept empty = dept(2L, "教务处", 0, null);
|
||||
FlwDept off = dept(3L, "保卫处", 1, null);
|
||||
when(deptRepository.findBySchIdAndStatusOrderByIdAsc(SCH, 0)).thenReturn(Arrays.asList(with, empty));
|
||||
when(memberRepository.countByDeptIdAndStatus(1L, 0)).thenReturn(2L);
|
||||
when(memberRepository.countByDeptIdAndStatus(2L, 0)).thenReturn(0L);
|
||||
|
||||
assertEquals(Collections.singleton("1"), service.enabledDeptKeys(SCH));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveEnabled_宽容口径() {
|
||||
// deptKey 不存在(旧映射 deptKey=UserBase 组 id 切源后即此态)→ 空,不抛
|
||||
when(deptRepository.findBySchIdAndId(SCH, 123L)).thenReturn(Optional.empty());
|
||||
assertTrue(service.resolveEnabled(SCH, "123").isEmpty());
|
||||
// 非数字 deptKey → 空,不抛(脏定义防御)
|
||||
assertTrue(service.resolveEnabled(SCH, "abc").isEmpty());
|
||||
// 科室停用 → 空
|
||||
when(deptRepository.findBySchIdAndId(SCH, 2L)).thenReturn(Optional.of(dept(2L, "教务处", 1, null)));
|
||||
assertTrue(service.resolveEnabled(SCH, "2").isEmpty());
|
||||
// 启用科室 → 启用成员
|
||||
FlwDept on = dept(1L, "人事处", 0, null);
|
||||
when(deptRepository.findBySchIdAndId(SCH, 1L)).thenReturn(Optional.of(on));
|
||||
when(memberRepository.findByDeptIdAndStatusOrderByIdAsc(1L, 0))
|
||||
.thenReturn(Arrays.asList(member(1L, 11, "张三"), member(1L, 12, "李四")));
|
||||
assertEquals(2, service.resolveEnabled(SCH, "1").size());
|
||||
}
|
||||
|
||||
@Test
|
||||
void deptName_切源唯一出口() {
|
||||
when(deptRepository.findBySchIdAndId(SCH, 1L)).thenReturn(Optional.of(dept(1L, "人事处", 0, null)));
|
||||
assertEquals("人事处", service.deptName(SCH, "1"));
|
||||
when(deptRepository.findBySchIdAndId(SCH, 9L)).thenReturn(Optional.empty());
|
||||
assertNull(service.deptName(SCH, "9"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void create_name必填() {
|
||||
assertEquals("新科室", service.create(SCH, " 新科室 ").getDeptName());
|
||||
assertThrows(com.yunhai.platform.apistd.BizException.class, () -> service.create(SCH, " "));
|
||||
}
|
||||
|
||||
@Test
|
||||
void delete_级联删成员_跨校拒() {
|
||||
FlwDept d = dept(1L, "人事处", 0, null);
|
||||
when(deptRepository.findById(1L)).thenReturn(Optional.of(d));
|
||||
service.delete(SCH, 1L);
|
||||
verify(memberRepository).deleteByDeptId(1L);
|
||||
verify(deptRepository).delete(d);
|
||||
|
||||
FlwDept other = dept(2L, "x", 0, null);
|
||||
other.setSchId(2L);
|
||||
when(deptRepository.findById(2L)).thenReturn(Optional.of(other));
|
||||
assertThrows(com.yunhai.platform.apistd.BizException.class, () -> service.delete(SCH, 2L));
|
||||
}
|
||||
|
||||
@Test
|
||||
void memberAdd_跳过已存在_失败降级井号() {
|
||||
FlwDept d = dept(1L, "人事处", 0, null);
|
||||
when(deptRepository.findById(1L)).thenReturn(Optional.of(d));
|
||||
when(memberRepository.findByDeptIdAndUserId(1L, 11)).thenReturn(Optional.of(member(1L, 11, "张三")));
|
||||
when(mapAdminService.lookupUser(12)).thenThrow(new RuntimeException("userbase down"));
|
||||
|
||||
int added = service.memberAdd(SCH, 1L, Arrays.asList(11, 12));
|
||||
|
||||
assertEquals(1, added);
|
||||
ArgumentCaptor<FlwDeptMember> cap = ArgumentCaptor.forClass(FlwDeptMember.class);
|
||||
verify(memberRepository, times(1)).save(cap.capture());
|
||||
assertEquals(12, cap.getValue().getUserId());
|
||||
assertEquals("#12", cap.getValue().getUserName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void importGroups_首拉新建_重复拉取刷新并对齐成员集() {
|
||||
when(mapAdminService.previewGroupDepts(SCH)).thenReturn(Arrays.asList(
|
||||
groupVo(7001, "人事处", userVo(11, "张三"), userVo(12, "李四"))));
|
||||
// 首拉:无既有行 → 新建 + 灌成员
|
||||
FlwDept created = dept(101L, "人事处", 0, 7001);
|
||||
when(deptRepository.findBySchIdAndSourceGroupId(SCH, 7001)).thenReturn(Optional.empty());
|
||||
when(deptRepository.save(any())).thenReturn(created);
|
||||
when(memberRepository.findByDeptIdOrderByIdAsc(101L)).thenReturn(Collections.emptyList());
|
||||
|
||||
FlowDeptAdminService.GroupImportResultVo r1 = service.importGroups(SCH);
|
||||
assertEquals(1, r1.getCreated());
|
||||
assertEquals(2, r1.getUsers());
|
||||
verify(memberRepository, times(2)).save(any(FlwDeptMember.class));
|
||||
|
||||
// 重复拉取:命中 source_group_id → 刷新组名;成员集对齐(11 留、12 删、13 增)
|
||||
FlwDept existing = dept(101L, "人事处旧名", 0, 7001);
|
||||
when(deptRepository.findBySchIdAndSourceGroupId(SCH, 7001)).thenReturn(Optional.of(existing));
|
||||
when(mapAdminService.previewGroupDepts(SCH)).thenReturn(Arrays.asList(
|
||||
groupVo(7001, "人事处新名", userVo(11, "张三"), userVo(13, "王五"))));
|
||||
FlwDeptMember old12 = member(101L, 12, "李四");
|
||||
FlwDeptMember old11 = member(101L, 11, "张三");
|
||||
when(memberRepository.findByDeptIdOrderByIdAsc(101L)).thenReturn(Arrays.asList(old11, old12));
|
||||
when(memberRepository.findByDeptIdAndUserId(eq(101L), anyInt())).thenReturn(Optional.empty());
|
||||
when(memberRepository.findByDeptIdAndUserId(101L, 11)).thenReturn(Optional.of(old11));
|
||||
|
||||
FlowDeptAdminService.GroupImportResultVo r2 = service.importGroups(SCH);
|
||||
assertEquals(1, r2.getRefreshed());
|
||||
assertEquals(1, r2.getUsers());
|
||||
assertEquals("人事处新名", existing.getDeptName());
|
||||
verify(memberRepository).delete(old12);
|
||||
verify(memberRepository, never()).delete(old11);
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@ package com.yunhai.flowcenter.service;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.yunhai.flowcenter.controller.api.FlowAdminController;
|
||||
import com.yunhai.flowcenter.controller.api.FlowUserController;
|
||||
import com.yunhai.flowcenter.entity.FlwAssigneeMap;
|
||||
import com.yunhai.flowcenter.entity.FlwDeptMember;
|
||||
import com.yunhai.flowcenter.entity.FlwDef;
|
||||
import com.yunhai.flowcenter.entity.FlwInstance;
|
||||
import com.yunhai.flowcenter.entity.FlwTask;
|
||||
@@ -11,7 +11,6 @@ import com.yunhai.flowcenter.engine.AssigneeResolver;
|
||||
import com.yunhai.flowcenter.engine.FlowEngine;
|
||||
import com.yunhai.flowcenter.enums.FlwEnums;
|
||||
import com.yunhai.flowcenter.model.FlowModels;
|
||||
import com.yunhai.flowcenter.repository.FlwAssigneeMapRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwBranchRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDefRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
|
||||
@@ -85,7 +84,7 @@ class FlowDiagramServiceTest {
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"n2\"},{\"from\":\"n2\",\"to\":\"end\"}]}";
|
||||
|
||||
private FlwDefRepository defRepository;
|
||||
private FlwAssigneeMapRepository mapRepository;
|
||||
private com.yunhai.flowcenter.service.FlowDeptAdminService deptAdminService;
|
||||
private FlwTaskRepository taskRepository;
|
||||
private com.yunhai.flowcenter.repository.FlwCcRepository ccRepository;
|
||||
private OpenApiUserClient userClient;
|
||||
@@ -94,7 +93,7 @@ class FlowDiagramServiceTest {
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
defRepository = mock(FlwDefRepository.class);
|
||||
mapRepository = mock(FlwAssigneeMapRepository.class);
|
||||
deptAdminService = mock(com.yunhai.flowcenter.service.FlowDeptAdminService.class);
|
||||
taskRepository = mock(FlwTaskRepository.class);
|
||||
ccRepository = mock(com.yunhai.flowcenter.repository.FlwCcRepository.class);
|
||||
userClient = mock(OpenApiUserClient.class);
|
||||
@@ -107,7 +106,7 @@ class FlowDiagramServiceTest {
|
||||
taskRepository, mock(FlwBranchRepository.class), ccRepository,
|
||||
mock(AssigneeResolver.class), mock(com.yunhai.flowcenter.engine.ConditionRouteService.class),
|
||||
mock(ApplicationEventPublisher.class));
|
||||
service = new FlowDiagramService(defRepository, mapRepository,
|
||||
service = new FlowDiagramService(defRepository, deptAdminService,
|
||||
mock(com.yunhai.flowcenter.repository.FlwInstanceRepository.class),
|
||||
taskRepository, ccRepository,
|
||||
mock(com.yunhai.flowcenter.repository.FlwRouteLogRepository.class),
|
||||
@@ -127,11 +126,9 @@ class FlowDiagramServiceTest {
|
||||
return def;
|
||||
}
|
||||
|
||||
private FlwAssigneeMap mapRow(String deptName, int userId, String userName) {
|
||||
FlwAssigneeMap m = new FlwAssigneeMap();
|
||||
m.setSchId(SCH);
|
||||
m.setDeptKey("rs");
|
||||
m.setDeptName(deptName);
|
||||
private FlwDeptMember memberRow(int userId, String userName) {
|
||||
FlwDeptMember m = new FlwDeptMember();
|
||||
m.setDeptId(7L);
|
||||
m.setUserId(userId);
|
||||
m.setUserName(userName);
|
||||
m.setStatus(0);
|
||||
@@ -153,8 +150,9 @@ class FlowDiagramServiceTest {
|
||||
|
||||
@Test
|
||||
void c1_deptView_deptKeyNode_labelDeptName_subLabelCountAndDeadline() {
|
||||
when(mapRepository.findEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
mapRow("人事处", 11, "张三"), mapRow("人事处", 12, "李四")));
|
||||
when(deptAdminService.deptName(SCH, "rs")).thenReturn("人事处");
|
||||
when(deptAdminService.resolveEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
memberRow(11, "张三"), memberRow(12, "李四")));
|
||||
FlowModels.DiagramVo vo = service.build(def(DEPT_DEF_JSON), null, "dept");
|
||||
FlowModels.NodeVo n1 = node(vo, "n1");
|
||||
assertEquals("人事处", n1.getLabel());
|
||||
@@ -170,30 +168,32 @@ class FlowDiagramServiceTest {
|
||||
|
||||
@Test
|
||||
void c1_deptView_fallbackChain_deptKeyThenNodeName() {
|
||||
// 映射行全无名 → deptKey 兜底
|
||||
when(mapRepository.findEnabled(SCH, "rs"))
|
||||
.thenReturn(Collections.singletonList(mapRow("", 11, "张三")));
|
||||
// 科室已被删(deptName=null)→ 节点名兜底(成员解析空,人数照实)
|
||||
when(deptAdminService.resolveEnabled(SCH, "rs"))
|
||||
.thenReturn(Collections.singletonList(memberRow(11, "张三")));
|
||||
FlowModels.NodeVo n1 = node(service.build(def(DEPT_DEF_JSON), null, "dept"), "n1");
|
||||
assertEquals("rs", n1.getLabel());
|
||||
assertEquals("科室 · 1人 · 时限48h", n1.getSubLabel());
|
||||
// 无映射行 → 节点名兜底(人数照实为 0)
|
||||
when(mapRepository.findEnabled(SCH, "rs")).thenReturn(Collections.emptyList());
|
||||
n1 = node(service.build(def(DEPT_DEF_JSON), null, "dept"), "n1");
|
||||
assertEquals("人事处审批", n1.getLabel());
|
||||
assertEquals("科室 · 1人 · 时限48h", n1.getSubLabel());
|
||||
// 科室存在但成员为空 → 科室名照常,人数 0
|
||||
when(deptAdminService.deptName(SCH, "rs")).thenReturn("人事处");
|
||||
when(deptAdminService.resolveEnabled(SCH, "rs")).thenReturn(Collections.emptyList());
|
||||
n1 = node(service.build(def(DEPT_DEF_JSON), null, "dept"), "n1");
|
||||
assertEquals("人事处", n1.getLabel());
|
||||
assertEquals("科室 · 0人 · 时限48h", n1.getSubLabel());
|
||||
}
|
||||
|
||||
@Test
|
||||
void c1_anyCountersign_appendsSuffix() {
|
||||
when(mapRepository.findEnabled(SCH, "rs"))
|
||||
.thenReturn(Collections.singletonList(mapRow("人事处", 11, "张三")));
|
||||
when(deptAdminService.resolveEnabled(SCH, "rs"))
|
||||
.thenReturn(Collections.singletonList(memberRow(11, "张三")));
|
||||
FlowModels.NodeVo n1 = node(service.build(def(ANY_DEF_JSON), null, "dept"), "n1");
|
||||
assertEquals("科室 · 1人 · 任一人通过", n1.getSubLabel());
|
||||
}
|
||||
|
||||
@Test
|
||||
void c1_fixedLabels_andEdgesCarried() {
|
||||
when(mapRepository.findEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.resolveEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.deptName(anyLong(), anyString())).thenReturn(null);
|
||||
FlowModels.DiagramVo vo = service.build(def(DEPT_DEF_JSON), null, "dept");
|
||||
assertEquals("开始", node(vo, "start").getLabel());
|
||||
assertEquals("并行分发", node(vo, "sp1").getLabel());
|
||||
@@ -215,8 +215,9 @@ class FlowDiagramServiceTest {
|
||||
|
||||
@Test
|
||||
void c1_autoView_deptKeyNode_rendersDeptStyle() {
|
||||
when(mapRepository.findEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
mapRow("人事处", 11, "张三"), mapRow("人事处", 12, "李四")));
|
||||
when(deptAdminService.deptName(SCH, "rs")).thenReturn("人事处");
|
||||
when(deptAdminService.resolveEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
memberRow(11, "张三"), memberRow(12, "李四")));
|
||||
FlowModels.NodeVo n1 = node(service.build(def(DEPT_DEF_JSON), null, "auto"), "n1");
|
||||
assertEquals("人事处", n1.getLabel());
|
||||
assertEquals("科室 · 2人 · 时限48h", n1.getSubLabel());
|
||||
@@ -226,8 +227,9 @@ class FlowDiagramServiceTest {
|
||||
/** 2026-09-18:mode 缺省改为人员视图(原 auto 自适应)——老深链显式带 auto 仍按自适应出图 */
|
||||
@Test
|
||||
void c1_defaultMode_isUserView() {
|
||||
when(mapRepository.findEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
mapRow("人事处", 11, "张三"), mapRow("人事处", 12, "李四")));
|
||||
when(deptAdminService.deptName(SCH, "rs")).thenReturn("人事处");
|
||||
when(deptAdminService.resolveEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
memberRow(11, "张三"), memberRow(12, "李四")));
|
||||
FlowModels.DiagramVo vo = service.build(def(DEPT_DEF_JSON), null, null);
|
||||
assertEquals("user", vo.getMode());
|
||||
FlowModels.NodeVo n1 = node(vo, "n1");
|
||||
@@ -288,8 +290,9 @@ class FlowDiagramServiceTest {
|
||||
|
||||
@Test
|
||||
void c3_userView_deptKeyNode_listsMemberNames_blankNameDegradesToId() {
|
||||
when(mapRepository.findEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
mapRow("人事处", 11, "张三"), mapRow("人事处", 12, null)));
|
||||
when(deptAdminService.deptName(SCH, "rs")).thenReturn("人事处");
|
||||
when(deptAdminService.resolveEnabled(SCH, "rs")).thenReturn(Arrays.asList(
|
||||
memberRow(11, "张三"), memberRow(12, null)));
|
||||
FlowModels.NodeVo n1 = node(service.build(def(DEPT_DEF_JSON), null, "user"), "n1");
|
||||
// 人员视图:label=节点名,subLabel=映射成员名(空名降级 #id)+ 会签/时限后缀
|
||||
assertEquals("人事处审批", n1.getLabel());
|
||||
@@ -304,7 +307,8 @@ class FlowDiagramServiceTest {
|
||||
when(defRepository.findFirstBySchIdAndFlowGuidAndStatusOrderByVersionDesc(
|
||||
SCH, "g1", FlwEnums.DefStatus.PUBLISHED.getCode()))
|
||||
.thenReturn(Optional.of(def));
|
||||
when(mapRepository.findEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.resolveEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.deptName(anyLong(), anyString())).thenReturn(null);
|
||||
FlowModels.DiagramVo vo = service.byGuid(SCH, "g1", null);
|
||||
assertEquals("教师入职", vo.getName());
|
||||
assertEquals(Integer.valueOf(2), vo.getVersion());
|
||||
@@ -349,7 +353,8 @@ class FlowDiagramServiceTest {
|
||||
instance.setSchId(SCH);
|
||||
instance.setDefId(12L);
|
||||
when(defRepository.findById(12L)).thenReturn(Optional.of(def(DEPT_DEF_JSON)));
|
||||
when(mapRepository.findEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.resolveEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.deptName(anyLong(), anyString())).thenReturn(null);
|
||||
FlowModels.DiagramVo vo = service.byInstance(instance, "dept");
|
||||
assertEquals(Long.valueOf(100L), vo.getInstanceId());
|
||||
assertEquals(Long.valueOf(12L), vo.getDefId());
|
||||
@@ -360,7 +365,8 @@ class FlowDiagramServiceTest {
|
||||
void c6_build_draftDef_ok() {
|
||||
FlwDef draft = def(DEPT_DEF_JSON);
|
||||
draft.setStatus(FlwEnums.DefStatus.DRAFT.getCode());
|
||||
when(mapRepository.findEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.resolveEnabled(anyLong(), anyString())).thenReturn(Collections.emptyList());
|
||||
when(deptAdminService.deptName(anyLong(), anyString())).thenReturn(null);
|
||||
FlowModels.DiagramVo vo = service.build(draft, null, "auto");
|
||||
assertEquals(Integer.valueOf(0), vo.getStatus());
|
||||
assertEquals(5, vo.getNodes().size());
|
||||
@@ -484,7 +490,8 @@ class FlowDiagramServiceTest {
|
||||
mock(FlwInstanceRepository.class), diagramService,
|
||||
mock(com.yunhai.flowcenter.service.DiagramImageService.class),
|
||||
new ObjectMapper(),
|
||||
mock(com.yunhai.flowcenter.service.FlowAppAdminService.class));
|
||||
mock(com.yunhai.flowcenter.service.FlowAppAdminService.class),
|
||||
mock(com.yunhai.flowcenter.service.FlowDeptAdminService.class));
|
||||
}
|
||||
|
||||
private BoaUser user(int id, Integer type, Integer schId, Integer... roleIds) {
|
||||
|
||||
@@ -1,27 +1,34 @@
|
||||
package com.yunhai.flowcenter.support;
|
||||
|
||||
import com.yunhai.flowcenter.entity.FlwAssigneeMap;
|
||||
import com.yunhai.flowcenter.entity.FlwCallbackLog;
|
||||
import com.yunhai.flowcenter.entity.FlwCallbackReg;
|
||||
import com.yunhai.flowcenter.entity.FlwDef;
|
||||
import com.yunhai.flowcenter.entity.FlwDept;
|
||||
import com.yunhai.flowcenter.entity.FlwDeptMember;
|
||||
import com.yunhai.flowcenter.entity.FlwRouteLog;
|
||||
import com.yunhai.flowcenter.entity.FlwRouter;
|
||||
import com.yunhai.flowcenter.repository.FlwAssigneeMapRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwCallbackLogRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwCallbackRegRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwCcRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDefRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDeptMemberRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwDeptRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwInstanceRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwRouteLogRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwRouterRepository;
|
||||
import com.yunhai.flowcenter.repository.FlwTaskRepository;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* IT 公共基类:专用测试库 bsch_flowcenter_test,每例清表(引擎测试不能开测试事务——
|
||||
* AFTER_COMMIT 推进监听器依赖真实提交);提供定义落库/发布、映射注册的快捷方法。
|
||||
* AFTER_COMMIT 推进监听器依赖真实提交);提供定义落库/发布、科室注册的快捷方法。
|
||||
* 2026-10-10 科室切源:DEPT_KEY 解析读 flw_dept/flw_dept_member,deptKey=科室自增 id——
|
||||
* 用例仍以 tag("ybb"/"ka")书写,经 {@link #mapDept} 注册 tag→deptKey,def helper 输出
|
||||
* JSON 时替换(dk()),用例主体零改动。
|
||||
*/
|
||||
public abstract class FlowTestSupport {
|
||||
|
||||
@@ -34,7 +41,9 @@ public abstract class FlowTestSupport {
|
||||
@Autowired
|
||||
protected FlwTaskRepository taskRepository;
|
||||
@Autowired
|
||||
protected FlwAssigneeMapRepository mapRepository;
|
||||
protected FlwDeptRepository deptRepository;
|
||||
@Autowired
|
||||
protected FlwDeptMemberRepository deptMemberRepository;
|
||||
@Autowired
|
||||
protected FlwCallbackRegRepository regRepository;
|
||||
@Autowired
|
||||
@@ -46,6 +55,14 @@ public abstract class FlowTestSupport {
|
||||
@Autowired
|
||||
protected FlwRouteLogRepository routeLogRepository;
|
||||
|
||||
/** tag → 实际 deptKey(flw_dept.id 字符串);mapDept 注册,def helper 消费 */
|
||||
private final Map<String, String> deptKeyByTag = new HashMap<>();
|
||||
|
||||
/** tag 对应的实际 deptKey(未注册的 tag 原样返回——脏定义防御用例依赖此行为) */
|
||||
protected String dk(String tag) {
|
||||
return deptKeyByTag.getOrDefault(tag, tag);
|
||||
}
|
||||
|
||||
protected void cleanDb() {
|
||||
logRepository.deleteAll();
|
||||
regRepository.deleteAll();
|
||||
@@ -55,17 +72,38 @@ public abstract class FlowTestSupport {
|
||||
taskRepository.deleteAll();
|
||||
instanceRepository.deleteAll();
|
||||
defRepository.deleteAll();
|
||||
mapRepository.deleteAll();
|
||||
deptMemberRepository.deleteAll();
|
||||
deptRepository.deleteAll();
|
||||
deptKeyByTag.clear();
|
||||
}
|
||||
|
||||
protected FlwAssigneeMap mapDept(String deptKey, Integer userId, String userName) {
|
||||
FlwAssigneeMap map = new FlwAssigneeMap();
|
||||
map.setSchId(SCH);
|
||||
map.setDeptKey(deptKey);
|
||||
map.setDeptName(deptKey + "科");
|
||||
map.setUserId(userId);
|
||||
map.setUserName(userName);
|
||||
return mapRepository.save(map);
|
||||
/**
|
||||
* 注册科室成员(tag 复用同一科室行;未注册过的 tag 新建科室并登记 deptKey)。
|
||||
* 返回科室名(deptName=tag+"科",轨迹/图示断言用)。
|
||||
*/
|
||||
protected String mapDept(String tag, Integer userId, String userName) {
|
||||
FlwDept dept = deptKeyByTag.containsKey(tag) ? reloadDept(tag) : createDept(tag);
|
||||
deptKeyByTag.put(tag, String.valueOf(dept.getId()));
|
||||
FlwDeptMember member = new FlwDeptMember();
|
||||
member.setDeptId(dept.getId());
|
||||
member.setUserId(userId);
|
||||
member.setUserName(userName);
|
||||
member.setStatus(0);
|
||||
deptMemberRepository.save(member);
|
||||
return dept.getDeptName();
|
||||
}
|
||||
|
||||
private FlwDept reloadDept(String tag) {
|
||||
return deptRepository.findById(Long.valueOf(deptKeyByTag.get(tag)))
|
||||
.orElseThrow(() -> new IllegalStateException("科室行丢失:" + tag));
|
||||
}
|
||||
|
||||
private FlwDept createDept(String tag) {
|
||||
FlwDept dept = new FlwDept();
|
||||
dept.setSchId(SCH);
|
||||
dept.setDeptName(tag + "科");
|
||||
dept.setStatus(0);
|
||||
return deptRepository.save(dept);
|
||||
}
|
||||
|
||||
protected FlwDef saveAndPublishDef(String code, String name, String contentJson) {
|
||||
@@ -88,7 +126,7 @@ public abstract class FlowTestSupport {
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"" + nodeName + "\","
|
||||
+ "\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptKey + "\"},\"countersign\":\"ALL\"},"
|
||||
+ "\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptKey) + "\"},\"countersign\":\"ALL\"},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"n1\"},{\"from\":\"n1\",\"to\":\"end\"}],"
|
||||
@@ -102,8 +140,8 @@ public abstract class FlowTestSupport {
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"split1\",\"type\":\"PARALLEL_SPLIT\"},"
|
||||
+ "{\"id\":\"t_a\",\"type\":\"APPROVAL\",\"name\":\"甲科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"t_b\",\"type\":\"APPROVAL\",\"name\":\"乙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptB + "\"}},"
|
||||
+ "{\"id\":\"t_a\",\"type\":\"APPROVAL\",\"name\":\"甲科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"t_b\",\"type\":\"APPROVAL\",\"name\":\"乙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptB) + "\"}},"
|
||||
+ "{\"id\":\"join1\",\"type\":\"PARALLEL_JOIN\",\"waitFor\":\"ALL\"},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
@@ -121,7 +159,7 @@ public abstract class FlowTestSupport {
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"cc1\",\"type\":\"NOTIFY\",\"name\":\"抄送校领导\",\"receivers\":{\"type\":\"USERS\",\"userIds\":[301,302]}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"cc1\"},{\"from\":\"cc1\",\"to\":\"n1\"},"
|
||||
@@ -136,7 +174,7 @@ public abstract class FlowTestSupport {
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"split1\",\"type\":\"PARALLEL_SPLIT\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"cc1\",\"type\":\"NOTIFY\",\"name\":\"抄送\",\"receivers\":{\"type\":\"USERS\",\"userIds\":[301]}},"
|
||||
+ "{\"id\":\"join1\",\"type\":\"PARALLEL_JOIN\",\"waitFor\":\"ALL\"},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
@@ -158,8 +196,8 @@ public abstract class FlowTestSupport {
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"cond1\",\"type\":\"CONDITION\",\"name\":\"条件判断\",\"routerKey\":\"" + routerKey + "\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"甲线审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"n2\",\"type\":\"APPROVAL\",\"name\":\"乙线审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptB + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"甲线审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"n2\",\"type\":\"APPROVAL\",\"name\":\"乙线审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptB) + "\"}},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"cond1\"},"
|
||||
@@ -178,9 +216,9 @@ public abstract class FlowTestSupport {
|
||||
+ "\"code\":\"" + codeOf() + "\",\"name\":\"主线条件测试流程\",\"start\":\"start\","
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"n0\",\"type\":\"APPROVAL\",\"name\":\"入口\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptMain + "\"}},"
|
||||
+ "{\"id\":\"n0\",\"type\":\"APPROVAL\",\"name\":\"入口\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptMain) + "\"}},"
|
||||
+ "{\"id\":\"cond1\",\"type\":\"CONDITION\",\"name\":\"条件判断\",\"routerKey\":\"" + routerKey + "\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"甲线审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"甲线审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"n0\"},"
|
||||
@@ -213,8 +251,8 @@ public abstract class FlowTestSupport {
|
||||
+ "\"code\":\"" + codeOf() + "\",\"name\":\"多出口测试流程\",\"start\":\"start\","
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"入口审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"n2\",\"type\":\"APPROVAL\",\"name\":\"复核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptB + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"入口审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"n2\",\"type\":\"APPROVAL\",\"name\":\"复核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptB) + "\"}},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"n1\"},"
|
||||
@@ -230,7 +268,7 @@ public abstract class FlowTestSupport {
|
||||
+ "\"code\":\"" + codeOf() + "\",\"name\":\"夡签测试流程\",\"start\":\"start\","
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"任一人审批\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptKey + "\"},\"countersign\":\"ANY\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"任一人审批\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptKey) + "\"},\"countersign\":\"ANY\"},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"n1\"},{\"from\":\"n1\",\"to\":\"end\"}],"
|
||||
@@ -248,13 +286,13 @@ public abstract class FlowTestSupport {
|
||||
+ "\"code\":\"" + codeOf() + "\",\"name\":\"嵌套并行测试流程\",\"start\":\"start\","
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"入口\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptMain + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"入口\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptMain) + "\"}},"
|
||||
+ "{\"id\":\"s1\",\"type\":\"PARALLEL_SPLIT\"},"
|
||||
+ "{\"id\":\"ta\",\"type\":\"APPROVAL\",\"name\":\"甲科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"tb\",\"type\":\"APPROVAL\",\"name\":\"乙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptB + "\"}},"
|
||||
+ "{\"id\":\"ta\",\"type\":\"APPROVAL\",\"name\":\"甲科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"tb\",\"type\":\"APPROVAL\",\"name\":\"乙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptB) + "\"}},"
|
||||
+ "{\"id\":\"s2\",\"type\":\"PARALLEL_SPLIT\"},"
|
||||
+ "{\"id\":\"tc\",\"type\":\"APPROVAL\",\"name\":\"丙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptC + "\"}},"
|
||||
+ "{\"id\":\"td\",\"type\":\"APPROVAL\",\"name\":\"丁科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptD + "\"}},"
|
||||
+ "{\"id\":\"tc\",\"type\":\"APPROVAL\",\"name\":\"丙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptC) + "\"}},"
|
||||
+ "{\"id\":\"td\",\"type\":\"APPROVAL\",\"name\":\"丁科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptD) + "\"}},"
|
||||
+ "{\"id\":\"join2\",\"type\":\"PARALLEL_JOIN\",\"waitFor\":\"ALL\"},"
|
||||
+ "{\"id\":\"join1\",\"type\":\"PARALLEL_JOIN\",\"waitFor\":\"ALL\"},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
@@ -277,10 +315,10 @@ public abstract class FlowTestSupport {
|
||||
+ "\"code\":\"" + codeOf() + "\",\"name\":\"出口并行测试流程\",\"start\":\"start\","
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"分流审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptMain + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"分流审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptMain) + "\"}},"
|
||||
+ "{\"id\":\"s2\",\"type\":\"PARALLEL_SPLIT\"},"
|
||||
+ "{\"id\":\"p1\",\"type\":\"APPROVAL\",\"name\":\"并行甲\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"p2\",\"type\":\"APPROVAL\",\"name\":\"并行乙\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptB + "\"}},"
|
||||
+ "{\"id\":\"p1\",\"type\":\"APPROVAL\",\"name\":\"并行甲\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"p2\",\"type\":\"APPROVAL\",\"name\":\"并行乙\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptB) + "\"}},"
|
||||
+ "{\"id\":\"join2\",\"type\":\"PARALLEL_JOIN\",\"waitFor\":\"ALL\"},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
@@ -299,12 +337,12 @@ public abstract class FlowTestSupport {
|
||||
+ "\"code\":\"" + codeOf() + "\",\"name\":\"主线并行尾验流程\",\"start\":\"start\","
|
||||
+ "\"nodes\":["
|
||||
+ "{\"id\":\"start\",\"type\":\"START\",\"name\":\"开始\"},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"入口\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptMain + "\"}},"
|
||||
+ "{\"id\":\"n1\",\"type\":\"APPROVAL\",\"name\":\"入口\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptMain) + "\"}},"
|
||||
+ "{\"id\":\"split1\",\"type\":\"PARALLEL_SPLIT\"},"
|
||||
+ "{\"id\":\"ta\",\"type\":\"APPROVAL\",\"name\":\"甲科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"ka\"}},"
|
||||
+ "{\"id\":\"tb\",\"type\":\"APPROVAL\",\"name\":\"乙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"kb\"}},"
|
||||
+ "{\"id\":\"ta\",\"type\":\"APPROVAL\",\"name\":\"甲科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk("ka") + "\"}},"
|
||||
+ "{\"id\":\"tb\",\"type\":\"APPROVAL\",\"name\":\"乙科审核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk("kb") + "\"}},"
|
||||
+ "{\"id\":\"join1\",\"type\":\"PARALLEL_JOIN\",\"waitFor\":\"ALL\"},"
|
||||
+ "{\"id\":\"n3\",\"type\":\"APPROVAL\",\"name\":\"出口复核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + deptA + "\"}},"
|
||||
+ "{\"id\":\"n3\",\"type\":\"APPROVAL\",\"name\":\"出口复核\",\"assignee\":{\"type\":\"DEPT_KEY\",\"deptKey\":\"" + dk(deptA) + "\"}},"
|
||||
+ "{\"id\":\"end\",\"type\":\"END\"}"
|
||||
+ "],"
|
||||
+ "\"edges\":[{\"from\":\"start\",\"to\":\"n1\"},{\"from\":\"n1\",\"to\":\"split1\"},"
|
||||
|
||||
Reference in New Issue
Block a user