课程安排
- 了解快递员取派件任务需求
- 递员取派件任务相关功能开发
- 调度中心任务调度
- 整体业务功能测试
本章基础:对派件任务的增删改查
本章重点:
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

最低0.47元/天 解锁文章

8511

被折叠的 条评论
为什么被折叠?



