0
点赞
收藏
分享

微信扫一扫

项目实战(P15)(Day 43)

灵魂跑者 2022-04-27 阅读 38

目录

学习目标:

学习内容:

        客户流失实现:

客户流失的思想:

dao层

service层

出现问题:

遇到问题:

解决方法:

        客户流失管理和暂缓流失列表:

思想:

DAO层

 service层

 Controller层

确认流失操作

service层:

 controller层:


学习目标:

客户流失实现和客户流失页面和客户暂缓流失列表的增删改查


学习内容:

        客户流失实现:

客户流失的思想:

dao层

根据思路来书写查询语句

//查询带流失的客户
    List<Customer> queryLossCustomers();
//通过客户ID批量跟新客户流失状态
    int updateCustomerStateByIds(List<Integer> lossCustomerIds);



//通过客户ID查询最后一条订单记录
    CustomerOrder queryLossCustomerOrderByCustomerId(Integer id);
<!-- 查询待流失的客户 -->
    <select id="queryLossCustomers" resultType="com.xxxx.crm.vo.Customer">
      SELECT
      *
      FROM
      t_customer c
      WHERE
      is_valid = 1
      AND state = 0
      AND DATE_ADD(
      c.create_date,
      INTERVAL 6 MONTH
      ) &lt; NOW()
      AND c.id NOT IN (
      SELECT DISTINCT
      cus_id
      FROM
      t_customer_order o
      WHERE
      is_valid = 1
      AND state = 1
      AND DATE_ADD(
      o.order_date,
      INTERVAL 6 MONTH
      ) &gt; NOW()
      )
    </select>
<!-- 批量跟新客户流失状态 -->
  <update id="updateCustomerStateByIds" >
    update
        t_customer
    set
        state = 1
    where
        id in
            <foreach collection="list" item="item" open="(" close=")" separator=",">
                #{item}
            </foreach>
  </update>





<!-- 查询指定客户最后一条订单记录 -->
    <select id="queryLossCustomerOrderByCustomerId" parameterType="int" resultType="com.xxxx.crm.vo.CustomerOrder">
      SELECT
        *
      FROM
        t_customer_order
      WHERE
        is_valid = 1
        AND cus_id = {customerId}
      ORDER BY
        order_date DESC
        LIMIT 1
    </select>


<!-- 批量添加 -->
  <insert id="insertBatch">
    insert into
    t_customer_loss (cus_no, cus_name, cus_manager, last_order_time, confirm_loss_time, state, loss_reason, is_valid, create_date, update_date)
    values
    <foreach collection="list" separator="," item="item">
      (#{item.cusNo},#{item.cusName},#{item.cusManager},#{item.lastOrderTime},#{item.confirmLossTime},#{item.state},#{item.lossReason},1,now(),now())
    </foreach>
  </insert>

service层

先把所有的流失客户查出来,然后再把这些数据放到流失表中,最后跟新客户状态为流失

 /**
     * 更新客户流失状态
     *   1.查询待流失的客户数据
     *   2.将流失客户数据批量提案极爱到客户流失表中
     *   3.批量更新客户的流失状态 0=正常客户 1=流失客户
     * @author QQ星
     *
     * @param
     * @return void
     * @Date 2022/4/20 21:45
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateCustomerState(){
        /* 1.查询待流失的客户数据 */
        List<Customer> lossCustomerList = customerMapper.queryLossCustomers();

        /* 2.将流失客户数据批量添加到客户流失表中 */
        //判断流失客户数据是否存在
        if (lossCustomerList !=null && lossCustomerList.size()>0){
            //定义集合 用来接受流失客户ID
            List<Integer> lossCustomerIds = new ArrayList<>();
            //定义流失客户列表
            List<CustomerLoss> customerLossList = new ArrayList<>();
            //遍历查询到的流失客户数据
            lossCustomerList.forEach(customer -> {
                // 定义流失客户对象
                CustomerLoss customerLoss = new CustomerLoss();
                // 创建时间  系统当前时间
                customerLoss.setCreateDate(new Date());
                // 客户经理
                customerLoss.setCusManager(customer.getCusManager());
                // 客户名称
                customerLoss.setCusName(customer.getName());
                // 客户编号
                customerLoss.setCusNo(customer.getKhno());
                // 是否有效  1=有效
                customerLoss.setIsValid(1);
                // 修改时间  系统当前时间
                customerLoss.setUpdateDate(new Date());
                // 客户流失状态   0=暂缓流失状态  1=确认流失状态
                customerLoss.setState(0);
                //客户最后下单时间
                //通过客户ID查询最后的订单记录(最后一条订单记录)
                CustomerOrder customerOrder = customerOrderMapper.queryLossCustomerOrderByCustomerId(customer.getId());
                //判断客户订单是否存在,如果存在,则设置最后下单时间
                if(customerOrder !=null){
                    customerLoss.setLastOrderTime(customerOrder.getOrderDate());
                }
                //把流失客户对象设置到对应的集合中
                customerLossList.add(customerLoss);

                //将流失客户id设置到哦对应的集合里
                lossCustomerIds.add(customer.getId());
            });
            //批量添加流失客户记录
            AssertUtil.isTrue(customerLossMapper.inserBatch(customerLossList) !=customerLossList.size(),"客户流失数据转移失败");
            /* 3.批量更新客户的流失状态 */
            AssertUtil.isTrue(customerMapper.updateCustomerStateByIds(lossCustomerIds)!=lossCustomerIds.size(),"更新客户失败");
        }

    }
}

