!771 同步最新的 CRM 代码

Merge pull request !771 from 芋道源码/feature/crm
This commit is contained in:
芋道源码 2023-11-30 12:50:49 +00:00 committed by Gitee
commit fa1aa51c96
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
168 changed files with 2886 additions and 3412 deletions

View File

@ -1 +1,3 @@
SET NAMES utf8mb4;
-- `ruoyi-vue-pro`.crm_contact definition

View File

@ -1,88 +0,0 @@
-- ----------------------------
-- 客户公海配置
-- ----------------------------
-- 菜单 SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status, component_name
)
VALUES (
'客户公海配置', '', 2, 0, 2397,
'customer-pool-config', 'ep:data-analysis', 'crm/customerPoolConf/index', 0, 'CustomerPoolConf'
);
-- 按钮父菜单ID
-- 暂时只支持 MySQL如果你是 OraclePostgreSQLSQLServer 的话需要手动修改 @parentId 的部分的代码
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'客户公海配置保存', 'crm:customer-pool-config:update', 3, 1, @parentId,
'', '', '', 0
);
-- ----------------------------
-- 客户限制配置管理
-- ----------------------------
-- 菜单 SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status, component_name
)
VALUES (
'客户限制配置管理', '', 2, 0, 2397,
'customer-limit-config', '', 'crm/customerLimitConfig/index', 0, 'CrmCustomerLimitConfig'
);
-- 按钮父菜单ID
-- 暂时只支持 MySQL如果你是 OraclePostgreSQLSQLServer 的话需要手动修改 @parentId 的部分的代码
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'客户限制配置查询', 'crm:customer-limit-config:query', 3, 1, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'客户限制配置创建', 'crm:customer-limit-config:create', 3, 2, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'客户限制配置更新', 'crm:customer-limit-config:update', 3, 3, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'客户限制配置删除', 'crm:customer-limit-config:delete', 3, 4, @parentId,
'', '', '', 0
);
INSERT INTO system_menu(
name, permission, type, sort, parent_id,
path, icon, component, status
)
VALUES (
'客户限制配置导出', 'crm:customer-limit-config:export', 3, 5, @parentId,
'', '', '', 0
);

View File

@ -73,6 +73,23 @@ public class CollectionUtils {
return from.stream().filter(filter).map(func).filter(Objects::nonNull).collect(Collectors.toList());
}
public static <T, U> List<U> convertListByFlatMap(Collection<T> from,
Function<T, ? extends Stream<? extends U>> func) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
}
public static <T, U, R> List<R> convertListByFlatMap(Collection<T> from,
Function<? super T, ? extends U> mapper,
Function<U, ? extends Stream<? extends R>> func) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
}
public static <K, V> List<V> mergeValuesFromMap(Map<K, List<V>> map) {
return map.values()
.stream()
@ -101,6 +118,23 @@ public class CollectionUtils {
return from.stream().filter(filter).collect(Collectors.toMap(keyFunc, v -> v));
}
public static <T, U> Set<U> convertSetByFlatMap(Collection<T> from,
Function<T, ? extends Stream<? extends U>> func) {
if (CollUtil.isEmpty(from)) {
return new HashSet<>();
}
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
}
public static <T, U, R> Set<R> convertSetByFlatMap(Collection<T> from,
Function<? super T, ? extends U> mapper,
Function<U, ? extends Stream<? extends R>> func) {
if (CollUtil.isEmpty(from)) {
return new HashSet<>();
}
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
}
public static <T, K> Map<K, T> convertMap(Collection<T> from, Function<T, K> keyFunc) {
if (CollUtil.isEmpty(from)) {
return new HashMap<>();
@ -272,38 +306,4 @@ public class CollectionUtils {
return deptId == null ? Collections.emptyList() : Collections.singleton(deptId);
}
public static <T, U> List<U> convertListByFlatMap(Collection<T> from,
Function<T, ? extends Stream<? extends U>> func) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
}
public static <T, U, R> List<R> convertListByFlatMap(Collection<T> from,
Function<? super T, ? extends U> mapper,
Function<U, ? extends Stream<? extends R>> func) {
if (CollUtil.isEmpty(from)) {
return new ArrayList<>();
}
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toList());
}
public static <T, U> Set<U> convertSetByFlatMap(Collection<T> from,
Function<T, ? extends Stream<? extends U>> func) {
if (CollUtil.isEmpty(from)) {
return new HashSet<>();
}
return from.stream().flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
}
public static <T, U, R> Set<R> convertSetByFlatMap(Collection<T> from,
Function<? super T, ? extends U> mapper,
Function<U, ? extends Stream<? extends R>> func) {
if (CollUtil.isEmpty(from)) {
return new HashSet<>();
}
return from.stream().map(mapper).flatMap(func).filter(Objects::nonNull).collect(Collectors.toSet());
}
}

View File

