Ver código fonte

feat: 增加客户管理拜访计划

zhaojianyang 3 meses atrás
pai
commit
cfec9b6546

+ 52 - 1
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/controller/BlinkCustomerController.java

@@ -2,6 +2,7 @@ package com.wx.blink.backend.controller;
 
 import com.wx.blink.backend.domain.dto.*;
 import com.wx.blink.backend.domain.qry.BlinkBizFileQry;
+import com.wx.blink.backend.domain.qry.BlinkCustomerVisitPlanQry;
 import com.wx.blink.backend.service.*;
 import com.wx.blink.base.common.domain.PageResult;
 import com.wx.blink.base.common.domain.ResponseDTO;
@@ -39,6 +40,8 @@ public class BlinkCustomerController {
     private IBlinkCustomerFollowService followService;
     @Resource
     private IBlinkCustomerDecisionChainService decisionChainService;
+    @Resource
+    private IBlinkCustomerVisitPlanService visitPlanService;
 
     @Operation(summary = "新增客户")
     @PostMapping("/supports/customer/create")
@@ -203,9 +206,57 @@ public class BlinkCustomerController {
         return ResponseDTO.ok();
     }
 
-    @Operation(summary = "查询决策链团队")
+    @Operation(summary = "查询决策链列表")
     @GetMapping(value = "/supports/customer/getDecisionChainListByCustomerId/{customerId}")
     public ResponseDTO<List<BlinkCustomerDecisionChainVO>> getDecisionChainListByCusId(@PathVariable String customerId) {
         return ResponseDTO.ok(decisionChainService.getDecisionChainListByCustomerId(customerId));
     }
+
+    //---------------------------------------------拜访计划-------------------------------------------------------//
+
+    @Operation(summary = "创建拜访计划")
+    @PostMapping(value = "/supports/customer/visitPlan/add")
+    public ResponseDTO visitPlanAdd(@RequestBody BlinkCustomerVisitPlanVO vo) {
+        visitPlanService.addOrUpdate(vo);
+        return ResponseDTO.ok();
+    }
+
+    @Operation(summary = "取消拜访")
+    @PostMapping(value = "/supports/customer/visitPlan/cancel")
+    public ResponseDTO visitPlanCancel(@RequestBody BlinkCustomerVisitPlanVO vo) {
+        visitPlanService.visitCancel(vo);
+        return ResponseDTO.ok();
+    }
+
+    @Operation(summary = "拜访完成")
+    @PostMapping(value = "/supports/customer/visitPlan/completed")
+    public ResponseDTO visitPlanCompleted(@RequestBody BlinkCustomerVisitPlanVO vo) {
+        visitPlanService.visitCompleted(vo);
+        return ResponseDTO.ok();
+    }
+
+    @Operation(summary = "拜访计划日历数据个数查询")
+    @PostMapping(value = "/supports/customer/visitPlan/calendarNum")
+    public ResponseDTO<List<BlinkCustomerVisitPlanCalendarVO>> visitPlanCalendarNum() {
+        return ResponseDTO.ok(visitPlanService.getVisitPlanCalendarNum());
+    }
+
+    @Operation(summary = "拜访计划查询列表表头统计数据接口")
+    @PostMapping(value = "/supports/customer/visitPlan/statistics")
+    public ResponseDTO<BlinkCustomerVisitPlanStatisticsVO> visitPlanStatisticsInfo(@RequestBody BlinkCustomerVisitPlanQry qry) {
+        // BlinkCustomerVisitPlanQry qry = new BlinkCustomerVisitPlanQry();
+        return ResponseDTO.ok(visitPlanService.visitPlanStatisticsInfo(qry));
+    }
+
+    @Operation(summary = "查询拜访计划列表")
+    @PostMapping(value = "/supports/customer/visitPlan/queryPage")
+    public ResponseDTO<PageResult<BlinkCustomerVisitPlanVO>> visitPlanQueryPage(@RequestBody BlinkCustomerVisitPlanQry qry) {
+        return ResponseDTO.ok(visitPlanService.visitPlanQueryPage(qry));
+    }
+
+    @Operation(summary = "获取拜访计划详细信息")
+    @GetMapping(value = "/supports/customer/visitPlan/{id}")
+    public ResponseDTO<BlinkCustomerVisitPlanVO> visitPlanSingleQuery(@PathVariable String id) {
+        return ResponseDTO.ok(visitPlanService.visitPlanSingleQuery(id));
+    }
 }

