day09-智能调度之取派件调度

课程安排

  • 了解快递员取派件任务需求
  • 递员取派件任务相关功能开发
  • 调度中心任务调度
  • 整体业务功能测试

本章基础:对派件任务的增删改查

本章重点:

1更新取派件任务状态(根据不同的状态做不同的更新)

2调度中心(根据一定的规则选择一个快递员)

3生成任务(根据快递员id生成对应取派件任务,将数据保存入数据库)

1、背景说明

通过前面的学习,可以通过作业范围来确定网点或快递员。

下面要做的事情就是需要为快递员生成取派件任务

2、需求分析

快递员在登录到APP后,可以查看取派件任务列表

具体需求参见《快递员端产品》文档。

3、实现分析

3.1、表结构

快递员的取件和派件类型不同外其他的属性基本都是一样的,存储在一张表sl_pickup_dispatch_task中。

取派件任务存储在sl_work数据库中。

task_type:任务类型,1为取件任务,2为派件任务

status,sign_status,sign_recipient

agency_id,courier_id:关联的两个id

另:几个时间。estimated_start_time,actual_start_time,estimated_end_time,actual_end_time,cancel_time,created,updated

is_deleted:删除:0-否,1-是(取派件任务在快递员删除时为逻辑删除,防止后续需要数据恢复的情况)

