This commit is contained in:
shuhongfan
2023-09-04 16:40:17 +08:00
commit cf5ac25c14
8267 changed files with 1305066 additions and 0 deletions

View File

@@ -0,0 +1,3 @@
.idea
target/
*.iml

View File

@@ -0,0 +1,13 @@
FROM openjdk:11-jdk
LABEL maintainer="研究院研发组 <research@itcast.cn>"
# 时区修改为东八区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
WORKDIR /app
ARG JAR_FILE=target/*.jar
ADD ${JAR_FILE} app.jar
EXPOSE 8080
ENTRYPOINT ["sh","-c","java -Djava.security.egd=file:/dev/./urandom -jar $JAVA_OPTS app.jar"]

View File

@@ -0,0 +1,279 @@
# sl-express-ms-driver使用手册
## 1.说明
**该模块为司机相关微服务,主要提供司机作业单的操作和司机提货、交付、回车登记等动作。**<br />主要功能:
- 司机作业单的复杂查询、统计
- 司机作业单的增、删、改操作
- 司机提货、交付、回车登记、延迟提货的动作逻辑
## 2.使用
### 2.1导入依赖
如需使用司机作业单相关的服务功能需要引入司机微服务api
```xml
<dependency>
<groupId>com.sl-express.ms.driver</groupId>
<artifactId>sl-express-ms-driver-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
```
### 2.2feign方法
```java
@FeignClient(value = "sl-express-ms-driver", contextId = "DriverJob", path = "driver-job")
public interface DriverJobFeign {
/**
* 更新司机作业状态,不允许 PENDING 状态PROCESSING出库业务COMPLETED入库业务
*
* @param id 司机作业单id
* @param status 司机任务状态
* @return 是否成功
*/
@PutMapping
boolean updateStatus(@RequestParam("id") Long id, @RequestParam("status") DriverJobStatus status);
/**
* 获取司机作业单分页数据
*
* @param page 页码
* @param pageSize 页尺寸
* @param id 司机作业单id
* @param driverId 司机id
* @param status 作业状态
* @param transportTaskId 运输任务id
* @return 作业单数据
*/
@GetMapping("page")
PageResponse<DriverJobDTO> findByPage(@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(value = "id", required = false) Long id,
@RequestParam(value = "driverId", required = false) Long driverId,
@RequestParam(value = "status", required = false) DriverJobStatus status,
@RequestParam(value = "transportTaskId", required = false) Long transportTaskId);
/**
* 根据id获取司机作业单信息
*
* @param id 司机作业单id
* @return 司机作业单信息
*/
@GetMapping("{id}")
DriverJobDTO findById(@PathVariable("id") Long id);
/**
* 根据运输任务删除司机作业单
*
* @param transportTaskId 运输任务id
* @return 是否成功
*/
@PutMapping("removeByTransportTaskId/{transportTaskId}")
boolean removeByTransportTaskId(@PathVariable("transportTaskId") Long transportTaskId);
/**
* 根据运输任务生成司机作业单
*
* @param transportTaskId 运输任务id
* @param driverId 司机id
* @return 司机作业单id
*/
@PostMapping("createDriverJob/{transportTaskId}/{driverId}")
Long createDriverJob(@PathVariable("transportTaskId") Long transportTaskId, @PathVariable("driverId") Long driverId);
/**
* 司机入库,修改运单的当前节点和下个节点 以及 修改运单为待调度状态,结束运输任务
*
* @param driverDeliverDTO 司机作业单id
*/
@PostMapping("intoStorage")
void intoStorage(@RequestBody DriverDeliverDTO driverDeliverDTO);
/**
* 司机出库,修改运单为运输中状态,开始运输任务
*
* @param driverPickUpDTO 提货对象
*/
@PostMapping("outStorage")
void outStorage(@RequestBody DriverPickUpDTO driverPickUpDTO);
/**
* 条件分页查询
*
* @param driverJobConditionPageDTO 查询条件
* @return 司机作业单分页结果
*/
@PostMapping("conditionPage")
PageResponse<DriverJobDTO> conditionQueryByPage(@RequestBody DriverJobConditionPageDTO driverJobConditionPageDTO);
/**
* 延迟提货,延迟时间以提货时间往后推最多不超过2小时
*
* @param driverDelayDeliveryDTO 运输任务延时对象
*/
@PutMapping("delayDelivery")
void delayedDelivery(@RequestBody DriverDelayDeliveryDTO driverDelayDeliveryDTO);
/**
* 回车登记
*
* @param driverReturnRegisterDTO 回车登记对象
*/
@PostMapping("returnRegister")
void returnRegister(@RequestBody DriverReturnRegisterDTO driverReturnRegisterDTO);
/**
* 司机作业单月度统计
*
* @param driverId 司机id
* @param month 月份
* @return 统计数据
*/
@GetMapping("jobMonthlyStatistics/{driverId}/{month}")
DriverJobStatisticsDTO jobMonthlyStatistics(@PathVariable("driverId") String driverId, @PathVariable("month") String month);
}
```
### 2.3司机出库接口
**接口地址**:`/driver-job/outStorage`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**接口描述**:<p>司机出库,修改运单为运输中状态,开始运输任务</p>
**请求示例**:
```javascript
{
"cargoPickUpPicture": "",
"cargoPicture": "",
"id": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 |
|--------------------------------|-------------------|------|--------|------|
| driverPickUpDTO | driverPickUpDTO | body | true | 提货对象 |
| &emsp;&emsp;cargoPickUpPicture | 提货凭证,多个图片url以逗号分隔 || true | string |
| &emsp;&emsp;cargoPicture | 货物照片,多个图片url以逗号分隔 || true | string |
| &emsp;&emsp;id | 司机作业id || true | string |
### 2.4司机入库接口
**接口地址**:`/driver-job/intoStorage`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**接口描述**:<p>司机入库,修改运单的当前节点和下个节点 以及 修改运单为待调度状态,结束运输任务</p>
**请求示例**:
```javascript
{
"deliverPicture": "",
"id": "",
"transportCertificate": ""
}
```
**请求参数**:
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 |
|----------------------------------|-------------------|------|--------|--------|
| driverDeliverDTO | driverDeliverDTO | body | true | 司机交付对象 |
| &emsp;&emsp;deliverPicture | 交付图片,多个图片url以逗号分隔 || true | string |
| &emsp;&emsp;id | 司机作业id || true | string |
| &emsp;&emsp;transportCertificate | 交付凭证,多个图片url以逗号分隔 || true | string |
### 2.5回车登记接口
**接口地址**:`/driver-job/returnRegister`
**请求方式**:`POST`
**请求数据类型**:`application/json`
**接口描述**:<p>回车登记,并设置下一次车辆计划</p>
**请求示例**:
```javascript
{
"accidentDescription": "",
"accidentImages": "",
"accidentType": "",
"breakRulesDescription": "",
"breakRulesType": "",
"deductPoints": 0,
"faultDescription": "",
"faultImages": "",
"faultType": "",
"id": "",
"intoStorageTime": "2022-07-18 17:00:00",
"isAccident": true,
"isAvailable": true,
"isBreakRules": true,
"isFault": true,
"outStorageTime": "2022-07-18 17:00:00",
"penaltyAmount": 0
}
```
**请求参数**:
| 参数名称 | 参数说明 | 请求类型 | 是否必须 | 数据类型 |
|-----------------------------------|---------------------------------------------------------------------|-------|----------------|-------------------------|
| driverReturnRegisterDTO | driverReturnRegisterDTO | body | true | DriverReturnRegisterDTO |
| &emsp;&emsp;accidentDescription | 事故说明,类型为“其他”时填写 || false | string |
| &emsp;&emsp;accidentImages | 事故图片 || false | string |
| &emsp;&emsp;accidentType | 事故类型1-直行事故2-追尾事故3-超车事故4-左转弯事故5-右转弯事故6-弯道事故7-坡道事故8-会车事故9-其他 || false | string |
| &emsp;&emsp;breakRulesDescription | 违章说明,类型为“其他”时填写 || false | string |
| &emsp;&emsp;breakRulesType | 违章类型1-闯红灯2-无证驾驶3-超载4-酒后驾驶5-超速行驶6-其他 || false | string |
| &emsp;&emsp;deductPoints | 扣分数据 || false | integer(int32) |
| &emsp;&emsp;faultDescription | 故障说明,类型为“其他”时填写 || false | string |
| &emsp;&emsp;faultImages | 故障图片 || false | string |
| &emsp;&emsp;faultType | 故障类型1-发动机启动困难2-不着车3-漏油4-漏水5-照明失灵6-有异响7-排烟异常8-温度异常9-其他 || false | string |
| &emsp;&emsp;id | 运输任务id || true | string |
| &emsp;&emsp;intoStorageTime | 回车时间 || true | string |
| &emsp;&emsp;isAccident | 是否出现事故 || true | boolean |
| &emsp;&emsp;isAvailable | 车辆是否可用 || false | boolean |
| &emsp;&emsp;isBreakRules | 车辆是否违章 || true | boolean |
| &emsp;&emsp;isFault | 车辆是否故障 || true | boolean |
| &emsp;&emsp;outStorageTime | 出车时间 || true | string |
| &emsp;&emsp;penaltyAmount | 罚款金额 || false | number |
## 3.服务架构
### 3.1司机出库业务流程图
![司机出库业务流程图](../../docs/zh-cn/assets/司机出库业务流程图.png)
### 3.2司机入库业务流程图
![司机入库业务流程图](../../docs/zh-cn/assets/司机入库业务流程图.png)
### 3.3回车登记业务流程图
![回车登记业务流程图](../../docs/zh-cn/assets/回车登记业务流程图.png)

View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.sl-express</groupId>
<artifactId>sl-express-parent</artifactId>
<version>1.4</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>com.sl-express.ms.driver</groupId>
<artifactId>sl-express-ms-driver-service</artifactId>
<version>1.1-SNAPSHOT</version>
<description>司机微服务</description>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<sl-express-common.version>1.2-SNAPSHOT</sl-express-common.version>
<sl-express-ms-base-api.version>1.1-SNAPSHOT</sl-express-ms-base-api.version>
<sl-express-ms-work-api.version>1.1-SNAPSHOT</sl-express-ms-work-api.version>
<sl-express-ms-transport-api.version>1.1-SNAPSHOT</sl-express-ms-transport-api.version>
<sl-express-ms-driver-domain.version>1.1-SNAPSHOT</sl-express-ms-driver-domain.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>
<dependencies>
<dependency>
<groupId>com.sl-express.common</groupId>
<artifactId>sl-express-common</artifactId>
<version>${sl-express-common.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.base</groupId>
<artifactId>sl-express-ms-base-api</artifactId>
<version>${sl-express-ms-base-api.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.work</groupId>
<artifactId>sl-express-ms-work-api</artifactId>
<version>${sl-express-ms-work-api.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.transport</groupId>
<artifactId>sl-express-ms-transport-api</artifactId>
<version>${sl-express-ms-transport-api.version}</version>
</dependency>
<dependency>
<groupId>com.sl-express.ms.driver</groupId>
<artifactId>sl-express-ms-driver-domain</artifactId>
<version>${sl-express-ms-driver-domain.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.3.7.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
<goal>build-info</goal>
</goals>
</execution>
</executions>
<configuration>
<!--指定主类-->
<mainClass>com.sl.DriverApplication</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,19 @@
package com.sl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* @author ZJL
*/
@SpringBootApplication
@EnableFeignClients
@Slf4j
public class DriverApplication {
public static void main(String[] args) {
SpringApplication.run(DriverApplication.class, args);
}
}

View File

@@ -0,0 +1,35 @@
package com.sl.ms.driver.config;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.StrUtil;
import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
@Configuration
public class RedissonConfiguration {
@Resource
private RedisProperties redisProperties;
@Bean
public RedissonClient redissonSingle() {
Config config = new Config();
SingleServerConfig serverConfig = config.useSingleServer()
.setAddress("redis://" + redisProperties.getHost() + ":" + redisProperties.getPort());
if (null != (redisProperties.getTimeout())) {
serverConfig.setTimeout(1000 * Convert.toInt(redisProperties.getTimeout().getSeconds()));
}
if (StrUtil.isNotEmpty(redisProperties.getPassword())) {
serverConfig.setPassword(redisProperties.getPassword());
}
return Redisson.create(config);
}
}

View File

@@ -0,0 +1,117 @@
package com.sl.ms.driver.controller;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.sl.ms.driver.domain.dto.request.*;
import com.sl.ms.driver.domain.dto.response.DriverJobDTO;
import com.sl.ms.driver.domain.dto.response.DriverJobStatisticsDTO;
import com.sl.ms.driver.domain.enums.DriverJobStatus;
import com.sl.ms.driver.entity.DriverJobEntity;
import com.sl.ms.driver.enums.DriverExceptionEnum;
import com.sl.ms.driver.service.DriverJobService;
import com.sl.transport.common.exception.SLException;
import com.sl.transport.common.util.PageResponse;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
* 司机作业单 前端控制器
*/
@Slf4j
@RestController
@Api(tags = "司机作业单")
@RequestMapping("/driver-job")
public class DriverJobController {
@Resource
private DriverJobService driverJobService;
@PutMapping
@ApiOperation(value = "更新状态", notes = "更新司机作业状态,不允许 PENDING 状态PROCESSING出库业务COMPLETED入库业务")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "司机作业单id", required = true, dataTypeClass = Long.class),
@ApiImplicitParam(name = "status", value = "司机任务状态", required = true, dataTypeClass = DriverJobStatus.class),
})
public boolean updateStatus(@RequestParam("id") Long id,
@RequestParam("status") DriverJobStatus status) {
return this.driverJobService.updateStatus(id, status);
}
@GetMapping("{id}")
@ApiOperation(value = "id查询", notes = "根据id获取司机作业单信息")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "司机作业单id", required = true, dataTypeClass = Long.class)
})
public DriverJobDTO findById(@PathVariable("id") Long id) {
DriverJobEntity driverJob = this.driverJobService.getById(id);
if (ObjectUtil.isEmpty(driverJob)) {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_NOT_FOUND);
}
return BeanUtil.toBean(driverJob, DriverJobDTO.class);
}
@DeleteMapping("removeByTransportTaskId/{transportTaskId}")
@ApiOperation(value = "根据运输任务删除司机作业单", notes = "根据运输任务删除司机作业单")
@ApiImplicitParams({
@ApiImplicitParam(name = "transportTaskId", value = "运输任务id", required = true, dataTypeClass = Long.class)
})
public boolean removeByTransportTaskId(@PathVariable("transportTaskId") Long transportTaskId) {
return driverJobService.removeByTransportTaskId(transportTaskId);
}
@PostMapping("createDriverJob/{transportTaskId}/{driverId}")
@ApiOperation(value = "根据运输任务生成司机作业单", notes = "根据运输任务生成司机作业单")
@ApiImplicitParams({
@ApiImplicitParam(name = "transportTaskId", value = "运输任务id", required = true, dataTypeClass = Long.class),
@ApiImplicitParam(name = "driverId", value = "司机id", required = true, dataTypeClass = Long.class)
})
public Long createDriverJob(@PathVariable("transportTaskId") Long transportTaskId, @PathVariable("driverId") Long driverId) {
return driverJobService.createDriverJob(transportTaskId, driverId);
}
@PostMapping("intoStorage")
@ApiOperation(value = "司机入库", notes = "司机入库,修改运单的当前节点和下个节点 以及 修改运单为待调度状态,结束运输任务")
public void intoStorage(@RequestBody DriverDeliverDTO driverDeliverDTO) {
driverJobService.intoStorage(driverDeliverDTO);
}
@PostMapping("outStorage")
@ApiOperation(value = "司机出库", notes = "司机出库,修改运单为运输中状态,开始运输任务")
public void outStorage(@RequestBody DriverPickUpDTO driverPickUpDTO) {
driverJobService.outStorage(driverPickUpDTO);
}
@PutMapping("delayDelivery")
@ApiOperation(value = "延迟提货", notes = "延迟时间以提货时间往后推最多不超过2小时")
public void delayedDelivery(@RequestBody DriverDelayDeliveryDTO driverDelayDeliveryDTO) {
driverJobService.delayedDelivery(driverDelayDeliveryDTO);
}
@PostMapping("returnRegister")
@ApiOperation(value = "回车登记", notes = "回车登记,并设置下一次车辆计划")
public void returnRegister(@RequestBody DriverReturnRegisterDTO driverReturnRegisterDTO) {
driverJobService.returnRegister(driverReturnRegisterDTO);
}
@GetMapping("jobMonthlyStatistics/{driverId}/{month}")
@ApiOperation(value = "司机作业单月度统计", notes = "根据月份统计司机作业单数据")
@ApiImplicitParams({
@ApiImplicitParam(name = "driverId", value = "司机id", required = true, dataTypeClass = String.class),
@ApiImplicitParam(name = "month", value = "月份", example = "2022-07", required = true, dataTypeClass = String.class)
})
public DriverJobStatisticsDTO jobMonthlyStatistics(@PathVariable("driverId") String driverId, @PathVariable("month") String month) {
return driverJobService.jobMonthlyStatistics(driverId, month);
}
@PostMapping("pageQuery")
@ApiOperation(value = "分页查询")
public PageResponse<DriverJobDTO> pageQuery(@RequestBody DriverJobPageQueryDTO driverJobPageQueryDTO) {
return this.driverJobService.pageQuery(driverJobPageQueryDTO);
}
}