出现问题:

每次都需要把数据放到loss表中,那万一有傻呗天天刷新天天放数据效率太低,根据流失客户比较久的这个特性来设置一个任务来定时任务

/**
 * 定时任务
 * @author QQ星
 *
 * @Date 2022/4/21 23:30
 */
@Component
public class JobTask {

    @Resource
    private CustomerService customerService;

    /**
     * 每月最后一天的23:42分执行
     * @author QQ星
     *
     * @param
     * @return void
     * @Date 2022/4/21 23:44
     */
    //测试是否有效
    //@Scheduled(cron = "0/2 * * * * ?")
    @Scheduled(cron = "0 42 23 L * ? ")
    public void job(){
        System.out.println("定时任务开始执行 --> " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
        //调用需要被定时执行的方法
        customerService.updateCustomerState();
    }
}

遇到问题:

Spring默认定时@Scheduled不支持L关键字

解决方法:

        客户流失管理和暂缓流失列表:

思想:

可参考客户的开发计划

DAO层

加入两个多条件查询,用来查询列表

<!-- 多条件查询 -->
  <select id="selectByParams" parameterType="com.xxxx.crm.query.CustomerLossQuery" resultType="com.xxxx.crm.vo.CustomerLoss">
    select
    <include refid="Base_Column_List"></include>
    from
    t_customer_loss
    <where>
      is_valid = 1
      <if test="null != customerNo and customerNo != ''">
        and cus_no = #{customerNo}
      </if>
      <if test="null != customerName and customerName != ''">
        and cus_name like concat('%',#{customerName},'%')
      </if>
      <if test="null != state">
        and state = #{state}
      </if>
    </where>

  </select>

<!-- 多条件查询 -->
  <select id="selectByParams" parameterType="com.xxxx.crm.query.CustomerReprieveQuery" resultType="com.xxxx.crm.vo.CustomerReprieve">
    select
    <include refid="Base_Column_List"></include>
    from
    t_customer_reprieve
    <where>
      is_valid = 1
      <if test="null != lossId">
        and loss_id = #{lossId}
      </if>
    </where>
  </select>

 service层

CustomerLoss层只有一个分页查询与CustomerReprieve中分页查询一样,创建两个query供前端传给后端即可


public class CustomerLossQuery extends BaseQuery {

    // 客户编号
    private String customerNo;
    // 客户名称
    private String customerName;
    // 流失状态  0=暂缓流失状态  1=确认流失状态
    private Integer state;

    public String getCustomerNo() {
        return customerNo;
    }

    public void setCustomerNo(String customerNo) {
        this.customerNo = customerNo;
    }

    public String getCustomerName() {
        return customerName;
    }

    public void setCustomerName(String customerName) {
        this.customerName = customerName;
    }

    public Integer getState() {
        return state;
    }

    public void setState(Integer state) {
        this.state = state;
    }
}

public class CustomerReprieveQuery extends BaseQuery {

    //流失客户Id
    private Integer lossId;

    public Integer getLossId() {
        return lossId;
    }

    public void setLossId(Integer lossId) {
        this.lossId = lossId;
    }
}
@Service
public class CustomerReprieveService extends BaseService<CustomerReprieve,Integer> {

    @Resource
    private CustomerReprieveMapper customerReprieveMapper;
    @Resource
    private CustomerLossMapper customerLossMapper;

    /**
     * 分页查询流失客户暂缓操作的列表
     * @author QQ星
     *
     * @param customerReprieveQuery
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @Date 2022/4/26 22:06
     */
    public Map<String, Object> queryCustomerReprieveByParams(CustomerReprieveQuery customerReprieveQuery) {
        Map<String, Object> map = new HashMap<>();

        // 开启分页
        PageHelper.startPage(customerReprieveQuery.getPage(), customerReprieveQuery.getLimit());
        // 得到对应分页对象
        PageInfo<CustomerReprieve> pageInfo = new PageInfo<>(customerReprieveMapper.selectByParams(customerReprieveQuery));

        // 设置map对象
        map.put("code",0);
        map.put("msg","success");
        map.put("count",pageInfo.getTotal());
        // 设置分页好的列表
        map.put("data",pageInfo.getList());

        return map;
    }

    /**
     * 添加暂缓数据
     *   1. 参数校验
     *       流失客户ID  lossId
     *           非空,数据存在
     *       暂缓措施内容 measure
     *           非空
     *   2. 设置参数的默认值
     *       是否有效
     *           默认有效,1
     *       创建时间
     *           系统当前时间
     *       修改时间
     *           系统当前时间
     *   3. 执行添加操作,判断受影响的行数
     * @author QQ星
     *
     * @param customerReprieve
     * @return void
     * @Date 2022/4/26 22:55
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void addCustomerRepr(CustomerReprieve customerReprieve) {

        /* 1. 参数校验 */
        checkParams(customerReprieve.getLossId(), customerReprieve.getMeasure());

        /* 2. 设置参数的默认值 */
        customerReprieve.setIsValid(1);
        customerReprieve.setCreateDate(new Date());
        customerReprieve.setUpdateDate(new Date());

        /* 3. 执行添加操作,判断受影响的行数 */
        AssertUtil.isTrue(customerReprieveMapper.insertSelective(customerReprieve) < 1, "添加暂缓数据失败!");
    }

    /**
     * 参数校检
     * @author QQ星
     *
     * @param lossId
     * @param measure
     * @return void
     * @Date 2022/4/26 23:01
     */
    private void checkParams(Integer lossId, String measure) {
        // 流失客户ID lossId    非空,数据存在
        AssertUtil.isTrue(null == lossId
                || customerLossMapper.selectByPrimaryKey(lossId) == null, "流失客户记录不存在!");
        // 暂缓措施内容 measure   非空
        AssertUtil.isTrue(StringUtils.isBlank(measure), "暂缓措施内容不能为空!");

    }

    /**
     * 修改暂缓数据
     * 1. 参数校验
     *      主键ID    id
     *          非空,数据存在
     *      流失客户ID  lossId
     *          非空,数据存在
     *      暂缓措施内容 measure
     *          非空
     *  2. 设置参数的默认值
     *      修改时间
     *          系统当前时间
     *  3. 执行修改操作,判断受影响的行数
     * @author QQ星
     *
     * @param customerReprieve
     * @return void
     * @Date 2022/4/26 23:14
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateCustomerRepr(CustomerReprieve customerReprieve) {
        /* 1. 参数校验 */
        // 主键ID    id
        AssertUtil.isTrue(null == customerReprieve.getId()
                || customerReprieveMapper.selectByPrimaryKey(customerReprieve.getId()) == null, "待更新记录不存在!");
        // 参数校验
        checkParams(customerReprieve.getLossId(), customerReprieve.getMeasure());

        /* 2. 设置参数的默认值 */
        customerReprieve.setUpdateDate(new Date());

        /* 3. 执行修改操作,判断受影响的行数 */
        AssertUtil.isTrue(customerReprieveMapper.updateByPrimaryKeySelective(customerReprieve) < 1, "修改暂缓数据失败!");

    }
    /**
     * 删除暂缓数据
     *  1. 判断id是否为空,且数据存在
     *  2. 设置isvalid为0
     *  3. 执行更新操作,判断受影响的行数
     * @author QQ星
     *
     * @param id
     * @return void
     * @Date 2022/4/26 23:35
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteCustomerRepr(Integer id) {
        // 判断id是否为空
        AssertUtil.isTrue(null == id, "待删除记录不存在!");
        // 通过id查询暂缓数据
        CustomerReprieve customerReprieve = customerReprieveMapper.selectByPrimaryKey(id);
        // 判断数据是否存在
        AssertUtil.isTrue(null == customerReprieve, "待删除记录不存在!");

        // 设置isValid
        customerReprieve.setIsValid(0);
        customerReprieve.setUpdateDate(new Date());

        // 执行更新操作,判断受影响的行数
        AssertUtil.isTrue(customerReprieveMapper.updateByPrimaryKeySelective(customerReprieve) < 1, "删除暂缓数据失败!");
    }
}

 Controller层

在CustomerLossController层中书写首页和流失客户列表加上打开添加暂缓按钮的界面   


@RequestMapping("customer_loss")
@Controller
public class CustomerLossController extends BaseController {

    @Resource
    CustomerLossService customerLossService;

    /**
     * 进入客户流失管理页面
     * @author QQ星
     *
     * @param
     * @return java.lang.String
     * @Date 2022/4/26 0:27
     */
    @RequestMapping("index")
    public String index(){
        return "customerLoss/customer_loss";
    }

