Compare commits

...

3 Commits

Author SHA1 Message Date
furongxin
3c8796d0de Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud into frx 2025-02-22 16:31:29 +08:00
aikai
fb5607f1ea Merge branch 'dev' of http://git.znkjfw.com/ak/zn-cloud into dev 2025-02-22 16:13:48 +08:00
aikai
e34cd7cca6 feat(crm): 添加用户结构树功能
- 新增 UserLiveTree 相关的 VO、DO、Mapper、Service、Controller 等类
- 实现用户结构树
2025-02-22 16:13:41 +08:00
26 changed files with 574 additions and 30 deletions

View File

@ -0,0 +1,102 @@
package cn.iocoder.yudao.module.crm.controller.admin.userlivetree;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.security.access.prepost.PreAuthorize;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Operation;
import javax.validation.constraints.*;
import javax.validation.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.IOException;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.*;
import cn.iocoder.yudao.module.crm.dal.dataobject.userlivetree.UserLiveTreeDO;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
@Tag(name = "管理后台 - crm用户结构树")
@RestController
@RequestMapping("/crm/user-live-tree")
@Validated
public class UserLiveTreeController {
@Resource
private UserLiveTreeService userLiveTreeService;
@PostMapping("/create")
@Operation(summary = "创建crm用户结构树")
@PreAuthorize("@ss.hasPermission('crm:user-live-tree:create')")
public CommonResult<Long> createUserLiveTree(@Valid @RequestBody UserLiveTreeSaveReqVO createReqVO) {
return success(userLiveTreeService.createUserLiveTree(createReqVO));
}
@PostMapping("/list")
@Operation(summary = "crm用户结构树列表")
public CommonResult<List<UserLiveTreeListVO>> userLiveTreeList(@Valid @RequestBody UserLiveTreePageReqVO pageReqVO) {
return success(userLiveTreeService.userLiveTreeList(pageReqVO));
}
@PutMapping("/update")
@Operation(summary = "更新crm用户结构树")
@PreAuthorize("@ss.hasPermission('crm:user-live-tree:update')")
public CommonResult<Boolean> updateUserLiveTree(@Valid @RequestBody UserLiveTreeSaveReqVO updateReqVO) {
userLiveTreeService.updateUserLiveTree(updateReqVO);
return success(true);
}
@DeleteMapping("/delete")
@Operation(summary = "删除crm用户结构树")
@Parameter(name = "id", description = "编号", required = true)
@PreAuthorize("@ss.hasPermission('crm:user-live-tree:delete')")
public CommonResult<Boolean> deleteUserLiveTree(@RequestParam("id") Long id) {
userLiveTreeService.deleteUserLiveTree(id);
return success(true);
}
@GetMapping("/get")
@Operation(summary = "获得crm用户结构树")
@Parameter(name = "id", description = "编号", required = true, example = "1024")
@PreAuthorize("@ss.hasPermission('crm:user-live-tree:query')")
public CommonResult<UserLiveTreeRespVO> getUserLiveTree(@RequestParam("id") Long id) {
UserLiveTreeDO userLiveTree = userLiveTreeService.getUserLiveTree(id);
return success(BeanUtils.toBean(userLiveTree, UserLiveTreeRespVO.class));
}
@GetMapping("/page")
@Operation(summary = "获得crm用户结构树分页")
@PreAuthorize("@ss.hasPermission('crm:user-live-tree:query')")
public CommonResult<PageResult<UserLiveTreeRespVO>> getUserLiveTreePage(@Valid UserLiveTreePageReqVO pageReqVO) {
PageResult<UserLiveTreeDO> pageResult = userLiveTreeService.getUserLiveTreePage(pageReqVO);
return success(BeanUtils.toBean(pageResult, UserLiveTreeRespVO.class));
}
@GetMapping("/export-excel")
@Operation(summary = "导出crm用户结构树 Excel")
@PreAuthorize("@ss.hasPermission('crm:user-live-tree:export')")
@OperateLog(type = EXPORT)
public void exportUserLiveTreeExcel(@Valid UserLiveTreePageReqVO pageReqVO,
HttpServletResponse response) throws IOException {
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
List<UserLiveTreeDO> list = userLiveTreeService.getUserLiveTreePage(pageReqVO).getList();
// 导出 Excel
ExcelUtils.write(response, "crm用户结构树.xls", "数据", UserLiveTreeRespVO.class,
BeanUtils.toBean(list, UserLiveTreeRespVO.class));
}
}