View File

@@ -0,0 +1,78 @@
package com.sl.ms.driver.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.sl.ms.driver.domain.enums.DriverJobStatus;
import com.sl.transport.common.entity.BaseEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
/**
* 运输任务表
*/
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("sl_driver_job")
public class DriverJobEntity extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* 起始机构id
*/
private Long startAgencyId;
/**
* 目的机构id
*/
private Long endAgencyId;
/**
* 作业状态1为待执行对应 待提货、2为进行中对应在途、3为改派对应 已交付、4为已完成对应 已交付、5为已作废
*/
private DriverJobStatus status;
/**
* 司机id
*/
private Long driverId;
/**
* 运输任务id
*/
private Long transportTaskId;
/**
* 提货对接人
*/
private String startHandover;
/**
* 交付对接人
*/
private String finishHandover;
/**
* 计划发车时间
*/
private LocalDateTime planDepartureTime;
/**
* 实际发车时间
*/
private LocalDateTime actualDepartureTime;
/**
* 计划到达时间
*/
private LocalDateTime planArrivalTime;
/**
* 实际到达时间
*/
private LocalDateTime actualArrivalTime;
}

View File

@@ -0,0 +1,57 @@
package com.sl.ms.driver.enums;
import cn.hutool.core.util.EnumUtil;
import com.sl.transport.common.enums.BaseExceptionEnum;
/**
* 异常枚举
*
* @author zzj
* @version 1.0
*/
public enum DriverExceptionEnum implements BaseExceptionEnum {
TRANSPORT_TASK_NOT_FOUND(1009, "运输任务不存在"),
DRIVER_JOB_SAVE_ERROR(1010, "司机作业单保存失败"),
DRIVER_JOB_NOT_FOUND(1011, "司机作业单不存在"),
DRIVER_JOB_STATUS_NOT_PENDING(1012, "更新司机作业单不能更新成 PENDING 状态"),
DRIVER_JOB_STATUS_UNKNOWN(1023, "不能识别的状态"),
PROCESSING_DRIVER_JOB_NOT_EMPTY(1024, "司机仍有在途或交付任务,不可提货!"),
DRIVER_JOB_INTO_STORAGE_ERROR(1025, "入库失败"),
DRIVER_JOB_OUT_STORAGE_ERROR(1026, "出库失败");
private Integer code;
private Integer status;
private String value;
DriverExceptionEnum(Integer code, String value) {
this.code = code;
this.value = value;
this.status = 500;
}
DriverExceptionEnum(Integer code, Integer status, String value) {
this.code = code;
this.value = value;
this.status = status;
}
@Override
public Integer getCode() {
return this.code;
}
@Override
public String getValue() {
return this.value;
}
@Override
public Integer getStatus() {
return this.status;
}
public static DriverExceptionEnum codeOf(Integer code) {
return EnumUtil.getBy(DriverExceptionEnum::getCode, code);
}
}