    /**
     * 分页条件查询流失客户列表
     * @author QQ星
     *
     * @param customerLossQuery
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @Date 2022/4/26 1:14
     */
    @RequestMapping("list")
    @ResponseBody
    public Map<String, Object> queryCustomerLossByParams(CustomerLossQuery customerLossQuery) {
        return customerLossService.queryCustomerLossByParams(customerLossQuery);
    }

    /**
     * 打开添加暂缓页面
     * @author QQ星
     *
     * @param lossId
     * @param model
     * @return java.lang.String
     * @Date 2022/4/26 21:49
     */
    @RequestMapping("toCustomerLossPage")
    public String toCustomerLossPage(Integer lossId, Model model) {

        // 通过流失客户的ID查询对应流失客户的记录
        CustomerLoss customerLoss = customerLossService.selectByPrimaryKey(lossId);
        // 将流失客户对应的数据存到请求域中
        model.addAttribute("customerLoss", customerLoss);

        return "customerLoss/customer_rep";
    }
}

在CustomerReprieveController层中书写增删改查操做以及打开添加删除页面


@RequestMapping("customer_rep")
@Controller
public class CustomerReprieveController extends BaseController {

    @Resource
    private CustomerReprieveService customerReprieveService;

    /**
     * 分页查询流失客户暂缓操作列表
     * @author QQ星
     *
     * @param customerReprieveQuery
     * @return java.util.Map<java.lang.String,java.lang.Object>
     * @Date 2022/4/26 22:05
     */
    @RequestMapping("list")
    @ResponseBody
    public Map<String, Object> queryCustomerReprieveByParams(CustomerReprieveQuery customerReprieveQuery) {
        return customerReprieveService.queryCustomerReprieveByParams(customerReprieveQuery);
    }
    /**
     * 添加暂缓数据
     * @author QQ星
     *
     * @param customerReprieve
     * @return com.xxxx.crm.base.ResultInfo
     * @Date 2022/4/26 22:51
     */
    @PostMapping("add")
    @ResponseBody
    public ResultInfo addCustomerRepr(CustomerReprieve customerReprieve) {
        customerReprieveService.addCustomerRepr(customerReprieve);
        return success("添加暂缓数据成功!");
    }

