mirror of
https://gitee.com/zhijiantianya/yudao-cloud.git
synced 2026-10-06 07:22:58 +08:00
【同步】BOOT 和 CLOUD 的功能
This commit is contained in:
+1
-1
@@ -173,7 +173,7 @@ public class LambdaQueryWrapperX<T> extends LambdaQueryWrapper<T> {
|
||||
|
||||
@Override
|
||||
public LambdaQueryWrapperX<T> and(boolean condition, Consumer<LambdaQueryWrapper<T>> consumer) {
|
||||
super.and(condition,consumer);
|
||||
super.and(condition, consumer);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+3
-2
@@ -17,17 +17,19 @@ import jakarta.validation.constraints.NotNull;
|
||||
public class WebProperties {
|
||||
|
||||
@NotNull(message = "APP API 不能为空")
|
||||
@Valid
|
||||
private Api appApi = new Api("/app-api", "**.controller.app.**");
|
||||
@NotNull(message = "Admin API 不能为空")
|
||||
@Valid
|
||||
private Api adminApi = new Api("/admin-api", "**.controller.admin.**");
|
||||
|
||||
@NotNull(message = "Admin UI 不能为空")
|
||||
@Valid
|
||||
private Ui adminUi;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Valid
|
||||
public static class Api {
|
||||
|
||||
/**
|
||||
@@ -53,7 +55,6 @@ public class WebProperties {
|
||||
}
|
||||
|
||||
@Data
|
||||
@Valid
|
||||
public static class Ui {
|
||||
|
||||
/**
|
||||
|
||||
+17
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.d
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.BpmTaskCandidateStrategy;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
@@ -12,6 +13,7 @@ import jakarta.annotation.Resource;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
@@ -91,4 +93,19 @@ public abstract class AbstractBpmTaskCandidateDeptLeaderStrategy implements BpmT
|
||||
return deptApi.getDept(startUser.getDeptId()).getCheckedData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取发起人的部门(优先使用流程变量中的发起人编号)
|
||||
*
|
||||
* @param startUserId 发起人 Id(流程变量不存在时使用)
|
||||
* @param processVariables 流程变量
|
||||
* @return 发起人的部门
|
||||
*/
|
||||
protected DeptRespDTO getStartUserDept(Long startUserId, Map<String, Object> processVariables) {
|
||||
Long processStartUserId = FlowableUtils.getProcessInstanceStartUserId(processVariables);
|
||||
if (processStartUserId != null && processStartUserId > 0) {
|
||||
startUserId = processStartUserId;
|
||||
}
|
||||
return getStartUserDept(startUserId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -49,7 +49,7 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends AbstractBp
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
|
||||
// 获取发起人的 multi 部门负责人
|
||||
DeptRespDTO dept = super.getStartUserDept(startUserId);
|
||||
DeptRespDTO dept = super.getStartUserDept(startUserId, processInstance.getProcessVariables());
|
||||
if (dept == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
@@ -60,7 +60,7 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategy extends AbstractBp
|
||||
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||
int level = Integer.parseInt(param); // 参数是部门的层级
|
||||
DeptRespDTO dept = super.getStartUserDept(startUserId);
|
||||
DeptRespDTO dept = super.getStartUserDept(startUserId, processVariables);
|
||||
if (dept == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
+5
-4
@@ -48,19 +48,20 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategy extends AbstractBpmTask
|
||||
ProcessInstance processInstance = processInstanceService.getProcessInstance(execution.getProcessInstanceId());
|
||||
Long startUserId = NumberUtils.parseLong(processInstance.getStartUserId());
|
||||
// 获取发起人的部门负责人
|
||||
return getStartUserDeptLeader(startUserId, param);
|
||||
return getStartUserDeptLeader(startUserId, param, processInstance.getProcessVariables());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<Long> calculateUsersByActivity(BpmnModel bpmnModel, String activityId, String param,
|
||||
Long startUserId, String processDefinitionId, Map<String, Object> processVariables) {
|
||||
// 获取发起人的部门负责人
|
||||
return getStartUserDeptLeader(startUserId, param);
|
||||
return getStartUserDeptLeader(startUserId, param, processVariables);
|
||||
}
|
||||
|
||||
private Set<Long> getStartUserDeptLeader(Long startUserId, String param) {
|
||||
private Set<Long> getStartUserDeptLeader(Long startUserId, String param,
|
||||
Map<String, Object> processVariables) {
|
||||
int level = Integer.parseInt(param); // 参数是部门的层级
|
||||
DeptRespDTO dept = super.getStartUserDept(startUserId);
|
||||
DeptRespDTO dept = super.getStartUserDept(startUserId, processVariables);
|
||||
if (dept == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
|
||||
+12
@@ -1,5 +1,6 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.util;
|
||||
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
@@ -133,6 +134,17 @@ public class FlowableUtils {
|
||||
return (Integer) processVariables.get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_STATUS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程实例的发起用户 ID
|
||||
*
|
||||
* @param processVariables 流程实例的 variables
|
||||
* @return 发起用户 ID
|
||||
*/
|
||||
public static Long getProcessInstanceStartUserId(Map<String, Object> processVariables) {
|
||||
return processVariables == null ? null : Convert.toLong(
|
||||
processVariables.get(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得流程实例的审批原因
|
||||
*
|
||||
|
||||
+14
-5
@@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
@@ -13,6 +14,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
@@ -42,12 +45,16 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest extends BaseMo
|
||||
String param = "2";
|
||||
// mock 方法(获得流程发起人)
|
||||
Long startUserId = 1L;
|
||||
Long processVariableStartUserId = 2L;
|
||||
ProcessInstance processInstance = mock(ProcessInstance.class);
|
||||
DelegateExecution execution = mock(DelegateExecution.class);
|
||||
when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
|
||||
when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
|
||||
Map<String, Object> processVariables = new HashMap<>();
|
||||
processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId);
|
||||
when(processInstance.getProcessVariables()).thenReturn(processVariables);
|
||||
// mock 方法(获取发起人的 multi 部门负责人)
|
||||
mockGetStartUserDept(startUserId);
|
||||
mockGetStartUserDept(processVariableStartUserId);
|
||||
|
||||
// 调用
|
||||
Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
|
||||
@@ -61,12 +68,14 @@ public class BpmTaskCandidateStartUserDeptLeaderMultiStrategyTest extends BaseMo
|
||||
String param = "2";
|
||||
// mock 方法
|
||||
Long startUserId = 1L;
|
||||
mockGetStartUserDept(startUserId);
|
||||
Long processVariableStartUserId = 2L;
|
||||
Map<String, Object> processVariables = new HashMap<>();
|
||||
processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId);
|
||||
mockGetStartUserDept(processVariableStartUserId);
|
||||
|
||||
// 调用
|
||||
Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,
|
||||
startUserId, null, null);
|
||||
// 断言
|
||||
startUserId, null, processVariables);
|
||||
|
||||
assertEquals(Sets.newLinkedHashSet(11L, 1001L), userIds);
|
||||
}
|
||||
|
||||
|
||||
+14
-5
@@ -1,6 +1,7 @@
|
||||
package cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.dept;
|
||||
|
||||
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
@@ -13,6 +14,8 @@ import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
@@ -42,12 +45,16 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategyTest extends BaseMockito
|
||||
String param = "2";
|
||||
// mock 方法(获得流程发起人)
|
||||
Long startUserId = 1L;
|
||||
Long processVariableStartUserId = 2L;
|
||||
ProcessInstance processInstance = mock(ProcessInstance.class);
|
||||
DelegateExecution execution = mock(DelegateExecution.class);
|
||||
when(processInstanceService.getProcessInstance(eq(execution.getProcessInstanceId()))).thenReturn(processInstance);
|
||||
when(processInstance.getStartUserId()).thenReturn(startUserId.toString());
|
||||
Map<String, Object> processVariables = new HashMap<>();
|
||||
processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId);
|
||||
when(processInstance.getProcessVariables()).thenReturn(processVariables);
|
||||
// mock 方法(获取发起人的部门负责人)
|
||||
mockGetStartUserDeptLeader(startUserId);
|
||||
mockGetStartUserDeptLeader(processVariableStartUserId);
|
||||
|
||||
// 调用
|
||||
Set<Long> userIds = strategy.calculateUsersByTask(execution, param);
|
||||
@@ -61,12 +68,14 @@ public class BpmTaskCandidateStartUserDeptLeaderStrategyTest extends BaseMockito
|
||||
String param = "2";
|
||||
// mock 方法
|
||||
Long startUserId = 1L;
|
||||
mockGetStartUserDeptLeader(startUserId);
|
||||
Long processVariableStartUserId = 2L;
|
||||
Map<String, Object> processVariables = new HashMap<>();
|
||||
processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, processVariableStartUserId);
|
||||
mockGetStartUserDeptLeader(processVariableStartUserId);
|
||||
|
||||
// 调用
|
||||
Set<Long> userIds = strategy.calculateUsersByActivity(null, null, param,
|
||||
startUserId, null, null);
|
||||
// 断言
|
||||
startUserId, null, processVariables);
|
||||
|
||||
assertEquals(Sets.newLinkedHashSet(1001L), userIds);
|
||||
}
|
||||
|
||||
|
||||
+24
@@ -4,6 +4,7 @@ import cn.iocoder.yudao.framework.common.core.KeyValue;
|
||||
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO;
|
||||
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
|
||||
import cn.iocoder.yudao.module.bpm.enums.definition.BpmModelFormTypeEnum;
|
||||
import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
@@ -22,6 +23,29 @@ import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
*/
|
||||
class FlowableUtilsTest {
|
||||
|
||||
@Test
|
||||
public void testGetProcessInstanceStartUserId() {
|
||||
// 准备参数
|
||||
Map<String, Object> processVariables = new HashMap<>();
|
||||
processVariables.put(BpmnVariableConstants.PROCESS_INSTANCE_VARIABLE_START_USER_ID, "1");
|
||||
|
||||
// 调用
|
||||
Long startUserId = FlowableUtils.getProcessInstanceStartUserId(processVariables);
|
||||
|
||||
// 断言
|
||||
assertEquals(1L, startUserId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProcessInstanceStartUserId_empty() {
|
||||
// 准备参数
|
||||
Map<String, Object> processVariables = new HashMap<>();
|
||||
|
||||
// 调用 & 断言
|
||||
assertNull(FlowableUtils.getProcessInstanceStartUserId(processVariables));
|
||||
assertNull(FlowableUtils.getProcessInstanceStartUserId(null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetSummary_customSummary_parseDbFormFields() {
|
||||
// 准备参数:模拟 DB 中 form_fields 字段,列表里每个元素都是一个 form-create 字段 JSON。
|
||||
|
||||
+1
-1
@@ -102,7 +102,7 @@ public class FmsAccountUserServiceImpl implements FmsAccountUserService {
|
||||
FmsAccountUserUpdateReqVO.Member::getUserId, FmsAccountUserUpdateReqVO.Member::getLevel);
|
||||
Set<Long> memberUserIds = new HashSet<>(memberLevelMap.keySet());
|
||||
memberUserIds.removeAll(founderUserIds);
|
||||
adminUserApi.validateUserList(memberUserIds);
|
||||
adminUserApi.validateUserList(memberUserIds).checkError();
|
||||
|
||||
// 2.1 移出取消授权的成员
|
||||
Set<Long> currentMemberUserIds = convertSet(accountUsers, FmsAccountUserDO::getUserId,
|
||||
|
||||
+8
@@ -8,6 +8,7 @@ import cn.iocoder.yudao.module.fms.dal.mysql.config.FmsAccountUserMapper;
|
||||
import cn.iocoder.yudao.module.fms.enums.config.FmsAccountUserLevelEnum;
|
||||
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
@@ -22,6 +23,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -38,6 +41,11 @@ public class FmsAccountUserServiceImplTest extends BaseDbUnitTest {
|
||||
@MockitoBean
|
||||
private AdminUserApi adminUserApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(adminUserApi.validateUserList(anyCollection())).thenReturn(success(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateAccountOwner_firstAccountSet() {
|
||||
// 准备参数
|
||||
|
||||
+1
-1
@@ -312,7 +312,7 @@ public class HrmAttendanceGroupServiceImpl implements HrmAttendanceGroupService
|
||||
|
||||
private void validateAttendanceGroup(HrmAttendanceGroupSaveReqVO reqVO) {
|
||||
// 1. 校验适用部门存在
|
||||
deptApi.validateDeptList(reqVO.getDeptIds());
|
||||
deptApi.validateDeptList(reqVO.getDeptIds()).checkError();
|
||||
// 2. 校验适用员工存在
|
||||
employeeService.validateEmployeeListExists(reqVO.getEmployeeIds());
|
||||
}
|
||||
|
||||
+3
-3
@@ -628,7 +628,7 @@ public class HrmEmployeeServiceImpl implements HrmEmployeeService {
|
||||
throw exception(EMPLOYEE_CREATE_USER_LIST_DUPLICATE);
|
||||
}
|
||||
}
|
||||
adminUserApi.validateUserList(userIds);
|
||||
adminUserApi.validateUserList(userIds).checkError();
|
||||
Map<Long, AdminUserRespDTO> userMap = convertMap(
|
||||
adminUserApi.getUserList(userIds).getCheckedData(), AdminUserRespDTO::getId);
|
||||
// 1.2 构建并校验全部员工档案,避免部分数据校验失败时已经执行写库
|
||||
@@ -1179,7 +1179,7 @@ public class HrmEmployeeServiceImpl implements HrmEmployeeService {
|
||||
private void validateDeptAndLeader(Long employeeId, Long deptId, Long leaderEmployeeId) {
|
||||
// 1. 校验部门是否存在
|
||||
if (deptId != null) {
|
||||
deptApi.validateDeptList(Collections.singleton(deptId));
|
||||
deptApi.validateDeptList(Collections.singleton(deptId)).checkError();
|
||||
}
|
||||
// 2. 校验直属上级链路不存在自引用或环路
|
||||
if (leaderEmployeeId == null) {
|
||||
@@ -1417,7 +1417,7 @@ public class HrmEmployeeServiceImpl implements HrmEmployeeService {
|
||||
try {
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
|
||||
.setUserId(employee.getUserId()).setTemplateCode(templateCode)
|
||||
.setTemplateParams(Collections.singletonMap("employeeName", employee.getName())));
|
||||
.setTemplateParams(Collections.singletonMap("employeeName", employee.getName()))).checkError();
|
||||
return true;
|
||||
} catch (RuntimeException ex) {
|
||||
log.warn("[sendEmployeeMessage][employeeId({}) userId({}) templateCode({}) 发送失败]",
|
||||
|
||||
+1
-1
@@ -536,7 +536,7 @@ public class HrmInsuranceMonthEmployeeRecordServiceImpl implements HrmInsuranceM
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
|
||||
.setUserId(employee.getUserId())
|
||||
.setTemplateCode(MessageTemplateConstants.INSURANCE_MONTH_RECORD_CREATED)
|
||||
.setTemplateParams(templateParams));
|
||||
.setTemplateParams(templateParams)).checkError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+2
-2
@@ -350,7 +350,7 @@ public class HrmPerformanceAssessmentProcessServiceImpl
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
|
||||
.setUserId(handler.getUserId())
|
||||
.setTemplateCode(MessageTemplateConstants.PERFORMANCE_TASK_PENDING)
|
||||
.setTemplateParams(templateParams));
|
||||
.setTemplateParams(templateParams)).checkError();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -386,7 +386,7 @@ public class HrmPerformanceAssessmentProcessServiceImpl
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
|
||||
.setUserId(employee.getUserId())
|
||||
.setTemplateCode(MessageTemplateConstants.PERFORMANCE_PROCESS_RESULT)
|
||||
.setTemplateParams(templateParams));
|
||||
.setTemplateParams(templateParams)).checkError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -555,7 +555,7 @@ public class HrmPerformancePlanServiceImpl implements HrmPerformancePlanService
|
||||
employeeService.validateEmployeeListExists(employeeIds);
|
||||
}
|
||||
if (CollUtil.isNotEmpty(deptIds)) {
|
||||
deptApi.validateDeptList(deptIds);
|
||||
deptApi.validateDeptList(deptIds).checkError();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -351,7 +351,7 @@ public class HrmRecruitInterviewServiceImpl implements HrmRecruitInterviewServic
|
||||
templateParams.put("interviewTime", INTERVIEW_TIME_FORMATTER.format(recruitInterview.getInterviewTime()));
|
||||
userIds.forEach(userId -> notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
|
||||
.setUserId(userId).setTemplateCode(MessageTemplateConstants.RECRUIT_INTERVIEW_ARRANGED)
|
||||
.setTemplateParams(templateParams)));
|
||||
.setTemplateParams(templateParams)).checkError());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -146,7 +146,7 @@ public class HrmRecruitPostServiceImpl implements HrmRecruitPostService {
|
||||
// 1. 校验职位类型和用人部门存在
|
||||
recruitPostTypeService.validateRecruitPostTypeExists(reqVO.getPostTypeId());
|
||||
if (reqVO.getDeptId() != null) {
|
||||
deptApi.validateDeptList(Collections.singleton(reqVO.getDeptId()));
|
||||
deptApi.validateDeptList(Collections.singleton(reqVO.getDeptId())).checkError();
|
||||
}
|
||||
|
||||
// 2. 校验招聘负责人和面试官存在
|
||||
|
||||
+1
-1
@@ -221,7 +221,7 @@ public class HrmSalaryGroupServiceImpl implements HrmSalaryGroupService {
|
||||
// 1. 校验适用部门及其上下级部门未归属其他薪资组
|
||||
Set<Long> selectedDeptIds = CollUtil.isEmpty(deptIds)
|
||||
? Collections.emptySet() : new HashSet<>(deptIds);
|
||||
deptApi.validateDeptList(selectedDeptIds);
|
||||
deptApi.validateDeptList(selectedDeptIds).checkError();
|
||||
List<HrmSalaryGroupDO> otherSalaryGroups = convertList(salaryGroupMapper.selectListByIdDesc(),
|
||||
salaryGroup -> salaryGroup, salaryGroup -> ObjUtil.notEqual(salaryGroup.getId(), id));
|
||||
if (CollUtil.isNotEmpty(selectedDeptIds)) {
|
||||
|
||||
+1
-1
@@ -256,7 +256,7 @@ public class HrmSalarySlipServiceImpl implements HrmSalarySlipService {
|
||||
templateParams.put("realSalary", employeeRecord.getRealPaySalary().toPlainString());
|
||||
notifyMessageSendApi.sendSingleMessageToAdmin(new NotifySendSingleToUserReqDTO()
|
||||
.setUserId(employee.getUserId()).setTemplateCode(MessageTemplateConstants.SALARY_SLIP_SENT)
|
||||
.setTemplateParams(templateParams));
|
||||
.setTemplateParams(templateParams)).checkError();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-3
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.hrm.enums.attendance.config.HrmAttendanceMisscard
|
||||
import cn.iocoder.yudao.module.hrm.service.employee.info.HrmEmployeeService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -22,13 +23,23 @@ import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.*;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
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.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link HrmAttendanceGroupServiceImpl} 的单元测试类
|
||||
@@ -49,6 +60,11 @@ public class HrmAttendanceGroupServiceImplTest extends BaseMockitoUnitTest {
|
||||
@Mock
|
||||
private DeptApi deptApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
lenient().when(deptApi.validateDeptList(anyCollection())).thenReturn(success(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetAttendanceGroupMap_employeeAndDeptAndDefaultGroup() {
|
||||
// mock 数据
|
||||
|
||||
+4
@@ -68,6 +68,7 @@ import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.*;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@@ -128,6 +129,9 @@ public class HrmEmployeeServiceImplTest extends BaseDbUnitTest {
|
||||
HrmEmployeeChangeRecordCreateReqVO reqVO = invocation.getArgument(0);
|
||||
return BeanUtils.toBean(reqVO, HrmEmployeeChangeRecordDO.class).setId(randomLongId());
|
||||
});
|
||||
lenient().when(deptApi.validateDeptList(anyCollection())).thenReturn(success(true));
|
||||
lenient().when(adminUserApi.validateUserList(anyCollection())).thenReturn(success(true));
|
||||
lenient().when(notifyMessageSendApi.sendSingleMessageToAdmin(any())).thenReturn(success(randomLongId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+8
@@ -25,6 +25,7 @@ import cn.iocoder.yudao.module.hrm.service.insurance.config.HrmInsuranceSchemeSe
|
||||
import cn.iocoder.yudao.module.hrm.service.insurance.employee.HrmInsuranceEmployeeInfoService;
|
||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
@@ -37,6 +38,8 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.INSURANCE_EMPLOYEE_SCHEME_NOT_CONFIGURED;
|
||||
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.INSURANCE_MONTH_EMPLOYEE_NOT_ELIGIBLE;
|
||||
@@ -73,6 +76,11 @@ public class HrmInsuranceMonthEmployeeRecordServiceImplTest extends BaseDbUnitTe
|
||||
@MockitoBean
|
||||
private NotifyMessageSendApi notifyMessageSendApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(notifyMessageSendApi.sendSingleMessageToAdmin(any())).thenReturn(success(randomLongId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateMonthEmployeeRecordList_success() {
|
||||
// mock 数据
|
||||
|
||||
+8
@@ -43,6 +43,7 @@ import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -57,6 +58,7 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomPojo;
|
||||
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.PERFORMANCE_STAGE_NO_PERMISSION;
|
||||
@@ -70,6 +72,7 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -111,6 +114,11 @@ public class HrmPerformanceAssessmentProcessServiceImplTest extends BaseDbUnitTe
|
||||
@MockitoBean
|
||||
private HrmPerformanceAssessmentActionRecordService assessmentActionRecordService;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
lenient().when(notifyMessageSendApi.sendSingleMessageToAdmin(any())).thenReturn(success(randomLongId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInitializeAssessmentStages_unboundEmployee_fail() {
|
||||
// mock 数据
|
||||
|
||||
+7
@@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.hrm.service.employee.info.HrmEmployeeService;
|
||||
import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import cn.iocoder.yudao.module.system.api.notify.dto.NotifySendSingleToUserReqDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.springframework.context.annotation.Import;
|
||||
@@ -27,6 +28,7 @@ import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
@@ -68,6 +70,11 @@ public class HrmRecruitInterviewServiceImplTest extends BaseDbUnitTest {
|
||||
@MockitoBean
|
||||
private NotifyMessageSendApi notifyMessageSendApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(notifyMessageSendApi.sendSingleMessageToAdmin(any())).thenReturn(success(randomLongId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRecruitInterview_success() {
|
||||
// mock 数据
|
||||
|
||||
+8
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.hrm.enums.recruit.post.HrmRecruitPostStatusEnum;
|
||||
import cn.iocoder.yudao.module.hrm.service.employee.info.HrmEmployeeService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
@@ -25,6 +26,7 @@ import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.getDateTimeRange;
|
||||
@@ -44,6 +46,7 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoInteractions;
|
||||
|
||||
@@ -68,6 +71,11 @@ public class HrmRecruitPostServiceImplTest extends BaseDbUnitTest {
|
||||
@MockitoBean
|
||||
private DeptApi deptApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(deptApi.validateDeptList(anyCollection())).thenReturn(success(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateRecruitPost_success() {
|
||||
// 准备参数
|
||||
|
||||
+8
-2
@@ -13,6 +13,7 @@ import cn.iocoder.yudao.module.hrm.service.employee.info.HrmEmployeeService;
|
||||
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
|
||||
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
@@ -32,10 +33,10 @@ import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.ArgumentMatchers.anyCollection;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link HrmSalaryGroupServiceImpl} 的单元测试类
|
||||
@@ -58,6 +59,11 @@ public class HrmSalaryGroupServiceImplTest extends BaseDbUnitTest {
|
||||
@MockitoBean
|
||||
private DeptApi deptApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(deptApi.validateDeptList(anyCollection())).thenReturn(success(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSalaryGroup_success() {
|
||||
// 准备参数
|
||||
|
||||
+9
@@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.system.api.notify.NotifyMessageSendApi;
|
||||
import cn.iocoder.yudao.module.hrm.enums.salary.slip.HrmSalarySlipReadStatusEnum;
|
||||
import cn.iocoder.yudao.module.hrm.enums.salary.slip.HrmSalarySlipTemplateOptionTypeEnum;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.test.context.bean.override.mockito.MockitoBean;
|
||||
@@ -27,6 +28,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.SALARY_SLIP_ALREADY_SENT;
|
||||
import static cn.iocoder.yudao.module.hrm.enums.ErrorCodeConstants.SALARY_SLIP_NOT_EXISTS;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -37,6 +39,7 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
|
||||
|
||||
/**
|
||||
* {@link HrmSalarySlipServiceImpl} 的单元测试类
|
||||
@@ -56,6 +59,12 @@ public class HrmSalarySlipServiceImplTest extends BaseDbUnitTest {
|
||||
@MockitoBean
|
||||
private NotifyMessageSendApi notifyMessageSendApi;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
when(notifyMessageSendApi.sendSingleMessageToAdmin(org.mockito.ArgumentMatchers.any()))
|
||||
.thenReturn(success(randomLongId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCreateSalarySlipList_success() {
|
||||
// mock 数据
|
||||
|
||||
+1
@@ -54,6 +54,7 @@ public class PayClientFactoryImpl implements PayClientFactory {
|
||||
clientClass.put(ALIPAY_APP, AlipayAppPayClient.class);
|
||||
clientClass.put(ALIPAY_PC, AlipayPcPayClient.class);
|
||||
clientClass.put(ALIPAY_BAR, AlipayBarPayClient.class);
|
||||
clientClass.put(ALIPAY_LITE, AlipayLitePayClient.class);
|
||||
// 钱包支付客户端
|
||||
clientClass.put(WALLET, WalletPayClient.class);
|
||||
// Mock 支付客户端
|
||||
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
package cn.iocoder.yudao.module.pay.framework.pay.core.client.impl.alipay;
|
||||
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import cn.iocoder.yudao.module.pay.enums.PayChannelEnum;
|
||||
import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
||||
import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.framework.pay.core.enums.PayOrderDisplayModeEnum;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.domain.AlipayTradeCreateModel;
|
||||
import com.alipay.api.request.AlipayTradeCreateRequest;
|
||||
import com.alipay.api.response.AlipayTradeCreateResponse;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.invalidParamException;
|
||||
import static cn.iocoder.yudao.module.pay.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
|
||||
|
||||
/**
|
||||
* 支付宝【小程序】的 PayClient 实现类
|
||||
*
|
||||
* 文档:<a href="https://opendocs.alipay.com/mini/6039ed0c_alipay.trade.create">统一收单交易创建</a>
|
||||
*
|
||||
* @author graypxl
|
||||
*/
|
||||
public class AlipayLitePayClient extends AbstractAlipayPayClient {
|
||||
|
||||
public static final String BUYER_ID_KEY = "buyer_id";
|
||||
public static final String BUYER_OPEN_ID_KEY = "buyer_open_id";
|
||||
|
||||
public AlipayLitePayClient(Long channelId, AlipayPayClientConfig config) {
|
||||
super(channelId, PayChannelEnum.ALIPAY_LITE.getCode(), config);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PayOrderRespDTO doUnifiedOrder(PayOrderUnifiedReqDTO reqDTO) throws AlipayApiException {
|
||||
AlipayTradeCreateModel model = new AlipayTradeCreateModel();
|
||||
model.setOutTradeNo(reqDTO.getOutTradeNo());
|
||||
model.setSubject(reqDTO.getSubject());
|
||||
model.setBody(reqDTO.getBody());
|
||||
model.setTotalAmount(formatAmount(reqDTO.getPrice()));
|
||||
model.setTimeExpire(formatTime(reqDTO.getExpireTime()));
|
||||
model.setProductCode("JSAPI_PAY");
|
||||
model.setOpAppId(config.getAppId());
|
||||
applyBuyerIdentity(model, reqDTO);
|
||||
|
||||
AlipayTradeCreateRequest request = new AlipayTradeCreateRequest();
|
||||
request.setBizModel(model);
|
||||
request.setNotifyUrl(reqDTO.getNotifyUrl());
|
||||
|
||||
AlipayTradeCreateResponse response;
|
||||
if (Objects.equals(config.getMode(), MODE_CERTIFICATE)) {
|
||||
response = client.certificateExecute(request);
|
||||
} else {
|
||||
response = client.execute(request);
|
||||
}
|
||||
if (!response.isSuccess()) {
|
||||
return buildClosedPayOrderRespDTO(reqDTO, response);
|
||||
}
|
||||
return PayOrderRespDTO.waitingOf(PayOrderDisplayModeEnum.APP.getMode(), response.getTradeNo(),
|
||||
reqDTO.getOutTradeNo(), response);
|
||||
}
|
||||
|
||||
static void applyBuyerIdentity(AlipayTradeCreateModel model, PayOrderUnifiedReqDTO reqDTO) {
|
||||
String buyerId = MapUtil.getStr(reqDTO.getChannelExtras(), BUYER_ID_KEY);
|
||||
String buyerOpenId = MapUtil.getStr(reqDTO.getChannelExtras(), BUYER_OPEN_ID_KEY);
|
||||
if (StrUtil.isBlank(buyerOpenId)) {
|
||||
buyerOpenId = MapUtil.getStr(reqDTO.getChannelExtras(), "openid");
|
||||
}
|
||||
if (isAlipayUserId(buyerId)) {
|
||||
model.setBuyerId(buyerId);
|
||||
} else if (StrUtil.isNotBlank(buyerOpenId)) {
|
||||
model.setBuyerOpenId(buyerOpenId);
|
||||
} else if (StrUtil.isNotBlank(buyerId)) {
|
||||
model.setBuyerOpenId(buyerId);
|
||||
} else {
|
||||
throw invalidParamException("支付请求的 buyer_open_id 不能为空!");
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isAlipayUserId(String value) {
|
||||
return StrUtil.isNotBlank(value) && value.startsWith("2088") && value.length() <= 28
|
||||
&& StrUtil.isNumeric(value);
|
||||
}
|
||||
|
||||
}
|
||||
+201
@@ -0,0 +1,201 @@
|
||||
package cn.iocoder.yudao.module.pay.framework.pay.core.client.impl.alipay;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
|
||||
import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderRespDTO;
|
||||
import cn.iocoder.yudao.module.pay.framework.pay.core.client.dto.order.PayOrderUnifiedReqDTO;
|
||||
import cn.iocoder.yudao.module.pay.framework.pay.core.enums.PayOrderDisplayModeEnum;
|
||||
import cn.iocoder.yudao.module.pay.framework.pay.core.client.exception.PayClientException;
|
||||
import com.alipay.api.AlipayApiException;
|
||||
import com.alipay.api.domain.AlipayTradeCreateModel;
|
||||
import com.alipay.api.request.AlipayTradeCreateRequest;
|
||||
import com.alipay.api.response.AlipayTradeCreateResponse;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentMatcher;
|
||||
import org.mockito.InjectMocks;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||
import static cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum.CLOSED;
|
||||
import static cn.iocoder.yudao.module.pay.enums.order.PayOrderStatusEnum.WAITING;
|
||||
import static cn.iocoder.yudao.module.pay.framework.pay.core.client.impl.alipay.AlipayPayClientConfig.MODE_CERTIFICATE;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
/**
|
||||
* {@link AlipayLitePayClient} 单元测试
|
||||
*
|
||||
* @author graypxl
|
||||
*/
|
||||
public class AlipayLitePayClientTest extends AbstractAlipayClientTest {
|
||||
|
||||
@InjectMocks
|
||||
private AlipayLitePayClient client = new AlipayLitePayClient(randomLongId(), config);
|
||||
|
||||
@Override
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
setClient(client);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:buyer_open_id 下单成功")
|
||||
public void testUnifiedOrder_buyerOpenId() throws AlipayApiException {
|
||||
String buyerOpenId = "060d4dhFytu7VF5haNiDacG7b-n5toPeevhdLa07Kz9ass8";
|
||||
String tradeNo = randomString();
|
||||
AlipayTradeCreateResponse response = randomPojo(AlipayTradeCreateResponse.class, o -> {
|
||||
o.setSubCode("");
|
||||
o.setTradeNo(tradeNo);
|
||||
});
|
||||
when(defaultAlipayClient.execute(argThat(assertRequest(config.getAppId(), null, buyerOpenId))))
|
||||
.thenReturn(response);
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(Map.of(AlipayLitePayClient.BUYER_OPEN_ID_KEY, buyerOpenId));
|
||||
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
|
||||
assertEquals(WAITING.getStatus(), resp.getStatus());
|
||||
assertEquals(reqDTO.getOutTradeNo(), resp.getOutTradeNo());
|
||||
assertNull(resp.getChannelOrderNo());
|
||||
assertNull(resp.getChannelUserId());
|
||||
assertNull(resp.getSuccessTime());
|
||||
assertEquals(PayOrderDisplayModeEnum.APP.getMode(), resp.getDisplayMode());
|
||||
assertEquals(tradeNo, resp.getDisplayContent());
|
||||
assertSame(response, resp.getRawData());
|
||||
assertNull(resp.getChannelErrorCode());
|
||||
assertNull(resp.getChannelErrorMsg());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:buyer_id 下单成功")
|
||||
public void testUnifiedOrder_buyerId() throws AlipayApiException {
|
||||
String buyerId = "2088123456789012";
|
||||
AlipayTradeCreateResponse response = randomPojo(AlipayTradeCreateResponse.class, o -> o.setSubCode(""));
|
||||
when(defaultAlipayClient.execute(argThat(assertRequest(config.getAppId(), buyerId, null))))
|
||||
.thenReturn(response);
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(Map.of(AlipayLitePayClient.BUYER_ID_KEY, buyerId));
|
||||
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
|
||||
assertEquals(WAITING.getStatus(), resp.getStatus());
|
||||
assertEquals(reqDTO.getOutTradeNo(), resp.getOutTradeNo());
|
||||
assertEquals(PayOrderDisplayModeEnum.APP.getMode(), resp.getDisplayMode());
|
||||
assertSame(response, resp.getRawData());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:兼容 openid 参数")
|
||||
public void testUnifiedOrder_openidAlias() throws AlipayApiException {
|
||||
String buyerOpenId = randomString();
|
||||
AlipayTradeCreateResponse response = randomPojo(AlipayTradeCreateResponse.class, o -> o.setSubCode(""));
|
||||
when(defaultAlipayClient.execute(argThat(assertRequest(config.getAppId(), null, buyerOpenId))))
|
||||
.thenReturn(response);
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(Map.of("openid", buyerOpenId));
|
||||
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
|
||||
assertEquals(WAITING.getStatus(), resp.getStatus());
|
||||
assertEquals(reqDTO.getOutTradeNo(), resp.getOutTradeNo());
|
||||
assertEquals(PayOrderDisplayModeEnum.APP.getMode(), resp.getDisplayMode());
|
||||
assertSame(response, resp.getRawData());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:证书模式下单成功")
|
||||
public void testUnifiedOrder_certificateMode() throws AlipayApiException {
|
||||
config.setMode(MODE_CERTIFICATE);
|
||||
String buyerOpenId = randomString();
|
||||
AlipayTradeCreateResponse response = randomPojo(AlipayTradeCreateResponse.class, o -> o.setSubCode(""));
|
||||
when(defaultAlipayClient.certificateExecute(argThat(assertRequest(config.getAppId(), null, buyerOpenId))))
|
||||
.thenReturn(response);
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(Map.of(AlipayLitePayClient.BUYER_OPEN_ID_KEY, buyerOpenId));
|
||||
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
|
||||
assertEquals(WAITING.getStatus(), resp.getStatus());
|
||||
assertEquals(reqDTO.getOutTradeNo(), resp.getOutTradeNo());
|
||||
assertEquals(PayOrderDisplayModeEnum.APP.getMode(), resp.getDisplayMode());
|
||||
assertSame(response, resp.getRawData());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:渠道返回失败")
|
||||
public void testUnifiedOrder_channelFailed() throws AlipayApiException {
|
||||
String subCode = randomString();
|
||||
String subMsg = randomString();
|
||||
AlipayTradeCreateResponse response = randomPojo(AlipayTradeCreateResponse.class, o -> {
|
||||
o.setSubCode(subCode);
|
||||
o.setSubMsg(subMsg);
|
||||
});
|
||||
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeCreateRequest>) request -> true)))
|
||||
.thenReturn(response);
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(Map.of(AlipayLitePayClient.BUYER_OPEN_ID_KEY, randomString()));
|
||||
|
||||
PayOrderRespDTO resp = client.unifiedOrder(reqDTO);
|
||||
|
||||
assertEquals(CLOSED.getStatus(), resp.getStatus());
|
||||
assertEquals(reqDTO.getOutTradeNo(), resp.getOutTradeNo());
|
||||
assertNull(resp.getChannelOrderNo());
|
||||
assertNull(resp.getChannelUserId());
|
||||
assertNull(resp.getSuccessTime());
|
||||
assertNull(resp.getDisplayMode());
|
||||
assertNull(resp.getDisplayContent());
|
||||
assertSame(response, resp.getRawData());
|
||||
assertEquals(subCode, resp.getChannelErrorCode());
|
||||
assertEquals(subMsg, resp.getChannelErrorMsg());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:买家标识为空")
|
||||
public void testUnifiedOrder_buyerEmpty() {
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(new HashMap<>());
|
||||
|
||||
assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:抛出业务异常")
|
||||
public void testUnifiedOrder_throwServiceException() throws AlipayApiException {
|
||||
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeCreateRequest>) request -> true)))
|
||||
.thenThrow(ServiceExceptionUtil.exception(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR));
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(Map.of(AlipayLitePayClient.BUYER_OPEN_ID_KEY, randomString()));
|
||||
|
||||
assertThrows(ServiceException.class, () -> client.unifiedOrder(reqDTO));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("支付宝小程序支付:抛出系统异常")
|
||||
public void testUnifiedOrder_throwPayException() throws AlipayApiException {
|
||||
when(defaultAlipayClient.execute(argThat((ArgumentMatcher<AlipayTradeCreateRequest>) request -> true)))
|
||||
.thenThrow(new RuntimeException("系统异常"));
|
||||
PayOrderUnifiedReqDTO reqDTO = buildOrderUnifiedReqDTO(randomURL(), randomString(), randomInteger());
|
||||
reqDTO.setChannelExtras(Map.of(AlipayLitePayClient.BUYER_OPEN_ID_KEY, randomString()));
|
||||
|
||||
assertThrows(PayClientException.class, () -> client.unifiedOrder(reqDTO));
|
||||
}
|
||||
|
||||
private static ArgumentMatcher<AlipayTradeCreateRequest> assertRequest(String appId, String buyerId,
|
||||
String buyerOpenId) {
|
||||
return request -> {
|
||||
AlipayTradeCreateModel model = (AlipayTradeCreateModel) request.getBizModel();
|
||||
assertEquals("JSAPI_PAY", model.getProductCode());
|
||||
assertEquals(appId, model.getOpAppId());
|
||||
assertEquals(buyerId, model.getBuyerId());
|
||||
assertEquals(buyerOpenId, model.getBuyerOpenId());
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
+14
@@ -398,4 +398,18 @@ public class MailTemplateServiceImplTest extends BaseDbUnitTest {
|
||||
assertFalse(formattedContent.contains("{activationLink}"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFormatMailTemplateContent_dollarInCodeBlock() {
|
||||
// 准备参数
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
|
||||
// 测试代码块中包含 $ 与 \\(历史上 appendReplacement 会抛 IllegalArgumentException: Illegal group reference)
|
||||
String content = "<pre><code>echo $HOME && ls \\root</code></pre>";
|
||||
|
||||
// 调用,并断言内容原样保留
|
||||
String result = mailTemplateService.formatMailTemplateContent(content, params);
|
||||
assertTrue(result.contains("echo $HOME && ls \\root"));
|
||||
assertTrue(result.contains("<div><code>"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user