View File

@@ -0,0 +1,12 @@
package com.sl.ms.driver.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sl.ms.driver.entity.DriverJobEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* 司机作业单 Mapper 接口
*/
@Mapper
public interface DriverJobMapper extends BaseMapper<DriverJobEntity> {
}

View File

@@ -0,0 +1,87 @@
package com.sl.ms.driver.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sl.ms.driver.domain.dto.request.*;
import com.sl.ms.driver.domain.dto.response.DriverJobDTO;
import com.sl.ms.driver.domain.dto.response.DriverJobStatisticsDTO;
import com.sl.ms.driver.domain.enums.DriverJobStatus;
import com.sl.ms.driver.entity.DriverJobEntity;
import com.sl.transport.common.util.PageResponse;
/**
* 司机作业 服务类
*/
public interface DriverJobService extends IService<DriverJobEntity> {
/**
* 根据运输任务生成司机作业单
*
* @param transportTaskId 运输任务id
* @param driverId 司机id
* @return 司机作业单id
*/
Long createDriverJob(Long transportTaskId, Long driverId);
/**
* 更新司机作业状态,不允许 PENDING 状态
*
* @param id 司机作业单id
* @param status 司机任务状态
* @return 是否成功
*/
boolean updateStatus(Long id, DriverJobStatus status);
/**
* 司机入库,修改运单的当前节点和下个节点 以及 修改运单为待调度状态,结束运输任务
*
* @param driverDeliverDTO 司机作业单id
*/
void intoStorage(DriverDeliverDTO driverDeliverDTO);
/**
* 司机出库,修改运单为运输中状态,开始运输任务
*
* @param driverPickUpDTO 司机作业单id
*/
void outStorage(DriverPickUpDTO driverPickUpDTO);
/**
* 根据运输任务删除司机作业单
*
* @param transportTaskId 运输任务id
* @return 是否成功
*/
boolean removeByTransportTaskId(Long transportTaskId);
/**
* 延迟提货
*
* @param driverDelayDeliveryDTO 延迟提货对象
*/
void delayedDelivery(DriverDelayDeliveryDTO driverDelayDeliveryDTO);
/**
* 回车登记
*
* @param driverReturnRegisterDTO 回车登记对象
*/
void returnRegister(DriverReturnRegisterDTO driverReturnRegisterDTO);
/**
* 司机作业单月度统计
*
* @param driverId 司机id
* @param month 月份
* @return 统计数据
*/
DriverJobStatisticsDTO jobMonthlyStatistics(String driverId, String month);
/**
* 分页查询
*
* @param dto 查询条件
* @return 司机作业单分页结果
*/
PageResponse<DriverJobDTO> pageQuery(DriverJobPageQueryDTO dto);
}

