Commit 1e784b08 by Ren Ping

fix:处理初始化工程师容量定时任务

1 parent 8905fedb
......@@ -2,6 +2,7 @@ package com.dituhui.pea.dispatch.constraint;
import java.util.List;
import cn.hutool.core.util.StrUtil;
import org.optaplanner.core.api.score.buildin.hardsoftlong.HardSoftLongScore;
import org.optaplanner.core.api.score.stream.Constraint;
import org.optaplanner.core.api.score.stream.ConstraintFactory;
......@@ -15,7 +16,7 @@ public class DispatchConstraintProvider implements ConstraintProvider {
@Override
public Constraint[] defineConstraints(ConstraintFactory factory) {
return new Constraint[] {
return new Constraint[]{
// 硬约束
// 运行时长提升效果
// 5s/60s: 技能权重4-技能匹配问题0个,时间窗问题14个
......@@ -95,12 +96,10 @@ public class DispatchConstraintProvider implements ConstraintProvider {
protected Constraint dispatchedMatch(ConstraintFactory factory) {
return factory.forEach(Customer.class).filter(customer ->
// 已分配
(customer.getDispatchedTechnicianCode() != null && ((customer.getTechnician() == null)
|| (!StringUtils.equals(customer.getDispatchedTechnicianCode(), customer.getTechnician().getCode()))))
||
// 已排除
(customer.getExclusiveTechnicianCode() != null && ((customer.getTechnician() == null) || (StringUtils
.equals(customer.getExclusiveTechnicianCode(), customer.getTechnician().getCode())))))
(customer.getDispatchedTechnicianCode() != null
&& (customer.getTechnician() == null || !StringUtils.equals(customer.getDispatchedTechnicianCode(), customer.getTechnician().getCode())))
|| (customer.getExclusiveTechnicianCode() != null
&& (customer.getTechnician() == null || StrUtil.contains("," + customer.getExclusiveTechnicianCode() + ",", "," + customer.getTechnician().getCode() + ","))))
.penalizeLong(HardSoftLongScore.ONE_HARD, customer -> 50)
.asConstraint(ConstraintNameEnum.dispatchedMatch.name());
}
......
......@@ -197,4 +197,25 @@ public class OrderInfo implements Serializable {
@Column(name = "update_time")
private LocalDateTime updateTime;
/**
* 是否重物搬运(双人上门) 0:否 1:是 默认0
*/
@Column(name = "is_multiple")
private Integer isMultiple = 0;
/**
* 是否指定某个工程师/是否排除某个工程师 0:否 1:指定 2:排除 默认0
*/
@Column(name = "is_appoint_engineer")
private Integer isAppointEngineer = 0;
/**
* 指定某个工程师/排除某个工程师 codes 多个,分割
*/
@Column(name = "appoint_engineer_codes")
private String appointEngineerCodes;
}
package com.dituhui.pea.dispatch.quartz.engineerCapacity;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.dituhui.pea.dispatch.common.DateUtil;
import com.dituhui.pea.dispatch.common.DateUtils;
import com.dituhui.pea.dispatch.common.OccupyInfoDetail;
......@@ -189,7 +190,7 @@ public class InitEngineerCapacityScheduler {
// 初始化一个工程师、一天的容量
CapacityEngineerStatEntity statEntity = capacityEngineerStatDao.getByWorkdayAndEngineerCode(date, engineerCode);
if (statEntity != null && !rewriteForce) {
log.error("技术员容量信息记录已存在, 直接返回");
log.error("技术员容量信息记录(engineer: {}, date:{})已存在, 直接返回", engineerCode, date);
return;
}
log.info("日期[{}] 技术员[{}] 有日历记录需要特别处理 ===", date, engineerCode);
......@@ -212,10 +213,11 @@ public class InitEngineerCapacityScheduler {
}
public void initOneEngineerByDays(String bdate, String edate, String branchId) {
List<String> allEngineerCodes = engineerInfoDao.getAllByBranchId(branchId).stream().map(EngineerInfo::getEngineerCode).collect(Collectors.toList());
log.warn(">>> 分部工程师容量初始化开始,branchId: {},工程师数量:{}", branchId, allEngineerCodes.size());
for (String engineerCode : allEngineerCodes) {
LocalDate currentDate = DateUtils.localDateFromStr(bdate);
LocalDate endDate = DateUtils.localDateFromStr(edate);
List<String> allEngineerCodes = engineerInfoDao.getAllByBranchId(branchId).stream().map(EngineerInfo::getEngineerCode).collect(Collectors.toList());
for(String engineerCode: allEngineerCodes){
while (!currentDate.isAfter(endDate)) {
initOneEngineer(DateUtils.formatDate(currentDate), engineerCode);
currentDate = currentDate.plusDays(1);
......
......@@ -84,7 +84,7 @@ public class SchedulerServiceImpl implements SchedulerService {
return;
}
OrgGroup orgGroup=orgGroupRepository.findByGroupId(orgTeamEntity.getGroupId()).get();
OrgGroup orgGroup = orgGroupRepository.findByGroupId(orgTeamEntity.getGroupId()).get();
if (ObjectUtil.equals(2, orgGroup.getCategory())) {
log.error(">>> teamId:{} 来自网点,不自动派工", teamId);
......@@ -97,6 +97,7 @@ public class SchedulerServiceImpl implements SchedulerService {
}
LocalDateTime now = LocalDateTime.now();
String today = DateUtil.format(now, "yyyy-MM-dd");
String nowTime = DateUtil.format(now, "HH:mm");
String nowTimePlus30 = DateUtil.format(now.plusMinutes(30), "HH:mm");
......@@ -109,10 +110,13 @@ public class SchedulerServiceImpl implements SchedulerService {
String groupId = orgTeamEntity.getGroupId();
log.info("dispatchRun group:{}, team:{} done", groupId, teamId);
for (int i = 1; i <= nextDaysLimit; i++) {
String currDay = LocalDate.now().plusDays(i).format(DateTimeFormatter.ISO_LOCAL_DATE);
Optional<DispatchBatch> optional = dispatchBatchRepository.findByTeamIdAndBatchDate(teamId, currDay);
if (optional.isPresent() && Objects.nonNull(optional.get().getCutoffedTime())) {
if (optional.isPresent()
&& Objects.nonNull(optional.get().getCutoffedTime())
&& today.equals(DateUtil.format(optional.get().getCutoffedTime(), "yyyy-MM-dd"))) {
//自动任务截止
log.error(">>> teamId:{}, day:{} 自动任务已截止", teamId, currDay);
continue;
......
package com.dituhui.pea.dispatch.service.impl;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.dituhui.pea.dispatch.common.GeoDistanceCalculator;
import com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider;
import com.dituhui.pea.dispatch.dao.DispatchEngineerRepository;
import com.dituhui.pea.dispatch.dao.DispatchOrderRepository;
import com.dituhui.pea.dispatch.dao.OrgGroupRepository;
import com.dituhui.pea.dispatch.dao.OrgTeamDao;
import com.dituhui.pea.dispatch.dao.*;
import com.dituhui.pea.dispatch.entity.DispatchOrder;
import com.dituhui.pea.dispatch.entity.OrderInfo;
import com.dituhui.pea.dispatch.entity.OrgGroup;
import com.dituhui.pea.dispatch.entity.OrgTeamEntity;
import com.dituhui.pea.dispatch.pojo.*;
......@@ -59,6 +58,9 @@ public class SolveServiceImpl implements SolveService {
DispatchOrderRepository dispatchOrderRepo;
@Autowired
private OrderInfoRepository orderInfoRepository;
@Autowired
OrgGroupRepository groupRepository;
......@@ -252,6 +254,17 @@ public class SolveServiceImpl implements SolveService {
}
Customer customer = new Customer(order.getId(), order.getOrderId(), order.getDt(), location, start, end, order.getSkills(), order.getTakeTime());
OrderInfo orderInfo = orderInfoRepository.findByOrderId(order.getOrderId()).get(0);
if ((StrUtil.equals("MANUAL", orderInfo.getAppointmentMethod())
&& StrUtil.equals("CONFIRM", orderInfo.getAppointmentStatus()))
|| ObjectUtil.equal(1, orderInfo.getIsAppointEngineer())) {
customer.setDispatchedTechnicianCode(orderInfo.getEngineerCode());
}
if (ObjectUtil.equal(2, orderInfo.getIsAppointEngineer())) {
customer.setExclusiveTechnicianCode(Objects.nonNull(orderInfo.getAppointEngineerCodes()) ?
orderInfo.getAppointEngineerCodes().trim() : null);
}
customerList.add(customer);
});
......
......@@ -3,7 +3,7 @@ server:
dispatch:
cron:
expr: 0 14 8-22 * * ?
expr: 0 55 8-22 * * ?
next-day-limit: 2
# expr: 0 */10 8-18 * * ?
......@@ -11,9 +11,9 @@ scheduler:
init-engineer-capacity:
# 每天22点1次
#cron-expr: 0 0 22 * * ?
cron-expr: 0 29 * * * ?
cron-expr: 0 51 * * * ?
day-offset-begin: 0
day-offset-end: 14
day-offset-end: 20
rewrite-force: true
calc-engineer-capacity:
......@@ -49,12 +49,12 @@ spring:
enabled: false
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/saas_aftersale_test?serverTimezone=Asia/Shanghai
username: root
password: 123456
# url: jdbc:mysql://localhost:32306/saas_aftersale_test?serverTimezone=Asia/Shanghai
# username: boxi
# password: boxi_dev_0725
# url: jdbc:mysql://127.0.0.1:3306/saas_aftersale_test?serverTimezone=Asia/Shanghai
# username: root
# password: 123456
url: jdbc:mysql://localhost:32306/saas_aftersale_test?serverTimezone=Asia/Shanghai
username: boxi
password: boxi_dev_0725
type: com.alibaba.druid.pool.DruidDataSource
jpa:
......
......@@ -73,6 +73,24 @@
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 异常文件输出设置,将异常堆栈另外保存一份到单独的文件中,方便查找 -->
<appender name="FILE_WARN"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>${LOG_FILE}/warn/${spring.application.name:-}.warn.log</File>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<FileNamePattern>${LOG_FILE}/warn/${spring.application.name:-}.warn-%d{yyyy-MM-dd}-%i.zip
</FileNamePattern>
<maxFileSize>${LOG_MAXFILESIZE}</maxFileSize>
<maxHistory>${LOG_FILEMAXDAY}</maxHistory>
<totalSizeCap>500MB</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level - %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印警告日志 -->
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
......@@ -118,6 +136,7 @@
<appender-ref ref="console"/>
<appender-ref ref="FileAppender"/>
<appender-ref ref="FILE_ERROR"/>
<appender-ref ref="FILE_WARN"/>
</root>
</configuration>
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!