    /**
     * 跟新暂缓数据
     * @author QQ星
     *
     * @param customerReprieve
     * @return com.xxxx.crm.base.ResultInfo
     * @Date 2022/4/26 23:11
     */
    @PostMapping("update")
    @ResponseBody
    public ResultInfo updateCustomerRepr(CustomerReprieve customerReprieve) {
        customerReprieveService.updateCustomerRepr(customerReprieve);
        return success("修改暂缓数据成功!");
    }

    /**
     * 打开添加/修改暂缓数据的页面
     * @author QQ星
     *
     * @param lossId
     * @param request
     * @param id
     * @return java.lang.String
     * @Date 2022/4/26 23:25
     */
    @RequestMapping("toAddOrUpdateCustomerReprPage")
    public String toAddOrUpdateCustomerReprPage(Integer lossId, HttpServletRequest request, Integer id) {
        // 将流失客户ID存到作用域中
        request.setAttribute("lossId", lossId);

        // 判断ID是否为空
        if (id != null) {
            // 通过主键ID查询暂缓数据
            CustomerReprieve customerRep = customerReprieveService.selectByPrimaryKey(id);
            // 设置到请求域中
            request.setAttribute("customerRep", customerRep);
        }

        return "customerLoss/customer_rep_add_update";
    }