View File

@@ -0,0 +1,490 @@
package com.sl.ms.driver.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.text.CharSequenceUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sl.ms.base.api.common.MessageFeign;
import com.sl.ms.base.api.truck.TruckFeign;
import com.sl.ms.base.api.truck.TruckPlanFeign;
import com.sl.ms.base.api.truck.TruckReturnRegisterFeign;
import com.sl.ms.base.domain.base.MessageAddDTO;
import com.sl.ms.base.domain.enums.MessageBussinessTypeEnum;
import com.sl.ms.base.domain.enums.MessageContentTypeEnum;
import com.sl.ms.base.domain.enums.StatusEnum;
import com.sl.ms.base.domain.enums.TruckRunStatusEnum;
import com.sl.ms.base.domain.truck.TruckDto;
import com.sl.ms.base.domain.truck.TruckPlanDto;
import com.sl.ms.base.domain.truck.TruckReturnRegisterDTO;
import com.sl.ms.driver.domain.dto.request.*;
import com.sl.ms.driver.domain.dto.response.DailyMileageDTO;
import com.sl.ms.driver.domain.dto.response.DriverJobDTO;
import com.sl.ms.driver.domain.dto.response.DriverJobStatisticsDTO;
import com.sl.ms.driver.domain.enums.DriverJobStatus;
import com.sl.ms.driver.entity.DriverJobEntity;
import com.sl.ms.driver.enums.DriverExceptionEnum;
import com.sl.ms.driver.mapper.DriverJobMapper;
import com.sl.ms.driver.service.DriverJobService;
import com.sl.ms.transport.api.OrganFeign;
import com.sl.ms.work.api.TransportOrderFeign;
import com.sl.ms.work.api.TransportTaskFeign;
import com.sl.ms.work.domain.dto.TransportTaskDTO;
import com.sl.ms.work.domain.dto.request.TransportTaskCompleteDTO;
import com.sl.ms.work.domain.dto.request.TransportTaskDelayDeliveryDTO;
import com.sl.ms.work.domain.dto.request.TransportTaskStartDTO;
import com.sl.ms.work.domain.dto.response.TransportTaskMonthlyDistanceDTO;
import com.sl.ms.work.domain.enums.transportorder.TransportOrderStatus;
import com.sl.ms.work.domain.enums.transporttask.TransportTaskStatus;
import com.sl.transport.common.constant.Constants;
import com.sl.transport.common.exception.SLException;
import com.sl.transport.common.util.ObjectUtil;
import com.sl.transport.common.util.PageResponse;
import com.sl.transport.domain.OrganDTO;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Service
@Slf4j
public class DriverJobServiceImpl extends ServiceImpl<DriverJobMapper, DriverJobEntity> implements DriverJobService {
@Resource
private TransportOrderFeign transportOrderFeign;
@Resource
private TransportTaskFeign transportTaskFeign;
@Resource
private TruckPlanFeign truckPlanFeign;
@Resource
private TruckFeign truckFeign;
@Resource
private RedissonClient redissonClient;
@Resource
private TruckReturnRegisterFeign truckReturnRegisterFeign;
@Resource
private MessageFeign messageFeign;
@Resource
private OrganFeign organFeign;
@Override
@Transactional
public Long createDriverJob(Long transportTaskId, Long driverId) {
//查询运输任务
TransportTaskDTO transportTaskDTO = this.transportTaskFeign.findById(transportTaskId);
if (ObjectUtil.isEmpty(transportTaskDTO)) {
throw new SLException(DriverExceptionEnum.TRANSPORT_TASK_NOT_FOUND);
}
DriverJobEntity driverJobEntity = new DriverJobEntity();
driverJobEntity.setDriverId(driverId);
driverJobEntity.setStartAgencyId(transportTaskDTO.getStartAgencyId());
driverJobEntity.setEndAgencyId(transportTaskDTO.getEndAgencyId());
driverJobEntity.setStatus(DriverJobStatus.PENDING);
driverJobEntity.setTransportTaskId(transportTaskId);
//根据车辆计划id查询预计发车时间和预计到达时间
TruckPlanDto truckPlanDto = this.truckPlanFeign.findById(transportTaskDTO.getTruckPlanId());
driverJobEntity.setPlanDepartureTime(truckPlanDto.getPlanDepartureTime()); //计划发车时间
driverJobEntity.setPlanArrivalTime(truckPlanDto.getPlanArrivalTime()); //实际到达时间
boolean result = super.save(driverJobEntity);
if (result) {
//构建消息内容
TruckDto truckDto = truckFeign.fineById(transportTaskDTO.getTruckId());
OrganDTO startOrgan = organFeign.queryById(transportTaskDTO.getStartAgencyId());
OrganDTO endOrgan = organFeign.queryById(transportTaskDTO.getEndAgencyId());
String content = CharSequenceUtil.format("运输车辆:{}\n运输路线{}——{}", truckDto.getLicensePlate(), startOrgan.getName(), endOrgan.getName());
//构建消息对象
MessageAddDTO messageAddDTO = new MessageAddDTO();
messageAddDTO.setTitle("您有新的运输任务!");
messageAddDTO.setContent(content);
messageAddDTO.setBussinessType(MessageBussinessTypeEnum.DRIVER.getCode());
messageAddDTO.setUserId(driverId);
messageAddDTO.setContentType(MessageContentTypeEnum.DRIVER_SYSTEM_NOTICE.getCode());
messageAddDTO.setRelevantId(driverJobEntity.getId());
messageFeign.add(messageAddDTO);
return driverJobEntity.getId();
}
throw new SLException(DriverExceptionEnum.DRIVER_JOB_SAVE_ERROR);
}
@Override
@GlobalTransactional
public boolean updateStatus(Long id, DriverJobStatus status) {
DriverJobEntity driverJobEntity = new DriverJobEntity();
driverJobEntity.setId(id);
switch (status) {
case PENDING: {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_STATUS_NOT_PENDING);
}
case PROCESSING: {
//司机出库
DriverPickUpDTO driverPickUpDTO = new DriverPickUpDTO();
driverPickUpDTO.setId(String.valueOf(id));
this.outStorage(driverPickUpDTO);
break;
}
case CONFIRM: {
//改派,暂时只做状态修改处理
driverJobEntity.setStatus(DriverJobStatus.CONFIRM);
break;
}
case DELIVERED: {
//司机入库
DriverDeliverDTO driverDeliverDTO = new DriverDeliverDTO();
driverDeliverDTO.setId(String.valueOf(id));
this.intoStorage(driverDeliverDTO);
break;
}
case CANCELLED: {
//已作废,暂时只做状态修改处理
driverJobEntity.setStatus(DriverJobStatus.CANCELLED);
break;
}
default: {
break;
}
}
if (ObjectUtil.isNotEmpty(driverJobEntity.getStatus())) {
//更新状态
return super.updateById(driverJobEntity);
}
return true;
}
/**
* 司机入库,修改运单的当前节点和下个节点 以及 修改运单为待调度状态,结束运输任务
*
* @param driverDeliverDTO 司机作业单id
*/
@Override
@GlobalTransactional
public void intoStorage(DriverDeliverDTO driverDeliverDTO) {
//1.司机作业单获取运输任务id
DriverJobEntity driverJob = super.getById(driverDeliverDTO.getId());
if (ObjectUtil.isEmpty(driverJob)) {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_NOT_FOUND);
}
if (ObjectUtil.notEqual(driverJob.getStatus(), DriverJobStatus.PROCESSING)) {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_STATUS_UNKNOWN);
}
//运输任务id
Long transportTaskId = driverJob.getTransportTaskId();
//2.更新运输任务状态为完成
//加锁,只能有一个司机操作,任务已经完成的话,就不需要进行流程流转,只要完成司机自己的作业单即可
String lockRedisKey = Constants.LOCKS.DRIVER_JOB_LOCK_PREFIX + transportTaskId;
//2.1获取锁
RLock lock = this.redissonClient.getFairLock(lockRedisKey);
if (lock.tryLock()) {
//2.2获取到锁
try {
//2.3查询运输任务
TransportTaskDTO transportTask = this.transportTaskFeign.findById(transportTaskId);
//2.4判断任务是否已结束,不能再修改流转
if (ObjectUtil.equalsAny(transportTask.getStatus(), TransportTaskStatus.CANCELLED, TransportTaskStatus.COMPLETED)) {
return;
}
//2.5修改运单流转节点,修改当前节点和下一个节点
this.transportOrderFeign.updateByTaskId(String.valueOf(transportTaskId));
//2.6结束运输任务
TransportTaskCompleteDTO transportTaskCompleteDTO = BeanUtil.toBean(driverDeliverDTO, TransportTaskCompleteDTO.class);
transportTaskCompleteDTO.setTransportTaskId(String.valueOf(transportTaskId));
this.transportTaskFeign.completeTransportTask(transportTaskCompleteDTO);
} finally {
lock.unlock();
}
} else {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_INTO_STORAGE_ERROR);
}
//3.修改所有与运输任务id相关联的司机作业单状态和实际到达时间
LambdaUpdateWrapper<DriverJobEntity> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(ObjectUtil.isNotEmpty(transportTaskId), DriverJobEntity::getTransportTaskId, transportTaskId)
.set(DriverJobEntity::getStatus, DriverJobStatus.DELIVERED)
.set(DriverJobEntity::getActualArrivalTime, LocalDateTime.now());
this.update(updateWrapper);
}
/**
* 司机出库,修改运单为运输中状态,开始运输任务
*
* @param driverPickUpDTO 司机作业单id
*/
@Override
@GlobalTransactional
public void outStorage(DriverPickUpDTO driverPickUpDTO) {
//1.司机作业单获取运输任务id
DriverJobEntity driverJob = super.getById(driverPickUpDTO.getId());
if (ObjectUtil.isEmpty(driverJob)) {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_NOT_FOUND);
}
if (ObjectUtil.notEqual(driverJob.getStatus(), DriverJobStatus.PENDING)) {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_STATUS_UNKNOWN);
}
//查询当前司机是否有在途或交付任务,如有则不可提货
long count = this.getCount4Processing(driverJob.getDriverId());
if (count > 0) {
throw new SLException(DriverExceptionEnum.PROCESSING_DRIVER_JOB_NOT_EMPTY);
}
//运输任务id
Long transportTaskId = driverJob.getTransportTaskId();
//2.更新运输任务和运输运单
//加锁,只能有一个司机操作,任务已经为在途的话,就不需要进行流程流转,只要完成司机自己的作业单即可
String lockRedisKey = Constants.LOCKS.DRIVER_JOB_LOCK_PREFIX + transportTaskId;
//2.1获取锁
RLock lock = this.redissonClient.getFairLock(lockRedisKey);
if (lock.tryLock()) {
//2.2锁定
try {
//2.3查询运输任务
TransportTaskDTO transportTask = this.transportTaskFeign.findById(transportTaskId);
//2.4判断任务是否正在进行,不能再修改流转
if (ObjectUtil.equalsAny(transportTask.getStatus(), TransportTaskStatus.PROCESSING, TransportTaskStatus.CONFIRM)) {
return;
}
//2.5修改运单状态为 运输中
List<String> transportOrderIdList = this.transportTaskFeign.queryTransportOrderIdListById(transportTaskId);
this.transportOrderFeign.updateStatus(transportOrderIdList, TransportOrderStatus.PROCESSING);
//2.6开始运输任务
TransportTaskStartDTO transportTaskStartDTO = BeanUtil.toBean(driverPickUpDTO, TransportTaskStartDTO.class);
transportTaskStartDTO.setTransportTaskId(String.valueOf(transportTaskId));
this.transportTaskFeign.startTransportTask(transportTaskStartDTO);
} finally {
lock.unlock();
}
} else {
throw new SLException(DriverExceptionEnum.DRIVER_JOB_OUT_STORAGE_ERROR);
}
//3.修改所有与运输任务id相关联的司机作业单状态和实际出发时间
LambdaUpdateWrapper<DriverJobEntity> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(ObjectUtil.isNotEmpty(transportTaskId), DriverJobEntity::getTransportTaskId, transportTaskId)
.set(DriverJobEntity::getStatus, DriverJobStatus.PROCESSING)
.set(DriverJobEntity::getActualDepartureTime, LocalDateTime.now());
this.update(updateWrapper);
//4.修改车辆状态为运输中,调用base服务需要注意事务问题
TransportTaskDTO transportTask = this.transportTaskFeign.findById(transportTaskId);
this.truckFeign.updateRunStatus(transportTask.getTruckId(), TruckRunStatusEnum.RUNNING);
}
@Override
public boolean removeByTransportTaskId(Long transportTaskId) {
LambdaQueryWrapper<DriverJobEntity> queryWrapper = Wrappers.<DriverJobEntity>lambdaQuery()
.eq(DriverJobEntity::getTransportTaskId, transportTaskId);
return super.remove(queryWrapper);
}
/**
* 查询当前司机的在途和交付任务数量
*
* @param driverId 司机id
* @return 数量
*/
private long getCount4Processing(Long driverId) {
LambdaQueryWrapper<DriverJobEntity> countQueryWrapper = Wrappers.<DriverJobEntity>lambdaQuery()
.eq(ObjectUtil.isNotEmpty(driverId), DriverJobEntity::getDriverId, driverId)
.in(DriverJobEntity::getStatus, ListUtil.of(DriverJobStatus.PROCESSING, DriverJobStatus.DELIVERED));
return this.count(countQueryWrapper);
}
/**
* 延迟提货
*
* @param driverDelayDeliveryDTO 延迟提货对象
*/
@Override
@GlobalTransactional
public void delayedDelivery(DriverDelayDeliveryDTO driverDelayDeliveryDTO) {
//1.根据id查询司机作业单得到运输任务id
DriverJobEntity driverJobEntity = this.getById(driverDelayDeliveryDTO.getId());
Long transportTaskId = driverJobEntity.getTransportTaskId();
//2.更改同一运输任务的所有司机作业单计划发车时间
LocalDateTime delayTime = LocalDateTimeUtil.parse(driverDelayDeliveryDTO.getDelayTime(), DatePattern.NORM_DATETIME_PATTERN);
LambdaUpdateWrapper<DriverJobEntity> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(ObjectUtil.isNotEmpty(transportTaskId), DriverJobEntity::getTransportTaskId, transportTaskId)
.set(ObjectUtil.isNotEmpty(delayTime), DriverJobEntity::getPlanDepartureTime, delayTime);
this.update(updateWrapper);
//3.更改运输任务计划发车时间和备注
TransportTaskDelayDeliveryDTO transportTaskDelayDeliveryDTO = BeanUtil.toBean(driverDelayDeliveryDTO, TransportTaskDelayDeliveryDTO.class);
transportTaskDelayDeliveryDTO.setTransportTaskId(String.valueOf(transportTaskId));
transportTaskFeign.delayedDelivery(transportTaskDelayDeliveryDTO);
}
/**
* 回车登记
*
* @param driverReturnRegisterDTO 回车登记对象
*/
@Override
@GlobalTransactional
public void returnRegister(DriverReturnRegisterDTO driverReturnRegisterDTO) {
//更新关联运输任务id的司机作业单状态为已完成
LambdaUpdateWrapper<DriverJobEntity> updateWrapper = Wrappers.<DriverJobEntity>lambdaUpdate()
.eq(DriverJobEntity::getTransportTaskId, driverReturnRegisterDTO.getId())
.set(DriverJobEntity::getStatus, DriverJobStatus.COMPLETED);
this.update(updateWrapper);
//根据id查询运输任务
TransportTaskDTO transportTaskDTO = transportTaskFeign.findById(Long.valueOf(driverReturnRegisterDTO.getId()));
//构建回车登记对象
TruckReturnRegisterDTO truckReturnRegisterDTO = BeanUtil.toBean(driverReturnRegisterDTO, TruckReturnRegisterDTO.class);
truckReturnRegisterDTO.setTransportTaskId(Long.valueOf(driverReturnRegisterDTO.getId()));
truckReturnRegisterDTO.setTruckId(transportTaskDTO.getTruckId());
truckReturnRegisterFeign.save(truckReturnRegisterDTO);
//司机回车登记不修改车辆状态,由后台操作
truckPlanFeign.finished(transportTaskDTO.getStartAgencyId(), transportTaskDTO.getTruckPlanId(), transportTaskDTO.getTruckId(), StatusEnum.NORMAL);
}
/**
* 司机作业单月度统计
*
* @param driverId 司机id
* @param month 月份
* @return 统计数据
*/
@Override
public DriverJobStatisticsDTO jobMonthlyStatistics(String driverId, String month) {
//起止时间
DateTime dateTime = DateUtil.parse(month, DatePattern.NORM_MONTH_PATTERN);
LocalDateTime startTime = LocalDateTimeUtil.of(dateTime);
LocalDateTime endTime = LocalDateTimeUtil.of(DateUtil.endOfMonth(dateTime));
//根据计划到达时间统计当前司机月度任务总数
LambdaQueryWrapper<DriverJobEntity> totalQueryWrapper = new LambdaQueryWrapper<>();
totalQueryWrapper
.eq(ObjectUtil.isNotEmpty(driverId), DriverJobEntity::getDriverId, driverId)
.between(DriverJobEntity::getPlanArrivalTime, startTime, endTime);
long taskAmounts = this.count(totalQueryWrapper);
//根据实际到达时间查询当前司机月度任务列表
LambdaQueryWrapper<DriverJobEntity> completedQueryWrapper = new LambdaQueryWrapper<>();
completedQueryWrapper
.eq(ObjectUtil.isNotEmpty(driverId), DriverJobEntity::getDriverId, driverId)
.between(DriverJobEntity::getActualArrivalTime, startTime, endTime);
List<DriverJobEntity> completedList = this.list(completedQueryWrapper);
//从司机作业单中获取运输任务id列表
List<String> transportTaskIds = completedList.stream().map(x -> String.valueOf(x.getTransportTaskId())).collect(Collectors.toList());
//根据实际到达时间查询运输任务每日距离
List<DailyMileageDTO> dailyMileageDTOS = new ArrayList<>();
long transportMileage = 0L;
if (ObjectUtil.isNotEmpty(transportTaskIds)) {
List<TransportTaskMonthlyDistanceDTO> transportTaskMonthlyDistanceDTOS = transportTaskFeign.monthlyDistanceStatistics(transportTaskIds, month);
dailyMileageDTOS = transportTaskMonthlyDistanceDTOS.stream().map(x -> {
DailyMileageDTO dailyMileageDTO = BeanUtil.toBean(x, DailyMileageDTO.class);
//原始单位米,转换成公里四舍五入取整
long mileage = Math.round(x.getMileage() / 1000);
dailyMileageDTO.setMileage(mileage);
return dailyMileageDTO;
}).collect(Collectors.toList());
//统计月度总距离
transportMileage = dailyMileageDTOS.stream().mapToLong(DailyMileageDTO::getMileage).sum();
}
//封装数据并返回
DriverJobStatisticsDTO driverJobStatisticsDTO = new DriverJobStatisticsDTO();
driverJobStatisticsDTO.setTaskAmounts(Math.toIntExact(taskAmounts));
driverJobStatisticsDTO.setCompletedAmounts(completedList.size());
driverJobStatisticsDTO.setTransportMileage(transportMileage);
driverJobStatisticsDTO.setDailyMileage(dailyMileageDTOS);
return driverJobStatisticsDTO;
}
/**
* 分页查询
*
* @param dto 查询条件
* @return 司机作业单分页结果
*/
@Override
public PageResponse<DriverJobDTO> pageQuery(DriverJobPageQueryDTO dto) {
//1.构造查询条件
Page<DriverJobEntity> page = new Page<>(dto.getPage(), dto.getPageSize());
LambdaQueryWrapper<DriverJobEntity> queryWrapper = Wrappers.<DriverJobEntity>lambdaQuery()
.eq(ObjectUtil.isNotEmpty(dto.getId()), DriverJobEntity::getId, dto.getId())
.eq(ObjectUtil.isNotEmpty(dto.getDriverId()), DriverJobEntity::getDriverId, dto.getDriverId())
.eq(ObjectUtil.isNotEmpty(dto.getTransportTaskId()), DriverJobEntity::getTransportTaskId, dto.getTransportTaskId())
.in(ObjectUtil.isNotEmpty(dto.getStatusList()), DriverJobEntity::getStatus, dto.getStatusList());
//2.不同的状态查询不同的时间,待提货筛选的是预计发车时间,在途筛选的是计划到达时间,已完成筛选的是实际到达时间
if (CollUtil.isNotEmpty(dto.getStatusList()) && dto.getStatusList().contains(DriverJobStatus.PENDING)) {
queryWrapper
.between(ObjectUtil.isNotEmpty(dto.getMinTaskTime()), DriverJobEntity::getPlanDepartureTime, dto.getMinTaskTime(), dto.getMaxTaskTime())
.orderByAsc(DriverJobEntity::getPlanDepartureTime);
} else if (CollUtil.isNotEmpty(dto.getStatusList()) && dto.getStatusList().contains(DriverJobStatus.COMPLETED)) {
queryWrapper
.between(ObjectUtil.isNotEmpty(dto.getMinTaskTime()), DriverJobEntity::getActualArrivalTime, dto.getMinTaskTime(), dto.getMaxTaskTime())
.orderByDesc(DriverJobEntity::getActualArrivalTime);
} else if (CollUtil.isNotEmpty(dto.getStatusList()) && dto.getStatusList().contains(DriverJobStatus.PROCESSING)) {
queryWrapper
.between(ObjectUtil.isNotEmpty(dto.getMinTaskTime()), DriverJobEntity::getPlanArrivalTime, dto.getMinTaskTime(), dto.getMaxTaskTime())
.orderByAsc(DriverJobEntity::getPlanArrivalTime);
} else {
queryWrapper
.between(ObjectUtil.isNotEmpty(dto.getMinTaskTime()), DriverJobEntity::getCreated, dto.getMinTaskTime(), dto.getMaxTaskTime())
.orderByAsc(DriverJobEntity::getCreated);
}
//3.分页查询
Page<DriverJobEntity> pageResult = this.page(page, queryWrapper);
if (CollUtil.isEmpty(pageResult.getRecords())) {
return new PageResponse<>(pageResult);
}
//4.实体类转dto
List<DriverJobDTO> list = BeanUtil.copyToList(pageResult.getRecords(), DriverJobDTO.class);
//5.查询提货任务时,需要判断任务是否可提
if (dto.getPage().equals(1) && CollUtil.isNotEmpty(dto.getStatusList()) && dto.getStatusList().contains(DriverJobStatus.PENDING)) {
long count = getCount4Processing(dto.getDriverId());
//如果不存在在途或已交付任务,设置最早的任务可以提货
if (count == 0L) {
list.get(0).setEnablePickUp(true);
}
}
//6.封装分页结果
PageResponse<DriverJobDTO> pageResponse = PageResponse.of(pageResult);
pageResponse.setItems(list);
return pageResponse;
}
}

