package cn.iocoder.yudao.module.crm.controller.admin.clue; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog; import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; import cn.iocoder.yudao.framework.ip.core.utils.AreaUtils; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmCluePageReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueRespVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueSaveReqVO; import cn.iocoder.yudao.module.crm.controller.admin.clue.vo.CrmClueTransferReqVO; import cn.iocoder.yudao.module.crm.dal.dataobject.clue.CrmClueDO; import cn.iocoder.yudao.module.crm.dal.dataobject.customer.CrmCustomerDO; import cn.iocoder.yudao.module.crm.service.clue.CrmClueService; import cn.iocoder.yudao.module.crm.service.customer.CrmCustomerService; 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.tags.Tag; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletResponse; import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; 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.apilog.core.enums.OperateTypeEnum.EXPORT; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.PageParam.PAGE_SIZE_NONE; 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.security.core.util.SecurityFrameworkUtils.getLoginUserId; import static java.util.Collections.singletonList; @Tag(name = "管理后台 - 线索") @RestController @RequestMapping("/crm/clue") @Validated public class CrmClueController { @Resource private CrmClueService clueService; @Resource private CrmCustomerService customerService; @Resource private AdminUserApi adminUserApi; @Resource private DeptApi deptApi; @PostMapping("/create") @Operation(summary = "创建线索") @PreAuthorize("@ss.hasPermission('crm:clue:create')") public CommonResult createClue(@Valid @RequestBody CrmClueSaveReqVO createReqVO) { return success(clueService.createClue(createReqVO)); } @PutMapping("/update") @Operation(summary = "更新线索") @PreAuthorize("@ss.hasPermission('crm:clue:update')") public CommonResult updateClue(@Valid @RequestBody CrmClueSaveReqVO updateReqVO) { clueService.updateClue(updateReqVO); return success(true); } @DeleteMapping("/delete") @Operation(summary = "删除线索") @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('crm:clue:delete')") public CommonResult deleteClue(@RequestParam("id") Long id) { clueService.deleteClue(id); return success(true); } @GetMapping("/get") @Operation(summary = "获得线索") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('crm:clue:query')") public CommonResult getClue(@RequestParam("id") Long id) { CrmClueDO clue = clueService.getClue(id); return success(buildClueDetail(clue)); } private CrmClueRespVO buildClueDetail(CrmClueDO clue) { if (clue == null) { return null; } return buildClueDetailList(singletonList(clue)).get(0); } @GetMapping("/page") @Operation(summary = "获得线索分页") @PreAuthorize("@ss.hasPermission('crm:clue:query')") public CommonResult> getCluePage(@Valid CrmCluePageReqVO pageVO) { PageResult pageResult = clueService.getCluePage(pageVO, getLoginUserId()); return success(new PageResult<>(buildClueDetailList(pageResult.getList()), pageResult.getTotal())); } @GetMapping("/export-excel") @Operation(summary = "导出线索 Excel") @PreAuthorize("@ss.hasPermission('crm:clue:export')") @ApiAccessLog(operateType = EXPORT) public void exportClueExcel(@Valid CrmCluePageReqVO pageReqVO, HttpServletResponse response) throws IOException { pageReqVO.setPageSize(PAGE_SIZE_NONE); List list = clueService.getCluePage(pageReqVO, getLoginUserId()).getList(); // 导出 Excel ExcelUtils.write(response, "线索.xls", "数据", CrmClueRespVO.class, buildClueDetailList(list)); } private List buildClueDetailList(List list) { if (CollUtil.isEmpty(list)) { return Collections.emptyList(); } // 1.1 获取客户列表 Map customerMap = customerService.getCustomerMap( convertSet(list, CrmClueDO::getCustomerId)); // 1.2 获取创建人、负责人列表 Map userMap = adminUserApi.getUserMap(convertListByFlatMap(list, contact -> Stream.of(NumberUtils.parseLong(contact.getCreator()), contact.getOwnerUserId()))); Map deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId)); // 2. 转换成 VO return BeanUtils.toBean(list, CrmClueRespVO.class, clueVO -> { clueVO.setAreaName(AreaUtils.format(clueVO.getAreaId())); // 2.1 设置客户名称 MapUtils.findAndThen(customerMap, clueVO.getCustomerId(), customer -> clueVO.setCustomerName(customer.getName())); // 2.2 设置创建人、负责人名称 MapUtils.findAndThen(userMap, NumberUtils.parseLong(clueVO.getCreator()), user -> clueVO.setCreatorName(user.getNickname())); MapUtils.findAndThen(userMap, clueVO.getOwnerUserId(), user -> { clueVO.setOwnerUserName(user.getNickname()); MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> clueVO.setOwnerUserDeptName(dept.getName())); }); }); } @PutMapping("/transfer") @Operation(summary = "线索转移") @PreAuthorize("@ss.hasPermission('crm:clue:update')") public CommonResult transferClue(@Valid @RequestBody CrmClueTransferReqVO reqVO) { clueService.transferClue(reqVO, getLoginUserId()); return success(true); } @PutMapping("/transform") @Operation(summary = "线索转化为客户") @Parameter(name = "id", description = "编号", required = true) @PreAuthorize("@ss.hasPermission('crm:clue:update')") public CommonResult transformClue(@RequestParam("id") Long id) { clueService.transformClue(id, getLoginUserId()); return success(Boolean.TRUE); } @GetMapping("/follow-count") @Operation(summary = "获得分配给我的、待跟进的线索数量") @PreAuthorize("@ss.hasPermission('crm:clue:query')") public CommonResult getFollowClueCount() { return success(clueService.getFollowClueCount(getLoginUserId())); } }