收敛充电订单开票待办接收人

This commit is contained in:
jsowell
2026-07-17 17:30:29 +08:00
parent c416bdacc9
commit 5c7f4dccec
9 changed files with 112 additions and 7 deletions

View File

@@ -26,7 +26,7 @@ import static org.mockito.Mockito.when;
class OrderInvoiceRecordTodoTest { class OrderInvoiceRecordTodoTest {
@Test @Test
void insert_shouldCreateTodoForEachMerchantUser() { void insert_shouldCreateTodoForEachMerchantAdmin() {
OrderInvoiceRecordMapper mapper = mock(OrderInvoiceRecordMapper.class); OrderInvoiceRecordMapper mapper = mock(OrderInvoiceRecordMapper.class);
PileMerchantInfoService merchantService = mock(PileMerchantInfoService.class); PileMerchantInfoService merchantService = mock(PileMerchantInfoService.class);
TodoTaskAssigneeService assigneeService = mock(TodoTaskAssigneeService.class); TodoTaskAssigneeService assigneeService = mock(TodoTaskAssigneeService.class);
@@ -44,7 +44,7 @@ class OrderInvoiceRecordTodoTest {
PileMerchantInfo merchantInfo = new PileMerchantInfo(); PileMerchantInfo merchantInfo = new PileMerchantInfo();
merchantInfo.setDeptId("200"); merchantInfo.setDeptId("200");
when(merchantService.selectPileMerchantInfoById(100L)).thenReturn(merchantInfo); when(merchantService.selectPileMerchantInfoById(100L)).thenReturn(merchantInfo);
when(assigneeService.findActiveUserIdsByDeptTree(200L)).thenReturn(Arrays.asList(8L, 9L)); when(assigneeService.findActiveOperatorAdminUserIdsByDeptTree(200L)).thenReturn(Arrays.asList(8L, 9L));
when(todoTaskService.createTask(any(TodoTaskCreateCommand.class))).thenReturn(new SysTodoTask()); when(todoTaskService.createTask(any(TodoTaskCreateCommand.class))).thenReturn(new SysTodoTask());
service.insertOrderInvoiceRecord(invoiceRecord); service.insertOrderInvoiceRecord(invoiceRecord);
@@ -56,6 +56,8 @@ class OrderInvoiceRecordTodoTest {
commands.get(0).getAssigneeUserId(), commands.get(1).getAssigneeUserId())); commands.get(0).getAssigneeUserId(), commands.get(1).getAssigneeUserId()));
assertEquals("ORDER_INVOICE_RECORD", commands.get(0).getBusinessType()); assertEquals("ORDER_INVOICE_RECORD", commands.get(0).getBusinessType());
assertEquals("55", commands.get(0).getBusinessId()); assertEquals("55", commands.get(0).getBusinessId());
assertEquals("充电订单开票申请", commands.get(0).getTitle());
assertEquals("有新的充电订单开票申请需要处理申请单号55", commands.get(0).getSummary());
assertEquals("invoiceDetail", commands.get(0).getRouteName()); assertEquals("invoiceDetail", commands.get(0).getRouteName());
assertEquals(TodoTaskConstants.PRIORITY_IMPORTANT, commands.get(0).getPriority()); assertEquals(TodoTaskConstants.PRIORITY_IMPORTANT, commands.get(0).getPriority());
assertEquals("INVOICE_REVIEW:ORDER_INVOICE_RECORD:55:8", commands.get(0).getIdempotentKey()); assertEquals("INVOICE_REVIEW:ORDER_INVOICE_RECORD:55:8", commands.get(0).getIdempotentKey());

View File

@@ -0,0 +1,52 @@
package com.jsowell.system.service;
import com.jsowell.system.mapper.SysUserMapper;
import com.jsowell.system.service.impl.TodoTaskAssigneeServiceImpl;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import java.util.Collections;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
class TodoTaskAssigneeServiceImplTest {
@Test
void findOperatorAdmins_shouldUseConfiguredRole() {
SysUserMapper mapper = mock(SysUserMapper.class);
TodoTaskAssigneeServiceImpl service = new TodoTaskAssigneeServiceImpl();
setField(service, "userMapper", mapper);
setField(service, "operatorAdminRoleId", 7L);
when(mapper.selectActiveUserIdsByDeptTreeAndRole(200L, 7L))
.thenReturn(Collections.singletonList(8L));
assertEquals(Collections.singletonList(8L),
service.findActiveOperatorAdminUserIdsByDeptTree(200L));
verify(mapper).selectActiveUserIdsByDeptTreeAndRole(200L, 7L);
}
@Test
void findOperatorAdmins_shouldFallbackToExistingMerchantAdminRole() {
SysUserMapper mapper = mock(SysUserMapper.class);
TodoTaskAssigneeServiceImpl service = new TodoTaskAssigneeServiceImpl();
setField(service, "userMapper", mapper);
when(mapper.selectActiveUserIdsByDeptTreeAndRole(200L, 3L))
.thenReturn(Collections.singletonList(8L));
service.findActiveOperatorAdminUserIdsByDeptTree(200L);
verify(mapper).selectActiveUserIdsByDeptTreeAndRole(200L, 3L);
}
private static void setField(Object target, String fieldName, Object value) {
try {
Field field = target.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(target, value);
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}

View File

@@ -121,7 +121,7 @@ class TodoTaskServiceImplTest {
private static TodoTaskCreateCommand createCommand() { private static TodoTaskCreateCommand createCommand() {
return TodoTaskCreateCommand.builder() return TodoTaskCreateCommand.builder()
.taskType("INVOICE_REVIEW") .taskType("INVOICE_REVIEW")
.title("司机开票申请") .title("充电订单开票申请")
.businessType("INVOICE_APPLY") .businessType("INVOICE_APPLY")
.businessId("100") .businessId("100")
.routeName("InvoiceApplyDetail") .routeName("InvoiceApplyDetail")

View File

@@ -251,9 +251,9 @@ public class OrderInvoiceRecordServiceImpl implements OrderInvoiceRecordService
return; return;
} }
List<Long> assigneeUserIds = todoTaskAssigneeService.findActiveUserIdsByDeptTree(merchantDeptId); List<Long> assigneeUserIds = todoTaskAssigneeService.findActiveOperatorAdminUserIdsByDeptTree(merchantDeptId);
if (CollectionUtils.isEmpty(assigneeUserIds)) { if (CollectionUtils.isEmpty(assigneeUserIds)) {
log.warn("开票申请运营商部门下没有正常用户无法创建待办invoiceId={}, deptId={}", log.warn("开票申请运营商部门下没有正常管理员无法创建待办invoiceId={}, deptId={}",
invoiceRecord.getId(), merchantInfo.getDeptId()); invoiceRecord.getId(), merchantInfo.getDeptId());
return; return;
} }
@@ -263,8 +263,8 @@ public class OrderInvoiceRecordServiceImpl implements OrderInvoiceRecordService
+ invoiceRecord.getId() + ":" + assigneeUserId; + invoiceRecord.getId() + ":" + assigneeUserId;
todoTaskService.createTask(TodoTaskCreateCommand.builder() todoTaskService.createTask(TodoTaskCreateCommand.builder()
.taskType(TODO_TASK_TYPE) .taskType(TODO_TASK_TYPE)
.title("司机开票申请") .title("充电订单开票申请")
.summary("有新的司机开票申请需要处理,申请单号:" + invoiceRecord.getId()) .summary("有新的充电订单开票申请需要处理,申请单号:" + invoiceRecord.getId())
.businessType(TODO_BUSINESS_TYPE) .businessType(TODO_BUSINESS_TYPE)
.businessId(String.valueOf(invoiceRecord.getId())) .businessId(String.valueOf(invoiceRecord.getId()))
.routeName(TODO_ROUTE_NAME) .routeName(TODO_ROUTE_NAME)

View File

@@ -25,6 +25,8 @@ public final class TodoTaskConstants {
public static final int DEFAULT_HOME_LIMIT = 3; public static final int DEFAULT_HOME_LIMIT = 3;
public static final int MAX_HOME_LIMIT = 10; public static final int MAX_HOME_LIMIT = 10;
/** 现有运营商创建流程使用的运营商管理员角色 ID正式环境可通过配置覆盖。 */
public static final long DEFAULT_OPERATOR_ADMIN_ROLE_ID = 3L;
public static boolean isActiveStatus(String status) { public static boolean isActiveStatus(String status) {
return STATUS_PENDING.equals(status) || STATUS_PROCESSING.equals(status); return STATUS_PENDING.equals(status) || STATUS_PROCESSING.equals(status);

View File

@@ -27,6 +27,16 @@ public interface SysUserMapper {
*/ */
List<Long> selectActiveUserIdsByDeptTree(@Param("deptId") Long deptId); List<Long> selectActiveUserIdsByDeptTree(@Param("deptId") Long deptId);
/**
* 查询部门及下级部门中拥有指定角色的正常用户 ID。
*
* @param deptId 部门 ID
* @param roleId 角色 ID
* @return 用户 ID 集合
*/
List<Long> selectActiveUserIdsByDeptTreeAndRole(@Param("deptId") Long deptId,
@Param("roleId") Long roleId);
/** /**
* 根据条件分页查询已配用户角色列表 * 根据条件分页查询已配用户角色列表
* *

View File

@@ -9,4 +9,6 @@ import java.util.List;
*/ */
public interface TodoTaskAssigneeService { public interface TodoTaskAssigneeService {
List<Long> findActiveUserIdsByDeptTree(Long deptId); List<Long> findActiveUserIdsByDeptTree(Long deptId);
List<Long> findActiveOperatorAdminUserIdsByDeptTree(Long deptId);
} }

View File

@@ -1,9 +1,11 @@
package com.jsowell.system.service.impl; package com.jsowell.system.service.impl;
import com.jsowell.common.exception.ServiceException; import com.jsowell.common.exception.ServiceException;
import com.jsowell.system.constant.TodoTaskConstants;
import com.jsowell.system.mapper.SysUserMapper; import com.jsowell.system.mapper.SysUserMapper;
import com.jsowell.system.service.TodoTaskAssigneeService; import com.jsowell.system.service.TodoTaskAssigneeService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List; import java.util.List;
@@ -15,6 +17,9 @@ import java.util.List;
*/ */
@Service @Service
public class TodoTaskAssigneeServiceImpl implements TodoTaskAssigneeService { public class TodoTaskAssigneeServiceImpl implements TodoTaskAssigneeService {
@Value("${todo.operator-admin-role-id:3}")
private Long operatorAdminRoleId;
@Autowired @Autowired
private SysUserMapper userMapper; private SysUserMapper userMapper;
@@ -25,4 +30,14 @@ public class TodoTaskAssigneeServiceImpl implements TodoTaskAssigneeService {
} }
return userMapper.selectActiveUserIdsByDeptTree(deptId); return userMapper.selectActiveUserIdsByDeptTree(deptId);
} }
@Override
public List<Long> findActiveOperatorAdminUserIdsByDeptTree(Long deptId) {
if (deptId == null || deptId <= 0) {
throw new ServiceException("待办接收部门不能为空");
}
Long roleId = operatorAdminRoleId == null || operatorAdminRoleId <= 0
? TodoTaskConstants.DEFAULT_OPERATOR_ADMIN_ROLE_ID : operatorAdminRoleId;
return userMapper.selectActiveUserIdsByDeptTreeAndRole(deptId, roleId);
}
} }

View File

@@ -108,6 +108,28 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by u.user_id order by u.user_id
</select> </select>
<select id="selectActiveUserIdsByDeptTreeAndRole" resultType="Long">
select distinct u.user_id
from sys_user u
inner join sys_user_role ur on ur.user_id = u.user_id
inner join sys_role r on r.role_id = ur.role_id
where u.status = '0'
and u.del_flag = '0'
and r.status = '0'
and r.del_flag = '0'
and ur.role_id = #{roleId}
and (
u.dept_id = #{deptId}
or u.dept_id in (
select d.dept_id
from sys_dept d
where find_in_set(#{deptId}, d.ancestors)
and d.status = '0'
)
)
order by u.user_id
</select>
<select id="selectAllocatedList" parameterType="com.jsowell.common.core.domain.entity.SysUser" resultMap="SysUserResult"> <select id="selectAllocatedList" parameterType="com.jsowell.common.core.domain.entity.SysUser" resultMap="SysUserResult">
select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phone, u.status, u.create_time select distinct u.user_id, u.dept_id, u.user_name, u.nick_name, u.email, u.phone, u.status, u.create_time
from sys_user u from sys_user u