View File

@@ -0,0 +1,7 @@
_ ${spring.application.name} ${application.version}
___ | | ___ __ __ _ __ _ __ ___ ___ ___ Port: ${server.port}
/ __|| | _____ / _ \\ \/ /| '_ \ | '__|/ _ \/ __|/ __| Pid: ${pid} Profile(s): ${AnsiColor.GREEN}${spring.profiles.active}${AnsiColor.DEFAULT}
\__ \| ||_____|| __/ > < | |_) || | | __/\__ \\__ \
|___/|_| \___|/_/\_\| .__/ |_| \___||___/|___/ https://sl-express.itheima.net/
|_|

View File

@@ -0,0 +1,31 @@
server:
port: 18098
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: nacos
server-addr: 192.168.150.101:8848
discovery:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
ip: 192.168.150.1
config:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,30 @@
server:
port: 18098
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: vO5/dZ9,iL
server-addr: nacos-service.yjy-public-slwl-java-prod.svc.cluster.local:8848
discovery:
namespace: 92312ba8-1119-440f-81af-c29618df303b
config:
namespace: 92312ba8-1119-440f-81af-c29618df303b
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,30 @@
server:
port: 18098
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: nacos
server-addr: 192.168.150.101:8848
discovery:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
config:
namespace: ecae68ba-7b43-4473-a980-4ddeb6157bdc
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,30 @@
server:
port: 18098
tomcat:
uri-encoding: UTF-8
threads:
max: 1000
min-spare: 30
spring:
cloud:
nacos:
username: nacos
password: nacos
server-addr: nacos-service.yjy-public-slwl-java.svc.cluster.local:8848
discovery:
namespace: 92312ba8-1119-440f-81af-c29618df303b
config:
namespace: 92312ba8-1119-440f-81af-c29618df303b
shared-configs: #共享配置
- data-id: shared-spring-seata.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mysql.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-mybatis-plus.yml
group: SHARED_GROUP
refresh: false
- data-id: shared-spring-redis.yml
group: SHARED_GROUP
refresh: false

