mirror of
https://github.com/1Panel-dev/CordysCRM.git
synced 2026-05-24 03:38:42 +08:00
refactor: lead pool service
This commit is contained in:
@@ -13,12 +13,11 @@ import io.cordys.crm.customer.domain.CustomerPoolRelation;
|
||||
import io.cordys.crm.customer.dto.CustomerPoolDTO;
|
||||
import io.cordys.crm.customer.dto.request.CustomerPoolSaveRequest;
|
||||
import io.cordys.crm.customer.mapper.ExtCustomerPoolMapper;
|
||||
import io.cordys.crm.system.constants.ScopeKey;
|
||||
import io.cordys.crm.system.domain.Department;
|
||||
import io.cordys.crm.system.domain.Role;
|
||||
import io.cordys.crm.system.domain.User;
|
||||
import io.cordys.crm.system.dto.ScopeNameDTO;
|
||||
import io.cordys.crm.system.mapper.ExtUserMapper;
|
||||
import io.cordys.crm.system.service.UserExtendService;
|
||||
import io.cordys.mybatis.BaseMapper;
|
||||
import io.cordys.mybatis.lambda.LambdaQueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -29,8 +28,6 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -54,6 +51,8 @@ public class CustomerPoolService {
|
||||
private BaseMapper<CustomerPoolRelation> customerPoolRelationMapper;
|
||||
@Resource
|
||||
private ExtCustomerPoolMapper extCustomerPoolMapper;
|
||||
@Resource
|
||||
private UserExtendService userExtendService;
|
||||
|
||||
/**
|
||||
* 分页获取公海池
|
||||
@@ -76,8 +75,8 @@ public class CustomerPoolService {
|
||||
List<Role> roles = roleMapper.selectByIds(unionIds.toArray(new String[0]));
|
||||
List<Department> departments = departmentMapper.selectByIds(unionIds.toArray(new String[0]));
|
||||
pools.forEach(pool -> {
|
||||
pool.setMembers(getScope(users, roles, departments, JSON.parseArray(pool.getScopeId(), String.class)));
|
||||
pool.setOwners(getScope(users, roles, departments, JSON.parseArray(pool.getOwnerId(), String.class)));
|
||||
pool.setMembers(userExtendService.getScope(users, roles, departments, JSON.parseArray(pool.getScopeId(), String.class)));
|
||||
pool.setOwners(userExtendService.getScope(users, roles, departments, JSON.parseArray(pool.getOwnerId(), String.class)));
|
||||
});
|
||||
return pools;
|
||||
}
|
||||
@@ -189,34 +188,4 @@ public class CustomerPoolService {
|
||||
throw new GenericException(Translator.get("customer_pool_access_fail"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取成员范围集合
|
||||
* @param users 用户
|
||||
* @param roles 角色
|
||||
* @param departments 部门
|
||||
* @param scopeIds 范围ID集合
|
||||
* @return 范围集合
|
||||
*/
|
||||
private List<ScopeNameDTO> getScope(List<User> users, List<Role> roles, List<Department> departments, List<String> scopeIds) {
|
||||
Map<String, String> userMap = users.stream().collect(Collectors.toMap(User::getId, User::getName));
|
||||
Map<String, String> roleMap = roles.stream().collect(Collectors.toMap(Role::getId, Role::getName));
|
||||
Map<String, String> departmentMap = departments.stream().collect(Collectors.toMap(Department::getId, Department::getName));
|
||||
List<ScopeNameDTO> scopes = new ArrayList<>();
|
||||
scopeIds.forEach(scopeId -> {
|
||||
ScopeNameDTO scope = ScopeNameDTO.builder().id(scopeId).build();
|
||||
if (userMap.containsKey(scopeId)) {
|
||||
scope.setName(userMap.get(scopeId));
|
||||
scope.setScope(ScopeKey.USER.name());
|
||||
} else if (roleMap.containsKey(scopeId)) {
|
||||
scope.setName(roleMap.get(scopeId));
|
||||
scope.setScope(ScopeKey.ROLE.name());
|
||||
} else if (departmentMap.containsKey(scopeId)) {
|
||||
scope.setName(departmentMap.get(scopeId));
|
||||
scope.setScope(ScopeKey.DEPARTMENT.name());
|
||||
}
|
||||
scopes.add(scope);
|
||||
});
|
||||
return scopes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package io.cordys.crm.lead.dto;
|
||||
|
||||
import io.cordys.crm.lead.domain.LeadPool;
|
||||
import io.cordys.crm.system.dto.ScopeNameDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
public class LeadPoolDTO extends LeadPool {
|
||||
|
||||
@Schema(description = "管理员")
|
||||
private String ownerName;
|
||||
|
||||
@Schema(description = "成员")
|
||||
private String scopeName;
|
||||
@Schema(description = "成员集合")
|
||||
private List<ScopeNameDTO> members;
|
||||
@Schema(description = "管理员集合")
|
||||
private List<ScopeNameDTO> owners;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package io.cordys.crm.lead.dto.request;
|
||||
|
||||
import io.cordys.crm.system.dto.RuleConditionDTO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
public class LeadPoolRecycleRuleSaveRequest {
|
||||
@@ -20,5 +23,5 @@ public class LeadPoolRecycleRuleSaveRequest {
|
||||
private String operator;
|
||||
|
||||
@Schema(description = "回收条件")
|
||||
private String condition;
|
||||
private List<RuleConditionDTO> conditions;
|
||||
}
|
||||
|
||||
@@ -4,11 +4,14 @@ import io.cordys.common.groups.Created;
|
||||
import io.cordys.common.groups.Updated;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
public class LeadPoolSaveRequest {
|
||||
@@ -23,13 +26,13 @@ public class LeadPoolSaveRequest {
|
||||
@Schema(description = "线索池名称")
|
||||
private String name;
|
||||
|
||||
@NotBlank
|
||||
@Schema(description = "成员ID")
|
||||
private String scopeId;
|
||||
@NotNull
|
||||
@Schema(description = "范围ID集合")
|
||||
private List<String> scopeIds;
|
||||
|
||||
@NotBlank
|
||||
@Schema(description = "管理员ID")
|
||||
private String ownerId;
|
||||
@NotNull
|
||||
@Schema(description = "管理员ID集合")
|
||||
private List<String> ownerIds;
|
||||
|
||||
@NonNull
|
||||
@Schema(description = "启用/禁用")
|
||||
|
||||
@@ -4,6 +4,7 @@ import io.cordys.common.exception.GenericException;
|
||||
import io.cordys.common.pager.condition.BasePageRequest;
|
||||
import io.cordys.common.uid.IDGenerator;
|
||||
import io.cordys.common.util.BeanUtils;
|
||||
import io.cordys.common.util.JSON;
|
||||
import io.cordys.common.util.Translator;
|
||||
import io.cordys.context.OrganizationContext;
|
||||
import io.cordys.crm.lead.domain.LeadPool;
|
||||
@@ -14,7 +15,10 @@ import io.cordys.crm.lead.dto.LeadPoolDTO;
|
||||
import io.cordys.crm.lead.dto.request.LeadPoolSaveRequest;
|
||||
import io.cordys.crm.lead.mapper.ExtLeadPoolMapper;
|
||||
import io.cordys.crm.system.domain.Department;
|
||||
import io.cordys.crm.system.domain.Role;
|
||||
import io.cordys.crm.system.domain.User;
|
||||
import io.cordys.crm.system.mapper.ExtUserMapper;
|
||||
import io.cordys.crm.system.service.UserExtendService;
|
||||
import io.cordys.mybatis.BaseMapper;
|
||||
import io.cordys.mybatis.lambda.LambdaQueryWrapper;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -25,16 +29,22 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class LeadPoolService {
|
||||
|
||||
@Resource
|
||||
private ExtUserMapper extUserMapper;
|
||||
@Resource
|
||||
private BaseMapper<LeadPool> leadPoolMapper;
|
||||
@Resource
|
||||
private BaseMapper<User> userMapper;
|
||||
@Resource
|
||||
private BaseMapper<Role> roleMapper;
|
||||
@Resource
|
||||
private BaseMapper<Department> departmentMapper;
|
||||
@Resource
|
||||
private BaseMapper<LeadPoolPickRule> leadPoolPickRuleMapper;
|
||||
@Resource
|
||||
private BaseMapper<LeadPoolRecycleRule> leadPoolRecycleRuleMapper;
|
||||
@@ -42,6 +52,8 @@ public class LeadPoolService {
|
||||
private BaseMapper<LeadPoolRelation> leadPoolRelationMapper;
|
||||
@Resource
|
||||
private ExtLeadPoolMapper extLeadPoolMapper;
|
||||
@Resource
|
||||
private UserExtendService userExtendService;
|
||||
|
||||
/**
|
||||
* 分页获取线索池
|
||||
@@ -49,7 +61,25 @@ public class LeadPoolService {
|
||||
* @return 线索池列表
|
||||
*/
|
||||
public List<LeadPoolDTO> page(BasePageRequest request) {
|
||||
return extLeadPoolMapper.list(request, OrganizationContext.getOrganizationId());
|
||||
List<LeadPoolDTO> pools = extLeadPoolMapper.list(request, OrganizationContext.getOrganizationId());
|
||||
if (CollectionUtils.isEmpty(pools)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
List<String> scopeIds = new ArrayList<>();
|
||||
List<String> ownerIds = new ArrayList<>();
|
||||
pools.forEach(pool -> {
|
||||
scopeIds.addAll(JSON.parseArray(pool.getScopeId(), String.class));
|
||||
ownerIds.addAll(JSON.parseArray(pool.getOwnerId(), String.class));
|
||||
});
|
||||
List<String> unionIds = ListUtils.union(scopeIds, ownerIds).stream().distinct().toList();
|
||||
List<User> users = userMapper.selectByIds(unionIds.toArray(new String[0]));
|
||||
List<Role> roles = roleMapper.selectByIds(unionIds.toArray(new String[0]));
|
||||
List<Department> departments = departmentMapper.selectByIds(unionIds.toArray(new String[0]));
|
||||
pools.forEach(pool -> {
|
||||
pool.setMembers(userExtendService.getScope(users, roles, departments, JSON.parseArray(pool.getScopeId(), String.class)));
|
||||
pool.setOwners(userExtendService.getScope(users, roles, departments, JSON.parseArray(pool.getOwnerId(), String.class)));
|
||||
});
|
||||
return pools;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -60,6 +90,8 @@ public class LeadPoolService {
|
||||
LeadPool pool = new LeadPool();
|
||||
BeanUtils.copyBean(pool, request);
|
||||
pool.setOrganizationId(currentOrgId);
|
||||
pool.setOwnerId(JSON.toJSONString(request.getOwnerIds()));
|
||||
pool.setScopeId(JSON.toJSONString(request.getScopeIds()));
|
||||
pool.setUpdateTime(System.currentTimeMillis());
|
||||
pool.setUpdateUser(currentUserId);
|
||||
LeadPoolPickRule pickRule = new LeadPoolPickRule();
|
||||
@@ -68,6 +100,7 @@ public class LeadPoolService {
|
||||
pickRule.setUpdateUser(currentUserId);
|
||||
LeadPoolRecycleRule recycleRule = new LeadPoolRecycleRule();
|
||||
BeanUtils.copyBean(recycleRule, request.getRecycleRule());
|
||||
recycleRule.setCondition(JSON.toJSONString(request.getRecycleRule().getConditions()));
|
||||
recycleRule.setUpdateTime(System.currentTimeMillis());
|
||||
recycleRule.setUpdateUser(currentUserId);
|
||||
if (pool.getId() == null) {
|
||||
@@ -150,9 +183,9 @@ public class LeadPoolService {
|
||||
* @param accessUserId 访问用户ID
|
||||
*/
|
||||
private void checkPoolOwner(LeadPool pool, String accessUserId) {
|
||||
// split multiple owner by comma
|
||||
List<String> ownerIds = List.of(pool.getOwnerId().split(","));
|
||||
if (!ownerIds.contains(accessUserId)) {
|
||||
List<String> ownerIds = JSON.parseArray(pool.getOwnerId(), String.class);
|
||||
List<String> ownerUserIds = extUserMapper.getUserIdsByScope(ownerIds, pool.getOrganizationId());
|
||||
if (!ownerUserIds.contains(accessUserId)) {
|
||||
throw new GenericException(Translator.get("lead_pool_access_fail"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package io.cordys.crm.system.service;
|
||||
|
||||
import io.cordys.crm.system.constants.ScopeKey;
|
||||
import io.cordys.crm.system.domain.Department;
|
||||
import io.cordys.crm.system.domain.Role;
|
||||
import io.cordys.crm.system.domain.User;
|
||||
import io.cordys.crm.system.dto.ScopeNameDTO;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
public class UserExtendService {
|
||||
|
||||
/**
|
||||
* 获取成员范围集合
|
||||
* @param users 用户
|
||||
* @param roles 角色
|
||||
* @param departments 部门
|
||||
* @param scopeIds 范围ID集合
|
||||
* @return 范围集合
|
||||
*/
|
||||
public List<ScopeNameDTO> getScope(List<User> users, List<Role> roles, List<Department> departments, List<String> scopeIds) {
|
||||
Map<String, String> userMap = users.stream().collect(Collectors.toMap(User::getId, User::getName));
|
||||
Map<String, String> roleMap = roles.stream().collect(Collectors.toMap(Role::getId, Role::getName));
|
||||
Map<String, String> departmentMap = departments.stream().collect(Collectors.toMap(Department::getId, Department::getName));
|
||||
List<ScopeNameDTO> scopes = new ArrayList<>();
|
||||
scopeIds.forEach(scopeId -> {
|
||||
ScopeNameDTO scope = ScopeNameDTO.builder().id(scopeId).build();
|
||||
if (userMap.containsKey(scopeId)) {
|
||||
scope.setName(userMap.get(scopeId));
|
||||
scope.setScope(ScopeKey.USER.name());
|
||||
} else if (roleMap.containsKey(scopeId)) {
|
||||
scope.setName(roleMap.get(scopeId));
|
||||
scope.setScope(ScopeKey.ROLE.name());
|
||||
} else if (departmentMap.containsKey(scopeId)) {
|
||||
scope.setName(departmentMap.get(scopeId));
|
||||
scope.setScope(ScopeKey.DEPARTMENT.name());
|
||||
}
|
||||
scopes.add(scope);
|
||||
});
|
||||
return scopes;
|
||||
}
|
||||
}
|
||||
@@ -5,9 +5,9 @@ CREATE TABLE lead_pool
|
||||
(
|
||||
`id` VARCHAR(32) NOT NULL COMMENT 'id',
|
||||
`name` VARCHAR(255) NOT NULL COMMENT '线索池名称',
|
||||
`scope_id` VARCHAR(1000) NOT NULL COMMENT '成员id',
|
||||
`scope_id` TEXT NOT NULL COMMENT '成员id',
|
||||
`organization_id` VARCHAR(32) NOT NULL COMMENT '组织架构id',
|
||||
`owner_id` VARCHAR(1000) NOT NULL COMMENT '管理员id',
|
||||
`owner_id` TEXT NOT NULL COMMENT '管理员id',
|
||||
`enable` BIT(1) NOT NULL DEFAULT 1 COMMENT '启用/禁用',
|
||||
`auto` BIT(1) NOT NULL DEFAULT 0 COMMENT '自动回收',
|
||||
`create_time` BIGINT NOT NULL COMMENT '创建时间',
|
||||
|
||||
@@ -3,6 +3,7 @@ package io.cordys.crm.lead.controller;
|
||||
import io.cordys.common.pager.Pager;
|
||||
import io.cordys.common.pager.condition.BasePageRequest;
|
||||
import io.cordys.common.util.BeanUtils;
|
||||
import io.cordys.common.util.JSON;
|
||||
import io.cordys.common.util.Translator;
|
||||
import io.cordys.crm.base.BaseTest;
|
||||
import io.cordys.crm.lead.domain.LeadPool;
|
||||
@@ -13,6 +14,7 @@ import io.cordys.crm.lead.dto.LeadPoolDTO;
|
||||
import io.cordys.crm.lead.dto.request.LeadPoolPickRuleSaveRequest;
|
||||
import io.cordys.crm.lead.dto.request.LeadPoolRecycleRuleSaveRequest;
|
||||
import io.cordys.crm.lead.dto.request.LeadPoolSaveRequest;
|
||||
import io.cordys.crm.system.dto.RuleConditionDTO;
|
||||
import io.cordys.mybatis.BaseMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.MethodOrderer;
|
||||
@@ -54,10 +56,16 @@ public class LeadPoolControllerTests extends BaseTest {
|
||||
LeadPool leadPool = createLeadPool();
|
||||
LeadPoolSaveRequest request = new LeadPoolSaveRequest();
|
||||
BeanUtils.copyBean(request, leadPool);
|
||||
request.setOwnerIds(List.of("cc"));
|
||||
request.setScopeIds(List.of("cc"));
|
||||
LeadPoolPickRuleSaveRequest pickRule = LeadPoolPickRuleSaveRequest.builder()
|
||||
.pickNumber(1).limitOnNumber(true).pickIntervalDays(1).limitPreOwner(true).build();
|
||||
request.setPickRule(pickRule);
|
||||
LeadPoolRecycleRuleSaveRequest recycleRule = LeadPoolRecycleRuleSaveRequest.builder().expireNotice(true).noticeDays(10).build();
|
||||
RuleConditionDTO condition = new RuleConditionDTO();
|
||||
condition.setColumn("name");
|
||||
condition.setOperator("=");
|
||||
condition.setValues(List.of("cc"));
|
||||
LeadPoolRecycleRuleSaveRequest recycleRule = LeadPoolRecycleRuleSaveRequest.builder().expireNotice(true).noticeDays(10).conditions(List.of(condition)).build();
|
||||
request.setRecycleRule(recycleRule);
|
||||
this.requestPostWithOk("/lead-pool/add", request);
|
||||
}
|
||||
@@ -80,6 +88,8 @@ public class LeadPoolControllerTests extends BaseTest {
|
||||
leadPool.setId(testLeadPool.getId());
|
||||
LeadPoolSaveRequest request = new LeadPoolSaveRequest();
|
||||
BeanUtils.copyBean(request, leadPool);
|
||||
request.setOwnerIds(List.of("cc"));
|
||||
request.setScopeIds(List.of("cc"));
|
||||
LeadPoolPickRuleSaveRequest pickRule = LeadPoolPickRuleSaveRequest.builder()
|
||||
.pickNumber(1).limitOnNumber(true).pickIntervalDays(1).limitPreOwner(true).build();
|
||||
request.setPickRule(pickRule);
|
||||
@@ -88,9 +98,9 @@ public class LeadPoolControllerTests extends BaseTest {
|
||||
MvcResult mvcResult = this.requestPost("/lead-pool/update", request).andExpect(status().is5xxServerError()).andReturn();
|
||||
assert mvcResult.getResponse().getContentAsString().contains(Translator.get("lead_pool_access_fail"));
|
||||
// update owner id by sql
|
||||
leadPool.setOwnerId("admin");
|
||||
leadPool.setOwnerId(JSON.toJSONString(List.of("admin")));
|
||||
leadPoolMapper.updateById(leadPool);
|
||||
request.setOwnerId("admin");
|
||||
request.setOwnerIds(List.of("admin"));
|
||||
this.requestPostWithOk("/lead-pool/update", request);
|
||||
}
|
||||
|
||||
@@ -128,9 +138,8 @@ public class LeadPoolControllerTests extends BaseTest {
|
||||
private LeadPool createLeadPool() {
|
||||
LeadPool leadPool = new LeadPool();
|
||||
leadPool.setName("default-lead-pool");
|
||||
leadPool.setScopeId("default-dp");
|
||||
leadPool.setScopeId(JSON.toJSONString(List.of("default-dp")));
|
||||
leadPool.setOrganizationId(DEFAULT_ORGANIZATION_ID);
|
||||
leadPool.setOwnerId("default-owner");
|
||||
leadPool.setEnable(true);
|
||||
leadPool.setAuto(true);
|
||||
return leadPool;
|
||||
|
||||
Reference in New Issue
Block a user