    /**
     * 删除暂缓数据
     * @author QQ星
     *
     * @param id
     * @return com.xxxx.crm.base.ResultInfo
     * @Date 2022/4/26 23:28
     */
    @PostMapping("delete")
    @ResponseBody
    public ResultInfo updateCustomerRepr(Integer id) {
        customerReprieveService.deleteCustomerRepr(id);
        return success("删除暂缓数据成功!");
    }
}

确认流失操作

service层:

    /**
     * 更新流失客户的流失状态
     *  1. 参数校验
     *      判断id非空且对应的数据存在
     *      流失原因非空
     *  2. 设置参数的默认值
     *      设置流失状态  state=1  0=暂缓流失,1=确认流失
     *      流失原因
     *      客户流失时间  系统当前时间
     *      更新时间     系统当前时间
     *  3. 执行更新操作,判断受影响的行数
     * @author QQ星
     *
     * @param id
     * @param lossReason
     * @return void
     * @Date 2022/4/26 00:30
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateCustomerLossStateById(Integer id, String lossReason) {
        /* 1. 参数校验 */
        // 判断id非空
        AssertUtil.isTrue(null == id, "待确认流失的客户不存在!");
        // 通过id查询流失客户的记录
        CustomerLoss customerLoss = customerLossMapper.selectByPrimaryKey(id);
        // 判断流失客户记录是否存在
        AssertUtil.isTrue(null == customerLoss, "待确认流失的客户不存在!");
        // 流失原因非空
        AssertUtil.isTrue(StringUtils.isBlank(lossReason), "流失原因不能为空!");

        /* 2. 设置参数的默认值 */
        // 设置流失状态  state=1  0=暂缓流失,1=确认流失
        customerLoss.setState(1);
        // 设置流失原因
        customerLoss.setLossReason(lossReason);
        // 客户流失时间  系统当前时间
        customerLoss.setConfirmLossTime(new Date());
        // 更新时间     系统当前时间
        customerLoss.setUpdateDate(new Date());

        /* 3. 执行更新操作,判断受影响的行数 */
        AssertUtil.isTrue(customerLossMapper.updateByPrimaryKeySelective(customerLoss) < 1, "确认流失失败!");
    }

 controller层:

/**
     * 确认流失
     * @author QQ星
     *
     * @param id
     * @param lossReason
     * @return com.xxxx.crm.base.ResultInfo
     * @Date 2022/4/26 00:11
     */
    @PostMapping("updateCustomerLossStateById")
    @ResponseBody
    public ResultInfo updateCustomerLossStateById(Integer id, String lossReason) {
        customerLossService.updateCustomerLossStateById(id, lossReason);
        return success("确认流失成功!");
    }
举报

相关推荐

0 条评论