View File

@@ -0,0 +1,23 @@
application:
version: v1.0
logging:
config: classpath:logback-spring.xml
spring:
application:
name: sl-express-ms-driver
profiles:
active: local
mvc:
pathmatch:
#解决异常swagger Failed to start bean 'documentationPluginsBootstrapper'; nested exception is java.lang.NullPointerException
#因为Springfox使用的路径匹配是基于AntPathMatcher的而Spring Boot 2.6.X使用的是PathPatternMatcher
matching-strategy: ant_path_matcher
sl:
swagger:
package-path: com.sl.ms.driver.controller
title: 神领物流 - 司机微服务接口文档
description: 该微服务完成司机相关业务。
contact-name: 传智教育·研究院
contact-url: http://www.itcast.cn/
contact-email: yjy@itcast.cn
version: ${application.version}

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--scan: 当此属性设置为true时配置文件如果发生改变将会被重新加载默认值为true。-->
<!--scanPeriod: 设置监测配置文件是否有修改的时间间隔如果没有给出时间单位默认单位是毫秒。当scan为true时此属性生效。默认的时间间隔为1分钟。-->
<!--debug: 当此属性设置为true时将打印出logback内部日志信息实时查看logback运行状态。默认值为false。-->
<configuration debug="false" scan="false" scanPeriod="60 seconds">
<springProperty scope="context" name="appName" source="spring.application.name"/>
<!--文件名-->
<property name="logback.appname" value="${appName}"/>
<!--文件位置-->
<property name="logback.logdir" value="/data/logs"/>
<!-- 定义控制台输出 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} - [%thread] - %-5level - %logger{50} - %msg%n</pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
<File>${logback.logdir}/${logback.appname}/${logback.appname}.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${logback.logdir}/${logback.appname}/${logback.appname}.%d{yyyy-MM-dd}.log.zip</FileNamePattern>
<maxHistory>90</maxHistory>
</rollingPolicy>
<encoder>
<charset>UTF-8</charset>
<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>
</encoder>
</appender>
<!--evel:用来设置打印级别大小写无关TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF-->
<!--不能设置为INHERITED或者同义词NULL。默认是DEBUG。-->
<root level="INFO">
<appender-ref ref="stdout"/>
</root>
</configuration>