+ 77 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/domain/dataobject/BlinkCustomerVisitPlanDO.java

@@ -0,0 +1,77 @@
+package com.wx.blink.backend.domain.dataobject;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.wx.blink.base.common.domain.BaseEntity;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+
+/*客户拜访计划*/
+@Data
+@TableName("blink_customer_visit_plan")
+public class BlinkCustomerVisitPlanDO extends BaseEntity {
+
+    @Schema(description = "id")
+    @TableId(type = IdType.ASSIGN_UUID)
+    private String id;
+
+    @Schema(description = "计划名称")
+    @TableField("plan_name")
+    private String planName;
+    @Schema(description = "预计时间")
+    @TableField("expected_time")
+    private Date expectedTime;
+    @Schema(description = "提前提醒时间")
+    @TableField("reminder_time")
+    private Double reminderTime;
+    @Schema(description = "时间类型")
+    @TableField("time_type")
+    private String timeType;
+    @Schema(description = "客户")
+    @TableField("customer_id")
+    private String customerId;
+    @Schema(description = "项目名称")
+    @TableField("project_id")
+    private String projectId;
+    @Schema(description = "拜访目的")
+    @TableField("visit_purpose")
+    private String visitPurpose;
+    @Schema(description = "拜访省市区")
+    @TableField("visit_ssq")
+    private String visitSsq;
+    @Schema(description = "拜访地址")
+    @TableField("visit_address")
+    private String visitAddress;
+    @Schema(description = "拜访责任人")
+    @TableField("visit_responsible_man")
+    private String visitResponsibleMan;
+    @Schema(description = "完成客户名称")
+    @TableField("completed_customer_id")
+    private String completedCustomerId;
+    @Schema(description = "完成项目名称")
+    @TableField("completed_project_id")
+    private String completedProjectId;
+    @Schema(description = "完成拜访省市区")
+    @TableField("completed_visit_ssq")
+    private String completedVisitSsq;
+    @Schema(description = "完成拜访地址")
+    @TableField("completed_visit_address")
+    private String completedVisitAddress;
+    @Schema(description = "拜访结果")
+    @TableField("visit_result")
+    private String visitResult;
+    @Schema(description = "取消原因")
+    @TableField("cancel_reason")
+    private String cancelReason;
+    @Schema(description = "原因说明")
+    @TableField("reason_description")
+    private String reasonDescription;
+    @Schema(description = "状态(0新创建,1已完成,2已取消)")
+    @TableField("status")
+    private Integer status;
+
+}

+ 18 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/domain/dto/BlinkCustomerVisitPlanCalendarVO.java

@@ -0,0 +1,18 @@
+package com.wx.blink.backend.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class BlinkCustomerVisitPlanCalendarVO {
+
+    /**
+     *  周几
+     */
+    private Integer dayOfMonth;
+
+    /**
+     * 数据数量
+     */
+    private Integer dailyCount;
+
+}

+ 18 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/domain/dto/BlinkCustomerVisitPlanStatisticsVO.java

@@ -0,0 +1,18 @@
+package com.wx.blink.backend.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class BlinkCustomerVisitPlanStatisticsVO{
+
+    /**
+     *  待完成
+     */
+    private Integer toBeCompletedQty;
+
+    /**
+     * 已完成
+     */
+    private Integer completedQty;
+
+}

+ 82 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/domain/dto/BlinkCustomerVisitPlanVO.java