View File

@ -0,0 +1,37 @@
package cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class UserLiveTreeListVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2907")
private Long id;
@Schema(description = "用户id", example = "4341")
private Long userId;
@Schema(description = "上级用户id", example = "6431")
private Long pid;
@Schema(description = "用户账号", example = "6431")
private String username;
@Schema(description = "用户昵称", example = "6431")
private String nickname;
@Schema(description = "部门 ID", example = "6431")
private Long deptId;
@Schema(description = "部门 名称", example = "6431")
private String deptName;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
private LocalDateTime createTime;
@Schema(description = "子集列表", example = "6431")
private List<UserLiveTreeListVO> items;
}

View File

@ -0,0 +1,28 @@
package cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo;
import lombok.*;
import java.util.*;
import io.swagger.v3.oas.annotations.media.Schema;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
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 UserLiveTreePageReqVO extends PageParam {
@Schema(description = "用户id", example = "4341")
private Long userId;
@Schema(description = "上级用户id", example = "6431")
private Long pid;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import java.util.*;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import com.alibaba.excel.annotation.*;
@Schema(description = "管理后台 - crm用户结构树 Response VO")
@Data
@ExcelIgnoreUnannotated
public class UserLiveTreeRespVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2907")
@ExcelProperty("主键")
private Long id;
@Schema(description = "用户id", example = "4341")
@ExcelProperty("用户id")
private Long userId;
@Schema(description = "上级用户id", example = "6431")
@ExcelProperty("上级用户id")
private Long pid;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.*;
import javax.validation.constraints.*;
import java.util.*;
@Schema(description = "管理后台 - crm用户结构树新增/修改 Request VO")
@Data
public class UserLiveTreeSaveReqVO {
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "2907")
private Long id;
@Schema(description = "用户id", example = "4341")
private Long userId;
@Schema(description = "上级用户id", example = "6431")
private Long pid;
}

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.crm.dal.dataobject.userlivetree;
import lombok.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.LocalDateTime;
import com.baomidou.mybatisplus.annotation.*;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
/**
* crm用户结构树 DO
*
* @author 艾楷
*/
@TableName("crm_user_live_tree")
@KeySequence("crm_user_live_tree_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserLiveTreeDO extends BaseDO {
/**
* 主键
*/
@TableId
private Long id;
/**
* 用户id
*/
private Long userId;
/**
* 上级用户id
*/
private Long pid;
}

View File

@ -0,0 +1,35 @@
package cn.iocoder.yudao.module.crm.dal.mysql.userlivetree;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreeListVO;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreePageReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.userlivetree.UserLiveTreeDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/**
* crm用户结构树 Mapper
*
* @author 艾楷
*/
@Mapper
public interface UserLiveTreeMapper extends BaseMapperX<UserLiveTreeDO> {
default PageResult<UserLiveTreeDO> selectPage(UserLiveTreePageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<UserLiveTreeDO>()
.eqIfPresent(UserLiveTreeDO::getUserId, reqVO.getUserId())
.eqIfPresent(UserLiveTreeDO::getPid, reqVO.getPid())
.betweenIfPresent(UserLiveTreeDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(UserLiveTreeDO::getId));
}
/**
* 获取用户结构树列表
*
* @return
*/
List<UserLiveTreeListVO> userLiveTreeList();
}

View File

