package com.budwk.app; import cn.afterturn.easypoi.excel.ExcelImportUtil; import cn.afterturn.easypoi.excel.annotation.Excel; import cn.afterturn.easypoi.excel.entity.ImportParams; import cn.hutool.core.date.DateUtil; import cn.hutool.core.lang.Dict; import cn.hutool.core.util.StrUtil; import com.budwk.app.base.constant.RoleConstant; import com.budwk.app.base.sms.SmsService; import com.budwk.app.flow.constant.FlowConst; import com.budwk.app.flow.engine.FlowEngine; import com.budwk.app.flow.engine.model.*; import com.budwk.app.flow.entity.ProcessTask; import com.budwk.app.flow.enums.ProcessSubmitTypeEnum; import com.budwk.app.sys.models.Sys_role; import com.budwk.app.sys.models.Sys_user; import com.budwk.app.sys.models.Sys_user_role; import com.budwk.app.sys.services.SysRoleService; import lombok.Data; import org.junit.Test; import org.junit.runner.RunWith; import org.nutz.aop.interceptor.ioc.TransAop; import org.nutz.boot.test.junit4.NbJUnit4Runner; import org.nutz.dao.Chain; import org.nutz.dao.Cnd; import org.nutz.dao.Dao; import org.nutz.ioc.aop.Aop; import org.nutz.ioc.loader.annotation.Inject; import org.nutz.ioc.loader.annotation.IocBean; import org.nutz.lang.Lang; import java.io.File; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; @IocBean @RunWith(NbJUnit4Runner.class) public class FlowTest { @Inject private FlowEngine flowEngine; @Inject private Dao dao; @Inject private SmsService smsService; @Inject private SysRoleService sysRoleService; @Test @Aop(TransAop.READ_COMMITTED) public void startInstance() { String operator = "17a7f8ad3ee947b4a26175049a9c253d"; //ProcessInstance instance = flowEngine.startProcessInstanceByKey("JDHTA", "1", "17a7f8ad3ee947b4a26175049a9c253d", Dict.create()); //System.out.println(instance); Long instanceId = 108L; // 完成提交任务 //List applyTasks = flowEngine.executeProcessTask(199L, operator, Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.APPLY.getCode())); //System.out.println("发起任务:" + applyTasks.size()); // 完成邀请复疑人任务 同时邀请复疑人 // Dict dict2 = Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.AGREE.getCode()); // dict2.set(FlowConst.NEXT_NODE_OPERATOR, List.of("00198c31ee094466845979ab8dabf83b", "00266dbf9e014376ab76072851b1a8ac")); // List inviteTasks = flowEngine.executeProcessTask(200L, operator, dict2); // System.out.println("邀请任务:" + inviteTasks.size()); // 完成第一个复疑人任务 List inviteTasks = flowEngine.executeProcessTask(215L, "00266dbf9e014376ab76072851b1a8ac", Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.COUNTERSIGN_DISAGREE.getCode())); // 完成第二个复疑人任务 不同意 // List inviteTasks = flowEngine.executeProcessTask(202L, "00266dbf9e014376ab76072851b1a8ac", // Dict.of(FlowConst.SUBMIT_TYPE, ProcessSubmitTypeEnum.COUNTERSIGN_DISAGREE.getCode())); } public static void findForkTaskNames(NodeModel node, StringBuilder buffer, Set visitedNodes) { if (node == null) return; // 防止循环引用 String nodeId = node.getName(); if (visitedNodes.contains(nodeId)) return; visitedNodes.add(nodeId); // 如果遇到fork节点,停止递归 if (node instanceof ForkModel) return; List inputs = node.getInputs(); for (TransitionModel tm : inputs) { NodeModel source = tm.getSource(); if (source instanceof TaskModel) { String taskName = source.getName(); // 避免重复添加 if (!buffer.toString().contains(taskName)) { if (buffer.length() > 0) buffer.append(","); buffer.append(taskName); } } // 递归处理上游节点 findForkTaskNames(source, buffer, visitedNodes); } } @Test public void testForkJoin() { JoinModel joinModel = new JoinModel(); } @Test public void importZJIPCMemberRoster() { File dir = new File("C:\\Users\\mayn\\Desktop\\客户\\浙江工业职业学院\\基础数据\\浙江工业职业技术学院最新会员名册"); File[] files = dir.listFiles((file, name) -> name.endsWith(".xls") || name.endsWith(".xlsx")); if (files == null || files.length == 0) { System.out.println("未找到会员名单 Excel 文件"); return; } Arrays.sort(files, Comparator.comparing(File::getName)); ImportParams importParams = new ImportParams(); importParams.setTitleRows(1); importParams.setHeadRows(1); List importList = new ArrayList<>(); for (File file : files) { List rows = ExcelImportUtil.importExcel(file, MemberRosterImportTemp.class, importParams); importList.addAll(rows.stream() .filter(row -> StrUtil.isNotBlank(row.getLoginName())) .toList()); } List loginNames = importList.stream() .map(MemberRosterImportTemp::getLoginName) .map(String::trim) .distinct() .toList(); if (Lang.isEmpty(loginNames)) { System.out.println("Excel 中未读取到有效教工号"); return; } Sys_role memberRole = sysRoleService.getByCode(RoleConstant.MEMBER); if (memberRole == null) { System.out.println("会员角色不存在"); return; } List users = dao.query(Sys_user.class, Cnd.where(Sys_user::getLoginname, "in", loginNames)); Map userMap = users.stream().collect(Collectors.toMap(Sys_user::getLoginname, Function.identity(), (a, b) -> a)); List missingLoginNames = loginNames.stream() .filter(loginName -> !userMap.containsKey(loginName)) .toList(); if (Lang.isNotEmpty(missingLoginNames)) { System.out.println("系统中未匹配到的教工号:" + missingLoginNames); } List userIds = users.stream().map(Sys_user::getId).distinct().toList(); if (Lang.isEmpty(userIds)) { System.out.println("没有可导入为会员的用户"); return; } // 模仿 /platform/member/info/batchMake/batchMake:设置会员状态和入会时间。 dao.update(Sys_user.class, Chain.make("member", true) .add("memberTime", DateUtil.now()), Cnd.where(Sys_user::getId, "in", userIds)); List existingRoles = dao.query(Sys_user_role.class, Cnd.where(Sys_user_role::getUserId, "in", userIds) .and(Sys_user_role::getRoleId, "=", memberRole.getId())); Set hasRoleUserIds = existingRoles.stream().map(Sys_user_role::getUserId).collect(Collectors.toSet()); List roleList = userIds.stream() .filter(userId -> !hasRoleUserIds.contains(userId)) .map(userId -> { Sys_user_role userRole = new Sys_user_role(); userRole.setUserId(userId); userRole.setRoleId(memberRole.getId()); return userRole; }) .toList(); if (Lang.isNotEmpty(roleList)) { dao.insert(roleList); } System.out.println("Excel 读取人数:" + importList.size()); System.out.println("有效教工号数:" + loginNames.size()); System.out.println("匹配并设置会员人数:" + userIds.size()); System.out.println("新增会员角色人数:" + roleList.size()); } @Data public static class MemberRosterImportTemp { @Excel(name = "姓名") private String userName; @Excel(name = "部门") private String unitName; @Excel(name = "教工号") private String loginName; @Excel(name = "联系电话") private String mobile; } }