@@ -0,0 +1,82 @@
+package com.wx.blink.backend.domain.dto;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.wx.blink.base.common.domain.BaseEntity;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BlinkCustomerVisitPlanVO extends BaseEntity {
+
+    @Schema(description = "id")
+    private String id;
+
+    @Schema(description = "计划名称")
+    @TableField("plan_name")
+    private String planName;
+    @Schema(description = "预计时间")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @TableField("expected_time")
+    private Date expectedTime;
+    @Schema(description = "提前提醒时间")
+    @TableField("reminder_time")
+    private Double reminderTime;
+    @Schema(description = "时间类型")
+    @TableField("time_type")
+    private String timeType;
+    @Schema(description = "客户")
+    @TableField("customer_id")
+    private String customerId;
+    @Schema(description = "项目名称")
+    @TableField("project_id")
+    private String projectId;
+    @Schema(description = "拜访目的")
+    @TableField("visit_purpose")
+    private String visitPurpose;
+    @Schema(description = "拜访省市区")
+    @TableField("visit_ssq")
+    private String visitSsq;
+    @Schema(description = "拜访地址")
+    @TableField("visit_address")
+    private String visitAddress;
+    @Schema(description = "拜访责任人")
+    @TableField("visit_responsible_man")
+    private String visitResponsibleMan;
+    @Schema(description = "完成客户名称")
+    @TableField("completed_customer_id")
+    private String completedCustomerId;
+    @Schema(description = "完成项目名称")
+    @TableField("completed_project_id")
+    private String completedProjectId;
+    @Schema(description = "完成拜访省市区")
+    @TableField("completed_visit_ssq")
+    private String completedVisitSsq;
+    @Schema(description = "完成拜访地址")
+    @TableField("completed_visit_address")
+    private String completedVisitAddress;
+    @Schema(description = "拜访结果")
+    @TableField("visit_result")
+    private String visitResult;
+    @Schema(description = "取消原因")
+    @TableField("cancel_reason")
+    private String cancelReason;
+    @Schema(description = "原因说明")
+    @TableField("reason_description")
+    private String reasonDescription;
+    @Schema(description = "状态(0新创建,1已完成,2已取消)")
+    @TableField("status")
+    private Integer status;
+
+
+    @Schema(description = "客户名称")
+    @TableField("customer_name")
+    private String customerName;
+    @Schema(description = "项目名称")
+    @TableField("project_name")
+    private String projectName;
+
+
+}

+ 43 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/domain/qry/BlinkCustomerVisitPlanQry.java

@@ -0,0 +1,43 @@
+package com.wx.blink.backend.domain.qry;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.wx.blink.base.common.domain.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.util.Date;
+
+@Data
+public class BlinkCustomerVisitPlanQry extends PageParam {
+
+    /**
+     * id
+     */
+    private String id;
+
+    /**
+     * 计划名称
+     */
+    private String planName;
+    /**
+     * 预计时间
+     */
+    private Date expectedTime;
+    /**
+     * 预计时间开始
+     */
+    private Date expectedTimeStart;
+    /**
+     * 预计时间结束
+     */
+    private Date expectedTimeEnd;
+    /**
+     * 拜访责任人
+     */
+    private String visitResponsibleMan;
+    /**
+     * 拜访省市区
+     */
+    private String visitSsq;
+
+}

+ 127 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/manager/BlinkCustomerVisitPlanImpl.java