CREATE TABLE `sl_pickup_dispatch_task` (
  `id` bigint NOT NULL COMMENT 'id',
  `order_id` bigint NOT NULL COMMENT '关联订单id',
  `task_type` tinyint DEFAULT NULL COMMENT '任务类型,1为取件任务,2为派件任务',
  `status` int DEFAULT NULL COMMENT '任务状态,1为新任务、2为已完成、3为已取消',
  `sign_status` int DEFAULT '0' COMMENT '签收状态(0为未签收, 1为已签收,2为拒收)',
  `sign_recipient` tinyint DEFAULT '0' COMMENT '签收人,1本人,2代收',
  `agency_id` bigint DEFAULT NULL COMMENT '网点ID',
  `courier_id` bigint DEFAULT NULL COMMENT '快递员ID',
  `estimated_start_time` datetime DEFAULT NULL COMMENT '预计取/派件开始时间',
  `actual_start_time` datetime DEFAULT NULL COMMENT '实际开始时间',
  `estimated_end_time` datetime DEFAULT NULL COMMENT '预计完成时间',
  `actual_end_time` datetime DEFAULT NULL COMMENT '实际完成时间',
  `cancel_time` datetime DEFAULT NULL COMMENT '取消时间',
  `cancel_reason` int DEFAULT NULL COMMENT '取消原因',
  `cancel_reason_description` varchar(100) CHARACTER SET armscii8 COLLATE armscii8_general_ci DEFAULT NULL COMMENT '取消原因具体描述',
  `assigned_status` int NOT NULL COMMENT '任务分配状态(1未分配2已分配3待人工分配)',
  `mark` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '备注',
  `created` datetime DEFAULT NULL COMMENT '创建时间',
  `updated` datetime DEFAULT NULL COMMENT '更新时间',
  `is_deleted` int DEFAULT '0' COMMENT '删除:0-否,1-是',
  PRIMARY KEY (`id`) USING BTREE,
  KEY `order_id` (`order_id`) USING BTREE,
  KEY `created` (`created`) USING BTREE,
  KEY `task_type` (`task_type`) USING BTREE,
  KEY `courier_id` (`courier_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='取件、派件任务信息表';

3.2、业务流程

3.2.1、取件任务流程

用户在下单后,订单微服务会发消息出来,消息会在dispatch微服务中进行调度,最终会向work微服务发送消息,生成快递员的取件任务的实体,向数据库sl_pickup_dispatch_task中插入数据。

细节:1返回快递员列表为升序排序,选择任务少的快递员进行取派

2取件时间>2小时不着急,系统延迟发消息给快递员

取消任务重新生成取件时:发送实时消息

3.2.2、派件任务流程

都为实时任务

派件任务会在两个场景下生成:

  • 场景一,司机入库时,运单流转到最后一个节点,需要快递员派件
  • 场景二,发件人与收件人的服务网点是同一个网点时,无需转运,直接生成派件任务

场景一:

场景二:

4、取派件任务

针对于取派件任务进行相应的数据管理,下面我们将逐一进行实现。

4.1、新增取派件任务

新增取派件任务不对外开放,所以在Controller中是没有方法定义的,只是在消息处理中进行调用生成任务。

4.1.1、定义方法

/**
     * 新增取派件任务
     *
     * @param taskPickupDispatch 取派件任务信息
     * @return 取派件任务信息
     */
    PickupDispatchTaskEntity saveTaskPickupDispatch(PickupDispatchTaskEntity taskPickupDispatch);

4.1.2、实现方法

@Override
    public PickupDispatchTaskEntity saveTaskPickupDispatch(PickupDispatchTaskEntity taskPickupDispatch) {
        // 设置任务状态为新任务
        taskPickupDispatch.setStatus(PickupDispatchTaskStatus.NEW);
        boolean result = super.save(taskPickupDispatch);
        if (result) {
            //TODO 同步快递员任务到es
            //TODO 生成运单跟踪消息和快递员端取件/派件消息通知
            return taskPickupDispatch;
        }
        throw new SLException(WorkExceptionEnum.PICKUP_DISPATCH_TASK_SAVE_ERROR);
    }

4.2、分页查询取派件任务

LambdaQueryWrapper查询:模糊查询like,等值查询eq,范围查询between

4.2.1、Controller

@PostMapping("page")
    @ApiOperation(value = "分页查询", notes = "获取取派件任务分页数据")
    public PageResponse<PickupDispatchTaskDTO> findByPage(@RequestBody PickupDispatchTaskPageQueryDTO dto) {
        return this.pickupDispatchTaskService.findByPage(dto);
    }

4.2.2、Service

/**
     * 分页查询取派件任务
     *
     * @param dto 查询条件
     * @return 分页结果
     */
    PageResponse<PickupDispatchTaskDTO> findByPage(PickupDispatchTaskPageQueryDTO dto);

4.2.3、ServiceImpl

查询数据库时使用entity实体(格式)

PickupDispatchTaskEntity::getId后不加括号,不是调用的函数

/**
     * 分页查询取派件任务
     *
     * @param dto 查询条件
     * @return 分页结果
     */
    @Override
    public PageResponse<PickupDispatchTaskDTO> findByPage(PickupDispatchTaskPageQueryDTO dto) {
        //1.构造条件
        Page<PickupDispatchTaskEntity> iPage = new Page<>(dto.getPage(), dto.getPageSize());
        LambdaQueryWrapper<PickupDispatchTaskEntity> queryWrapper = Wrappers.<PickupDispatchTaskEntity>lambdaQuery()
                .like(ObjectUtil.isNotEmpty(dto.getId()), PickupDispatchTaskEntity::getId, dto.getId())
                .like(ObjectUtil.isNotEmpty(dto.getOrderId()), PickupDispatchTaskEntity::getOrderId, dto.getOrderId())
                .eq(ObjectUtil.isNotEmpty(dto.getAgencyId()), PickupDispatchTaskEntity::getAgencyId, dto.getAgencyId())
                .eq(ObjectUtil.isNotEmpty(dto.getCourierId()), PickupDispatchTaskEntity::getCourierId, dto.getCourierId())
                .eq(ObjectUtil.isNotEmpty(dto.getTaskType()), PickupDispatchTaskEntity::getTaskType, dto.getTaskType())
                .eq(ObjectUtil.isNotEmpty(dto.getStatus()), PickupDispatchTaskEntity::getStatus, dto.getStatus())
                .eq(ObjectUtil.isNotEmpty(dto.getAssignedStatus()), PickupDispatchTaskEntity::getAssignedStatus, dto.getAssignedStatus())
                .eq(ObjectUtil.isNotEmpty(dto.getSignStatus()), PickupDispatchTaskEntity::getSignStatus, dto.getSignStatus())
                .eq(ObjectUtil.isNotEmpty(dto.getIsDeleted()), PickupDispatchTaskEntity::getIsDeleted, dto.getIsDeleted())
                .between(ObjectUtil.isNotEmpty(dto.getMinEstimatedEndTime()), PickupDispatchTaskEntity::getEstimatedEndTime, dto.getMinEstimatedEndTime(), dto.getMaxEstimatedEndTime())
                .between(ObjectUtil.isNotEmpty(dto.getMinActualEndTime()), PickupDispatchTaskEntity::getActualEndTime, dto.getMinActualEndTime(), dto.getMaxActualEndTime())
                .orderByDesc(PickupDispatchTaskEntity::getUpdated);
        //2.分页查询
        Page<PickupDispatchTaskEntity> result = super.page(iPage, queryWrapper);
        if (ObjectUtil.isEmpty(result.getRecords())) {
            return new PageResponse<>(result);
        }
        //3.组装分页数据
      &nb

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值