MybatisPlus增删改查方法总结
查询
DriverSet driverSet = driverSetMapper.selectOne( //selectList是查询多个
new LambdaQueryWrapper<DriverSet>() // 指定数据库字段对应的实体类
.eq(DriverSet::getDriverId, driverId)
);
链式调用
List<DriverSet> drivers = driverSetMapper.selectList(
new LambdaQueryWrapper<DriverSet>()
.eq(DriverSet::getStatus, 1)
.like(DriverSet::getDriverName, "张") // 模糊查询
.between(DriverSet::getCreateTime, startTime, endTime) // 时间范围
.orderByDesc(DriverSet::getCreateTime) // 按创建时间倒序
);
修改
boolean updated = new LambdaUpdateWrapper<DriverSet>()
.eq(DriverSet::getDriverId, driverId) // 条件
.set(DriverSet::getDriverName, "新司机名") // 设置新值
.set(DriverSet::getStatus, 1)
.update(); // 执行更新
删除
boolean deleted = new LambdaQueryWrapper<DriverSet>()
.eq(DriverSet::getDriverId, driverId)
.remove(); // 执行删除,也会批量删除
增加
DriverSet driver = new DriverSet();
driver.setDriverId(1001L);
driver.setDriverName("张三");
driver.setStatus(1);
int rows = driverSetMapper.insert(driver); // 返回 1 表示成功
Long id = driver.getId(); // 返回对应的id(如果满足下面的条件)
- 数据库主键是自增类型(如 MySQL AUTO_INCREMENT、PostgreSQL SERIAL)
- 实体类主键字段标注 @TableId(type = IdType.AUTO)
分布式任务调度(xxl-job)
XXL-JOB 是一个分布式任务调度平台,其核心设计目标是开发快速、学习简单、轻量级、易扩展。
xxl-job入门案例
第一步、下载xxl-job的示例代码:xxl-job: 一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。
第二步、创建doc文件夹里的数据库
第三步、修改调度中心的相关配置,比如端口,数据库url、密码等。
第四步、启动调度中心,进入:localhost:8080/xxl-job-admin/toLogin
用户名默认为admin,密码为123456
第五步、部署执行器项目(就是指具体做什么,比如每5分钟发车.....就是要做的业务)
在案例里的springboot项目里修改application配置文件,包括日志路径、调度中心部署地址、项目运行时的端口
配置文件
# web port
server.port=8281
# log config
logging.config=classpath:logback.xml
### 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册;
xxl.job.admin.addresses=http://127.0.0.1:8080/xxl-job-admin
### 执行器通讯TOKEN [选填]:非空时启用;
xxl.job.accessToken=
### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册
xxl.job.executor.appname=xxl-job-executor-sample
### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
xxl.job.executor.address=
### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
xxl.job.executor.ip=
### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
xxl.job.executor.port=9999
### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
xxl.job.executor.logpath=D:\\BaiduNetdiskDownload\\代码\\代码\\xxl-job-master\\doc
### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
xxl.job.executor.logretentiondays=30
六、配置好执行器项目之后就可以启动。
可以在调度中心看到
七、开发执行器项目的job方法
之前的步骤已经将执行器和调度中心的相关配置,之后就可以开发具体要调度执行的业务相关代码
首先要知道图形化界面也是可以创建出job方法
在图形化界面执行任务,执行完任务就可以在调度日志里查看到
具体项目里使用代码完成调度任务注册
该操作是将xxl-job-executor-sample-springboot文件里的任务添加到本地具体项目来完成任务注册
我们使用单独的一个微服务模块 service-dispatch 集成 XXL-JOB 执行器
一、导入依赖并修改nacos注册中心里的相关配置
在 service-dispatch微服务里导入依赖
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
之后在nacos里配置调度中心的相关配置,比如IP地址
xxl:
job:
admin:
# 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册
addresses: http://localhost:8080/xxl-job-admin
# 执行器通讯TOKEN [选填]:非空时启用
accessToken: default_token
executor:
# appname是调度中心里注册的任务的名字
appname: xxl-job-executor-sample
# 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。
address:
# 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务";
ip:
# 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口;
port: 9999
# 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径;
logpath: /data/applogs/xxl-job/jobhandler
# 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能;
logretentiondays: 30
client:
jobGroupId: 1
# 下面是之后在JobInfoController里创建的方法注册到nacos里
addUrl: ${xxl.job.admin.addresses}/jobinfo/addJob
removeUrl: ${xxl.job.admin.addresses}/jobinfo/removeJob
startJobUrl: ${xxl.job.admin.addresses}/jobinfo/startJob
stopJobUrl: ${xxl.job.admin.addresses}/jobinfo/stopJob
addAndStartUrl: ${xxl.job.admin.addresses}/jobinfo/addAndStartJob
二、配置xxl
如上图创建xxl-config文件夹,放入以下的配置类
@Configuration
public class XxlJobConfig {
private Logger logger = LoggerFactory.getLogger(XxlJobConfig.class);
@Value("${xxl.job.admin.addresses}")
private String adminAddresses;
@Value("${xxl.job.accessToken}")
private String accessToken;
@Value("${xxl.job.executor.appname}")
private String appname;
@Value("${xxl.job.executor.address}")
private String address;
@Value("${xxl.job.executor.ip}")
private String ip;
@Value("${xxl.job.executor.port}")
private int port;
@Value("${xxl.job.executor.logpath}")
private String logPath;
@Value("${xxl.job.executor.logretentiondays}")
private int logRetentionDays;
@Bean
public XxlJobSpringExecutor xxlJobExecutor() {
logger.info(">>>>>>>>>>> xxl-job config init.");
XxlJobSpringExecutor xxlJobSpringExecutor = new XxlJobSpringExecutor();
xxlJobSpringExecutor.setAdminAddresses(adminAddresses);
xxlJobSpringExecutor.setAppname(appname);
xxlJobSpringExecutor.setAddress(address);
xxlJobSpringExecutor.setIp(ip);
xxlJobSpringExecutor.setPort(port);
xxlJobSpringExecutor.setAccessToken(accessToken);
xxlJobSpringExecutor.setLogPath(logPath);
xxlJobSpringExecutor.setLogRetentionDays(logRetentionDays);
return xxlJobSpringExecutor;
}
}
三、在xxl文件夹下创建job文件夹编写job工作(接下来是基于xxljob的图形界面进行设置调度任务的,实际开发看下一个:项目组封装xxl-job客户端)
测试任务
@Component
public class DispatchJobHandler {
@XxlJob("firstJobHandler")
public void testJobHandler() {
System.out.println("xxl-job项目集成测试");
}
}
四、创建执行器
要启动调度中心项目(XxlJobAdminApplication)和调度任务项目的服务(自己创建的项目ServiceDispatchApplication)
启动完成之后,在执行器管理里面创建执行器:配置好执行器的名字(AppName,在项目的nacos配置文件里配置了,然后自动注册来自动获取IP地址)
创建成功如下
五、在任务管理中心创建任务并测试是否可以通过执行器执行任务
如果上面的注册中心可以看到执行器,表示执行器注册成功,之后就可以创建要定期执行的任务。
创建任务的具体如下:
创建之后执行一次,结果如下:
项目中封装xxl-job客户端
一、调度中心创建任务方法
调度中心的jobInfoController里创建接收任务的方法,因为自己的项目里要通过通过client远程调用jobInfoController里的方法返回一个jobId。
// 自定义任务操作的方法
// 添加任务
@RequestMapping("/addJob")
@ResponseBody
@PermissionLimit(limit = false)
public ReturnT<String> addJobInfo(@RequestBody XxlJobInfo jobInfo) {
return xxlJobService.add(jobInfo);
}
// 删除任务
@RequestMapping("/removeJob")
@ResponseBody
@PermissionLimit(limit = false)
public ReturnT<String> removeJob(@RequestBody XxlJobInfo jobInfo) {
return xxlJobService.remove(jobInfo.getId());
}
// 更新任务
@RequestMapping("/updateJob")
@ResponseBody
@PermissionLimit(limit = false)
public ReturnT<String> updateJob(@RequestBody XxlJobInfo jobInfo) {
return xxlJobService.update(jobInfo);
}
// 停止任务
@RequestMapping("/stopJob")
@ResponseBody
@PermissionLimit(limit = false)
public ReturnT<String> pauseJob(@RequestBody XxlJobInfo jobInfo) {
return xxlJobService.stop(jobInfo.getId());
}
// 启动任务
@RequestMapping("/startJob")
@ResponseBody
@PermissionLimit(limit = false)
public ReturnT<String> startJob(@RequestBody XxlJobInfo jobInfo) {
return xxlJobService.start(jobInfo.getId());
}
// 添加并执行任务
@RequestMapping("/addAndStartJob")
@ResponseBody
@PermissionLimit(limit = false)
public ReturnT<String> addAndStartJob(@RequestBody XxlJobInfo jobInfo) {
ReturnT<String> result = xxlJobService.add(jobInfo);
int id = Integer.valueOf(result.getContent());
xxlJobService.start(id);
// 立即执行一次
jobTriggerPoolHelper.trigger(id, TriggerTypeEnum.MANUAL, -1, null, jobInfo.getExecutorParam(), "");
return result;
}
这些方法也要注册到自己项目dispatch模块的nacos里
二、项目的service-dispatch模块添加相关配置类
创建配置类,读取配置文件中使用的调度中心任务操作的方法。
@Data
@Component
@ConfigurationProperties(prefix = "xxl.job.client")
public class XxlJobClientConfig {
private Integer jobGroupId;
private String addUrl;
private String removeUrl;
private String startJobUrl;
private String stopJobUrl;
private String addAndStartUrl;
}
三、创建远程调用的接口:在xxl文件夹下创建client文件夹
本地项目使用restTemplate来进行远程的调用,所有要先在该微服务的启动类中添加restTemplate
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
之后创建client文件夹,然后在里面创建XxxJobCilent类,用于远程调用调度中心
@Slf4j
@Component
public class XxlJobClient {
@Autowired
private XxlJobClientConfig xxlJobClientConfig;
// 客户端调用服务端里面的方法
@Autowired
private RestTemplate restTemplate;
@SneakyThrows
public Long addJob(String executorHandler, String param, String corn, String desc) {
XxlJobInfo xxJobInfo = new XxlJobInfo();
xxJobInfo.setJobGroup(xxlJobClientConfig.getJobGroupId());
xxJobInfo.setJobDesc(desc);
xxJobInfo.setAuthor("dy");
xxJobInfo.setScheduleType("CRON");
xxJobInfo.setScheduleConf(corn);
xxJobInfo.setGlueType("BEAN");
xxJobInfo.setExecutorHandler(executorHandler);
xxJobInfo.setExecutorParam(param);
xxJobInfo.setExecutorRouteStrategy("FIRST");
xxJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
xxJobInfo.setMisfireStrategy("FIRE_ONCE_NOW");
xxJobInfo.setExecutorTimeout(0);
xxJobInfo.setExecutorFailRetryCount(0);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxJobInfo, headers);
String url = xxlJobClientConfig.getAddUrl();
ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
if (response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
log.info("增加xxl执行任务成功,返回信息:{}", response.getBody().toJSONString());
return response.getBody().getLong("content"); // 得到jobId
}
log.info("调用xxl执行任务失败:{}", response.getBody().toJSONString());
throw new GuiguException(ResultCodeEnum.XXL_JOB_ERROR);
}
public Boolean startJob(Long jobId) {
XxlJobInfo xxJobInfo = new XxlJobInfo();
xxJobInfo.setId(jobId.intValue());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxJobInfo, headers);
String url = xxlJobClientConfig.getStartJobUrl();
ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
if (response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
log.info("启动xxl执行任务成功:{}", jobId);
response.getBody().toJSONString();
return true;
}
log.info("启动xxl执行任务失败:{},返回信息:{}", jobId, response.getBody().toJSONString());
throw new GuiguException(ResultCodeEnum.XXL_JOB_ERROR);
}
public Boolean stopJob(Long jobId) {
XxlJobInfo xxJobInfo = new XxlJobInfo();
xxJobInfo.setId(jobId.intValue());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxJobInfo, headers);
String url = xxlJobClientConfig.getStopJobUrl();
ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
if (response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
log.info("停止xxl执行任务成功:{},返回信息:{}", jobId, response.getBody().toJSONString());
return true;
}
log.info("停止xxl执行任务失败:{},返回信息:{}", jobId, response.getBody().toJSONString());
throw new GuiguException(ResultCodeEnum.XXL_JOB_ERROR);
}
public Boolean removeJob(Long jobId) {
XxlJobInfo xxJobInfo = new XxlJobInfo();
xxJobInfo.setId(jobId.intValue());
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxJobInfo, headers);
String url = xxlJobClientConfig.getRemoveUrl();
ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
if (response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
log.info("删除xxl执行任务成功:{},返回信息:{}", jobId, response.getBody().toJSONString());
return true;
}
log.info("删除xxl执行任务失败:{},返回信息:{}", jobId, response.getBody().toJSONString());
throw new GuiguException(ResultCodeEnum.XXL_JOB_ERROR);
}
public Long addAndStart(String executorHandler, String param, String corn, String desc) {
XxlJobInfo xxJobInfo = new XxlJobInfo();
xxJobInfo.setJobGroup(xxlJobClientConfig.getJobGroupId());
xxJobInfo.setJobDesc(desc);
xxJobInfo.setScheduleType("CRON");
xxJobInfo.setScheduleConf(corn);
xxJobInfo.setGlueType("BEAN");
xxJobInfo.setExecutorHandler(executorHandler);
xxJobInfo.setExecutorRouteStrategy("FIRST");
xxJobInfo.setExecutorBlockStrategy("SERIAL_EXECUTION");
xxJobInfo.setMisfireStrategy("FIRE_ONCE_NOW");
xxJobInfo.setExecutorTimeout(0);
xxJobInfo.setExecutorFailRetryCount(0);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<XxlJobInfo> request = new HttpEntity<>(xxJobInfo, headers);
String url = xxlJobClientConfig.getAddAndStartUrl();
ResponseEntity<JSONObject> response = restTemplate.postForEntity(url, request, JSONObject.class);
if (response.getStatusCode().value() == 200 && response.getBody().getIntValue("code") == 200) {
return response.getBody().getLong("content");
}
log.info("增加并开启执行xxl任务失败:{}", response.getBody().toJSONString());
throw new GuiguException(ResultCodeEnum.XXL_JOB_ERROR);
}
}
四、创建并远程提交执行器
service里将执行器远程传递到xxl-job的调度中心,(该步骤做完就创建执行器)
public Long addAndStartTask(NewOrderTaskVo newOrderTaskVo) {
// 通过订单查询要执行的任务
OrderJob orderJob = orderJobMapper.selectOne(new LambdaQueryWrapper<OrderJob>()
.eq(OrderJob::getOrderId, newOrderTaskVo.getOrderId()));
if (null == orderJob) { // 如果任务不存在,那么添加任务
//(远程调用xxljob-admin项目),添加成功返回一个任务id,存储到数据库里
// 返回一个任务id
Long jobId = xxJobClient.addAndStart("newOrderTaskHandler", "", "0 0/1 * * * ?",
"新订单任务,订单ID: " + newOrderTaskVo.getOrderId());
// 记录订单与任务的关联信息
orderJob = new OrderJob();
orderJob.setOrderId(newOrderTaskVo.getOrderId());
orderJob.setJobId(jobId);
orderJob.setParameter(JSONObject.toJSONString(newOrderTaskVo));
orderJobMapper.insert(orderJob);
}
return orderJob.getJobId();
}
在xxl文件夹的job下新建一个JobHandler执行器类,里面有要执行的任务(就是上面的"newOrderTaskHandler"方法)
@Component
public class JobHandler {
@Autowired
private XxlJobLogMapper xxlJobLogMapper;
@Autowired
private NewOrderService newOrderService;
@XxlJob("newOrderTaskHandler") // 添加与开始指定为该执行器,
public void newOrderTaskHandler() {
// 这个方法调度中心调用,通过client里的addAndStart方法将此方法传到调度中心
// 记录任务调度日志
XxlJobLog xxlJobLog = new XxlJobLog();
xxlJobLog.setJobId(XxlJobHelper.getJobId());
long startTime = System.currentTimeMillis();
try {
// 调用任务方法,通过jobid来执行任务
newOrderService.executeTask(XxlJobHelper.getJobId());
// 成功状态
xxlJobLog.setStatus(1);
} catch (Exception e) {
xxlJobLog.setStatus(0);
xxlJobLog.setError(e.getMessage());
e.printStackTrace();
} finally {
// 记录日志
long times = System.currentTimeMillis() - startTime;
xxlJobLog.setTimes(times);
xxlJobLogMapper.insert(xxlJobLog);
}
}
}
由上面的代码可见,执行器类里的任务其实大部分都是记录日志,而执行的任务有封装到executeTask方法里,所以开发executeTask方法。
五、开发执行的任务
提交订单并受到司机接单的任务逻辑
1 根据 job_id 查询数据库。当前任务是否已经创建,如果没有创建。不往下执行了
2 查询订单状态。如果当前订单接单状态,继续执行。如果当前订单不是接单状态,停止任务调度
3 远程调用:搜索附件满足条件可以接单的司机
4 远程调用之后,获取满足可以接单司机的集合
5 遍历司机集合,得到每个司机,为每个司机创建配临时队列,存储新订单信息
以上的业务涉及到两种Redis队列:
- 一种是订单ID为key的队列,乘客下单之后就有,用于存储可以接单的司机。
- 另一种是以各个司机的ID为key的队列,每个司机都有一个,用于存储订单。
@Override
public void executeTask(long jobId) {
OrderJob orderJob = orderJobMapper.selectOne(new LambdaQueryWrapper<OrderJob>().eq(OrderJob::getJobId, jobId));
if(orderJob == null){
return;
}
String jsonString = orderJob.getParameter();
NewOrderTaskVo newOrderTaskVo = JSONObject.parseObject(jsonString, NewOrderTaskVo.class);
// 前面的就是通过jobId获取新订单对象
Long orderId = newOrderTaskVo.getOrderId();
Integer status = orderInfoFeignClient.getOrderStatus(orderId).getData();
if (status.intValue() != OrderStatus.WAITING_ACCEPT.getStatus().intValue()) {
xxJobClient.stopJob(jobId);
log.info("停止任务调度: {}", JSON.toJSONString(newOrderTaskVo));
return ;
}
// 搜索附近满足条件的司机
SearchNearByDriverForm searchNearByDriverForm = new SearchNearByDriverForm();
searchNearByDriverForm.setLongitude(newOrderTaskVo.getStartPointLongitude());
searchNearByDriverForm.setLatitude(newOrderTaskVo.getStartPointLatitude());
searchNearByDriverForm.setMileageDistance(newOrderTaskVo.getExpectDistance());
List<NearByDriverVo> nearByDriverVoList =
locationFeignClient.searchNearByDriver(searchNearByDriverForm).getData();
nearByDriverVoList.forEach(driver -> {
// 使用Redis的set类型
// 根据订单id生成key
String repeatKey = RedisConstant.DRIVER_ORDER_REPEAT_LIST + newOrderTaskVo.getOrderId();
// 查看集合里有没有遍历到的司机
Boolean isMember = redisTemplate.opsForSet().isMember(repeatKey, driver.getDriverId());
if (!isMember) { // 不存在该司机
// 代码逻辑
redisTemplate.opsForSet().add(repeatKey, driver.getDriverId());
// 过期时间:15分钟,超过15分钟没有主动取消
redisTemplate.expire(repeatKey, RedisConstant.DRIVER_ORDER_REPEAT_LIST_EXPIRES_TIME, TimeUnit.MINUTES);
// 使用示例
NewOrderDataVo newOrderDataVo = new NewOrderDataVo();
newOrderDataVo.setOrderId(newOrderTaskVo.getOrderId());
newOrderDataVo.setStartLocation(newOrderTaskVo.getStartLocation());
newOrderDataVo.setEndLocation(newOrderTaskVo.getEndLocation());
newOrderDataVo.setExpectAmount(newOrderTaskVo.getExpectAmount());
newOrderDataVo.setExpectDistance(newOrderTaskVo.getExpectDistance());
newOrderDataVo.setExpectTime(newOrderTaskVo.getExpectTime());
newOrderDataVo.setFavourFee(newOrderTaskVo.getFavourFee());
newOrderDataVo.setDistance(driver.getDistance());
newOrderDataVo.setCreateTime(newOrderTaskVo.getCreateTime());
// 新订单保存司机的临时队列,Redis里面是list集合
String key = RedisConstant.DRIVER_ORDER_TEMP_LIST + driver.getDriverId();
redisTemplate.opsForList().leftPush(key, JSONObject.toJSONString(newOrderDataVo));
// 过期时间:1分钟
redisTemplate.expire(key, RedisConstant.DRIVER_ORDER_TEMP_LIST_EXPIRES_TIME, TimeUnit.MINUTES);
}
});
}
六、根据业务,乘客端调用调度任务
NewOrderTaskVo newOrderDispatchVo = new NewOrderTaskVo();
newOrderDispatchVo.setOrderId(orderId);
newOrderDispatchVo.setStartLocation(orderInfoForm.getStartLocation());
newOrderDispatchVo.setStartPointLongitude(orderInfoForm.getStartPointLongitude());
newOrderDispatchVo.setStartPointLatitude(orderInfoForm.getStartPointLatitude());
newOrderDispatchVo.setEndLocation(orderInfoForm.getEndLocation());
newOrderDispatchVo.setEndPointLongitude(orderInfoForm.getEndPointLongitude());
newOrderDispatchVo.setEndPointLatitude(orderInfoForm.getEndPointLatitude());
newOrderDispatchVo.setExpectAmount(orderInfoForm.getExpectAmount());
newOrderDispatchVo.setExpectDistance(orderInfoForm.getExpectDistance());
newOrderDispatchVo.setExpectTime(drivingLineVo.getDuration());
newOrderDispatchVo.setFavourFee(orderInfoForm.getFavourFee());
newOrderDispatchVo.setCreateTime(new Date());
// 远程调用,开启定时任务
Long jobId = newOrderFeignClient.addAndStartTask(newOrderDispatchVo).getData();