@@ -0,0 +1,127 @@
+package com.wx.blink.backend.manager;
+
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerDO;
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerMarketTeamDO;
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerVisitPlanDO;
+import com.wx.blink.backend.domain.dataobject.BlinkProviderDO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanCalendarVO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanStatisticsVO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanVO;
+import com.wx.blink.backend.domain.qry.BlinkCustomerVisitPlanQry;
+import com.wx.blink.backend.objectmapper.BlinkCustomerVisitPlanMapper;
+import com.wx.blink.backend.repository.BlinkCustomerVisitPlanRepository;
+import com.wx.blink.backend.service.IBlinkCustomerVisitPlanService;
+import com.wx.blink.base.common.domain.PageResult;
+import com.wx.blink.base.common.domain.ResponseDTO;
+import com.wx.blink.base.common.util.BlinkEntityUtil;
+import com.wx.blink.base.common.util.BlinkPageUtil;
+import com.wx.blink.common.qry.BlinkCustomerQry;
+import com.wx.blink.common.vo.BlinkCustomerStatisticsVO;
+import com.wx.blink.common.vo.BlinkCustomerVO;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.*;
+import java.util.stream.Collectors;
+
+
+@Service
+public class BlinkCustomerVisitPlanImpl extends ServiceImpl<BlinkCustomerVisitPlanRepository, BlinkCustomerVisitPlanDO> implements IBlinkCustomerVisitPlanService {
+
+    @Resource
+    private BlinkCustomerVisitPlanRepository customerVisitPlanRepository;
+    @Resource
+    private BlinkCustomerVisitPlanMapper customerVisitPlanMapper;
+
+    @Override
+    public void addOrUpdate(BlinkCustomerVisitPlanVO vo) {
+        BlinkCustomerVisitPlanDO visitPlanDO = customerVisitPlanMapper.customerVisitPlanDVOtoDomain(vo);
+        if (visitPlanDO != null) {
+            //有id更新,没有则新增
+            if (visitPlanDO.getId() == null || visitPlanDO.getId() == "") {
+                //创建人赋值
+                BlinkEntityUtil.setCreateInfo(visitPlanDO);
+                this.save(visitPlanDO);
+            } else {
+                //更新人赋值
+                BlinkEntityUtil.setUpdatedInfo(visitPlanDO);
+                this.updateById(visitPlanDO);
+            }
+        }
+    }
+
+    @Override
+    public void visitCancel(BlinkCustomerVisitPlanVO vo) {
+        UpdateWrapper<BlinkCustomerVisitPlanDO> updateWrapper = new UpdateWrapper<>();
+        updateWrapper
+                .eq("id", vo.getId())
+                .set("status", 2)
+                .set("cancel_reason", vo.getCancelReason())
+                .set("reason_description", vo.getReasonDescription());
+        this.update(null, updateWrapper);
+    }
+
+    @Override
+    public void visitCompleted(BlinkCustomerVisitPlanVO vo) {
+        UpdateWrapper<BlinkCustomerVisitPlanDO> updateWrapper = new UpdateWrapper<>();
+        updateWrapper
+                .eq("id", vo.getId())
+                .set("status", 1)
+                .set("completed_customer_id", vo.getCompletedCustomerId())
+                .set("completed_project_id", vo.getCompletedProjectId())
+                .set("completed_visit_ssq", vo.getCompletedVisitSsq())
+                .set("completed_visit_address", vo.getCompletedVisitAddress())
+                .set("visit_result", vo.getVisitResult());
+        this.update(null, updateWrapper);
+    }
+
+    @Override
+    public PageResult<BlinkCustomerVisitPlanVO> visitPlanQueryPage(BlinkCustomerVisitPlanQry qry) {
+        Page<?> page = BlinkPageUtil.convert2PageQuery(qry);
+        List<BlinkCustomerVisitPlanVO> list = customerVisitPlanRepository.visitPlanQueryPage(page, qry);
+        PageResult<BlinkCustomerVisitPlanVO> pageResult = BlinkPageUtil.convert2PageResult(page, list);
+        return pageResult;
+    }
+
+    @Override
+    public BlinkCustomerVisitPlanStatisticsVO visitPlanStatisticsInfo(BlinkCustomerVisitPlanQry qry) {
+        List<BlinkCustomerVisitPlanVO> list = customerVisitPlanRepository.visitPlanQueryPage(null, qry);
+        return getVisitPlanStatisticsInfo(list);
+    }
+
+    @Override
+    public List<BlinkCustomerVisitPlanCalendarVO> getVisitPlanCalendarNum() {
+        List<BlinkCustomerVisitPlanCalendarVO> list = customerVisitPlanRepository.getVisitPlanCalendarNum();
+        return list;
+    }
+
+    @Override
+    public BlinkCustomerVisitPlanVO visitPlanSingleQuery(String id) {
+        BlinkCustomerVisitPlanQry qry = new BlinkCustomerVisitPlanQry();
+        qry.setId(id);
+        List<BlinkCustomerVisitPlanVO> list = customerVisitPlanRepository.visitPlanQueryPage(null, qry);
+        if(list!=null&&!list.isEmpty()) return list.get(0);
+        else return new BlinkCustomerVisitPlanVO();
+    }
+
+    public BlinkCustomerVisitPlanStatisticsVO getVisitPlanStatisticsInfo(List<BlinkCustomerVisitPlanVO> list){
+        Map<Integer, Integer> countTypes = list.stream()
+                .map(obj -> obj.getStatus() == null ? 0: obj.getStatus()) // 将null转为字符串"00",作为待审核的状态
+                .collect(Collectors.groupingBy(
+                        status -> status,
+                        Collectors.reducing(
+                                0,  // 初始值
+                                obj -> 1,  // 映射函数,每个元素计为1
+                                Integer::sum  // 归约操作,累加
+                        )
+                ));
+        BlinkCustomerVisitPlanStatisticsVO statisticsVO = new BlinkCustomerVisitPlanStatisticsVO();
+        statisticsVO.setToBeCompletedQty(countTypes.getOrDefault(0,0));
+        statisticsVO.setCompletedQty(countTypes.getOrDefault(1,0));
+        return statisticsVO;
+    }
+
+}