@ -3,7 +3,7 @@ package cn.iocoder.yudao.framework.common.util.spring;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
@ -25,7 +25,7 @@ import java.util.Map;
public class SpringExpressionUtils {
/**
* spel表达式解析器
* Spring EL 表达式解析器
*/
private static final ExpressionParser EXPRESSION_PARSER = new SpelExpressionParser();
/**
@ -43,7 +43,7 @@ public class SpringExpressionUtils {
* @param expressionString EL 表达式数组
* @return 执行界面
*/
public static Object parseExpression(ProceedingJoinPoint joinPoint, String expressionString) {
public static Object parseExpression(JoinPoint joinPoint, String expressionString) {
Map<String, Object> result = parseExpressions(joinPoint, Collections.singletonList(expressionString));
return result.get(expressionString);
}
@ -55,7 +55,7 @@ public class SpringExpressionUtils {
* @param expressionStrings EL 表达式数组
* @return 结果key 为表达式value 为对应值
*/
public static Map<String, Object> parseExpressions(ProceedingJoinPoint joinPoint, List<String> expressionStrings) {
public static Map<String, Object> parseExpressions(JoinPoint joinPoint, List<String> expressionStrings) {
// 如果为空则不进行解析
if (CollUtil.isEmpty(expressionStrings)) {
return MapUtil.newHashMap();

View File

@ -1,61 +0,0 @@
package cn.iocoder.yudao.module.crm.enums;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import java.util.Arrays;
// TODO @liuhongfeng这个状态还是搞成专属 CrmReceivableDO 专属的 status
/**
* 流程审批状态枚举类
* 0 未审核 1 审核通过 2 审核拒绝 3 审核中 4 已撤回 TODO @liuhongfeng这一行可以删除因为已经有枚举属性了哈
* @author 赤焰
*/
// TODO @liuhongfeng可以使用 @Getter@AllArgsConstructor 简化 get构造方法
public enum AuditStatusEnum implements IntArrayValuable {
// TODO @liuhongfeng草稿 010 审核中20 审核通过30 审核拒绝40 已撤回主要是留好间隙万一每个地方要做点拓展 然后枚举字段的顺序调整下审批中一定要放两个审批通过拒绝前面哈
/**
* 未审批
*/
AUDIT_NEW(0, "未审批"),
/**
* 审核通过
*/
AUDIT_FINISH(1, "审核通过"),
/**
* 审核拒绝
*/
AUDIT_REJECT(2, "审核拒绝"),
/**
* 审核中
*/
AUDIT_DOING(3, "审核中"),
/**
* 已撤回
*/
AUDIT_RETURN(4, "已撤回");
// TODO liuhongfengvalue 改成 statusdesc 改成 name
private final Integer value;
private final String desc;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(AuditStatusEnum::getValue).toArray();
AuditStatusEnum(Integer value, String desc) {
this.value = value;
this.desc = desc;
}
public Integer getValue() {
return value;
}
public String getDesc() {
return desc;
}
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -11,6 +11,6 @@ public interface DictTypeConstants {
String CRM_CUSTOMER_INDUSTRY = "crm_customer_industry"; // CRM 客户所属行业
String CRM_CUSTOMER_LEVEL = "crm_customer_level"; // CRM 客户等级
String CRM_CUSTOMER_SOURCE = "crm_customer_source"; // CRM 客户来源
String CRM_RECEIVABLE_CHECK_STATUS = "crm_receivable_check_status"; // CRM 审批状态
String CRM_AUDIT_STATUS = "crm_audit_status"; // CRM 审批状态
}

View File

@ -20,8 +20,6 @@ public interface ErrorCodeConstants {
// TODO @lilleo商机状态商机类型都单独错误码段
ErrorCode BUSINESS_STATUS_TYPE_NOT_EXISTS = new ErrorCode(1_020_002_001, "商机状态类型不存在");
ErrorCode BUSINESS_STATUS_NOT_EXISTS = new ErrorCode(1_020_002_002, "商机状态不存在");
// ========== 联系人管理 1-020-003-000 ==========
ErrorCode CONTACT_NOT_EXISTS = new ErrorCode(1_020_003_000, "联系人不存在");
@ -34,18 +32,22 @@ public interface ErrorCodeConstants {
// ========== 客户管理 1_020_006_000 ==========
ErrorCode CUSTOMER_NOT_EXISTS = new ErrorCode(1_020_006_000, "客户不存在");
ErrorCode CUSTOMER_OWNER_EXISTS = new ErrorCode(1_020_006_001, "客户已存在所属负责人");
ErrorCode CUSTOMER_LOCKED = new ErrorCode(1_020_006_002, "客户状态已锁定");
ErrorCode CUSTOMER_OWNER_EXISTS = new ErrorCode(1_020_006_001, "客户【{}】已存在所属负责人");
ErrorCode CUSTOMER_LOCKED = new ErrorCode(1_020_006_002, "客户【{}】状态已锁定");
ErrorCode CUSTOMER_ALREADY_DEAL = new ErrorCode(1_020_006_003, "客户已交易");
// TODO @wanwan 2 个单独配置段噢
ErrorCode CUSTOMER_POOL_CONFIG_ERROR = new ErrorCode(1_020_006_001, "客户公海规则设置不正确");
ErrorCode CUSTOMER_LIMIT_CONFIG_NOT_EXISTS = new ErrorCode(1_020_006_002, "客户限制配置不存在");
ErrorCode CUSTOMER_IN_POOL = new ErrorCode(1_020_006_004, "客户【{}】放入公海失败,原因:已经是公海客户");
ErrorCode CUSTOMER_LOCKED_PUT_POOL_FAIL = new ErrorCode(1_020_006_005, "客户【{}】放入公海失败,原因:客户已锁定");
ErrorCode CUSTOMER_UPDATE_OWNER_USER_FAIL = new ErrorCode(1_020_006_006, "更新客户【{}】负责人失败, 原因:系统异常");
// ========== 权限管理 1_020_007_000 ==========
ErrorCode CRM_PERMISSION_NOT_EXISTS = new ErrorCode(1_020_007_000, "数据权限不存在");
ErrorCode CRM_PERMISSION_DENIED = new ErrorCode(1_020_007_001, "{}操作失败,原因:没有权限");
ErrorCode CRM_PERMISSION_MODEL_NOT_EXISTS = new ErrorCode(1_020_007_002, "{}不存在");
ErrorCode CRM_PERMISSION_MODEL_TRANSFER_FAIL_OWNER_USER_EXISTS = new ErrorCode(1_020_007_003, "{}操作失败,原因:转移对象已经是该负责人");
ErrorCode CRM_PERMISSION_DELETE_FAIL = new ErrorCode(1_020_007_004, "删除数据权限失败,原因:批量删除权限的时候,只能属于同一个 bizId 下");
ErrorCode CRM_PERMISSION_DELETE_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_005, "删除数据权限失败,原因:存在负责人");
ErrorCode CRM_PERMISSION_DELETE_DENIED = new ErrorCode(1_020_007_006, "删除数据权限失败,原因:没有权限");
ErrorCode CRM_PERMISSION_DELETE_SELF_PERMISSION_FAIL_EXIST_OWNER = new ErrorCode(1_020_007_007, "删除数据权限失败,原因:不能删除负责人");
// ========== 产品 1_020_008_000 ==========
ErrorCode PRODUCT_NOT_EXISTS = new ErrorCode(1_020_008_000, "产品不存在");
@ -54,4 +56,14 @@ public interface ErrorCodeConstants {
// ========== 产品分类 1_020_009_000 ==========
ErrorCode PRODUCT_CATEGORY_NOT_EXISTS = new ErrorCode(1_020_009_000, "产品分类不存在");
// ========== 商机状态类型 1_020_010_000 ==========
ErrorCode BUSINESS_STATUS_TYPE_NOT_EXISTS = new ErrorCode(1_020_010_000, "商机状态类型不存在");
ErrorCode BUSINESS_STATUS_TYPE_NAME_EXISTS = new ErrorCode(1_020_010_001, "商机状态类型名称已存在");
// ========== 商机状态 1_020_011_000 ==========
ErrorCode BUSINESS_STATUS_NOT_EXISTS = new ErrorCode(1_020_011_000, "商机状态不存在");
// ========== 客户公海规则设置 1_020_011_000 ==========
ErrorCode CUSTOMER_LIMIT_CONFIG_NOT_EXISTS = new ErrorCode(1_020_012_000, "客户限制配置不存在");
}

View File

@ -1,8 +0,0 @@
package cn.iocoder.yudao.module.crm.enums;
// TODO @liuhongfeng这个的作用是
/**
* @author 赤焰
*/
public enum ReturnTypeEnum {
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.crm.enums.common;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* CRM 的审批状态
*
* @author 赤焰
*/
@RequiredArgsConstructor
@Getter
public enum CrmAuditStatusEnum implements IntArrayValuable {
DRAFT(0, "未提交"),
PROCESS(10, "审批中"),
APPROVE(20, "审核通过"),
REJECT(30, "审核不通过"),
CANCEL(40, "已取消");
private final Integer status;
private final String name;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmAuditStatusEnum::getStatus).toArray();
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.framework.enums;
package cn.iocoder.yudao.module.crm.enums.common;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
@ -9,7 +9,7 @@ import lombok.RequiredArgsConstructor;
import java.util.Arrays;
/**
* Crm 类型枚举
* CRM 业务类型枚举
*
* @author HUIHUI
*/
@ -17,15 +17,14 @@ import java.util.Arrays;
@Getter
public enum CrmBizTypeEnum implements IntArrayValuable {
// TODO @puhui999如果类似 CrmBizPermission bizType 需要为空可以设置它是数组参考 Telephone payload
CRM_PERMISSION(0, "团队"), // CrmPermissionController 中使用
CRM_LEADS(1, "线索"),
CRM_CUSTOMER(2, "客户"),
CRM_CONTACTS(3, "联系人"),
CRM_BUSINESS(5, "商机"),
CRM_CONTRACT(6, "合同");
CRM_CONTACT(3, "联系人"),
CRM_BUSINESS(4, "商机"),
CRM_CONTRACT(5, "合同");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmBizTypeEnum::getType).toArray();
/**
* 类型
*/

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.enums.customer;
package cn.iocoder.yudao.module.crm.enums.common;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
@ -7,20 +7,19 @@ import lombok.Getter;
import java.util.Arrays;
// TODO @puhui999这个应该是 crm 全局的不仅仅属于 customer 客户哈
/**
* CRM 客户等级
* CRM 列表检索场景
*
* @author Wanwan
* @author HUIHUI
*/
@Getter
@AllArgsConstructor
public enum CrmCustomerSceneEnum implements IntArrayValuable {
public enum CrmSceneEnum implements IntArrayValuable {
OWNER(1, "我负责的客户"),
FOLLOW(2, "我关注的客户");
OWNER(1, "我负责的"),
FOLLOW(2, "我关注的");
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerSceneEnum::getType).toArray();
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmSceneEnum::getType).toArray();
/**
* 场景类型

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.crm.enums.customer;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
import lombok.AllArgsConstructor;
import lombok.Getter;
import java.util.Arrays;
/**
* CRM 客户限制配置规则类型
*
* @author Wanwan
*/
@Getter
@AllArgsConstructor
public enum CrmCustomerLimitConfigTypeEnum implements IntArrayValuable {
/**
* 拥有客户数限制
*/
CUSTOMER_QUANTITY_LIMIT(1, "拥有客户数限制"),
/**
* 锁定客户数限制
*/
CUSTOMER_LOCK_LIMIT(2, "锁定客户数限制"),
;
public static final int[] ARRAYS = Arrays.stream(values()).mapToInt(CrmCustomerLimitConfigTypeEnum::getCode).toArray();
/**
* 状态
*/
private final Integer code;
/**
* 状态名
*/
private final String name;
@Override
public int[] array() {
return ARRAYS;
}
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.framework.enums;
package cn.iocoder.yudao.module.crm.enums.permission;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.core.IntArrayValuable;
@ -8,7 +8,7 @@ import lombok.Getter;
import java.util.Arrays;
/**
* Crm 数据权限级别枚举
* CRM 数据权限级别枚举
*
* @author HUIHUI
*/

View File

@ -1,14 +1,24 @@
package cn.iocoder.yudao.module.crm.controller.admin.business;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.CrmContractPageReqVO;
import cn.iocoder.yudao.module.crm.convert.business.CrmBusinessConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessService;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusTypeService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -21,6 +31,9 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@ -35,6 +48,15 @@ public class CrmBusinessController {
@Resource
private CrmBusinessService businessService;
@Resource
private CrmCustomerService customerService;
@Resource
private CrmBusinessStatusTypeService businessStatusTypeService;
@Resource
private CrmBusinessStatusService businessStatusService;
@PostMapping("/create")
@Operation(summary = "创建商机")
@PreAuthorize("@ss.hasPermission('crm:business:create')")
@ -73,27 +95,72 @@ public class CrmBusinessController {
@PreAuthorize("@ss.hasPermission('crm:business:query')")
public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPage(@Valid CrmBusinessPageReqVO pageVO) {
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(pageVO, getLoginUserId());
return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult));
if (CollUtil.isEmpty(pageResult.getList())) {
return success(PageResult.empty(pageResult.getTotal()));
}
// 处理客户名称回显
// TODO @ljlleo可以使用 CollectionUtils.convertSet 替代常用的 stream 操作更简洁一点下面几个也是哈
Set<Long> customerIds = pageResult.getList().stream()
.map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet());
List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds);
// 处理商机状态类型名称回显
Set<Long> statusTypeIds = pageResult.getList().stream()
.map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());
CrmBusinessStatusTypeQueryVO queryStatusTypeVO = new CrmBusinessStatusTypeQueryVO();
queryStatusTypeVO.setIdList(statusTypeIds);
List<CrmBusinessStatusTypeDO> statusTypeList = businessStatusTypeService.selectList(queryStatusTypeVO);
// 处理商机状态名称回显
Set<Long> statusIds = pageResult.getList().stream()
.map(CrmBusinessDO::getStatusId).filter(Objects::nonNull).collect(Collectors.toSet());
CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO();
queryVO.setIdList(statusIds);
List<CrmBusinessStatusDO> statusList = businessStatusService.selectList(queryVO);
return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList));
}
@GetMapping("/page-by-customer")
@Operation(summary = "获得商机分页,基于指定客户")
public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPageByCustomer(@Valid CrmContractPageReqVO pageReqVO) {
Assert.notNull(pageReqVO.getCustomerId(), "客户编号不能为空");
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPageByCustomer(pageReqVO);
// 处理客户名称回显
// TODO @ljlleo可以使用 CollectionUtils.convertSet 替代常用的 stream 操作更简洁一点下面几个也是哈
Set<Long> customerIds = pageResult.getList().stream()
.map(CrmBusinessDO::getCustomerId).filter(Objects::nonNull).collect(Collectors.toSet());
List<CrmCustomerDO> customerList = customerService.getCustomerList(customerIds);
// 处理商机状态类型名称回显
Set<Long> statusTypeIds = pageResult.getList().stream()
.map(CrmBusinessDO::getStatusTypeId).filter(Objects::nonNull).collect(Collectors.toSet());
CrmBusinessStatusTypeQueryVO queryStatusTypeVO = new CrmBusinessStatusTypeQueryVO();
queryStatusTypeVO.setIdList(statusTypeIds);
List<CrmBusinessStatusTypeDO> statusTypeList = businessStatusTypeService.selectList(queryStatusTypeVO);
// 处理商机状态名称回显
Set<Long> statusIds = pageResult.getList().stream()
.map(CrmBusinessDO::getStatusId).filter(Objects::nonNull).collect(Collectors.toSet());
CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO();
queryVO.setIdList(statusIds);
List<CrmBusinessStatusDO> statusList = businessStatusService.selectList(queryVO);
return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult, customerList, statusTypeList, statusList));
}
@GetMapping("/pool-page")
@Operation(summary = "获得商机公海分页")
@PreAuthorize("@ss.hasPermission('crm:business:query')")
public CommonResult<PageResult<CrmBusinessRespVO>> getBusinessPoolPage(@Valid CrmBusinessPageReqVO pageVO) {
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(pageVO, CrmPermissionDO.POOL_USER_ID);
return success(CrmBusinessConvert.INSTANCE.convertPage(pageResult));
// TODO puhui999: 等数据权限完善后再实现
return null;
}
@GetMapping("/export-excel")
@Operation(summary = "导出商机 Excel")
@PreAuthorize("@ss.hasPermission('crm:business:export')")
@OperateLog(type = EXPORT)
public void exportBusinessExcel(@Valid CrmBusinessExportReqVO exportReqVO,
public void exportBusinessExcel(@Valid CrmBusinessPageReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<CrmBusinessDO> list = businessService.getBusinessList(exportReqVO);
PageResult<CrmBusinessDO> pageResult = businessService.getBusinessPage(exportReqVO, getLoginUserId());
// 导出 Excel
List<CrmBusinessExcelVO> datas = CrmBusinessConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessExcelVO.class, datas);
ExcelUtils.write(response, "商机.xls", "数据", CrmBusinessExcelVO.class,
CrmBusinessConvert.INSTANCE.convertList02(pageResult.getList()));
}
@PutMapping("/transfer")

View File

@ -1,14 +1,26 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype;
package cn.iocoder.yudao.module.crm.controller.admin.business;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo.*;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusQueryVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypePageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeQueryVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO;
import cn.iocoder.yudao.module.crm.convert.businessstatus.CrmBusinessStatusConvert;
import cn.iocoder.yudao.module.crm.convert.businessstatustype.CrmBusinessStatusTypeConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.businessstatustype.CrmBusinessStatusTypeDO;
import cn.iocoder.yudao.module.crm.service.businessstatustype.CrmBusinessStatusTypeService;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusService;
import cn.iocoder.yudao.module.crm.service.business.CrmBusinessStatusTypeService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -22,11 +34,13 @@ import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
// TODO @lilleo这个模块可以挪到 business 这样我打开 business 包下就知道~原来里面有 business 商机 type 状态类型status 具体状态
@Tag(name = "管理后台 - 商机状态类型")
@RestController
@RequestMapping("/crm/business-status-type")
@ -36,17 +50,23 @@ public class CrmBusinessStatusTypeController {
@Resource
private CrmBusinessStatusTypeService businessStatusTypeService;
@Resource
private CrmBusinessStatusService businessStatusService;
@Resource
private DeptApi deptApi;
@PostMapping("/create")
@Operation(summary = "创建商机状态类型")
@PreAuthorize("@ss.hasPermission('crm:business-status-type:create')")
public CommonResult<Long> createBusinessStatusType(@Valid @RequestBody CrmBusinessStatusTypeCreateReqVO createReqVO) {
public CommonResult<Long> createBusinessStatusType(@Valid @RequestBody CrmBusinessStatusTypeSaveReqVO createReqVO) {
return success(businessStatusTypeService.createBusinessStatusType(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新商机状态类型")
@PreAuthorize("@ss.hasPermission('crm:business-status-type:update')")
public CommonResult<Boolean> updateBusinessStatusType(@Valid @RequestBody CrmBusinessStatusTypeUpdateReqVO updateReqVO) {
public CommonResult<Boolean> updateBusinessStatusType(@Valid @RequestBody CrmBusinessStatusTypeSaveReqVO updateReqVO) {
businessStatusTypeService.updateBusinessStatusType(updateReqVO);
return success(true);
}
@ -66,45 +86,62 @@ public class CrmBusinessStatusTypeController {
@PreAuthorize("@ss.hasPermission('crm:business-status-type:query')")
public CommonResult<CrmBusinessStatusTypeRespVO> getBusinessStatusType(@RequestParam("id") Long id) {
CrmBusinessStatusTypeDO businessStatusType = businessStatusTypeService.getBusinessStatusType(id);
return success(CrmBusinessStatusTypeConvert.INSTANCE.convert(businessStatusType));
}
// TODO @lilleo这个接口暂时用不到可以考虑先删除掉
@GetMapping("/list")
@Operation(summary = "获得商机状态类型列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('crm:business-status-type:query')")
public CommonResult<List<CrmBusinessStatusTypeRespVO>> getBusinessStatusTypeList(@RequestParam("ids") Collection<Long> ids) {
List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.getBusinessStatusTypeList(ids);
return success(CrmBusinessStatusTypeConvert.INSTANCE.convertList(list));
// 处理状态回显
// TODO @ljlleo可以使用 CollectionUtils.convertSet 替代常用的 stream 操作更简洁一点下面几个也是哈
CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO();
queryVO.setTypeId(id);
List<CrmBusinessStatusDO> statusList = businessStatusService.selectList(queryVO);
return success(CrmBusinessStatusTypeConvert.INSTANCE.convert(businessStatusType, statusList));
}
@GetMapping("/page")
@Operation(summary = "获得商机状态类型分页")
@PreAuthorize("@ss.hasPermission('crm:business-status-type:query')")
public CommonResult<PageResult<CrmBusinessStatusTypeRespVO>> getBusinessStatusTypePage(@Valid CrmBusinessStatusTypePageReqVO pageVO) {
PageResult<CrmBusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageVO);
return success(CrmBusinessStatusTypeConvert.INSTANCE.convertPage(pageResult));
public CommonResult<PageResult<CrmBusinessStatusTypeRespVO>> getBusinessStatusTypePage(@Valid CrmBusinessStatusTypePageReqVO pageReqVO) {
PageResult<CrmBusinessStatusTypeDO> pageResult = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO);
// 处理部门回显
// TODO @ljlleo可以使用 CollectionUtils.convertSet 替代常用的 stream 操作更简洁一点下面几个也是哈
Set<Long> deptIds = pageResult.getList().stream()
.map(CrmBusinessStatusTypeDO::getDeptIds)
.filter(Objects::nonNull)
.flatMap(Collection::stream)
.collect(Collectors.toSet());
List<DeptRespDTO> deptList = deptApi.getDeptList(deptIds);
return success(CrmBusinessStatusTypeConvert.INSTANCE.convertPage(pageResult, deptList));
}
@GetMapping("/export-excel")
@Operation(summary = "导出商机状态类型 Excel")
@PreAuthorize("@ss.hasPermission('crm:business-status-type:export')")
@OperateLog(type = EXPORT)
public void exportBusinessStatusTypeExcel(@Valid CrmBusinessStatusTypeExportReqVO exportReqVO,
public void exportBusinessStatusTypeExcel(@Valid CrmBusinessStatusTypePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.getBusinessStatusTypeList(exportReqVO);
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.getBusinessStatusTypePage(pageReqVO).getList();
// 导出 Excel
List<CrmBusinessStatusTypeExcelVO> datas = CrmBusinessStatusTypeConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "商机状态类型.xls", "数据", CrmBusinessStatusTypeExcelVO.class, datas);
ExcelUtils.write(response, "商机状态类型.xls", "数据", CrmBusinessStatusTypeRespVO.class,
BeanUtils.toBean(list, CrmBusinessStatusTypeRespVO.class));
}
@GetMapping("/get-simple-list")
@Operation(summary = "获得商机状态类型列表")
@PreAuthorize("@ss.hasPermission('crm:business-status-type:query')")
public CommonResult<List<CrmBusinessStatusTypeRespVO>> getBusinessStatusTypeList() {
List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.getBusinessStatusTypeListByStatus(CommonStatusEnum.ENABLE.getStatus());
return success(CrmBusinessStatusTypeConvert.INSTANCE.convertList(list));
CrmBusinessStatusTypeQueryVO queryVO = new CrmBusinessStatusTypeQueryVO();
queryVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
List<CrmBusinessStatusTypeDO> list = businessStatusTypeService.selectList(queryVO);
return success(BeanUtils.toBean(list, CrmBusinessStatusTypeRespVO.class));
}
// TODO @ljlleo 这个接口是不是可以和 getBusinessStatusTypeList 合并成一个
@GetMapping("/get-status-list")
@Operation(summary = "获得商机状态列表")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<List<CrmBusinessStatusRespVO>> getBusinessStatusListByTypeId(@RequestParam("typeId") Long typeId) {
CrmBusinessStatusQueryVO queryVO = new CrmBusinessStatusQueryVO();
queryVO.setTypeId(typeId);
List<CrmBusinessStatusDO> list = businessStatusService.selectList(queryVO);
return success(CrmBusinessStatusConvert.INSTANCE.convertList(list));
}
}

View File

@ -1,4 +0,0 @@
/**
* 商机销售机会
*/
package cn.iocoder.yudao.module.crm.controller.admin.business;

View File

@ -1,74 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 商机 Excel 导出 Request VO参数和 CrmBusinessPageReqVO 是一致的")
@Data
public class CrmBusinessExportReqVO {
@Schema(description = "商机名称", example = "李四")
private String name;
@Schema(description = "商机状态类型编号", example = "25714")
private Long statusTypeId;
@Schema(description = "商机状态编号", example = "30320")
private Long statusId;
@Schema(description = "下次联系时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] contactNextTime;
@Schema(description = "客户编号", example = "10299")
private Long customerId;
@Schema(description = "预计成交日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] dealTime;
@Schema(description = "商机金额", example = "12371")
private BigDecimal price;
@Schema(description = "整单折扣")
private BigDecimal discountPercent;
@Schema(description = "产品总金额", example = "12025")
private BigDecimal productPrice;
@Schema(description = "备注", example = "随便")
private String remark;
@Schema(description = "负责人的用户编号", example = "25562")
private Long ownerUserId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "只读权限的用户编号数组")
private String roUserIds;
@Schema(description = "读写权限的用户编号数组")
private String rwUserIds;
@Schema(description = "1赢单2输单3无效", example = "1")
private Integer endStatus;
@Schema(description = "结束时的备注", example = "你说的对")
private String endRemark;
@Schema(description = "最后跟进时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] contactLastTime;
@Schema(description = "跟进状态", example = "1")
private Integer followUpStatus;
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
@ -15,4 +15,7 @@ public class CrmBusinessPageReqVO extends PageParam {
@Schema(description = "商机名称", example = "李四")
private String name;
@Schema(description = "客户编号", example = "10795")
private Long customerId;
}

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@ -16,4 +16,13 @@ public class CrmBusinessRespVO extends CrmBusinessBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
private String customerName;
@Schema(description = "状态类型名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "进行中")
private String statusTypeName;
@Schema(description = "状态名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "跟进中")
private String statusName;
}

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.business;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.CrmBusinessBaseVO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
@ -12,7 +12,4 @@ import lombok.ToString;
@ToString(callSuper = true)
public class CrmBusinessStatusPageReqVO extends PageParam {
@Schema(description = "状态类型编号", example = "22882")
private Long typeId;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import java.util.Collection;
@Schema(description = "管理后台 - 商机状态 Query VO")
@Data
@ToString(callSuper = true)
public class CrmBusinessStatusQueryVO {
@Schema(description = "主键集合")
private Collection<Long> idList;
@Schema(description = "状态类型编号")
private Long typeId;
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(description = "管理后台 - 商机状态 Response VO")
@Data
@ExcelIgnoreUnannotated
public class CrmBusinessStatusRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "23899")
@ExcelProperty("主键")
private Long id;
@Schema(description = "状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7139")
@ExcelProperty("状态类型编号")
private Long typeId;
@Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@ExcelProperty("状态名")
private String name;
@Schema(description = "赢单率")
@ExcelProperty("赢单率")
private String percent;
@Schema(description = "排序", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@ExcelProperty("排序")
private Integer sort;
}

View File

@ -1,25 +1,24 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.status;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
/**
* 商机状态 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Schema(description = "管理后台 - 商机状态新增/修改 Request VO")
@Data
public class CrmBusinessStatusBaseVO {
public class CrmBusinessStatusSaveReqVO {
// TODO @lilleoexample 要写下
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "23899")
private Long id;
@Schema(description = "状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "22882")
@Schema(description = "状态类型编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "7139")
@NotNull(message = "状态类型编号不能为空")
private Long typeId;
@Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@NotNull(message = "状态名不能为空")
@Schema(description = "状态名", requiredMode = Schema.RequiredMode.REQUIRED, example = "王五")
@NotEmpty(message = "状态名不能为空")
private String name;
// TODO @lilleopercent 应该是 Integer

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo;
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
@ -12,10 +12,4 @@ import lombok.ToString;
@ToString(callSuper = true)
public class CrmBusinessStatusTypePageReqVO extends PageParam {
@Schema(description = "状态类型名", example = "芋艿")
private String name;
@Schema(description = "开启状态", example = "1")
private Boolean status;
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import java.util.Collection;
@Schema(description = "管理后台 - 商机状态类型 Query VO")
@Data
@ToString(callSuper = true)
public class CrmBusinessStatusTypeQueryVO {
@Schema(description = "主键集合")
private Collection<Long> idList;
@Schema(description = "状态")
private Integer status;
}

View File

@ -0,0 +1,44 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Schema(description = "管理后台 - 商机状态类型 Response VO")
@Data
@ExcelIgnoreUnannotated
public class CrmBusinessStatusTypeRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934")
@ExcelProperty("主键")
private Long id;
@Schema(description = "状态类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@ExcelProperty("状态类型名")
private String name;
@Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("使用的部门编号")
private List<Long> deptIds;
@Schema(description = "使用的部门名称", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("使用的部门名称")
private List<String> deptNames;
@Schema(description = "创建人", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建人")
private String creator;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
// TODO @ljlleo 字段后缀改成 statuses保持和 deptIds 风格一致CrmBusinessStatusDO 改成 VO 一般不使用 do 直接返回
@Schema(description = "状态集合", requiredMode = Schema.RequiredMode.REQUIRED)
private List<CrmBusinessStatusDO> statusList;
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.crm.controller.admin.business.vo.type;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO;
import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotEmpty;
import java.util.List;
@Schema(description = "管理后台 - 商机状态类型新增/修改 Request VO")
@Data
public class CrmBusinessStatusTypeSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2934")
private Long id;
@Schema(description = "状态类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "李四")
@NotEmpty(message = "状态类型名不能为空")
private String name;
@Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED)
private List<Long> deptIds = Lists.newArrayList();
// TODO @ljlleo VO 里面我们不使用默认值哈这里 Lists.newArrayList() 看看怎么去掉上面 deptIds 也是类似噢
@Schema(description = "商机状态集合", requiredMode = Schema.RequiredMode.REQUIRED)
private List<CrmBusinessStatusSaveReqVO> statusList = Lists.newArrayList();
}

View File

@ -1,119 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo.*;
import cn.iocoder.yudao.module.crm.convert.businessstatus.CrmBusinessStatusConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.businessstatus.CrmBusinessStatusDO;
import cn.iocoder.yudao.module.crm.service.businessstatus.CrmBusinessStatusService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
// TODO @lilleo这个模块可以挪到 business 这样我打开 business 包下就知道~原来里面有 business 商机 type 状态类型status 具体状态
@Tag(name = "管理后台 - 商机状态")
@RestController
@RequestMapping("/crm/business-status")
@Validated
public class CrmBusinessStatusController {
@Resource
private CrmBusinessStatusService businessStatusService;
@PostMapping("/create")
@Operation(summary = "创建商机状态")
@PreAuthorize("@ss.hasPermission('crm:business-status:create')")
public CommonResult<Long> createBusinessStatus(@Valid @RequestBody CrmBusinessStatusCreateReqVO createReqVO) {
return success(businessStatusService.createBusinessStatus(createReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新商机状态")
@PreAuthorize("@ss.hasPermission('crm:business-status:update')")
public CommonResult<Boolean> updateBusinessStatus(@Valid @RequestBody CrmBusinessStatusUpdateReqVO updateReqVO) {
businessStatusService.updateBusinessStatus(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除商机状态")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('crm:business-status:delete')")
public CommonResult<Boolean> deleteBusinessStatus(@RequestParam("id") Long id) {
businessStatusService.deleteBusinessStatus(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得商机状态")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<CrmBusinessStatusRespVO> getBusinessStatus(@RequestParam("id") Long id) {
CrmBusinessStatusDO businessStatus = businessStatusService.getBusinessStatus(id);
return success(CrmBusinessStatusConvert.INSTANCE.convert(businessStatus));
}
// TODO @lilleo这个接口暂时用不到可以考虑先删除掉
@GetMapping("/list")
@Operation(summary = "获得商机状态列表")
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<List<CrmBusinessStatusRespVO>> getBusinessStatusList(@RequestParam("ids") Collection<Long> ids) {
List<CrmBusinessStatusDO> list = businessStatusService.getBusinessStatusList(ids);
return success(CrmBusinessStatusConvert.INSTANCE.convertList(list));
}
@GetMapping("/page")
@Operation(summary = "获得商机状态分页")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<PageResult<CrmBusinessStatusRespVO>> getBusinessStatusPage(@Valid CrmBusinessStatusPageReqVO pageVO) {
PageResult<CrmBusinessStatusDO> pageResult = businessStatusService.getBusinessStatusPage(pageVO);
return success(CrmBusinessStatusConvert.INSTANCE.convertPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出商机状态 Excel")
@PreAuthorize("@ss.hasPermission('crm:business-status:export')")
@OperateLog(type = EXPORT)
public void exportBusinessStatusExcel(@Valid CrmBusinessStatusExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<CrmBusinessStatusDO> list = businessStatusService.getBusinessStatusList(exportReqVO);
// 导出 Excel
List<CrmBusinessStatusExcelVO> datas = CrmBusinessStatusConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "商机状态.xls", "数据", CrmBusinessStatusExcelVO.class, datas);
}
// TODO 芋艿后续再看看
@GetMapping("/get-simple-list")
@Operation(summary = "获得商机状态列表")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<List<CrmBusinessStatusRespVO>> getBusinessStatusListByTypeId(@RequestParam("typeId") Integer typeId) {
List<CrmBusinessStatusDO> list = businessStatusService.getBusinessStatusListByTypeId(typeId);
return success(CrmBusinessStatusConvert.INSTANCE.convertList(list));
}
// TODO 芋艿后续再看看
@GetMapping("/get-all-list")
@Operation(summary = "获得商机状态列表")
@PreAuthorize("@ss.hasPermission('crm:business-status:query')")
public CommonResult<List<CrmBusinessStatusRespVO>> getBusinessStatusList() {
List<CrmBusinessStatusDO> list = businessStatusService.getBusinessStatusList();
return success(CrmBusinessStatusConvert.INSTANCE.convertList(list));
}
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import javax.validation.constraints.*;
@Schema(description = "管理后台 - 商机状态创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmBusinessStatusCreateReqVO extends CrmBusinessStatusBaseVO {
}

View File

@ -1,30 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
// TODO @lilleo这个暂时不需要嘿嘿~不是每个模块都需要导出哈
/**
* 商机状态 Excel VO
*
* @author ljlleo
*/
@Data
public class CrmBusinessStatusExcelVO {
@ExcelProperty("主键")
private Long id;
@ExcelProperty("状态类型编号")
private Long typeId;
@ExcelProperty("状态名")
private String name;
@ExcelProperty("赢单率")
private String percent;
@ExcelProperty("排序")
private Integer sort;
}

View File

@ -1,23 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
// TODO @lilleo这个暂时不需要嘿嘿~不是每个模块都需要导出哈
@Schema(description = "管理后台 - 商机状态 Excel 导出 Request VO参数和 CrmBusinessStatusPageReqVO 是一致的")
@Data
public class CrmBusinessStatusExportReqVO {
@Schema(description = "状态类型编号", example = "22882")
private Long typeId;
@Schema(description = "状态名", example = "李四")
private String name;
@Schema(description = "赢单率")
private String percent;
@Schema(description = "排序")
private Integer sort;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
@Schema(description = "管理后台 - 商机状态 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmBusinessStatusRespVO extends CrmBusinessStatusBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6802")
private Long id;
}

View File

@ -1,20 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - 商机状态更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmBusinessStatusUpdateReqVO extends CrmBusinessStatusBaseVO {
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "6802")
@NotNull(message = "编号不能为空")
private Long id;
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 商机状态类型 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class CrmBusinessStatusTypeBaseVO {
@Schema(description = "状态类型名", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋艿")
@NotNull(message = "状态类型名不能为空")
private String name;
@Schema(description = "使用的部门编号", requiredMode = Schema.RequiredMode.REQUIRED)
@NotNull(message = "使用的部门编号不能为空")
private String deptIds;
@Schema(description = "开启状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
@NotNull(message = "开启状态不能为空")
private Boolean status;
}

View File

@ -1,15 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
// TODO 状态类型和状态添加是在一个请求里所以需要把 CrmBusinessStatusCreateReqVO 融合进来
@Schema(description = "管理后台 - 商机状态类型创建 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmBusinessStatusTypeCreateReqVO extends CrmBusinessStatusTypeBaseVO {
}

View File

@ -1,32 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.time.LocalDateTime;
// TODO @lilleo这个暂时不需要嘿嘿~不是每个模块都需要导出哈
/**
* 商机状态类型 Excel VO
*
* @author ljlleo
*/
@Data
public class CrmBusinessStatusTypeExcelVO {
@ExcelProperty("主键")
private Long id;
@ExcelProperty("状态类型名")
private String name;
@ExcelProperty("使用的部门编号")
private String deptIds;
@ExcelProperty("开启状态")
private Boolean status;
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -1,29 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
// TODO @lilleo这个暂时不需要嘿嘿~不是每个模块都需要导出哈
@Schema(description = "管理后台 - 商机状态类型 Excel 导出 Request VO参数和 CrmBusinessStatusTypePageReqVO 是一致的")
@Data
public class CrmBusinessStatusTypeExportReqVO {
@Schema(description = "状态类型名", example = "芋艿")
private String name;
@Schema(description = "使用的部门编号")
private String deptIds;
@Schema(description = "开启状态", example = "1")
private Boolean status;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -1,19 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 商机状态类型 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmBusinessStatusTypeRespVO extends CrmBusinessStatusTypeBaseVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "24019")
private Long id;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
}

View File

@ -1,21 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
// TODO 状态类型和状态添加是在一个请求里所以需要把 CrmBusinessStatusUpdateReqVO 融合进来
@Schema(description = "管理后台 - 商机状态类型更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmBusinessStatusTypeUpdateReqVO extends CrmBusinessStatusTypeBaseVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "24019")
@NotNull(message = "主键不能为空")
private Long id;
}

View File

@ -1,135 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerExportReqVO;
import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.service.contact.ContactService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
// TODO @zyacrm 所有的类dou带 Crm 前缀因为它的名字太通用了可能和后续的 erp 之类的冲突
@Tag(name = "管理后台 - CRM 联系人")
@RestController
@RequestMapping("/crm/contact")
@Validated
public class ContactController {
@Resource
private ContactService contactService;
// TODO @zyna模块内注入的变量不用带 crm 前缀哈
@Resource
private CrmCustomerService crmCustomerService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建联系人")
@PreAuthorize("@ss.hasPermission('crm:contact:create')")
public CommonResult<Long> createContact(@Valid @RequestBody ContactCreateReqVO createReqVO) {
return success(contactService.createContact(createReqVO, getLoginUserId()));
}
@PutMapping("/update")
@Operation(summary = "更新联系人")
@PreAuthorize("@ss.hasPermission('crm:contact:update')")
public CommonResult<Boolean> updateContact(@Valid @RequestBody ContactUpdateReqVO updateReqVO) {
contactService.updateContact(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除联系人")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('crm:contact:delete')")
public CommonResult<Boolean> deleteContact(@RequestParam("id") Long id) {
contactService.deleteContact(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得联系人")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
public CommonResult<ContactRespVO> getContact(@RequestParam("id") Long id) {
ContactDO contact = contactService.getContact(id);
// TODO @zyna需要考虑 null 的情况
ContactRespVO contactRespVO = ContactConvert.INSTANCE.convert(contact);
// TODO @zyna可以把数据读完后convert 统一交给 ContactConvert controller 更简洁 convert 专门去做一些转换逻辑
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList(
NumberUtil.parseLong(contact.getCreator()))));
contactRespVO.setCreatorName(Optional.ofNullable(userMap.get(NumberUtil.parseLong(contact.getCreator()))).map(AdminUserRespDTO::getNickname).orElse(null));
contactRespVO.setCustomerName(Optional.ofNullable(crmCustomerService.getCustomer(contact.getCustomerId())).map(CrmCustomerDO::getName).orElse(null));
return success(contactRespVO);
}
// TODO @zynaurl 使用中划线噢然后单词的拼写也要注意呀AllList 是不是更好呀
@GetMapping("/simpleAlllist")
@Operation(summary = "获得联系人列表")
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
public CommonResult<List<ContactSimpleRespVO>> simpleAlllist() {
// TODO @zyna方法名改成getContactList方法命名要动名词get 动词all 可以去掉因为没条件自然是全部
List<ContactDO> list = contactService.allContactList();
return success(ContactConvert.INSTANCE.convertAllList(list));
}
@GetMapping("/page")
@Operation(summary = "获得联系人分页")
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
public CommonResult<PageResult<ContactRespVO>> getContactPage(@Valid ContactPageReqVO pageVO) {
PageResult<ContactDO> pageData = contactService.getContactPage(pageVO);
PageResult<ContactRespVO> pageResult =ContactConvert.INSTANCE.convertPage(pageData);
// TODO @zyna需要考虑 null 的情况
// TODO @zyna可以把数据读完后convert 统一交给 ContactConvert controller 更简洁 convert 专门去做一些转换逻辑
//待接口实现后修改
List<CrmCustomerDO> crmCustomerDOList = crmCustomerService.getCustomerList(new CrmCustomerExportReqVO());
Map<Long,CrmCustomerDO> crmCustomerDOMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId,v->v));
pageResult.getList().forEach(item -> {
item.setCustomerName(Optional.ofNullable(crmCustomerDOMap.get(item.getCustomerId())).map(CrmCustomerDO::getName).orElse(null));
});
return success(pageResult);
}
// TODO @zyna可以看下新的导出写法这里调整下
@GetMapping("/export-excel")
@Operation(summary = "导出联系人 Excel")
@PreAuthorize("@ss.hasPermission('crm:contact:export')")
@OperateLog(type = EXPORT)
public void exportContactExcel(@Valid ContactExportReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<ContactDO> list = contactService.getContactList(exportReqVO);
// 导出 Excel
List<ContactExcelVO> datas = ContactConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "crm联系人.xls", "数据", ContactExcelVO.class, datas);
}
}

View File

@ -0,0 +1,163 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
import cn.iocoder.yudao.module.crm.convert.contact.ContactConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.crm.service.contact.CrmContactService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
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.convertListByFlatMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "管理后台 - CRM 联系人")
@RestController
@RequestMapping("/crm/contact")
@Validated
@Slf4j
public class CrmContactController {
@Resource
private CrmContactService contactService;
@Resource
private CrmCustomerService customerService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建联系人")
@PreAuthorize("@ss.hasPermission('crm:contact:create')")
public CommonResult<Long> createContact(@Valid @RequestBody CrmContactCreateReqVO createReqVO) {
return success(contactService.createContact(createReqVO, getLoginUserId()));
}
@PutMapping("/update")
@Operation(summary = "更新联系人")
@PreAuthorize("@ss.hasPermission('crm:contact:update')")
public CommonResult<Boolean> updateContact(@Valid @RequestBody CrmContactUpdateReqVO updateReqVO) {
contactService.updateContact(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除联系人")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('crm:contact:delete')")
public CommonResult<Boolean> deleteContact(@RequestParam("id") Long id) {
contactService.deleteContact(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得联系人")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
public CommonResult<CrmContactRespVO> getContact(@RequestParam("id") Long id) {
CrmContactDO contact = contactService.getContact(id);
if (contact == null) {
throw exception(ErrorCodeConstants.CONTACT_NOT_EXISTS);
}
// 1. 获取用户名
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(CollUtil.removeNull(Lists.newArrayList(
NumberUtil.parseLong(contact.getCreator()), contact.getOwnerUserId())));
// 2. 获取客户信息
List<CrmCustomerDO> customerList = customerService.getCustomerList(Collections.singletonList(contact.getCustomerId()));
// 3. 直属上级
List<CrmContactDO> parentContactList = contactService.getContactList(Collections.singletonList(contact.getParentId()));
return success(ContactConvert.INSTANCE.convert(contact, userMap, customerList, parentContactList));
}
@GetMapping("/simple-all-list")
@Operation(summary = "获得联系人列表")
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
public CommonResult<List<CrmContactSimpleRespVO>> getSimpleContactList() {
List<CrmContactDO> list = contactService.getContactList();
return success(ContactConvert.INSTANCE.convertAllList(list));
}
@GetMapping("/page")
@Operation(summary = "获得联系人分页")
@PreAuthorize("@ss.hasPermission('crm:contact:query')")
public CommonResult<PageResult<CrmContactRespVO>> getContactPage(@Valid CrmContactPageReqVO pageVO) {
PageResult<CrmContactDO> pageResult = contactService.getContactPage(pageVO);
return success(convertDetailContactPage(pageResult));
}
@GetMapping("/page-by-customer")
@Operation(summary = "获得联系人分页,基于指定客户")
public CommonResult<PageResult<CrmContactRespVO>> getContactPageByCustomer(@Valid CrmContactPageReqVO pageVO) {
Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
PageResult<CrmContactDO> pageResult = contactService.getContactPageByCustomer(pageVO);
return success(convertDetailContactPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出联系人 Excel")
@PreAuthorize("@ss.hasPermission('crm:contact:export')")
@OperateLog(type = EXPORT)
public void exportContactExcel(@Valid CrmContactPageReqVO exportReqVO,
HttpServletResponse response) throws IOException {
exportReqVO.setPageNo(PageParam.PAGE_SIZE_NONE);
PageResult<CrmContactDO> pageResult = contactService.getContactPage(exportReqVO);
ExcelUtils.write(response, "联系人.xls", "数据", CrmContactRespVO.class,
convertDetailContactPage(pageResult).getList());
}
/**
* 转换成详细的联系人分页即读取关联信息
*
* @param pageResult 联系人分页
* @return 详细的联系人分页
*/
private PageResult<CrmContactRespVO> convertDetailContactPage(PageResult<CrmContactDO> pageResult) {
List<CrmContactDO> contactList = pageResult.getList();
if (CollUtil.isEmpty(contactList)) {
return PageResult.empty(pageResult.getTotal());
}
// 1. 获取客户列表
List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList(
convertSet(contactList, CrmContactDO::getCustomerId));
// 2. 获取创建人负责人列表
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
// 3. 直属上级
List<CrmContactDO> parentContactList = contactService.getContactList(
convertSet(contactList, CrmContactDO::getParentId));
return ContactConvert.INSTANCE.convertPage(pageResult, userMap, crmCustomerDOList, parentContactList);
}
}

View File

@ -1,73 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
// TODO zyna参考新的 vo重新拆分下 VO
/**
* CRM 联系人 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ContactBaseVO {
// TODO @zynaexample 最好都写下
// TODO @zyna必要的字段校验例如说 @Mobile@Emal 等等
@Schema(description = "下次联系时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
private LocalDateTime nextTime;
@Schema(description = "手机号")
private String mobile;
@Schema(description = "电话")
private String telephone;
@Schema(description = "电子邮箱")
private String email;
@Schema(description = "客户编号", example = "10795")
private Long customerId;
@Schema(description = "地址")
private String address;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "最后跟进时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime lastTime;
@Schema(description = "直属上级", example = "23457")
private Long parentId;
@Schema(description = "姓名", example = "芋艿")
private String name;
@Schema(description = "职位")
private String post;
@Schema(description = "QQ")
private Long qq;
@Schema(description = "微信")
private String webchat;
@Schema(description = "性别")
private Integer sex;
@Schema(description = "是否关键决策人")
private Boolean policyMakers;
@Schema(description = "负责人用户编号", example = "14334")
private String ownerUserId;
}

View File

@ -1,72 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;
import java.time.LocalDateTime;
// TODO @zyna参考新的 VO 结构 ContactExcelVO 融合到 ContactRespVO
/**
* crm联系人 Excel VO
*
* @author 芋道源码
*/
@Data
@Deprecated
public class ContactExcelVO {
@ExcelProperty("下次联系时间")
private LocalDateTime nextTime;
@ExcelProperty("手机号")
private String mobile;
@ExcelProperty("电话")
private String telephone;
@ExcelProperty("电子邮箱")
private String email;
@ExcelProperty("客户编号")
private Long customerId;
@ExcelProperty("地址")
private String address;
@ExcelProperty("备注")
private String remark;
@ExcelProperty("创建时间")
private LocalDateTime createTime;
@ExcelProperty("最后跟进时间")
private LocalDateTime lastTime;
@ExcelProperty("主键")
private Long id;
@ExcelProperty("直属上级")
private Long parentId;
@ExcelProperty("姓名")
private String name;
@ExcelProperty("职位")
private String post;
@ExcelProperty("QQ")
private Long qq;
@ExcelProperty("微信")
private String webchat;
@ExcelProperty("性别")
private Integer sex;
@ExcelProperty("是否关键决策人")
private Boolean policyMakers;
@ExcelProperty("负责人用户编号")
private String ownerUserId;
}

View File

@ -1,71 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
// TODO @zyna参考新的 VO 结构使用 ContactPageReqVO 查询导出的数据
@Schema(description = "管理后台 - crm联系人 Excel 导出 Request VO参数和 ContactPageReqVO 是一致的")
@Data
@Deprecated
public class ContactExportReqVO {
@Schema(description = "下次联系时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] nextTime;
@Schema(description = "手机号")
private String mobile;
@Schema(description = "电话")
private String telephone;
@Schema(description = "电子邮箱")
private String email;
@Schema(description = "客户编号", example = "10795")
private Long customerId;
@Schema(description = "地址")
private String address;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "最后跟进时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] lastTime;
@Schema(description = "直属上级", example = "23457")
private Long parentId;
@Schema(description = "姓名", example = "芋艿")
private String name;
@Schema(description = "职位")
private String post;
@Schema(description = "QQ")
private Long qq;
@Schema(description = "微信")
private String webchat;
@Schema(description = "性别")
private Integer sex;
@Schema(description = "是否关键决策人")
private Boolean policyMakers;
@Schema(description = "负责人用户编号", example = "14334")
private String ownerUserId;
}

View File

@ -1,79 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - crm联系人分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContactPageReqVO extends PageParam {
// TODO @zyna筛选条件
// 客户
// 姓名
// 手机电话座机QQ微信邮箱
@Schema(description = "下次联系时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] nextTime;
@Schema(description = "手机号")
private String mobile;
@Schema(description = "电话")
private String telephone;
@Schema(description = "电子邮箱")
private String email;
@Schema(description = "客户编号", example = "10795")
private Long customerId;
@Schema(description = "地址")
private String address;
@Schema(description = "备注", example = "你说的对")
private String remark;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
@Schema(description = "最后跟进时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] lastTime;
@Schema(description = "直属上级", example = "23457")
private Long parentId;
@Schema(description = "姓名", example = "芋艿")
private String name;
@Schema(description = "职位")
private String post;
@Schema(description = "QQ")
private Long qq;
@Schema(description = "微信")
private String webchat;
@Schema(description = "性别")
private Integer sex;
@Schema(description = "是否关键决策人")
private Boolean policyMakers;
@Schema(description = "负责人用户编号", example = "14334")
private String ownerUserId;
}

View File

@ -1,27 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - CRM 联系人 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContactRespVO extends ContactBaseVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
private Long id;
@Schema(description = "创建时间")
private LocalDateTime createTime;
// TODO @zynaexample 最好写下
@Schema(description = "创建人")
private String creatorName;
@Schema(description = "客户名字")
private String customerName;
}

View File

@ -0,0 +1,103 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import cn.iocoder.yudao.framework.common.validation.Mobile;
import cn.iocoder.yudao.framework.common.validation.Telephone;
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
import cn.iocoder.yudao.module.infra.enums.DictTypeConstants;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotNull;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
// TODO zyna要不按照新的干掉这个 basevo都放子类里
/**
* CRM 联系人 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
@ExcelIgnoreUnannotated
public class CrmContactBaseVO {
@ExcelProperty(value = "姓名",order = 1)
@Schema(description = "姓名", example = "芋艿")
@NotNull(message = "姓名不能为空")
private String name;
@Schema(description = "客户编号", example = "10795")
private Long customerId;
@ExcelProperty(value = "性别", converter = DictConvert.class, order = 3)
@DictFormat(cn.iocoder.yudao.module.system.enums.DictTypeConstants.USER_SEX)
@Schema(description = "性别")
private Integer sex;
@Schema(description = "职位")
@ExcelProperty(value = "职位", order = 3)
private String post;
@Schema(description = "是否关键决策人")
@ExcelProperty(value = "是否关键决策人", converter = DictConvert.class, order = 3)
@DictFormat(DictTypeConstants.BOOLEAN_STRING)
private Boolean master;
@Schema(description = "直属上级", example = "23457")
private Long parentId;
@Schema(description = "手机号",example = "1387171766")
@Mobile
@ExcelProperty(value = "手机号",order = 4)
private String mobile;
@Schema(description = "座机",example = "021-0029922")
@Telephone
@ExcelProperty(value = "座机",order = 4)
private String telephone;
@ExcelProperty(value = "QQ",order = 4)
@Schema(description = "QQ",example = "197272662")
private Long qq;
@ExcelProperty(value = "微信",order = 4)
@Schema(description = "微信",example = "zzz3883")
private String wechat;
@Schema(description = "电子邮箱",example = "1111@22.com")
@Email
@ExcelProperty(value = "邮箱",order = 4)
private String email;
@ExcelProperty(value = "地址",order = 5)
@Schema(description = "地址")
private String address;
@Schema(description = "下次联系时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY)
@ExcelProperty(value = "下次联系时间",order = 6)
private LocalDateTime nextTime;
@Schema(description = "备注", example = "你说的对")
@ExcelProperty(value = "备注",order = 6)
private String remark;
@Schema(description = "最后跟进时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
@ExcelProperty(value = "最后跟进时间",order = 6)
private LocalDateTime lastTime;
@Schema(description = "负责人用户编号", example = "14334")
@NotNull(message = "负责人不能为空")
private Long ownerUserId;
@Schema(description = "地区编号", example = "20158")
private Integer areaId;
}

View File

@ -9,6 +9,6 @@ import lombok.ToString;
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContactCreateReqVO extends ContactBaseVO {
public class CrmContactCreateReqVO extends CrmContactBaseVO {
}

View File

@ -0,0 +1,36 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - CRM 联系人分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmContactPageReqVO extends PageParam {
@Schema(description = "姓名", example = "芋艿")
private String name;
@Schema(description = "客户编号", example = "10795")
private Long customerId;
@Schema(description = "手机号", example = "13898273941")
private String mobile;
@Schema(description = "电话", example = "021-383773")
private String telephone;
@Schema(description = "电子邮箱", example = "111@22.com")
private String email;
@Schema(description = "QQ", example = "3882872")
private Long qq;
@Schema(description = "微信", example = "zzZ98373")
private String wechat;
}

View File

@ -0,0 +1,50 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - CRM 联系人 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@ExcelIgnoreUnannotated
public class CrmContactRespVO extends CrmContactBaseVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
private Long id;
@Schema(description = "创建时间")
@ExcelProperty(value = "创建时间", order = 8)
private LocalDateTime createTime;
@Schema(description = "更新时间")
@ExcelProperty(value = "更新时间", order = 8)
private LocalDateTime updateTime;
@Schema(description = "创建人", example = "25682")
private String creator;
@Schema(description = "创建人名字", example = "test")
@ExcelProperty(value = "创建人", order = 8)
private String creatorName;
@ExcelProperty(value = "客户名称",order = 2)
@Schema(description = "客户名字", example = "test")
private String customerName;
@Schema(description = "负责人", example = "test")
@ExcelProperty(value = "负责人", order = 7)
private String ownerUserName;
@Schema(description = "直属上级名", example = "芋头")
@ExcelProperty(value = "直属上级", order = 4)
private String parentName;
@Schema(description = "地区名", example = "上海上海市浦东新区")
@ExcelProperty(value = "地区", order = 5)
private String areaName;
}

View File

@ -4,14 +4,15 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Schema(description = "管理后台 - CRM 联系人 Response VO")
@Schema(description = "管理后台 - CRM 联系人的精简 Response VO")
@Data
@ToString(callSuper = true)
public class ContactSimpleRespVO {
@Schema(description = "姓名", example = "芋艿") // TODO @zynarequiredMode = Schema.RequiredMode.REQUIRED需要空一行字段的顺序改下id name 前面会更干净
private String name;
public class CrmContactSimpleRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
private Long id;
@Schema(description = "姓名", example = "芋艿")
private String name;
}

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.crm.controller.admin.contact.vo;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -11,7 +11,7 @@ import javax.validation.constraints.NotNull;
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContactUpdateReqVO extends ContactBaseVO {
public class CrmContactUpdateReqVO extends CrmContactBaseVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "3167")
@NotNull(message = "主键不能为空")

View File

@ -1,13 +1,20 @@
package cn.iocoder.yudao.module.crm.controller.admin.contract;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
import cn.iocoder.yudao.module.crm.convert.contract.ContractConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO;
import cn.iocoder.yudao.module.crm.service.contract.ContractService;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.service.contract.CrmContractService;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
@ -20,8 +27,12 @@ import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertListByFlatMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@ -29,22 +40,27 @@ import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUti
@RestController
@RequestMapping("/crm/contract")
@Validated
public class ContractController {
public class CrmContractController {
@Resource
private ContractService contractService;
private CrmContractService contractService;
@Resource
private CrmCustomerService customerService;
@Resource
private AdminUserApi adminUserApi;
@PostMapping("/create")
@Operation(summary = "创建合同")
@PreAuthorize("@ss.hasPermission('crm:contract:create')")
public CommonResult<Long> createContract(@Valid @RequestBody ContractCreateReqVO createReqVO) {
public CommonResult<Long> createContract(@Valid @RequestBody CrmContractCreateReqVO createReqVO) {
return success(contractService.createContract(createReqVO, getLoginUserId()));
}
@PutMapping("/update")
@Operation(summary = "更新合同")
@PreAuthorize("@ss.hasPermission('crm:contract:update')")
public CommonResult<Boolean> updateContract(@Valid @RequestBody ContractUpdateReqVO updateReqVO) {
public CommonResult<Boolean> updateContract(@Valid @RequestBody CrmContractUpdateReqVO updateReqVO) {
contractService.updateContract(updateReqVO);
return success(true);
}
@ -63,28 +79,56 @@ public class ContractController {
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
public CommonResult<ContractRespVO> getContract(@RequestParam("id") Long id) {
ContractDO contract = contractService.getContract(id);
CrmContractDO contract = contractService.getContract(id);
return success(ContractConvert.INSTANCE.convert(contract));
}
@GetMapping("/page")
@Operation(summary = "获得合同分页")
@PreAuthorize("@ss.hasPermission('crm:contract:query')")
public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid ContractPageReqVO pageVO) {
PageResult<ContractDO> pageResult = contractService.getContractPage(pageVO);
return success(ContractConvert.INSTANCE.convertPage(pageResult));
public CommonResult<PageResult<ContractRespVO>> getContractPage(@Valid CrmContractPageReqVO pageVO) {
PageResult<CrmContractDO> pageResult = contractService.getContractPage(pageVO);
return success(convertDetailContractPage(pageResult));
}
@GetMapping("/page-by-customer")
@Operation(summary = "获得联系人分页,基于指定客户")
public CommonResult<PageResult<ContractRespVO>> getContractPageByCustomer(@Valid CrmContractPageReqVO pageVO) {
Assert.notNull(pageVO.getCustomerId(), "客户编号不能为空");
PageResult<CrmContractDO> pageResult = contractService.getContractPageByCustomer(pageVO);
return success(convertDetailContractPage(pageResult));
}
@GetMapping("/export-excel")
@Operation(summary = "导出合同 Excel")
@PreAuthorize("@ss.hasPermission('crm:contract:export')")
@OperateLog(type = EXPORT)
public void exportContractExcel(@Valid ContractExportReqVO exportReqVO,
public void exportContractExcel(@Valid CrmContractPageReqVO exportReqVO,
HttpServletResponse response) throws IOException {
List<ContractDO> list = contractService.getContractList(exportReqVO);
PageResult<CrmContractDO> pageResult = contractService.getContractPage(exportReqVO);
// 导出 Excel
List<ContractExcelVO> datas = ContractConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "合同.xls", "数据", ContractExcelVO.class, datas);
ExcelUtils.write(response, "合同.xls", "数据", CrmContractExcelVO.class,
ContractConvert.INSTANCE.convertList02(pageResult.getList()));
}
/**
* 转换成详细的联系人分页即读取关联信息
*
* @param pageResult 联系人分页
* @return 详细的联系人分页
*/
private PageResult<ContractRespVO> convertDetailContractPage(PageResult<CrmContractDO> pageResult) {
List<CrmContractDO> contactList = pageResult.getList();
if (CollUtil.isEmpty(contactList)) {
return PageResult.empty(pageResult.getTotal());
}
// 1. 获取客户列表
List<CrmCustomerDO> customerList = customerService.getCustomerList(
convertSet(contactList, CrmContractDO::getCustomerId));
// 2. 获取创建人负责人列表
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertListByFlatMap(contactList,
contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId())));
return ContractConvert.INSTANCE.convertPage(pageResult, userMap, customerList);
}
@PutMapping("/transfer")

View File

@ -1,37 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - CRM 合同 Excel 导出 Request VO参数和 ContractPageReqVO 是一致的")
@Data
public class ContractExportReqVO {
@Schema(description = "合同名称", example = "王五")
private String name;
@Schema(description = "客户编号", example = "18336")
private Long customerId;
@Schema(description = "商机编号", example = "10864")
private Long businessId;
@Schema(description = "下单日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] orderDate;
@Schema(description = "合同编号")
private String no;
@Schema(description = "整单折扣")
private Integer discountPercent;
@Schema(description = "产品总金额", example = "19510")
private Integer productPrice;
}

View File

@ -11,7 +11,7 @@ import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContractRespVO extends ContractBaseVO {
public class ContractRespVO extends CrmContractBaseVO {
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
private Long id;
@ -19,4 +19,19 @@ public class ContractRespVO extends ContractBaseVO {
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "创建人", example = "25682")
private String creator;
@Schema(description = "创建人名字", example = "test")
private String creatorName;
@Schema(description = "客户名字", example = "test")
private String customerName;
@Schema(description = "负责人", example = "test")
private String ownerUserName;
@Schema(description = "审批状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "0")
private Integer auditStatus;
}

View File

@ -9,13 +9,12 @@ import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
// TODO @dhb52所有类带下 Crm 前缀避免和别的模块重复
/**
* 合同 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*/
@Data
public class ContractBaseVO {
public class CrmContractBaseVO {
// TODO @dhb52类似 no 字段的 example 要写xia

View File

@ -9,6 +9,6 @@ import lombok.ToString;
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContractCreateReqVO extends ContractBaseVO {
public class CrmContractCreateReqVO extends CrmContractBaseVO {
}

View File

@ -11,7 +11,7 @@ import java.time.LocalDateTime;
* @author dhb52
*/
@Data
public class ContractExcelVO {
public class CrmContractExcelVO {
@ExcelProperty("合同编号")
private Long id;

View File

@ -5,17 +5,15 @@ import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - CRM 合同分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContractPageReqVO extends PageParam {
public class CrmContractPageReqVO extends PageParam {
@Schema(description = "合同编号", example = "XYZ008")
private String no;
@Schema(description = "合同名称", example = "王五")
private String name;
@ -26,17 +24,4 @@ public class ContractPageReqVO extends PageParam {
@Schema(description = "商机编号", example = "10864")
private Long businessId;
@Schema(description = "下单日期")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] orderDate;
@Schema(description = "合同编号")
private String no;
@Schema(description = "整单折扣")
private Integer discountPercent;
@Schema(description = "产品总金额", example = "19510")
private Integer productPrice;
}

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.crm.controller.admin.contract.vo;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -14,19 +15,12 @@ public class CrmContractTransferReqVO {
@NotNull(message = "联系人编号不能为空")
private Long id;
/**
* 新负责人的用户编号
*/
@Schema(description = "新负责人的用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
@NotNull(message = "新负责人的用户编号不能为空")
private Long newOwnerUserId;
/**
* 老负责人加入团队后的权限级别如果 null 说明移除
*
* 关联 {@link CrmPermissionLevelEnum}
*/
@Schema(description = "老负责人加入团队后的权限级别", requiredMode = Schema.RequiredMode.REQUIRED, example = "2")
@InEnum(value = CrmPermissionLevelEnum.class)
private Integer oldOwnerPermissionLevel;
}

View File

@ -11,7 +11,7 @@ import javax.validation.constraints.NotNull;
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ContractUpdateReqVO extends ContractBaseVO {
public class CrmContractUpdateReqVO extends CrmContractBaseVO {
@Schema(description = "合同编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "10430")
@NotNull(message = "合同编号不能为空")

View File

@ -0,0 +1,6 @@
### 请求 /update
GET {{baseUrl}}/crm/customer/page?pageNo=1&pageSize=10&name="张三"
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}

View File

@ -1,7 +1,6 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
@ -9,20 +8,17 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
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;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.mapstruct.ap.internal.util.Collections;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
@ -30,17 +26,17 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Stream;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static java.util.Collections.singletonList;
@Tag(name = "管理后台 - CRM 客户")
@RestController
@ -55,8 +51,6 @@ public class CrmCustomerController {
private DeptApi deptApi;
@Resource
private AdminUserApi adminUserApi;
@Resource
private CrmPermissionService permissionService;
@PostMapping("/create")
@Operation(summary = "创建客户")
@ -92,73 +86,38 @@ public class CrmCustomerController {
if (customer == null) {
return success(null);
}
// 2. 拼接数据
// 2.1 获取负责人
List<CrmPermissionDO> ownerList = permissionService.getPermissionByBizTypeAndBizIdsAndLevel(
CrmBizTypeEnum.CRM_CUSTOMER.getType(), Collections.singletonList(customer.getId()),
CrmPermissionLevelEnum.OWNER.getLevel());
Map<Long, CrmPermissionDO> ownerMap = convertMap(ownerList, CrmPermissionDO::getBizId);
// 2.2 获取负责人详情
Set<Long> userIds = convertSet(ownerList, CrmPermissionDO::getUserId);
userIds.add(Long.parseLong(customer.getCreator())); // 加入创建者
List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIds);
Map<Long, AdminUserRespDTO> userMap = convertMap(userList, AdminUserRespDTO::getId);
// 2.3 获取部门详情
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
return success(CrmCustomerConvert.INSTANCE.convert(customer, ownerMap, userMap, deptMap));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
Collections.asSet(Long.valueOf(customer.getCreator()), customer.getOwnerUserId()));
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
return success(CrmCustomerConvert.INSTANCE.convert(customer, userMap, deptMap));
}
// TODO @puhui999可以在 CrmCustomerPageReqVO 里面加个 pool 参数 true 代表来自公海客户的分页
@GetMapping("/page")
@Operation(summary = "获得客户分页")
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
public CommonResult<PageResult<CrmCustomerRespVO>> getCustomerPage(@Valid CrmCustomerPageReqVO pageVO) {
// 1. 查询客户分页
PageResult<CrmCustomerDO> pageResult = customerService.getCustomerPage(pageVO, getLoginUserId());
if (CollUtil.isEmpty(pageResult.getList())) {
return success(PageResult.empty(pageResult.getTotal()));
}
// 拼接数据
// TODO @puhui999这块的拼接逻辑可以和 convertPage 合并下
// Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
// convertSetByFlatMap(pageResult.getList(), user -> Stream.of(NumberUtil.parseLong(user.getCreator()), user.getOwnerUserId())));
// Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(
// convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
return convertPage(customerService.getCustomerPage(pageVO, getLoginUserId()));
}
// TODO @puhui999
@GetMapping("/pool-page")
@Operation(summary = "获得公海客户分页")
@PreAuthorize("@ss.hasPermission('crm:customer:query')")
public CommonResult<PageResult<CrmCustomerRespVO>> getPoolCustomerPage(@Valid CrmCustomerPageReqVO pageVO) {
return convertPage(customerService.getCustomerPage(pageVO, CrmPermissionDO.POOL_USER_ID));
}
private CommonResult<PageResult<CrmCustomerRespVO>> convertPage(PageResult<CrmCustomerDO> pageResult) {
// 2. 拼接数据
Set<Long> ids = convertSet(pageResult.getList(), CrmCustomerDO::getId);
// 2.1 获取负责人
List<CrmPermissionDO> ownerList = permissionService.getPermissionByBizTypeAndBizIdsAndLevel(
CrmBizTypeEnum.CRM_CUSTOMER.getType(), ids, CrmPermissionLevelEnum.OWNER.getLevel());
Map<Long, CrmPermissionDO> ownerMap = convertMap(ownerList, CrmPermissionDO::getBizId);
// 2.2 获取负责人详情
Set<Long> userIds = convertSet(ownerList, CrmPermissionDO::getUserId);
userIds.addAll(convertSet(pageResult.getList(), item -> Long.parseLong(item.getCreator()))); // 加入创建者
List<AdminUserRespDTO> userList = adminUserApi.getUserList(userIds);
Map<Long, AdminUserRespDTO> userMap = convertMap(userList, AdminUserRespDTO::getId);
// 2.3 获取部门详情
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, ownerMap, userMap, deptMap));
Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(
convertSetByFlatMap(pageResult.getList(), user -> Stream.of(Long.parseLong(user.getCreator()), user.getOwnerUserId())));
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));
return success(CrmCustomerConvert.INSTANCE.convertPage(pageResult, userMap, deptMap));
}
@GetMapping("/export-excel")
@Operation(summary = "导出客户 Excel")
@PreAuthorize("@ss.hasPermission('crm:customer:export')")
@OperateLog(type = EXPORT)
public void exportCustomerExcel(@Valid CrmCustomerExportReqVO exportReqVO,
public void exportCustomerExcel(@Valid CrmCustomerPageReqVO pageVO,
HttpServletResponse response) throws IOException {
List<CrmCustomerDO> list = customerService.getCustomerList(exportReqVO);
pageVO.setPageSize(PAGE_SIZE_NONE); // 不分页
List<CrmCustomerDO> list = customerService.getCustomerPage(pageVO, getLoginUserId()).getList();
// 导出 Excel
List<CrmCustomerExcelVO> datas = CrmCustomerConvert.INSTANCE.convertList02(list);
ExcelUtils.write(response, "客户.xls", "数据", CrmCustomerExcelVO.class, datas);
@ -181,30 +140,48 @@ public class CrmCustomerController {
return success(true);
}
@PutMapping("/receive")
@Operation(summary = "领取公海客户")
// TODO @xiaqing1receiveCustomer 方法名字2cIds 改成 ids要加下 @RequestParam还有 swagger 注解3参数非空使用 validator 校验4返回 true 即可
@PreAuthorize("@ss.hasPermission('crm:customer:receive')")
public CommonResult<String> receiveByIds(List<Long> cIds){
// 判断是否为空
if(CollectionUtils.isEmpty(cIds))
return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),GlobalErrorCodeConstants.BAD_REQUEST.getMsg());
// 领取公海任务
// TODO @xiaqinguserid通过 controller 传递给 service不要在 service 里面获取无状态
customerService.receive(cIds);
return success("领取成功");
// ==================== 公海相关操作 ====================
@PutMapping("/put-pool")
@Operation(summary = "数据放入公海")
@Parameter(name = "id", description = "客户编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:customer:update')")
public CommonResult<Boolean> putCustomerPool(@RequestParam("id") Long id) {
customerService.putCustomerPool(id);
return success(true);
}
// TODO @xiaqing1distributeCustomer 方法名2cIds 同上3参数校验同上4ownerId 改成 ownerUserId和别的模块统一5返回 true 即可
@PutMapping("/distributeByIds")
@PutMapping("/receive")
@Operation(summary = "领取公海客户")
@Parameter(name = "ids", description = "编号数组", required = true, example = "1,2,3")
@PreAuthorize("@ss.hasPermission('crm:customer:receive')")
public CommonResult<Boolean> receiveCustomer(@RequestParam(value = "ids") List<Long> ids) {
customerService.receiveCustomer(ids, getLoginUserId());
return success(true);
}
@PutMapping("/distribute")
@Operation(summary = "分配公海给对应负责人")
@PreAuthorize("@ss.hasPermission('crm:customer:distributeByIds')")
public CommonResult<String> distributeByIds(Long ownerId,List<Long>cIds){
//判断参数不能为空
if(ownerId==null || CollectionUtils.isEmpty(cIds))
return error(GlobalErrorCodeConstants.BAD_REQUEST.getCode(),GlobalErrorCodeConstants.BAD_REQUEST.getMsg());
customerService.distributeByIds(cIds,ownerId);
return success("分配成功");
@Parameters({
@Parameter(name = "ids", description = "客户编号数组", required = true, example = "1,2,3"),
@Parameter(name = "ownerUserId", description = "分配的负责人编号", required = true, example = "12345")
})
@PreAuthorize("@ss.hasPermission('crm:customer:distribute')")
public CommonResult<Boolean> distributeCustomer(@RequestParam(value = "ids") List<Long> ids,
@RequestParam(value = "ownerUserId") Long ownerUserId) {
// 领取公海数据
customerService.receiveCustomer(ids, ownerUserId);
return success(true);
}
// TODO 芋艿这个接口要调整下
@GetMapping("/query-all-list")
@Operation(summary = "查询客户列表")
@PreAuthorize("@ss.hasPermission('crm:customer:all')")
public CommonResult<List<CrmCustomerQueryAllRespVO>> queryAll(){
List<CrmCustomerDO> crmCustomerDOList = customerService.getCustomerList();
List<CrmCustomerQueryAllRespVO> data = CrmCustomerConvert.INSTANCE.convertQueryAll(crmCustomerDOList);
return success(data);
}
}

View File

@ -3,13 +3,13 @@ package cn.iocoder.yudao.module.crm.controller.admin.customer;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLimitConfigCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLimitConfigPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLimitConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLimitConfigUpdateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigPageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerLimitConfigConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.customerlimitconfig.CrmCustomerLimitConfigDO;
import cn.iocoder.yudao.module.crm.service.customerlimitconfig.CrmCustomerLimitConfigService;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerLimitConfigService;
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;
@ -29,7 +29,7 @@ import java.util.Map;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSetByFlatMap;
@Tag(name = "管理后台 - 客户限制配置")
@Tag(name = "管理后台 - CRM 客户限制配置")
@RestController
@RequestMapping("/crm/customer-limit-config")
@Validated

View File

@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPoolConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerPoolConfigUpdateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig.CrmCustomerPoolConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig.CrmCustomerPoolConfigSaveReqVO;
import cn.iocoder.yudao.module.crm.convert.customer.CrmCustomerConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerPoolConfigService;
@ -34,12 +34,11 @@ public class CrmCustomerPoolConfigController {
return success(CrmCustomerConvert.INSTANCE.convert(customerPoolConfig));
}
// TODO @wanwan这个请求搞成 save
@PutMapping("/update")
@PutMapping("/save")
@Operation(summary = "更新客户公海规则设置")
@PreAuthorize("@ss.hasPermission('crm:customer-pool-config:update')")
public CommonResult<Boolean> updateCustomerPoolConfig(@Valid @RequestBody CrmCustomerPoolConfigUpdateReqVO updateReqVO) {
customerPoolConfigService.updateCustomerPoolConfig(updateReqVO);
public CommonResult<Boolean> saveCustomerPoolConfig(@Valid @RequestBody CrmCustomerPoolConfigSaveReqVO updateReqVO) {
customerPoolConfigService.saveCustomerPoolConfig(updateReqVO);
return success(true);
}

View File

@ -1,17 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
// TODO 芋艿导出最后做等基本确认的差不多之后
@Schema(description = "管理后台 - CRM 客户 Excel 导出 Request VO参数和 CrmCustomerPageReqVO 是一致的")
@Data
public class CrmCustomerExportReqVO {
@Schema(description = "客户名称", example = "赵六")
private String name;
@Schema(description = "手机", example = "18000000000")
private String mobile;
}

View File

@ -1,12 +1,14 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.crm.enums.customer.CrmCustomerSceneEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmSceneEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.NotNull;
@Schema(description = "管理后台 - CRM 客户分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ -31,9 +33,13 @@ public class CrmCustomerPageReqVO extends PageParam {
/**
* 场景类型
*
* 关联 {@link CrmCustomerSceneEnum}
* 关联 {@link CrmSceneEnum}
*/
@Schema(description = "场景类型", example = "1")
private Integer sceneType;
@Schema(description = "是否为公海数据", requiredMode = Schema.RequiredMode.REQUIRED, example = "false")
@NotNull(message = "是否为公海数据不能为空")
private Boolean pool;
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
@Schema(description = "管理后台 - CRM 客户更新 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmCustomerPoolConfigUpdateReqVO extends CrmCustomerPoolConfigBaseVO {
}

View File

@ -0,0 +1,17 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
// TODO 芋艿这块要统一下
@Schema(description = "管理后台 - CRM 全部客户 Response VO")
@Data
public class CrmCustomerQueryAllRespVO{
@Schema(description = "编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "13563")
private Long id;
@Schema(description = "客户名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "赵六")
private String name;
}

View File

@ -1,6 +1,6 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -6,7 +6,6 @@ import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
// TODO @wanwanvo 可以新建一个 limitconfig放它的 vo
/**
* 客户限制配置 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@ -18,10 +20,10 @@ public class CrmCustomerLimitConfigRespVO extends CrmCustomerLimitConfigBaseVO {
private Long id;
@Schema(description = "规则适用人群名称")
private String userNames;
private List<AdminUserRespDTO> users;
@Schema(description = "规则适用部门名称")
private String deptNames;
private List<DeptRespDTO> depts;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,4 +1,4 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@ -12,7 +12,6 @@ import javax.validation.constraints.NotNull;
@Data
public class CrmCustomerPoolConfigBaseVO {
// TODO @wanwan参数校验
@Schema(description = "是否启用客户公海", requiredMode = Schema.RequiredMode.REQUIRED, example = "true")
@NotNull(message = "是否启用客户公海不能为空")
private Boolean enabled;

View File

@ -1,11 +1,10 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo;
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
// TODO @wanwanvo 可以新建一个 poolconfig放它的 vo
@Schema(description = "管理后台 - CRM 客户公海规则 Response VO")
@Data
@EqualsAndHashCode(callSuper = true)

View File

@ -0,0 +1,38 @@
package cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig;
import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.ObjectUtil;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import javax.validation.constraints.AssertTrue;
import java.util.Objects;
@Schema(description = "管理后台 - CRM 客户公海配置的保存 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class CrmCustomerPoolConfigSaveReqVO extends CrmCustomerPoolConfigBaseVO {
// TODO @wanwanAssertTrue 必须 is 开头哈注意需要 json 忽略下避免被序列化
@AssertTrue(message = "客户公海规则设置不正确")
// TODO @wanwan这个方法是不是拆成 2 一个校验 contactExpireDays一个校验 dealExpireDays
public boolean poolEnableValid() {
if (!BooleanUtil.isTrue(getEnabled())) {
return true;
}
return ObjectUtil.isAllNotEmpty(getContactExpireDays(), getDealExpireDays());
}
@AssertTrue(message = "客户公海规则设置不正确")
// TODO @wanwan这个方法是不是改成 isNotifyDaysValid() 更好点本质校验的是 notifyDays 是否为空
public boolean notifyEnableValid() {
if (!BooleanUtil.isTrue(getNotifyEnabled())) {
return true;
}
return Objects.nonNull(getNotifyDays());
}
}

View File

@ -1,5 +1,5 @@
### 请求 /add
PUT {{baseUrl}}/crm/permission/add
POST {{baseUrl}}/crm/permission/create
Content-Type: application/json
Authorization: Bearer {{token}}
tenant-id: {{adminTenentId}}

View File

@ -1,16 +1,15 @@
package cn.iocoder.yudao.module.crm.controller.admin.permission;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.permission.vo.CrmPermissionUpdateReqVO;
import cn.iocoder.yudao.module.crm.convert.permission.CrmPermissionConvert;
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
import cn.iocoder.yudao.module.crm.framework.core.annotations.CrmPermission;
import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.service.permission.CrmPermissionService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.PostApi;
@ -29,17 +28,12 @@ import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;
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.anyMatch;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.crm.enums.ErrorCodeConstants.CRM_PERMISSION_NOT_EXISTS;
@Tag(name = "管理后台 - CRM 数据权限(数据团队成员操作)")
@Tag(name = "管理后台 - CRM 数据权限")
@RestController
@RequestMapping("/crm/permission")
@Validated
@ -55,87 +49,45 @@ public class CrmPermissionController {
@Resource
private PostApi postApi;
// TODO @puhui999保持统一create 然后是 PostMapping
@PutMapping("/add")
@Operation(summary = "添加团队成员")
@PostMapping("/create")
@Operation(summary = "创建数据权限")
@PreAuthorize("@ss.hasPermission('crm:permission:create')")
@CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId",
level = CrmPermissionLevelEnum.OWNER)
@CrmPermission(bizTypeValue = "#reqVO.bizType", bizId = "#reqVO.bizId", level = CrmPermissionLevelEnum.OWNER)
public CommonResult<Boolean> addPermission(@Valid @RequestBody CrmPermissionCreateReqVO reqVO) {
permissionService.createPermission(CrmPermissionConvert.INSTANCE.convert(reqVO));
return success(true);
}
// TODO @puhui999领取公海客户是不是放到客户那更合适哈
@PutMapping("/receive")
@Operation(summary = "领取公海数据")
@PreAuthorize("@ss.hasPermission('crm:permission:update')")
public CommonResult<Boolean> receive(@RequestParam("bizType") Integer bizType, @RequestParam("bizId") Long bizId) {
permissionService.receiveBiz(bizType, bizId, getLoginUserId());
return success(true);
}
// TODO @puhui999是不是放到客户那更合适哈
@PutMapping("/put-pool")
@Operation(summary = "数据放入公海")
@PreAuthorize("@ss.hasPermission('crm:permission:update')")
@CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#bizType", bizId = "#bizId"
, level = CrmPermissionLevelEnum.OWNER)
public CommonResult<Boolean> putPool(@RequestParam(value = "bizType") Integer bizType, @RequestParam("bizId") Long bizId) {
permissionService.putPool(bizType, bizId, getLoginUserId());
return success(true);
}
@PutMapping("/update")
@Operation(summary = "编辑团队成员权限")
@Operation(summary = "编辑数据权限")
@PreAuthorize("@ss.hasPermission('crm:permission:update')")
@CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId"
@CrmPermission(bizTypeValue = "#updateReqVO.bizType", bizId = "#updateReqVO.bizId"
, level = CrmPermissionLevelEnum.OWNER)
public CommonResult<Boolean> updatePermission(@Valid @RequestBody CrmPermissionUpdateReqVO updateReqVO) {
permissionService.updatePermission(updateReqVO);
return success(true);
}
// TODO @puhui999bizType bizId 是不是不用啦因为参数校验需要 bizType bizId可以先查询下在直接调用方法不一定都要注解哈
@DeleteMapping("/delete")
@Operation(summary = "移除团队成员")
@Parameters({
@Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"),
@Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024"),
@Parameter(name = "ids", description = "团队成员编号", required = true, example = "1024")
})
@Operation(summary = "删除数据权限")
@Parameter(name = "ids", description = "数据权限编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:permission:delete')")
@CrmPermission(bizType = CrmBizTypeEnum.CRM_PERMISSION, bizTypeValue = "#bizType", bizId = "#bizId"
, level = CrmPermissionLevelEnum.OWNER) // 为了校验权限请求必须带上 bizType bizId
public CommonResult<Boolean> deletePermission(@RequestParam("bizType") Integer bizType,
@RequestParam("bizId") Long bizId,
@RequestParam("ids") Collection<Long> ids) {
permissionService.deletePermission(ids);
public CommonResult<Boolean> deletePermission(@RequestParam("ids") Collection<Long> ids) {
permissionService.deletePermissionBatch(ids, getLoginUserId());
return success(true);
}
// TODO @puhui999deleteSelfPermission尽量归成 crud 这样的操作哈
@DeleteMapping("/quit-team")
@Operation(summary = "退出团队")
@Parameters({
// TODO @puhui999这个可以拿出来不用包在 @Parameters 在只有一个参数时哈
@Parameter(name = "id", description = "团队成员编号", required = true, example = "1024")
})
@DeleteMapping("/delete-self")
@Operation(summary = "删除自己的数据权限")
@Parameter(name = "id", description = "数据权限编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:permission:delete')")
public CommonResult<Boolean> deletePermission(@RequestParam("id") Long id) {
// 校验数据存在且是自己
CrmPermissionDO permission = permissionService.getPermissionByIdAndUserId(id, getLoginUserId());
if (permission == null) {
throw exception(CRM_PERMISSION_NOT_EXISTS);
}
// 删除
permissionService.deletePermission(Collections.singletonList(id));
public CommonResult<Boolean> deleteSelfPermission(@RequestParam("id") Long id) {
permissionService.deleteSelfPermission(id, getLoginUserId());
return success(true);
}
@GetMapping("/list")
@Operation(summary = "取团队成员")
@Operation(summary = "获得数据权限列表")
@Parameters({
@Parameter(name = "bizType", description = "CRM 类型", required = true, example = "2"),
@Parameter(name = "bizId", description = "CRM 类型数据编号", required = true, example = "1024")
@ -143,23 +95,15 @@ public class CrmPermissionController {
@PreAuthorize("@ss.hasPermission('crm:permission:query')")
public CommonResult<List<CrmPermissionRespVO>> getPermissionList(@RequestParam("bizType") Integer bizType,
@RequestParam("bizId") Long bizId) {
List<CrmPermissionDO> permission = permissionService.getPermissionByBizTypeAndBizId(bizType, bizId);
List<CrmPermissionDO> permission = permissionService.getPermissionListByBiz(bizType, bizId);
if (CollUtil.isEmpty(permission)) {
return success(Collections.emptyList());
}
// TODO @puhui999池子的逻辑
// 判断是否是公海数据
// TODO @puhui999这段逻辑可以删除么
Predicate<CrmPermissionDO> filter = item -> ObjUtil.equal(item.getUserId(), CrmPermissionDO.POOL_USER_ID);
if (anyMatch(permission, filter)) {
permission.removeIf(filter); // 排除
}
// 拼接数据
List<AdminUserRespDTO> userList = adminUserApi.getUserList(convertSet(permission, CrmPermissionDO::getUserId));
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userList, AdminUserRespDTO::getDeptId));
// TODO @puhui999CollectionUtils.convertSetByFlatMap() 看看可以不
Set<Long> postIds = userList.stream().flatMap(item -> item.getPostIds().stream()).collect(Collectors.toSet());
Set<Long> postIds = CollectionUtils.convertSetByFlatMap(userList, AdminUserRespDTO::getPostIds, Collection::stream);
Map<Long, PostRespDTO> postMap = postApi.getPostMap(postIds);
return success(CrmPermissionConvert.INSTANCE.convert(permission, userList, deptMap, postMap));
}

View File

@ -1,15 +1,15 @@
package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
/**
* 数据权限团队成员 Base VO提供给添加修改详细的子 VO 使用
* 数据权限 Base VO提供给添加修改详细的子 VO 使用
* 如果子 VO 存在差异的字段请不要添加到这里影响 Swagger 文档生成
*
* @author HUIHUI

View File

@ -6,7 +6,7 @@ import lombok.Data;
import java.time.LocalDateTime;
import java.util.Set;
@Schema(description = "管理后台 - CRM 数据权限(团队成员) Response VO")
@Schema(description = "管理后台 - CRM 数据权限 Response VO")
@Data
public class CrmPermissionRespVO extends CrmPermissionBaseVO {

View File

@ -1,8 +1,8 @@
package cn.iocoder.yudao.module.crm.controller.admin.permission.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.crm.framework.enums.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.framework.enums.CrmPermissionLevelEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmBizTypeEnum;
import cn.iocoder.yudao.module.crm.enums.permission.CrmPermissionLevelEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.crm.enums.AuditStatusEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
@ -34,7 +34,7 @@ public class CrmReceivableBaseVO {
// TODO @liuhongfeng这个字段应该不是前端传递的噢而是后端自己生成的
@Schema(description = "审批状态", example = "1")
@InEnum(AuditStatusEnum.class)
@InEnum(CrmAuditStatusEnum.class)
private Integer checkStatus;
@Schema(description = "回款日期")

View File

@ -28,7 +28,7 @@ public class CrmReceivableExcelVO {
private Long contractId;
@ExcelProperty(value = "审批状态", converter = DictConvert.class)
@DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_RECEIVABLE_CHECK_STATUS)
@DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_AUDIT_STATUS)
private Integer checkStatus;
@ExcelProperty("工作流编号")

View File

@ -1,7 +1,7 @@
package cn.iocoder.yudao.module.crm.controller.admin.receivable.vo;
import cn.iocoder.yudao.framework.common.validation.InEnum;
import cn.iocoder.yudao.module.crm.enums.AuditStatusEnum;
import cn.iocoder.yudao.module.crm.enums.common.CrmAuditStatusEnum;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
@ -28,7 +28,7 @@ public class CrmReceivablePlanBaseVO {
private Integer status;
@Schema(description = "审批状态", example = "1")
@InEnum(AuditStatusEnum.class)
@InEnum(CrmAuditStatusEnum.class)
private Integer checkStatus;
@Schema(description = "计划回款金额", example = "29675")

View File

@ -31,7 +31,7 @@ public class CrmReceivablePlanExcelVO {
private Integer status;
@ExcelProperty(value = "审批状态", converter = DictConvert.class)
@DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_RECEIVABLE_CHECK_STATUS)
@DictFormat(cn.iocoder.yudao.module.crm.enums.DictTypeConstants.CRM_AUDIT_STATUS)
private Integer checkStatus;
//@ExcelProperty("工作流编号")

View File

@ -1,8 +1,11 @@
package cn.iocoder.yudao.module.crm.convert.business;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.*;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.business.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
@ -10,6 +13,9 @@ import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 商机 Convert
@ -37,4 +43,18 @@ public interface CrmBusinessConvert {
})
CrmPermissionTransferReqBO convert(CrmBusinessTransferReqVO reqVO, Long userId);
default PageResult<CrmBusinessRespVO> convertPage(PageResult<CrmBusinessDO> page, List<CrmCustomerDO> customerList,
List<CrmBusinessStatusTypeDO> statusTypeList, List<CrmBusinessStatusDO> statusList) {
PageResult<CrmBusinessRespVO> result = convertPage(page);
// 拼接关联字段
Map<Long, String> customerMap = convertMap(customerList, CrmCustomerDO::getId, CrmCustomerDO::getName);
Map<Long, String> statusTypeMap = convertMap(statusTypeList, CrmBusinessStatusTypeDO::getId, CrmBusinessStatusTypeDO::getName);
Map<Long, String> statusMap = convertMap(statusList, CrmBusinessStatusDO::getId, CrmBusinessStatusDO::getName);
result.getList().forEach(type -> type
.setCustomerName(customerMap.get(type.getCustomerId()))
.setStatusTypeName(statusTypeMap.get(type.getStatusTypeId()))
.setStatusName(statusMap.get(type.getStatusId())));
return result;
}
}

View File

@ -1,13 +1,13 @@
package cn.iocoder.yudao.module.crm.convert.businessstatus;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.status.CrmBusinessStatusSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.crm.controller.admin.businessstatus.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.businessstatus.CrmBusinessStatusDO;
import java.util.List;
/**
* 商机状态 Convert
@ -19,9 +19,7 @@ public interface CrmBusinessStatusConvert {
CrmBusinessStatusConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusConvert.class);
CrmBusinessStatusDO convert(CrmBusinessStatusCreateReqVO bean);
CrmBusinessStatusDO convert(CrmBusinessStatusUpdateReqVO bean);
CrmBusinessStatusDO convert(CrmBusinessStatusSaveReqVO bean);
CrmBusinessStatusRespVO convert(CrmBusinessStatusDO bean);
@ -29,6 +27,4 @@ public interface CrmBusinessStatusConvert {
PageResult<CrmBusinessStatusRespVO> convertPage(PageResult<CrmBusinessStatusDO> page);
List<CrmBusinessStatusExcelVO> convertList02(List<CrmBusinessStatusDO> list);
}

View File

@ -1,13 +1,19 @@
package cn.iocoder.yudao.module.crm.convert.businessstatustype;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.business.vo.type.CrmBusinessStatusTypeSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.business.CrmBusinessStatusTypeDO;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import cn.iocoder.yudao.module.crm.controller.admin.businessstatustype.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.businessstatustype.CrmBusinessStatusTypeDO;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
/**
* 商机状态类型 Convert
@ -19,16 +25,25 @@ public interface CrmBusinessStatusTypeConvert {
CrmBusinessStatusTypeConvert INSTANCE = Mappers.getMapper(CrmBusinessStatusTypeConvert.class);
CrmBusinessStatusTypeDO convert(CrmBusinessStatusTypeCreateReqVO bean);
CrmBusinessStatusTypeDO convert(CrmBusinessStatusTypeUpdateReqVO bean);
CrmBusinessStatusTypeDO convert(CrmBusinessStatusTypeSaveReqVO bean);
CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean);
List<CrmBusinessStatusTypeRespVO> convertList(List<CrmBusinessStatusTypeDO> list);
PageResult<CrmBusinessStatusTypeRespVO> convertPage(PageResult<CrmBusinessStatusTypeDO> page);
List<CrmBusinessStatusTypeExcelVO> convertList02(List<CrmBusinessStatusTypeDO> list);
default PageResult<CrmBusinessStatusTypeRespVO> convertPage(PageResult<CrmBusinessStatusTypeDO> page, List<DeptRespDTO> deptList) {
PageResult<CrmBusinessStatusTypeRespVO> pageResult = convertPage(page);
// 拼接关联字段
Map<Long, String> deptMap = convertMap(deptList, DeptRespDTO::getId, DeptRespDTO::getName);
pageResult.getList().forEach(type -> type.setDeptNames(convertList(type.getDeptIds(), deptMap::get)));
return pageResult;
}
default CrmBusinessStatusTypeRespVO convert(CrmBusinessStatusTypeDO bean, List<CrmBusinessStatusDO> statusList) {
// TODO @ljlleo 可以链式赋值简化成一行
CrmBusinessStatusTypeRespVO result = convert(bean);
result.setStatusList(statusList);
return result;
}
}

View File

@ -1,18 +1,27 @@
package cn.iocoder.yudao.module.crm.convert.contact;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.module.crm.controller.admin.contact.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.ContactDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contact.CrmContactDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
// TODO 芋艿convert 后面在梳理下略微有点乱
/**
* crm联系人 Convert
* CRM 联系人 Convert
*
* @author 芋道源码
*/
@ -21,19 +30,23 @@ public interface ContactConvert {
ContactConvert INSTANCE = Mappers.getMapper(ContactConvert.class);
ContactDO convert(ContactCreateReqVO bean);
CrmContactDO convert(CrmContactCreateReqVO bean);
ContactDO convert(ContactUpdateReqVO bean);
CrmContactDO convert(CrmContactUpdateReqVO bean);
ContactRespVO convert(ContactDO bean);
CrmContactRespVO convert(CrmContactDO bean);
List<ContactRespVO> convertList(List<ContactDO> list);
List<CrmContactRespVO> convertList(List<CrmContactDO> list);
PageResult<ContactRespVO> convertPage(PageResult<ContactDO> page);
PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> page);
List<ContactExcelVO> convertList02(List<ContactDO> list);
default PageResult<CrmContactRespVO> convertPage(PageResult<CrmContactDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
List<CrmContactRespVO> list = converList(pageResult.getList(), userMap, customerList, parentContactList);
return convertPage(pageResult).setList(list);
}
List<ContactSimpleRespVO> convertAllList(List<ContactDO> list);
List<CrmContactSimpleRespVO> convertAllList(List<CrmContactDO> list);
@Mappings({
@Mapping(target = "bizId", source = "reqVO.id"),
@ -41,4 +54,54 @@ public interface ContactConvert {
})
CrmPermissionTransferReqBO convert(CrmContactTransferReqVO reqVO, Long userId);
/**
* 转换详情信息
*
* @param contactDO 联系人
* @param userMap 用户列表
* @param crmCustomerDOList 客户
* @return ContactRespVO
*/
default CrmContactRespVO convert(CrmContactDO contactDO, Map<Long, AdminUserRespDTO> userMap, List<CrmCustomerDO> crmCustomerDOList,
List<CrmContactDO> contactList) {
CrmContactRespVO contactVO = convert(contactDO);
setUserInfo(contactVO, userMap);
Map<Long, CrmCustomerDO> ustomerMap = crmCustomerDOList.stream().collect(Collectors.toMap(CrmCustomerDO::getId, v -> v));
Map<Long, CrmContactDO> contactMap = contactList.stream().collect(Collectors.toMap(CrmContactDO::getId, v -> v));
findAndThen(ustomerMap, contactDO.getCustomerId(), customer -> contactVO.setCustomerName(customer.getName()));
findAndThen(contactMap, contactDO.getParentId(), contact -> contactVO.setParentName(contact.getName()));
return contactVO;
}
default List<CrmContactRespVO> converList(List<CrmContactDO> contactList, Map<Long, AdminUserRespDTO> userMap,
List<CrmCustomerDO> customerList, List<CrmContactDO> parentContactList) {
List<CrmContactRespVO> result = convertList(contactList);
Map<Long, CrmContactDO> parentContactMap = convertMap(parentContactList, CrmContactDO::getId);
Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
result.forEach(item -> {
setUserInfo(item, userMap);
findAndThen(customerMap, item.getCustomerId(), customer -> { // TODO @zyna这里的 { 可以去掉
item.setCustomerName(customer.getName());
});
findAndThen(parentContactMap, item.getParentId(), contactDO -> { // TODO @zyna这里的 { 可以去掉
item.setParentName(contactDO.getName());
});
});
return result;
}
/**
* 设置用户信息
*
* @param contactRespVO 联系人Response VO
* @param userMap 用户信息 map
*/
static void setUserInfo(CrmContactRespVO contactRespVO, Map<Long, AdminUserRespDTO> userMap) {
contactRespVO.setAreaName(AreaUtils.format(contactRespVO.getAreaId()));
findAndThen(userMap, contactRespVO.getOwnerUserId(), user -> {
contactRespVO.setOwnerUserName(user == null ? "" : user.getNickname());
});
findAndThen(userMap, Long.parseLong(contactRespVO.getCreator()), user -> contactRespVO.setCreatorName(user.getNickname()));
}
}

View File

@ -2,14 +2,20 @@ package cn.iocoder.yudao.module.crm.convert.contract;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.contract.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.ContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.contract.CrmContractDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen;
/**
* 合同 Convert
@ -21,17 +27,17 @@ public interface ContractConvert {
ContractConvert INSTANCE = Mappers.getMapper(ContractConvert.class);
ContractDO convert(ContractCreateReqVO bean);
CrmContractDO convert(CrmContractCreateReqVO bean);
ContractDO convert(ContractUpdateReqVO bean);
CrmContractDO convert(CrmContractUpdateReqVO bean);
ContractRespVO convert(ContractDO bean);
ContractRespVO convert(CrmContractDO bean);
List<ContractRespVO> convertList(List<ContractDO> list);
List<ContractRespVO> convertList(List<CrmContractDO> list);
PageResult<ContractRespVO> convertPage(PageResult<ContractDO> page);
PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> page);
List<ContractExcelVO> convertList02(List<ContractDO> list);
List<CrmContractExcelVO> convertList02(List<CrmContractDO> list);
@Mappings({
@Mapping(target = "bizId", source = "reqVO.id"),
@ -39,4 +45,25 @@ public interface ContractConvert {
})
CrmPermissionTransferReqBO convert(CrmContractTransferReqVO reqVO, Long userId);
default PageResult<ContractRespVO> convertPage(PageResult<CrmContractDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
List<CrmCustomerDO> customerList) {
return new PageResult<>(converList(pageResult.getList(), userMap, customerList), pageResult.getTotal());
}
default List<ContractRespVO> converList(List<CrmContractDO> contractList, Map<Long, AdminUserRespDTO> userMap,
List<CrmCustomerDO> customerList) {
List<ContractRespVO> result = convertList(contractList);
Map<Long, CrmCustomerDO> customerMap = convertMap(customerList, CrmCustomerDO::getId);
result.forEach(item -> {
setUserInfo(item, userMap);
findAndThen(customerMap, item.getCustomerId(), customer -> item.setCustomerName(customer.getName()));
});
return result;
}
static void setUserInfo(ContractRespVO contract, Map<Long, AdminUserRespDTO> userMap) {
findAndThen(userMap, contract.getOwnerUserId(), user -> contract.setOwnerUserName(user.getNickname()));
findAndThen(userMap, Long.parseLong(contract.getCreator()), user -> contract.setCreatorName(user.getNickname()));
}
}

View File

@ -1,13 +1,12 @@
package cn.iocoder.yudao.module.crm.convert.customer;
import cn.hutool.core.util.NumberUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.*;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig.CrmCustomerPoolConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.poolconfig.CrmCustomerPoolConfigSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerPoolConfigDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.permission.CrmPermissionDO;
import cn.iocoder.yudao.module.crm.service.permission.bo.CrmPermissionTransferReqBO;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
@ -37,38 +36,20 @@ public interface CrmCustomerConvert {
CrmCustomerRespVO convert(CrmCustomerDO bean);
default CrmCustomerRespVO convert(CrmCustomerDO customer, Map<Long, CrmPermissionDO> ownerMap,
Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
CrmCustomerRespVO customerResp = convert(customer);
findAndThen(ownerMap, customerResp.getId(), owner -> {
customerResp.setOwnerUserId(owner.getUserId());
customerResp.setAreaName(AreaUtils.format(customerResp.getAreaId()));
findAndThen(userMap, owner.getUserId(), user -> {
customerResp.setOwnerUserName(user.getNickname());
});
findAndThen(userMap, Long.parseLong(customerResp.getCreator()), user -> {
customerResp.setCreatorName(user.getNickname());
});
findAndThen(deptMap, customerResp.getOwnerUserId(), dept -> {
customerResp.setOwnerUserDeptName(dept.getName());
});
/**
* 设置用户信息
*
* @param customer CRM 客户 Response VO
* @param userMap 用户信息 map
* @param deptMap 用户部门信息 map
*/
static void setUserInfo(CrmCustomerRespVO customer, Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
customer.setAreaName(AreaUtils.format(customer.getAreaId()));
findAndThen(userMap, customer.getOwnerUserId(), user -> {
customer.setOwnerUserName(user.getNickname());
findAndThen(deptMap, user.getDeptId(), dept -> customer.setOwnerUserDeptName(dept.getName()));
});
return customerResp;
}
default PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page, Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
PageResult<CrmCustomerRespVO> result = convertPage(page);
result.getList().forEach(customerRespVO -> {
customerRespVO.setAreaName(AreaUtils.format(customerRespVO.getAreaId()));
MapUtils.findAndThen(userMap, NumberUtil.parseLong(customerRespVO.getCreator()), creator ->
customerRespVO.setCreatorName(creator.getNickname()));
MapUtils.findAndThen(userMap, customerRespVO.getOwnerUserId(), ownerUser -> {
customerRespVO.setOwnerUserName(ownerUser.getNickname());
MapUtils.findAndThen(deptMap, ownerUser.getDeptId(), dept ->
customerRespVO.setOwnerUserDeptName(dept.getName()));
});
});
return result;
findAndThen(userMap, Long.parseLong(customer.getCreator()), user -> customer.setCreatorName(user.getNickname()));
}
List<CrmCustomerExcelVO> convertList02(List<CrmCustomerDO> list);
@ -81,30 +62,24 @@ public interface CrmCustomerConvert {
PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> page);
// TODO @puhui999两个 convertPage 的逻辑合并下
default PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> pageResult, Map<Long, CrmPermissionDO> ownerMap,
Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap) {
default CrmCustomerRespVO convert(CrmCustomerDO customer, Map<Long, AdminUserRespDTO> userMap,
Map<Long, DeptRespDTO> deptMap) {
CrmCustomerRespVO customerResp = convert(customer);
setUserInfo(customerResp, userMap, deptMap);
return customerResp;
}
default PageResult<CrmCustomerRespVO> convertPage(PageResult<CrmCustomerDO> pageResult, Map<Long, AdminUserRespDTO> userMap,
Map<Long, DeptRespDTO> deptMap) {
PageResult<CrmCustomerRespVO> result = convertPage(pageResult);
result.getList().forEach(item -> {
findAndThen(ownerMap, item.getId(), owner -> {
item.setOwnerUserId(owner.getUserId());
item.setAreaName(AreaUtils.format(item.getAreaId()));
findAndThen(userMap, owner.getUserId(), user -> {
item.setOwnerUserName(user.getNickname());
});
findAndThen(userMap, Long.parseLong(item.getCreator()), user -> {
item.setCreatorName(user.getNickname());
});
findAndThen(deptMap, item.getOwnerUserId(), dept -> {
item.setOwnerUserDeptName(dept.getName());
});
});
});
result.getList().forEach(item -> setUserInfo(item, userMap, deptMap));
return result;
}
CrmCustomerPoolConfigRespVO convert(CrmCustomerPoolConfigDO customerPoolConfig);
CrmCustomerPoolConfigDO convert(CrmCustomerPoolConfigUpdateReqVO updateReqVO);
CrmCustomerPoolConfigDO convert(CrmCustomerPoolConfigSaveReqVO updateReqVO);
List<CrmCustomerQueryAllRespVO> convertQueryAll(List<CrmCustomerDO> crmCustomerDO);
}

View File

@ -1,10 +1,11 @@
package cn.iocoder.yudao.module.crm.convert.customer;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLimitConfigCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLimitConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.CrmCustomerLimitConfigUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customerlimitconfig.CrmCustomerLimitConfigDO;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigCreateReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigRespVO;
import cn.iocoder.yudao.module.crm.controller.admin.customer.vo.limitconfig.CrmCustomerLimitConfigUpdateReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerLimitConfigDO;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.mapstruct.Mapper;
@ -12,8 +13,6 @@ import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* 客户限制配置 Convert
@ -54,14 +53,11 @@ public interface CrmCustomerLimitConfigConvert {
*
* @param userMap 用户映射
* @param deptMap 部门映射
* @param respVo 响应实体
* @param respVo 响应实体
*/
static void fillNameField(Map<Long, AdminUserRespDTO> userMap, Map<Long, DeptRespDTO> deptMap, CrmCustomerLimitConfigRespVO respVo) {
// TODO wanwan返回 list具体怎么拼接叫给前端
respVo.setUserNames(respVo.getUserIds().stream().map(userMap::get)
.filter(Objects::nonNull).map(AdminUserRespDTO::getNickname).collect(Collectors.joining("")));
respVo.setDeptNames(respVo.getDeptIds().stream().map(deptMap::get)
.filter(Objects::nonNull).map(DeptRespDTO::getName).collect(Collectors.joining("")));
respVo.setUsers(CollectionUtils.convertList(respVo.getUserIds(), userMap::get));
respVo.setDepts(CollectionUtils.convertList(respVo.getDeptIds(), deptMap::get));
}
}

Some files were not shown because too many files have changed in this diff Show More