@ -28,6 +28,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmcontract.CrmContractMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcontractreceivables.CrmContractReceivablesMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.service.crmclues.CrmCluesService;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.ContractStatusEnum;
import cn.iocoder.yudao.module.hrm.enums.FlowStepEnum;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
@ -84,6 +85,8 @@ public class AchievementServiceImpl implements AchievementService {
@Resource
private BpmOAReceiptApi receiptApi;
@Resource
private UserLiveTreeService userLiveTreeService;
@Override
@ -180,7 +183,7 @@ public class AchievementServiceImpl implements AchievementService {
if (RelationEnum.MY.getValue().equals(relation)) {
userIds.add(userId);
} else if (RelationEnum.SUB.getValue().equals(relation)) {
userIds = adminUserApi.getUserListBySubordinateIds(userId).getData();
userIds = userLiveTreeService.getItemIdsByUserId(userId);
}
//合同目标
List<CrmAchievementDO> crmAchievementDO = achievementMapper.selectList(new LambdaQueryWrapperX<CrmAchievementDO>()
@ -346,7 +349,7 @@ public class AchievementServiceImpl implements AchievementService {
if (RelationEnum.MY.getValue().equals(relation)) {
userIds.add(userId);
} else if (RelationEnum.SUB.getValue().equals(relation)) {
userIds = adminUserApi.getUserListBySubordinateIds(userId).getData();
userIds = userLiveTreeService.getItemIdsByUserId(userId);
}
List<SalesVO> salesVOS = new ArrayList<>();
int i = 1;

View File

@ -17,6 +17,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmbusiness.CrmBusinessMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmbusiness.CrmBusinessProductMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
import cn.iocoder.yudao.module.hrm.enums.TypesEnum;
import cn.iocoder.yudao.module.product.api.storeproductattrvalue.StoreProductAttrValueApi;
@ -57,9 +58,9 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
@Resource
private CrmCustomerMapper customerMapper;
@Resource
private AdminUserApi adminUserApi;
@Resource
private CrmRecordMapper crmRecordMapper;
@Resource
private UserLiveTreeService userLiveTreeService;
@Override
@Transactional(rollbackFor = Exception.class)
@ -127,7 +128,7 @@ public class CrmBusinessServiceImpl implements CrmBusinessService {
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(adminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(adminId);
}
IPage mpPage = MyBatisUtils.buildPage(pageReqVO);

View File

@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.crmrecord.CrmRecordDO;
import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.CluesStatusEnum;
import cn.iocoder.yudao.module.hrm.enums.CustomerTypesEnum;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
@ -57,6 +58,8 @@ public class CrmCluesServiceImpl implements CrmCluesService {
private CrmCustomerMapper customerMapper;
@Resource
private CrmRecordMapper crmRecordMapper;
@Resource
private UserLiveTreeService userLiveTreeService;
@Override
public Long createClues(CrmCluesSaveReqVO createReqVO) {
@ -113,7 +116,7 @@ public class CrmCluesServiceImpl implements CrmCluesService {
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(adminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(adminId);
}
IPage mpPage = MyBatisUtils.buildPage(pageReqVO);

View File

@ -33,6 +33,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmflow.CrmFlowMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmflow.CrmFlowStepMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmflowlog.CrmFlowLogMapper;
import cn.iocoder.yudao.module.crm.service.crmoperatelog.CrmOperatelogService;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.ContractStatusEnum;
import cn.iocoder.yudao.module.hrm.enums.FlowStepEnum;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
@ -101,11 +102,11 @@ public class CrmContractServiceImpl implements CrmContractService {
@Resource
private RedissonClient redissonClient;
@Resource
private CrmOperatelogService crmOperatelogService;
@Resource
private AdminUserApi adminUserApi;
@Resource
private CrmCustomerContactsMapper crmCustomerContactsMapper;
@Resource
private UserLiveTreeService userLiveTreeService;
private static final String LOCK_KEY = "contract:check:lock";
@ -233,7 +234,7 @@ public class CrmContractServiceImpl implements CrmContractService {
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(loginAdminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(loginAdminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(loginAdminId);
}
pageReqVO.setLoginAdminId(loginAdminId);
IPage mpPage = MyBatisUtils.buildPage(pageReqVO);

View File

@ -28,6 +28,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmflow.CrmFlowMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmflow.CrmFlowStepMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmflowlog.CrmFlowLogMapper;
import cn.iocoder.yudao.module.crm.service.crmoperatelog.CrmOperatelogService;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.ContractStatusEnum;
import cn.iocoder.yudao.module.hrm.enums.FlowStepEnum;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
@ -83,6 +84,9 @@ public class CrmContractReceivablesServiceImpl implements CrmContractReceivables
private CrmFlowLogMapper crmFlowLogMapper;
@Resource
private AdminUserApi adminUserApi;
@Resource
private UserLiveTreeService userLiveTreeService;
private static final String LOCK_KEY = "receivables:check:lock";
@ -180,7 +184,7 @@ public class CrmContractReceivablesServiceImpl implements CrmContractReceivables
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(loginAdminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(loginAdminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(loginAdminId);
}
pageReqVO.setLoginAdminId(loginAdminId);
IPage mpPage = MyBatisUtils.buildPage(pageReqVO);

View File

@ -22,6 +22,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomercontacts.CrmCustomerContactsMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import cn.iocoder.yudao.module.crm.service.crmoperatelog.CrmOperatelogService;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.CustomerTypesEnum;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
import cn.iocoder.yudao.module.hrm.enums.TypesEnum;
@ -78,6 +79,8 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
private CrmContractMapper contractMapper;
@Resource
private CrmContractReceivablesMapper contractReceivablesMapper;
@Resource
private UserLiveTreeService userLiveTreeService;
@Override
@ -239,7 +242,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(adminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(adminId);
}
}
return customerMapper.selectPage(pageReqVO, ids);
@ -256,7 +259,7 @@ public class CrmCustomerServiceImpl implements CrmCustomerService {
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(adminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(adminId);
}
}
IPage mpPage = MyBatisUtils.buildPage(pageReqVO);

View File

@ -11,8 +11,8 @@ import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomer.CrmCustomerDO;
import cn.iocoder.yudao.module.crm.dal.dataobject.crmcustomercontacts.CrmCustomerContactsDO;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomercontacts.CrmCustomerContactsMapper;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
@ -38,7 +38,7 @@ public class CrmCustomerContactsServiceImpl implements CrmCustomerContactsServic
@Resource
private CrmCustomerMapper customerMapper;
@Resource
private AdminUserApi adminUserApi;
private UserLiveTreeService userLiveTreeService;
@Override
public Long createCustomerContacts(CrmCustomerContactsSaveReqVO createReqVO) {
@ -89,7 +89,7 @@ public class CrmCustomerContactsServiceImpl implements CrmCustomerContactsServic
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(adminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(adminId);
}
IPage mpPage = MyBatisUtils.buildPage(pageReqVO);
IPage<CrmCustomerContactsRespVO> pageResult = customerContactsMapper.selectPageList(mpPage, pageReqVO, ids);

View File

@ -21,6 +21,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomercontacts.CrmCustomerContactsMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
import cn.iocoder.yudao.module.system.api.notice.NoticeApi;
import cn.iocoder.yudao.module.system.api.notice.dto.NoticeDTO;
@ -65,6 +66,8 @@ public class CrmIndexServiceImpl implements CrmIndexService {
@Resource
private BpmOAReceiptApi receiptApi;
@Resource
private UserLiveTreeService userLiveTreeService;
@Override
@ -130,7 +133,7 @@ public class CrmIndexServiceImpl implements CrmIndexService {
if (RelationEnum.MY.getValue().equals(relation)) {
ids.add(adminId);
} else if (RelationEnum.SUB.getValue().equals(relation)) {
ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(adminId);
}
Long count01 = businessMapper.selectCount(new LambdaQueryWrapper<CrmBusinessDO>()

View File

@ -22,6 +22,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmflow.CrmFlowMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmflow.CrmFlowStepMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmflowlog.CrmFlowLogMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crminvoice.CrmInvoiceMapper;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.*;
import cn.iocoder.yudao.module.system.api.mail.MailSendApi;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
@ -67,6 +68,8 @@ public class CrmInvoiceServiceImpl implements CrmInvoiceService {
private RedissonClient redissonClient;
@Resource
private CrmFlowLogMapper crmFlowLogMapper;
@Resource
private UserLiveTreeService userLiveTreeService;
private static final String LOCK_KEY = "invoice:check:lock";
@ -176,7 +179,7 @@ public class CrmInvoiceServiceImpl implements CrmInvoiceService {
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(loginAdminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(loginAdminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(loginAdminId);
}
PageResult<CrmInvoiceRespVO> pageResult = invoiceMapper.selectPage2(pageReqVO, ids);
for (CrmInvoiceRespVO respVO : pageResult.getList()) {
@ -240,7 +243,7 @@ public class CrmInvoiceServiceImpl implements CrmInvoiceService {
CrmFlowStepDO next = flowStepMapper.selectOne(new LambdaQueryWrapper<CrmFlowStepDO>()
.eq(CrmFlowStepDO::getFlowId, invoiceDO.getFlowId()).eq(CrmFlowStepDO::getRelation, crmFlowStepDO.getRelation() + 1));
if (FlowStepEnum.TYPE_3.getValue().equals(next.getType())) {
list = adminUserApi.getUserListBySubordinateIds(next.getAdminIds()).getCheckedData();
list = userLiveTreeService.getItemIdsByUserId(next.getAdminIds());
} else {
list.add(next.getAdminIds());
}

View File

@ -20,6 +20,7 @@ import cn.iocoder.yudao.module.crm.dal.mysql.crmclues.CrmCluesMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmcustomer.CrmCustomerMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecord.CrmRecordMapper;
import cn.iocoder.yudao.module.crm.dal.mysql.crmrecorduser.CrmRecordUserMapper;
import cn.iocoder.yudao.module.crm.service.userlivetree.UserLiveTreeService;
import cn.iocoder.yudao.module.hrm.enums.RelationEnum;
import cn.iocoder.yudao.module.hrm.enums.TypesEnum;
import cn.iocoder.yudao.module.system.api.dict.DictDataApi;
@ -68,7 +69,8 @@ public class CrmRecordServiceImpl implements CrmRecordService {
private CrmCluesMapper cluesMapper;
@Resource
private DictDataApi dictDataApi;
@Resource
private UserLiveTreeService userLiveTreeService;
@Override
@Transactional(rollbackFor = Exception.class)
public Long createRecord(CrmRecordSaveReqVO createReqVO) {
@ -177,7 +179,7 @@ public class CrmRecordServiceImpl implements CrmRecordService {
if (RelationEnum.MY.getValue().equals(pageReqVO.getRelation())) {
ids.add(adminId);
} else if (RelationEnum.SUB.getValue().equals(pageReqVO.getRelation())) {
ids = adminUserApi.getUserListBySubordinateIds(adminId).getCheckedData();
ids = userLiveTreeService.getItemIdsByUserId(adminId);
}
LocalDateTime beginTime = pageReqVO.getNextTime() != null && pageReqVO.getNextTime().length > 0 ? pageReqVO.getNextTime()[0] : null;
LocalDateTime endTime = pageReqVO.getNextTime() != null && pageReqVO.getNextTime().length > 0 ? pageReqVO.getNextTime()[1] : null;

View File

@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.crm.service.userlivetree;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreeListVO;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreePageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreeSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.userlivetree.UserLiveTreeDO;
import javax.validation.Valid;
import java.util.List;
/**
* crm用户结构树 Service 接口
*
* @author 艾楷
*/
public interface UserLiveTreeService {
/**
* 创建crm用户结构树
*
* @param createReqVO 创建信息
* @return 编号
*/
Long createUserLiveTree(@Valid UserLiveTreeSaveReqVO createReqVO);
/**
* 更新crm用户结构树
*
* @param updateReqVO 更新信息
*/
void updateUserLiveTree(@Valid UserLiveTreeSaveReqVO updateReqVO);
/**
* 删除crm用户结构树
*
* @param id 编号
*/
void deleteUserLiveTree(Long id);
/**
* 获得crm用户结构树
*
* @param id 编号
* @return crm用户结构树
*/
UserLiveTreeDO getUserLiveTree(Long id);
/**
* 获得crm用户结构树分页
*
* @param pageReqVO 分页查询
* @return crm用户结构树分页
*/
PageResult<UserLiveTreeDO> getUserLiveTreePage(UserLiveTreePageReqVO pageReqVO);
/**
* 获取列表
*
* @param pageReqVO
* @return
*/
List<UserLiveTreeListVO> userLiveTreeList(@Valid UserLiveTreePageReqVO pageReqVO);
/**
* 通过用户id获取所有子集用户id
*
* @param id
* @return
*/
List<Long> getItemIdsByUserId(Long id);
}

View File

@ -0,0 +1,113 @@
package cn.iocoder.yudao.module.crm.service.userlivetree;
import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreeListVO;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreePageReqVO;
import cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreeSaveReqVO;
import cn.iocoder.yudao.module.crm.dal.dataobject.userlivetree.UserLiveTreeDO;
import cn.iocoder.yudao.module.crm.dal.mysql.userlivetree.UserLiveTreeMapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* crm用户结构树 Service 实现类
*
* @author 艾楷
*/
@Service
@Validated
public class UserLiveTreeServiceImpl implements UserLiveTreeService {
@Resource
private UserLiveTreeMapper userLiveTreeMapper;
@Override
public Long createUserLiveTree(UserLiveTreeSaveReqVO createReqVO) {
// 插入
UserLiveTreeDO userLiveTree = BeanUtils.toBean(createReqVO, UserLiveTreeDO.class);
userLiveTreeMapper.insert(userLiveTree);
// 返回
return userLiveTree.getId();
}
@Override
public void updateUserLiveTree(UserLiveTreeSaveReqVO updateReqVO) {
// 更新
UserLiveTreeDO updateObj = BeanUtils.toBean(updateReqVO, UserLiveTreeDO.class);
userLiveTreeMapper.updateById(updateObj);
}
@Override
public void deleteUserLiveTree(Long id) {
// 删除
userLiveTreeMapper.deleteById(id);
}
@Override
public UserLiveTreeDO getUserLiveTree(Long id) {
return userLiveTreeMapper.selectById(id);
}
@Override
public PageResult<UserLiveTreeDO> getUserLiveTreePage(UserLiveTreePageReqVO pageReqVO) {
return userLiveTreeMapper.selectPage(pageReqVO);
}
@Override
public List<UserLiveTreeListVO> userLiveTreeList(UserLiveTreePageReqVO pageReqVO) {
List<UserLiveTreeListVO> userLiveTreeDOS = this.userLiveTreeList();
return userLiveTreeDOS.stream()
.filter(vo -> vo.getPid() == 0)
.collect(Collectors.toList());
}
@Override
public List<Long> getItemIdsByUserId(Long userId) {
List<UserLiveTreeListVO> userLiveTreeListVOS = this.userLiveTreeList();
Map<Long, List<UserLiveTreeListVO>> map = userLiveTreeListVOS.stream().collect(Collectors.groupingBy(UserLiveTreeListVO::getUserId));
List<UserLiveTreeListVO> list = map.get(userId);
List<Long> ids = new ArrayList<>();
this.recursionGetId(list, ids);
ids.remove(userId);
return ids;
}
private void recursionGetId(List<UserLiveTreeListVO> list, List<Long> ids) {
if (CollectionUtil.isEmpty(list)){
return;
}
List<UserLiveTreeListVO> nextList = new ArrayList<>();
for (UserLiveTreeListVO userLiveTreeListVO : list) {
ids.add(userLiveTreeListVO.getUserId());
if (CollectionUtil.isNotEmpty(userLiveTreeListVO.getItems())){
nextList.addAll(userLiveTreeListVO.getItems());
}
}
recursionGetId(nextList, ids);
}
public List<UserLiveTreeListVO> userLiveTreeList(){
// -- 这里将所有的数据拉出来 -
List<UserLiveTreeListVO> userLiveTreeDOS = userLiveTreeMapper.userLiveTreeList();
// 1. 按父ID分组获取每个父节点下的子节点列表
Map<Long, List<UserLiveTreeListVO>> pidGroupMap = userLiveTreeDOS.stream()
.collect(Collectors.groupingBy(UserLiveTreeListVO::getPid));
// 2. 遍历所有节点设置它们的子节点列表
for (UserLiveTreeListVO vo : userLiveTreeDOS) {
vo.setItems(pidGroupMap.getOrDefault(vo.getUserId(), Collections.emptyList()));
}
return userLiveTreeDOS;
}
}

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.crm.dal.mysql.userlivetree.UserLiveTreeMapper">
<!--
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
文档可见https://www.iocoder.cn/MyBatis/x-plugins/
-->
<select id="userLiveTreeList"
resultType="cn.iocoder.yudao.module.crm.controller.admin.userlivetree.vo.UserLiveTreeListVO">
select
a.id,
a.user_id,
a.pid,
a.create_time,
b.username,
b.nickname,
b.dept_id as deptId,
c.name as deptName
from crm_user_live_tree as a
left join system_users as b on a.user_id = b.id
left join system_dept as c on b.dept_id = c.id
<where>
a.deleted = 0
and b.deleted = 0
and c.deleted = 0
and b.status = 0
</where>
</select>
</mapper>

View File

@ -147,7 +147,7 @@ public class AdminUserApiImpl implements AdminUserApi {
@Override
public CommonResult<List<AdminUserRespDTO>> getUserListAll(Integer userType, Long deptId, Integer status, String roleCodes) {
List<AdminUserDO> userList = userService.getUserListByStatus(userType, deptId, status, roleCodes);
List<AdminUserDO> userList = userService.getUserListByStatus(userType, deptId, status, roleCodes, null);
return success(BeanUtils.toBean(userList, AdminUserRespDTO.class));
}
@ -156,6 +156,7 @@ public class AdminUserApiImpl implements AdminUserApi {
return success(BeanUtils.toBean(userService.getUserPageByRole(dto), AdminUserApiVO.class));
}
@Override
public CommonResult<PageResult<AdminUserApiVO>> getUserBringDeptPage(AdminUserPageApiDTO dto) {
PageResult<AdminUserApiVO> vo = new PageResult<>();

View File

@ -164,8 +164,9 @@ public class UserController {
public CommonResult<List<UserSimpleRespVO>> getSimpleUserList(@RequestParam(required = false, defaultValue = "1") Integer userType,
@RequestParam(required = false) Long deptId,
@RequestParam(required = false, defaultValue = "0") Integer status,
@RequestParam(required = false) String roleCodes) {
List<AdminUserDO> list = userService.getUserListByStatus(userType, deptId, status, roleCodes);
@RequestParam(required = false) String roleCodes,
@RequestParam(required = false) Integer filterCrmUserFlag) {
List<AdminUserDO> list = userService.getUserListByStatus(userType, deptId, status, roleCodes, filterCrmUserFlag);
// 拼接数据
Map<Long, DeptDO> deptMap = deptService.getDeptMap(
convertList(list, AdminUserDO::getDeptId));
@ -178,9 +179,10 @@ public class UserController {
public CommonResult<List<UserSimpleRespVO>> getAllUserList(@RequestParam(required = false, defaultValue = "1") Integer userType,
@RequestParam(required = false) Long deptId,
@RequestParam(required = false, defaultValue = "0") Integer status,
@RequestParam(required = false) String roleCodes) {
@RequestParam(required = false) String roleCodes,
@RequestParam(required = false) Integer filterCrmUserFlag) {
List<AdminUserDO> list = userService.getUserListByStatus(userType, deptId, status, roleCodes);
List<AdminUserDO> list = userService.getUserListByStatus(userType, deptId, status, roleCodes, filterCrmUserFlag);
// 拼接数据
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertSet(list, AdminUserDO::getDeptId));
return success(UserConvert.INSTANCE.convertSimpleList(list, deptMap));
@ -346,7 +348,7 @@ public class UserController {
if (deptDO.getFactoryId() == null) {
return success(false);
}else {
} else {
return success(true);
}
}

View File

@ -65,7 +65,9 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
return selectList(new LambdaQueryWrapperX<AdminUserDO>().like(AdminUserDO::getNickname, nickname));
}
List<AdminUserDO> selectListByCondition(@Param("userType") Integer userType, @Param("deptIds") List<Long> deptIds, @Param("status") Integer status, @Param("roleCodeList") List<String> roleCodeList);
List<AdminUserDO> selectListByCondition(@Param("userType") Integer userType, @Param("deptIds") List<Long> deptIds,
@Param("status") Integer status, @Param("roleCodeList") List<String> roleCodeList,
@Param("filterCrmUserFlag") Integer filterCrmUserFlag);
default List<AdminUserDO> selectListByDeptIds(Collection<Long> deptIds, Integer status) {

View File

@ -299,7 +299,7 @@ public interface AdminUserService {
* @param roleCodes 角色编码
* @return 用户们
*/
List<AdminUserDO> getUserListByStatus(Integer userType, Long deptId, Integer status, String roleCodes);
List<AdminUserDO> getUserListByStatus(Integer userType, Long deptId, Integer status, String roleCodes,Integer filterCrmUserFlag);
/**
* 判断密码是否匹配

View File

@ -686,7 +686,7 @@ public class AdminUserServiceImpl implements AdminUserService {
}
@Override
public List<AdminUserDO> getUserListByStatus(Integer userType, Long deptId, Integer status, String roleCodes) {
public List<AdminUserDO> getUserListByStatus(Integer userType, Long deptId, Integer status, String roleCodes, Integer filterCrmUserFlag) {
List<Long> deptIds = new ArrayList<>();
if (deptId != null) {
deptIds = convertList(deptService.getChildDept(deptId), DeptDO::getId);
@ -695,7 +695,7 @@ public class AdminUserServiceImpl implements AdminUserService {
if (StringUtil.isNotEmpty(roleCodes)) {
roleCodeList = Arrays.asList(roleCodes.split(","));
}
return userMapper.selectListByCondition(userType, deptIds, status, roleCodeList);
return userMapper.selectListByCondition(userType, deptIds, status, roleCodeList, filterCrmUserFlag);
}
@Override

View File

@ -206,6 +206,9 @@
#{roleCode}
</foreach>
</if>
<if test="filterCrmUserFlag != null and filterCrmUserFlag == 1">
not exists (SELECT id from crm_user_live_tree where a.id = id)
</if>
</where>
</select>