+ 22 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/objectmapper/BlinkCustomerVisitPlanMapper.java

@@ -0,0 +1,22 @@
+package com.wx.blink.backend.objectmapper;
+
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerVisitPlanDO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanVO;
+import com.wx.blink.base.common.util.BlinkStringUtil;
+import org.mapstruct.Mapper;
+
+
+@Mapper(componentModel = "spring", imports = {BlinkStringUtil.class})
+public interface BlinkCustomerVisitPlanMapper {
+
+    /**
+     * 客户拜访计划数据VO转do
+     *
+     * @param vo
+     * @return
+     */
+    BlinkCustomerVisitPlanDO customerVisitPlanDVOtoDomain(BlinkCustomerVisitPlanVO vo);
+
+
+
+}

+ 31 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/repository/BlinkCustomerVisitPlanRepository.java

@@ -0,0 +1,31 @@
+package com.wx.blink.backend.repository;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerVisitPlanDO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanCalendarVO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanVO;
+import com.wx.blink.backend.domain.qry.BlinkCustomerVisitPlanQry;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+@Mapper
+public interface BlinkCustomerVisitPlanRepository extends BaseMapper<BlinkCustomerVisitPlanDO> {
+
+    /**
+     * 拜访查询
+     *
+     * @param page
+     * @param qry
+     * @return
+     */
+    List<BlinkCustomerVisitPlanVO> visitPlanQueryPage(Page<?> page, @Param("query") BlinkCustomerVisitPlanQry qry);
+    /**
+     * 拜访计划日历数据个数查询
+     *
+     * @return
+     */
+    List<BlinkCustomerVisitPlanCalendarVO> getVisitPlanCalendarNum();
+}

+ 69 - 0
bound-link-api/blink-backend/src/main/java/com/wx/blink/backend/service/IBlinkCustomerVisitPlanService.java

@@ -0,0 +1,69 @@
+package com.wx.blink.backend.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.wx.blink.backend.domain.dataobject.BlinkCustomerVisitPlanDO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanCalendarVO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanStatisticsVO;
+import com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanVO;
+import com.wx.blink.backend.domain.qry.BlinkCustomerVisitPlanQry;
+import com.wx.blink.base.common.domain.PageResult;
+import com.wx.blink.base.common.domain.ResponseDTO;
+import com.wx.blink.common.qry.BlinkCustomerQry;
+import com.wx.blink.common.vo.BlinkCustomerStatisticsVO;
+import com.wx.blink.common.vo.BlinkCustomerVO;
+
+import java.util.List;
+
+
+public interface IBlinkCustomerVisitPlanService extends IService<BlinkCustomerVisitPlanDO> {
+    /**
+     * 客户拜访新增、更新
+     *
+     * @param vo
+     * @return
+     */
+    void addOrUpdate(BlinkCustomerVisitPlanVO vo);
+    /**
+     * 取消拜访
+     *
+     * @param vo
+     * @return
+     */
+    void visitCancel(BlinkCustomerVisitPlanVO vo);
+    /**
+     * 完成拜访
+     *
+     * @param vo
+     * @return
+     */
+    void visitCompleted(BlinkCustomerVisitPlanVO vo);
+
+    /**
+     * 客户拜访查询
+     *
+     * @param qry
+     * @return
+     */
+    PageResult<BlinkCustomerVisitPlanVO> visitPlanQueryPage(BlinkCustomerVisitPlanQry qry);
+
+    /**
+     * 拜访计划查询列表表头统计数据接口
+     *
+     * @param qry
+     * @return
+     */
+    BlinkCustomerVisitPlanStatisticsVO visitPlanStatisticsInfo(BlinkCustomerVisitPlanQry qry);
+    /**
+     * 拜访计划日历数据个数查询
+     *
+     * @return
+     */
+    List<BlinkCustomerVisitPlanCalendarVO> getVisitPlanCalendarNum();
+    /**
+     * 获取拜访计划详细信息
+     *
+     * @param id
+     * @return
+     */
+    BlinkCustomerVisitPlanVO visitPlanSingleQuery(String id);
+}

+ 47 - 0
bound-link-api/blink-backend/src/main/resources/mapper/BlinkCustomerVisitPlanRepositoryMapper.xml

@@ -0,0 +1,47 @@
+<?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="com.wx.blink.backend.repository.BlinkCustomerVisitPlanRepository">
+    <select id="visitPlanQueryPage" resultType="com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanVO">
+        select a.*,b.customer_name,c.project_name
+        from blink_customer_visit_plan a
+        left join blink_customer b on a.customer_id=b.id
+        left join blink_project c on a.project_id=c.id
+        where a.deleted_flag = '0'
+        <if test="query.id != null and query.id !=''">
+            AND a.id = #{query.id}
+        </if>
+        <if test="query.planName != null and query.planName !=''">
+            AND a.plan_name like concat('%', #{query.planName}, '%')
+        </if>
+        <if test="query.visitResponsibleMan != null and query.visitResponsibleMan !=''">
+            AND a.visitResponsibleMan = #{query.visitResponsibleMan}
+        </if>
+        <if test="query.expectedTime != null and query.expectedTime !=''">
+            AND a.expected_time = #{query.expectedTime}
+        </if>
+        <if test="query.expectedTimeStart != null and query.expectedTimeStart !=''">
+            AND a.expected_time &gt;= #{query.expectedTimeStart}
+        </if>
+        <if test="query.expectedTimeEnd != null and query.expectedTimeEnd !=''">
+            AND a.expected_time &lt;= #{query.expectedTimeEnd}
+        </if>
+        <if test="query.visitSsq != null and query.visitSsq !=''">
+            AND a.visit_ssq = #{query.visitSsq}
+        </if>
+        order by a.create_time desc
+    </select>
+    <select id="getVisitPlanCalendarNum" resultType="com.wx.blink.backend.domain.dto.BlinkCustomerVisitPlanCalendarVO">
+        WITH RECURSIVE dates AS (
+            SELECT DATE(DATE_FORMAT(CURRENT_DATE(), '%Y-%m-01')) AS date
+            UNION ALL
+            SELECT date + INTERVAL 1 DAY
+            FROM dates
+            WHERE date &lt; LAST_DAY(CURRENT_DATE())
+        )
+        SELECT DAY(d.date) AS day_of_month,COUNT(t.id) AS daily_count
+        FROM dates d
+        LEFT JOIN blink_customer_visit_plan t ON DATE(t.expected_time) = d.date
+        GROUP BY d.date
+        ORDER BY day_of_month;
+    </select>
+</mapper>