Commit 44fb0b3f by 刘鑫

Merge branch 'develop' of https://gitlab.dituhui.com/bsh/project/project into develop

2 parents d2483d77 3fd98370
Showing with 2508 additions and 10 deletions
......@@ -62,6 +62,11 @@
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>project-interface</artifactId>
<version>${revision}</version>
......@@ -146,6 +151,17 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
<dependency>
<groupId>com.vladmihalcea</groupId>
<artifactId>hibernate-types-55</artifactId>
<version>2.21.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.22</version>
</dependency>
</dependencies>
<build>
......
......@@ -18,6 +18,7 @@ package com.dituhui.pea.dispatch;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
......@@ -25,6 +26,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
*/
@SpringBootApplication
@EnableScheduling
@EnableFeignClients(basePackages = {"com.dituhui.pea.user"})
public class DispatchServiceApplication {
public static void main(String[] args) {
......
package com.dituhui.pea.dispatch.common;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;
@Getter
@RequiredArgsConstructor
@AllArgsConstructor
public class DateSplit {
private Date startDateTime;
private Date endDateTime;
public void setStartDateTime(Date startDateTime) {
this.startDateTime = startDateTime;
}
public void setEndDateTime(Date endDateTime) {
this.endDateTime = endDateTime;
}
public LocalDateTime getStartLocalDateTime() {
return DateUtil.fromDate(this.startDateTime);
}
public LocalDateTime getLocalEndDateTime() {
return DateUtil.fromDate(this.endDateTime);
}
/**
* 获取开始时间片
*
* @return 开始时间
*/
public LocalTime getStartTime() {
return this.getStartLocalDateTime().toLocalTime();
}
/**
* 获取结束时间片
*
* @return 结束时间
*/
public LocalTime getEndTime() {
return this.getLocalEndDateTime().toLocalTime();
}
}
\ No newline at end of file
package com.dituhui.pea.dispatch.common;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.time.temporal.ChronoUnit;
import java.util.Locale;
public class DateUtils {
public static String toWeekChinese(String date) {
LocalDate d = LocalDate.parse(date);
return DateUtils.toWeekChinese(d.getDayOfWeek().getValue());
}
public static String toWeekChinese(int dayOfWeek) {
// TextStyle: SHORT 周一;LONG 星期一;NARROW 一
return DayOfWeek.of(dayOfWeek).getDisplayName(TextStyle.SHORT, Locale.CHINESE);
}
public static String formatDateTime(LocalDateTime d, String format) {
return d.format(DateTimeFormatter.ofPattern(format));
}
public static String formatDateTime(LocalDateTime d) {
return formatDateTime(d, DateUtil.PATTERN_DATETIME);
}
public static String formatDate(LocalDate d, String format) {
return d.format(DateTimeFormatter.ofPattern(format));
}
public static String formatDate(LocalDate d) {
return formatDate(d, DateUtil.PATTERN_DATE);
}
public static long getAge(String birth) {
return ChronoUnit.YEARS.between(LocalDate.parse(birth), LocalDate.now());
}
public static LocalDate localDateFromStr(String dateStr) {
return localDateFromStr(dateStr, "yyyy-MM-dd");
}
public static LocalDate localDateFromStr(String str, String pattern) {
if (str.length() > pattern.length()) {
str = str.substring(0, pattern.length());
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return LocalDate.parse(str, formatter);
}
public static LocalDateTime localDateTimeFromStr(String str) {
return localDateTimeFromStr(str, "yyyy-MM-dd HH:mm:ss");
}
public static LocalDateTime localDateTimeFromStr(String str, String pattern) {
if (str.length() > pattern.length()) {
str = str.substring(0, pattern.length());
}
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
return LocalDateTime.parse(str, formatter);
}
}
package com.dituhui.pea.dispatch.common;
import com.dituhui.pea.dispatch.dao.EngineerInfoRepository;
import com.dituhui.pea.dispatch.dao.OrgGroupRepository;
import com.dituhui.pea.dispatch.dao.OrgTeamEngineerDao;
import com.dituhui.pea.dispatch.entity.EngineerInfo;
import com.dituhui.pea.dispatch.entity.OrgGroup;
import com.dituhui.pea.dispatch.entity.OrgTeamEngineerEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class EngineerUtils {
@Autowired
private OrgTeamEngineerDao orgTeamEngineerDao;
@Autowired
private EngineerInfoRepository engineerInfoDao;
@Autowired
private OrgGroupRepository orgGroupDao;
public List<EngineerInfo> getEngineersByLevel(String levelType, String levelValue) {
List<EngineerInfo> engineers = null;
List<String> groupIds = null;
switch (levelType) {
case "team":
List<String> engineerCodes = orgTeamEngineerDao.findAllByTeamId(levelValue).stream()
.map(OrgTeamEngineerEntity::getEngineerCode).collect(Collectors.toList());
engineers = engineerInfoDao.findByEngineerCodeIn(engineerCodes);
break;
case "group":
engineers = engineerInfoDao.findByGroupId(levelValue);
break;
case "branch":
groupIds = orgGroupDao.findAllByBranchId(levelValue).stream()
.map(OrgGroup::getGroupId).collect(Collectors.toList());
engineers = engineerInfoDao.findByGroupIdIn(groupIds);
break;
default:
// "cluster".equals(levelType)
groupIds = orgGroupDao.findByClusterId(levelValue).stream()
.map(OrgGroup::getGroupId).collect(Collectors.toList());
engineers = engineerInfoDao.findByGroupIdIn(groupIds);
break;
}
return engineers;
}
public Page<EngineerInfo> filterEngineersByKeyAndPage(List<String> engineerCodes, String key, Integer page, Integer size) {
Pageable pageable = PageRequest.of(page - 1, size);
return engineerInfoDao.findAllByEngineerCodeIn(engineerCodes, buildSpecification(key), pageable);
}
public List<EngineerInfo> filterEngineersByKey(List<String> engineerCodes, String key) {
return engineerInfoDao.findAllByEngineerCodeIn(engineerCodes, buildSpecification(key));
}
private Specification<EngineerInfo> buildSpecification(String keyword) {
// 动态查询
return new Specification<EngineerInfo>() {
@Override
public Predicate toPredicate(Root<EngineerInfo> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
List<Predicate> predicates = new ArrayList<>();
// 构建查询条件
Predicate engineerCodePredicate = criteriaBuilder.like(root.get("engineerCode"), "%" + keyword + "%");
Predicate mobilePredicate = criteriaBuilder.like(root.get("phone"), "%" + keyword + "%");
Predicate msgContentPredicate = criteriaBuilder.like(root.get("name"), "%" + keyword + "%");
predicates.add(criteriaBuilder.or(engineerCodePredicate, mobilePredicate, msgContentPredicate));
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
}
};
}
}
package com.dituhui.pea.dispatch.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
@Data
@Accessors(chain = true)
@AllArgsConstructor
@NoArgsConstructor
public class OccupyInfo {
protected LocalDateTime beginTime;
protected LocalDateTime endTime;
}
package com.dituhui.pea.dispatch.common;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.time.LocalDateTime;
@EqualsAndHashCode(callSuper = true)
@Data
@Accessors(chain = true)
@NoArgsConstructor
public class OccupyInfoDetail extends OccupyInfo implements Comparable<OccupyInfoDetail> {
/**
* 时间片时长(分钟)
*/
private long duration;
public OccupyInfoDetail(LocalDateTime beginTime, LocalDateTime endTime, long duration) {
super(beginTime, endTime);
this.duration = duration;
}
public OccupyInfoDetail(LocalDateTime beginTime, LocalDateTime endTime) {
super(beginTime, endTime);
}
// 判断两个时间片是否有交集
public boolean overlaps(OccupyInfoDetail other) {
// 如果一个时间片的开始时间在另一个时间片的结束时间之后,或者一个时间片的结束时间在另一个时间片的开始时间之前,那么他们没有交集
LocalDateTime maxStart = this.beginTime.isAfter(other.beginTime) ? this.beginTime : other.beginTime;
LocalDateTime minEnd = this.endTime.isAfter(other.endTime) ? other.endTime : this.endTime;
return maxStart.isBefore(minEnd);
}
// 计算两个时间片的交集
public OccupyInfoDetail intersection(OccupyInfoDetail other) {
// 如果两个时间片没有交集,返回null
if (!this.overlaps(other)) {
return null;
}
// 否则,返回一个新的时间片,其开始时间是两个时间片中较晚的开始时间,其结束时间是两个时间片中较早的结束时间
return new OccupyInfoDetail(this.beginTime.isAfter(other.beginTime) ? this.beginTime : other.beginTime, this.endTime.isBefore(other.endTime) ? this.endTime : other.endTime);
}
@Override
public int compareTo(OccupyInfoDetail o) {
return this.beginTime.compareTo(o.beginTime);
}
}
package com.dituhui.pea.dispatch.common.jackson;
import com.dituhui.pea.dispatch.common.DateUtil;
import lombok.experimental.UtilityClass;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAccessor;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
/**
* DateTime 工具类
*
* @author liuxin
*/
@UtilityClass
public class DateTimeUtil {
/**
* yyyy-MM-dd HH:mm:ss
*/
public static final DateTimeFormatter DATETIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME);
/**
* yyyy-MM-dd HH:mm
*/
public static final DateTimeFormatter DATETIME_FORMAT_NON_SECONDS = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATETIME_NON_SECONDS);
/**
* 日期格式 yyyy-MM-dd
*/
public static final DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_DATE);
/**
* 时间格式 HH:mm:ss
*/
public static final DateTimeFormatter TIME_FORMAT = DateTimeFormatter.ofPattern(DateUtil.PATTERN_TIME);
/**
* 日期时间格式化
*
* @param temporal 时间
* @return 格式化后的时间
*/
public static String formatDateTime(TemporalAccessor temporal) {
return DATETIME_FORMAT.format(temporal);
}
/**
* 日期时间格式化
*
* @param temporal 时间
* @return 格式化后的时间
*/
public static String formatDate(TemporalAccessor temporal) {
return DATE_FORMAT.format(temporal);
}
/**
* 时间格式化
*
* @param temporal 时间
* @return 格式化后的时间
*/
public static String formatTime(TemporalAccessor temporal) {
return TIME_FORMAT.format(temporal);
}
/**
* 日期格式化
*
* @param temporal 时间
* @param pattern 表达式
* @return 格式化后的时间
*/
public static String format(TemporalAccessor temporal, String pattern) {
return DateTimeFormatter.ofPattern(pattern).format(temporal);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param pattern 表达式
* @return 时间
*/
public static TemporalAccessor parse(String dateStr, String pattern) {
DateTimeFormatter format = DateTimeFormatter.ofPattern(pattern);
return format.parse(dateStr);
}
/**
* 将字符串转换为时间
*
* @param dateStr 时间字符串
* @param formatter DateTimeFormatter
* @return 时间
*/
public static TemporalAccessor parse(String dateStr, DateTimeFormatter formatter) {
return formatter.parse(dateStr);
}
/**
* 时间转 Instant
*
* @param dateTime 时间
* @return Instant
*/
public static Instant toInstant(LocalDateTime dateTime) {
return dateTime.atZone(ZoneId.of("+8")).toInstant();
}
/**
* Instant 转 时间
*
* @param instant Instant
* @return Instant
*/
public static LocalDateTime toDateTime(Instant instant) {
return LocalDateTime.ofInstant(instant, ZoneId.of("+8"));
}
/**
* 获取当前东八区时间
*
* @return LocalDateTime东八区对象
*/
public static LocalDateTime generateLocalDateTime() {
return LocalDateTime.now(ZoneId.of("+8"));
}
/**
* 求两个时间差
*
* @param start 开始时间
* @param end 结束时间
* @param timeUnit 时间差单位 {@link TimeUnit}
* @return 指定单位时间差
*/
public static long betweenTwoTime(Temporal start, Temporal end, TimeUnit timeUnit) {
Duration duration = Duration.between(start, end);
long result;
switch (timeUnit) {
case DAYS:
result = duration.toDays();
break;
case HOURS:
result = duration.toHours();
break;
case MINUTES:
result = duration.toMinutes();
break;
case SECONDS:
result = duration.getSeconds();
break;
case MILLISECONDS:
result = duration.toMillis();
break;
case NANOSECONDS:
result = duration.toNanos();
break;
default:
throw new IllegalStateException("Unexpected value: " + timeUnit);
}
return result;
}
/**
* 当前时间是否在时间指定范围内, 包含起始时间<br>
*
* @param time 被检查的时间
* @param beginTime 起始时间
* @param endTime 结束时间
* @return 是否在范围内
* @since 3.0.8
*/
public static boolean isIn(LocalTime time, LocalTime beginTime, LocalTime endTime) {
if ((Objects.equals(beginTime, time) || beginTime.isBefore(time))
&& (endTime.isAfter(time) || Objects.equals(endTime, time))) {
return true;
}
return false;
}
}
package com.dituhui.pea.dispatch.common.jackson;
import com.dituhui.pea.dispatch.common.DateUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.Optional;
import java.util.TimeZone;
/**
* json 工具类 基于Jackson
*
* @author liuxin
*/
@UtilityClass
@Slf4j
public class JsonUtil {
/**
* 序列化对象为 json string
*
* @param value java对象
* @param <T> 泛型标记
* @return json字符串, 转换失败返回空白
*/
public static <T> String toJson(T value) {
try {
return value instanceof String ? (String) value : getInstance().writeValueAsString(value);
} catch (JsonProcessingException e) {
log.error("[JsonUtil][toJson] ------> {}", e.getMessage(), e);
return "";
}
}
/**
* 实体转格式化jsonString
*
* @param entity java对象
* @param <E> 泛型标记
* @return json string
*/
public static <E> String objectToJsonPretty(E entity) {
try {
return entity instanceof String ? (String) entity
: getInstance().writerWithDefaultPrettyPrinter()
.writeValueAsString(entity);
} catch (Exception e) {
log.error("[JsonUtil][toJson]----> Parse Object to Json error,ex:{}", e.getMessage(), e);
return "";
}
}
/**
* 实体转格式化jsonString 去除空值
*
* @param entity java对象
* @param <E> 泛型标记
* @return json string
*/
public static <E> String objectToJsonPrettyNoneNull(E entity) {
try {
return entity instanceof String ? (String) entity
: getNonNullInstance().writerWithDefaultPrettyPrinter()
.writeValueAsString(entity);
} catch (Exception e) {
log.error("[JsonUtil][toJson]----> Parse Object to Json error,ex:{}", e.getMessage(), e);
return "";
}
}
/**
* 将对象序列化成 json byte 数组
*
* @param object javaBean
* @return jsonString json字符串
*/
public static byte[] toJsonAsBytes(Object object) {
try {
return getInstance().writeValueAsBytes(object);
} catch (JsonProcessingException e) {
log.error("[JsonUtil][toJsonAsBytes]----> Parse Object to Json as byte error,ex:{}", e.getMessage(), e);
}
return new byte[0];
}
/**
* 将json反序列化成对象
*
* @param content content
* @param clazz class
* @param <T> T 泛型标记
* @return Bean
*/
public static <T> Optional<T> parse(String content, Class<T> clazz) {
try {
return Optional.of(getInstance().readValue(content, clazz));
} catch (Exception e) {
log.error("[JsonUtil][parse]----> Parse string to object with type error,ex:{}", e.getMessage(), e);
}
return Optional.empty();
}
/**
* 将json反序列化成对象
*
* @param content content
* @param typeReference 泛型类型
* @param <T> T 泛型标记
* @return Bean
*/
public static <T> Optional<T> parse(String content, TypeReference<T> typeReference) {
try {
return Optional.of(getInstance().readValue(content, typeReference));
} catch (IOException e) {
log.error("[JsonUtil][parse]----> Parse string to object with type reference error,ex:{}", e.getMessage(),
e);
}
return Optional.empty();
}
/**
* 将json字符串转成 JsonNode
*
* @param jsonString jsonString
* @return jsonString json字符串
*/
public static Optional<JsonNode> readTree(String jsonString) {
try {
return Optional.of(getInstance().readTree(jsonString));
} catch (IOException e) {
log.error("[JsonUtil][readTree]----> Parse string to json node error,ex:{}", e.getMessage(), e);
}
return Optional.empty();
}
/**
* 将json字符串转换为集合
*
* @param src jsonString
* @param collectionClass 集合类型 List, Set, Map
* @param elementClasses 集合内元素类型
* @param <T> 泛型标记
* @return 集合
*/
public static <T> Optional<T> parse(String src, Class<?> collectionClass, Class<?>... elementClasses) {
if (StringUtils.isBlank(src)) {
return Optional.empty();
}
JavaType javaType = getInstance().getTypeFactory().constructParametricType(collectionClass, elementClasses);
try {
return Optional.ofNullable(getInstance().readValue(src, javaType));
} catch (Exception e) {
log.error("【JsonUtil】---->Parse Json to collection error,ex:{}", e.getMessage());
return Optional.empty();
}
}
/**
* ObjectMapper 实例获取 (序列化后包含null值)
* @return ObjectMapper实例
*/
public static ObjectMapper getInstance() {
return JacksonHolder.INSTANCE;
}
/**
* ObjectMapper 实例获取 (序列化后不包含null值)
* @return ObjectMapper实例
*/
public static ObjectMapper getNonNullInstance() {
final ObjectMapper instance = new JacksonObjectMapper();
instance.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return instance;
}
/**
* 获取全局 JacksonObjectMapper
*/
private static class JacksonHolder {
private static final ObjectMapper INSTANCE = new JacksonObjectMapper();
}
/**
* 定义 JacksonObjectMapper 序列化
*/
public static class JacksonObjectMapper extends ObjectMapper {
private static final long serialVersionUID = 4288193147502386170L;
private static final Locale CHINA = Locale.CHINA;
/**
* 构造器初始化
*/
public JacksonObjectMapper() {
super();
// 设置地点为中国
super.setLocale(CHINA);
// 去掉默认的时间戳格式
super.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
// 设置为中国上海时区
super.setTimeZone(TimeZone.getTimeZone("+8"));
// 序列化时,日期的统一格式
super.setDateFormat(new SimpleDateFormat(DateUtil.PATTERN_DATETIME, Locale.CHINA));
// 序列化处理
super.configure(JsonReadFeature.ALLOW_UNESCAPED_CONTROL_CHARS.mappedFeature(), true);
super.configure(JsonReadFeature.ALLOW_BACKSLASH_ESCAPING_ANY_CHARACTER.mappedFeature(), true);
super.findAndRegisterModules();
// 失败处理
super.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
super.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 单引号处理
super.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
// 反序列化时,属性不存在的兼容处理s
super.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
// 日期格式化
super.registerModule(new LJavaTimeModule());
super.findAndRegisterModules();
}
}
}
package com.dituhui.pea.dispatch.common.jackson;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.PackageVersion;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
/**
* 定义java.util.time 序列化格式
*/
public class LJavaTimeModule extends SimpleModule {
/**
* 构造器定义时间序列化格式
*/
public LJavaTimeModule() {
super(PackageVersion.VERSION);
this.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeUtil.DATETIME_FORMAT));
this.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeUtil.DATE_FORMAT));
this.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeUtil.TIME_FORMAT));
this.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeUtil.DATETIME_FORMAT));
this.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeUtil.DATE_FORMAT));
this.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeUtil.TIME_FORMAT));
}
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.CapacityEngineerCalendarEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import java.time.LocalDateTime;
import java.util.List;
public interface CapacityEngineerCalendarDao extends JpaRepository<CapacityEngineerCalendarEntity, Integer> {
@Query("select a from CapacityEngineerCalendarEntity a where a.engineerCode=:engineerCode and a.workday between :beginDate and :endDate")
List<CapacityEngineerCalendarEntity> findCalendarByEngineerCodeAndDateBetween(String engineerCode, String beginDate, String endDate);
CapacityEngineerCalendarEntity getByPlanId(String planId);
@Query("select count(*) from CapacityEngineerCalendarEntity a where a.type = :type and (a.startTime BETWEEN :startDate and :endDate) and a.engineerCode in :engineers")
Integer queryEngineerPlanNum(List<String> engineers, LocalDateTime startDate, LocalDateTime endDate, String type);
@Modifying
@Query("delete from CapacityEngineerCalendarEntity a where a.engineerCode in :engineerCodes and a.type = :type and a.workday between :startDate and :endDate")
void deleteByTypeAndEngineerCodesAndBetweenDates(List<String> engineerCodes, String type, String startDate, String endDate);
List<CapacityEngineerCalendarEntity> findCalendarByWorkdayAndEngineerCode(String date, String engineerCode);
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.CapacityEngineerStatEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface CapacityEngineerStatDao extends JpaRepository<CapacityEngineerStatEntity, Integer> {
CapacityEngineerStatEntity getByWorkdayAndEngineerCode(String workday, String engineerCode);
List<CapacityEngineerStatEntity> getByWorkdayAndEngineerCodeIn(String workday, List<String> engineerCodes);
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.EngineerBusinessEntity;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @author zhangx
*/
public interface EngineerBusinessDao extends CrudRepository<EngineerBusinessEntity, Long> {
@Transactional
@Modifying
@Query("UPDATE EngineerBusinessEntity tt SET tt.address = :address, tt.X= :x, tt.Y=:y WHERE tt.engineerCode = :engineerCode")
void updateEngineerCenter(String address, String x, String y, String engineerCode);
EngineerBusinessEntity getByEngineerCode(String engineerCode);
List<EngineerBusinessEntity> findByEngineerCodeIn(List<String> engineerCodes);
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.EngineerInfo;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Optional;
public interface EngineerInfoRepository extends CrudRepository<EngineerInfo, Long> {
public interface EngineerInfoRepository extends CrudRepository<EngineerInfo, Long>,
JpaRepository<EngineerInfo, Long>,
JpaSpecificationExecutor<EngineerInfo> {
List<EngineerInfo> findByGroupIdIn(List<String> groupIds);
List<EngineerInfo> findByGroupId(String groupId);
EngineerInfo getByEngineerCode(String engineerCode);
Optional<EngineerInfo> findByEngineerCode(String engineerCode);
List<EngineerInfo> findByEngineerCodeIn(List<String> engineerCodes);
default List<EngineerInfo> findAllByEngineerCodeIn(List<String> engineerCodes, Specification<EngineerInfo> engineerInfoEntitySpecification) {
Specification<EngineerInfo> spec = Specification.where(engineerCodeIn(engineerCodes)).and(engineerInfoEntitySpecification);
return findAll(spec);
}
default Page<EngineerInfo> findAllByEngineerCodeIn(List<String> engineerCodes, Specification<EngineerInfo> engineerInfoEntitySpecification, Pageable pageable) {
Specification<EngineerInfo> spec = Specification.where(engineerCodeIn(engineerCodes)).and(engineerInfoEntitySpecification);
return findAll(spec, pageable);
}
static Specification<EngineerInfo> engineerCodeIn(List<String> engineerCodes) {
return (root, query, criteriaBuilder) -> root.get("engineerCode").in(engineerCodes);
}
@Query(value = "select t.* from engineer_info t\n" +
"join org_group g on g.group_id=t.group_id and g.`status`=1 and g.branch_id=?1",
nativeQuery = true)
List<EngineerInfo> getAllByBranchId(String branchId);
/**
* 查询工作队下的指定工程师信息
*
* @param engineerCode 工程师编号
* @param teamId 工作队ID
* @return 工作队下没有工程师则返回空
*/
@Query(value = "SELECT ei.* from org_team_engineer ote left join engineer_info ei ON ote.engineer_code = ei.engineer_code " +
"WHERE ote.team_id = :teamId AND ote.engineer_code = :engineerCode AND ote.`status` = 1", nativeQuery = true)
EngineerInfo selectEngineerByEngineerCodeAndTeamId(@Param("engineerCode") String engineerCode, @Param("teamId") String teamId);
}
\ No newline at end of file
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.CapacityEngineerSliceUsedEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface EngineerSliceUsedCapacityDao extends JpaRepository<CapacityEngineerSliceUsedEntity, Long> {
List<CapacityEngineerSliceUsedEntity> findByWorkdayAndEngineerCode(String workDay, String engineerCode);
List<CapacityEngineerSliceUsedEntity> deleteByWorkdayAndEngineerCode(String workDay, String engineerCode);
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.MapBlockInfoEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface MapBlockInfoDao extends JpaRepository<MapBlockInfoEntity, Integer>, JpaSpecificationExecutor<MapBlockInfoEntity> {
List<MapBlockInfoEntity> findByAreaIdsLikeAndLayerIdIn(String blockId, List<String> layerIds);
MapBlockInfoEntity findByAreaIds(String blockId);
List<MapBlockInfoEntity> findByGroupId(String groupId);
List<MapBlockInfoEntity> findByLayerId(String layerId);
MapBlockInfoEntity findByTeamIdAndLayerId(String teamId, String layerId);
List<MapBlockInfoEntity> findByAreaIdsIn(List<String> blockIds);
List<MapBlockInfoEntity> findByAreaIdsLike(String blockId);
@Query(value = "select mbi.* from map_block_info mbi left join map_layer_customize_skill mlcs on mlcs.layer_id = mbi.layer_id " +
"left join map_layer_customize mlc on mlc.layer_id = mbi.layer_id left join skill_info si on si.skill_code = mlcs.skill_code " +
"where si.brand = :brand and si.`type` = :productType and si.skill = :skill order by mlc.priority ", nativeQuery = true)
List<MapBlockInfoEntity> listTeamIdByBrandAndSkill(@Param("brand") String brand, @Param("productType") String productType,
@Param("skill") String skill);
}
......@@ -14,4 +14,6 @@ public interface OrgGroupRepository extends CrudRepository<OrgGroup, Long> {
Optional<OrgGroup> findByGroupId(String groupId);
List<OrgGroup> findAllByBranchId(String branchId);
List<OrgGroup> findByClusterId(String levelValue);
}
package com.dituhui.pea.dispatch.dao;
import java.util.List;
import java.util.Set;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
......@@ -24,4 +25,14 @@ public interface OrgTeamDao extends JpaRepository<OrgTeamEntity, Integer>, JpaSp
"join org_cluster c on c.cluster_id=b.cluster_id and c.`status`=1",
nativeQuery = true)
List<OrgTeamEntity> findAllTeam();
/**
* 获取工程师所在的工作队
*
* @param engineerCode 工程师代码
* @return 工程师所在工作队信息
*/
@Query(value = "SELECT ot.* FROM org_team_engineer ote LEFT JOIN org_team ot ON ote.team_id = ot.team_id WHERE ote.engineer_code = :engineerCode " +
" AND ote.`status` = 1 AND ot.status = 1 ", nativeQuery = true)
Set<OrgTeamEntity> selectTeamByEngineerCode(String engineerCode);
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.PubParamsEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface PubParamsDao extends JpaRepository<PubParamsEntity, Integer> {
List<PubParamsEntity> findByBiztype(String biztype);
List<PubParamsEntity> findByCatalogAndBiztype(String cagtalog, String biztype);
PubParamsEntity getByCatalogAndBiztypeAndPkey(String catalog, String biztype, String pkey);
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.SkillInfoEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface SkillInfoDao extends JpaRepository<SkillInfoEntity, Long> {
List<SkillInfoEntity> findAll();
Page<SkillInfoEntity> findAll(Pageable pageable);
SkillInfoEntity getByBrandAndTypeAndSkill(String brand, String type, String skill);
List<SkillInfoEntity> getByBrandAndTypeAndSkillCode(String brand, String type, String skillCode);
}
package com.dituhui.pea.dispatch.dao;
import com.dituhui.pea.dispatch.entity.TimeSliceEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
public interface TimeSliceDao extends JpaRepository<TimeSliceEntity, Long> {
List<TimeSliceEntity> findByType(String type);
}
package com.dituhui.pea.dispatch.dto;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.util.List;
public class CalendarBatAddDTO {
@lombok.Data
public static class Request {
/**
* 结束时间;如果是全天只需要填写日期;否则填写日期+时间
*/
@NotBlank
private String end;
/**
* 技术员code列表
*/
@NotEmpty
private List<String> engineerCodes;
/**
* 是否全天
*/
@NotNull
private Boolean isAllday;
/**
* 备注
*/
private String remark;
/**
* 重复截止日期
*/
// @NotBlank
private String repeatEndDate;
/**
* 重复类型
*/
@NotBlank
private String repeatType;
/**
* 开始时间;如果是全天只需要填写日期;否则填写日期+时间
*/
@NotBlank
private String start;
/**
* 日程类型
*/
@NotBlank
private String type;
}
}
package com.dituhui.pea.dispatch.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
public class CalendarBatDelDTO {
@lombok.Data
public static class Request {
/**
* 结束时间
*/
@NotBlank
@JsonFormat(pattern = "yyyy-MM-dd")
private String endDate;
/**
* 技术员code列表
*/
@NotEmpty
private List<String> engineerCodes;
/**
* 开始时间
*/
@NotBlank
@JsonFormat(pattern = "yyyy-MM-dd")
private String startDate;
/**
* 日程类型
*/
@NotBlank
private String type;
}
}
package com.dituhui.pea.dispatch.dto;
import javax.validation.constraints.NotBlank;
public class CalendarDeleteDTO {
@lombok.Data
public static class Request {
@NotBlank
private String engineerCode;
@NotBlank
private String planId;
}
}
package com.dituhui.pea.dispatch.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
public class CalendarDetailDTO {
@lombok.Data
public static class Request {
@NotBlank(message = "工程师编号不能为空")
private String engineerCode;
@NotBlank(message = "所属计划配置编码不能为空")
private String planId;
}
@lombok.Data
@Accessors(chain = true)
public static class Result {
private String engineerCode;
private String engineerName;
private String operator;
private String phone;
private String planId;
private String remark;
private String type;
private String typeName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String startTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String endTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private String updateTime;
}
}
package com.dituhui.pea.dispatch.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import java.util.List;
public class CalendarQueryNumDTO {
@lombok.Data
public static class Request {
@NotEmpty
private List<String> engineerCodes;
@NotBlank
private String type;
@NotBlank
@JsonFormat(pattern = "yyyy-MM-dd")
private String startDate;
@NotBlank
@JsonFormat(pattern = "yyyy-MM-dd")
private String endDate;
}
@lombok.Data
public static class Result {
private long planNum;
}
}
package com.dituhui.pea.dispatch.dto;
import lombok.Data;
import java.util.List;
public class CalendarTypeDTO {
@Data
public static class Result {
private List<Type> types;
}
@Data
public static class Type {
private BarStyle barStyle;
private TagStyle tagStyle;
private String type;
private String typeName;
}
@Data
public static class BarStyle {
private String backgroundColor;
private String color;
}
@Data
public static class TagStyle {
private String backgroundColor;
}
}
package com.dituhui.pea.dispatch.dto;
import javax.validation.constraints.NotBlank;
public class CalendarUpdateDTO {
@lombok.Data
public static class Request {
@NotBlank
private String startTime;
@NotBlank
private String endTime;
@NotBlank
private String engineerCode;
@NotBlank
private String planId;
private String remark;
}
}
package com.dituhui.pea.dispatch.dto;
import java.util.List;
public class EngineerCalendarDTO {
@lombok.Data
public static class Request {
private String date;
/**
* 姓名,工号
*/
private String key;
private String levelType;
private String levelValue;
private Integer size = 10;
private Integer page = 1;
}
@lombok.Data
public static class Result {
private long pageCurrent;
private long pages;
private long pageSize;
private long total;
private List<Engineer> engineers;
}
@lombok.Data
public static class Engineer {
private List<Calendar> calendar;
private String engineerCode;
private String name;
}
@lombok.Data
public static class Calendar {
private List<Content> content;
private String date;
private String week;
}
@lombok.Data
public static class Content {
private String title;
private String type;
private String value;
private String planId;
}
}
package com.dituhui.pea.dispatch.dto.param;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.validation.annotation.Validated;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.List;
/**
* 创单可用容量
*/
@Validated
@Setter
@Getter
public class CapacityQueryDTO {
/**
* 查询参数
*/
@Setter
@Getter
public static class Request {
/**
* 服务技能
*/
@Valid
private List<Service> services;
/**
* 地址坐标信息
*/
@Valid
@NotNull(message = "地址坐标信息不能为空")
private Location location;
/**
* 查询起始日期
*/
@NotNull(message = " 查询起始日期不能为空, 格式:yyyy-MM-dd ")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date beginDate;
/**
* 查询结束日期
*/
@NotNull(message = " 查询结束日期不能为空, 格式:yyyy-MM-dd ")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date endDate;
}
/**
* 返回值
*/
@Setter
@Getter
public static class Result {
/**
* 符合条件的履约组织网点)Id
*/
private String groupId;
/**
* 原始请求参数
*/
private Request params;
/**
* 需要的服务时长,单位: 分钟
*/
private int takeTime;
/**
* 查询容量返回结果
*/
private List<Data> datas;
}
/**
* 改派到人查询结果
*/
@Setter
@Getter
public static class PersonalResult {
/**
* 查询的工程师工号
*/
private String engineerCode;
/**
* 查询工程师姓名
*/
private String engineerName;
/**
* 查询容量返回结果
*/
private List<Data> datas;
}
/**
* 查询容量返回结果
*/
@Setter
@Getter
public static class Data {
/**
* 日期 yyyy-MM-dd
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date date;
/**
* 容量列表
*/
private List<Segment> segments;
}
/**
* 容量
*/
@Setter
@Getter
public static class Segment {
/**
* 最大可用时长, 单位: 分钟
*/
private long maxDuration;
/**
* 容量名称 全天/上午/下午/晚上/时间段
*/
private String name;
/**
* 起始时间 yyyy-MM-dd HH:mm:ss
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date beginTime;
/**
* 截止时间 yyyy-MM-dd HH:mm:ss
*/
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
/**
* 容量状态 0不可约;1可约;
*/
private int status;
/**
* 剩余容量
*/
private long remain;
/**
* 区间总容量
*/
private long totalCapacity;
}
/**
* 服务
*/
@Setter
@Getter
public static class Service {
/**
* 品牌 (CODE)
*/
@NotBlank(message = "品牌(code)不能为空")
private String brand;
/**
* 产品类型 (CODE)
*/
@NotBlank(message = "产品类型(code)不能为空")
private String productType;
/**
* 需要的技能 (CODE)
*/
@NotBlank(message = "技能(code)不能为空")
private String serviceType;
}
}
package com.dituhui.pea.dispatch.dto.param;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
/**
* 工程师基础信息
*/
@Setter
@Getter
@EqualsAndHashCode(callSuper = false)
public class EngineerBaseInfo extends EngineerCode {
/**
* 工程师名称
*/
private String engineerName;
}
package com.dituhui.pea.dispatch.dto.param;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
/**
* 工程师日历
*/
@Setter
@Getter
@EqualsAndHashCode
public class EngineerCalendar {
/**
* 日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date date;
/**
* 事件类型
*/
private String eventType;
/**
* 事件
*/
private String event;
/**
* 事件名称
*/
private String content;
/**
* 开始时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date beginTime;
/**
* 结束时间
*/
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date endTime;
/**
* 备注
*/
private String memo ;
}
package com.dituhui.pea.dispatch.dto.param;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* 技术员日历返回参数
*/
@Setter
@Getter
@EqualsAndHashCode(callSuper = false)
public class EngineerCalendarResultDTO extends EngineerBaseInfo {
/**
* 日历内容
*/
private List<EngineerCalendar> calendar;
}
package com.dituhui.pea.dispatch.dto.param;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotBlank;
/**
* 工程师编号
*/
@Setter
@Getter
@EqualsAndHashCode
public class EngineerCode {
/**
* 工程师工号
*/
@NotBlank(message = "工程师工号不能为空")
protected String engineerCode;
}
package com.dituhui.pea.dispatch.dto.param;
import lombok.Getter;
import lombok.Setter;
import javax.validation.constraints.NotNull;
/**
* 地址坐标信息
*/
@Setter
@Getter
public class Location {
/**
* 地址ID
*/
private String addressId;
/**
* 地点名称,例如:xx小区
*/
private String name;
/**
* 详细地址, xx路xx号等信息
*/
private String address;
/**
* 地址纬度
*/
@NotNull
private Double latitude;
/**
* 地址经度
*/
@NotNull
private Double longitude;
}
package com.dituhui.pea.dispatch.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "capacity_engineer_calendar")
@Data
public class CapacityEngineerCalendarEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String workday;
@Column(name = "engineer_code", nullable = false, columnDefinition = "varchar(50) default '0'")
private String engineerCode;
@Column(name = "start_time", nullable = false)
private LocalDateTime startTime;
@Column(name = "end_time", nullable = false)
private LocalDateTime endTime;
@Column(name = "plan_id")
private String planId;
@Column(nullable = false)
private String type;
@Column(name = "reason")
private String reason;
@Column(nullable = false)
private String memo = "";
@Column(name = "operator_id")
private String operatorId;
@Column(name = "operator_name")
private String operatorName;
@Column(name = "create_time", nullable = false, updatable = false, columnDefinition = "timestamp default current_timestamp")
private LocalDateTime createTime = LocalDateTime.now();
@Column(name = "update_time", nullable = false, columnDefinition = "timestamp default current_timestamp on update current_timestamp")
private LocalDateTime updateTime = LocalDateTime.now();
// 其他字段和关联关系的定义
// ...
}
package com.dituhui.pea.dispatch.entity;
import com.dituhui.pea.dispatch.common.OccupyInfoDetail;
import com.vladmihalcea.hibernate.type.json.JsonStringType;
import lombok.Getter;
import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.TypeDef;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
@Getter
@Entity
@Table(name = "capacity_engineer_slice_used")
@TypeDef(name = "json", typeClass = JsonStringType.class)
public class CapacityEngineerSliceUsedEntity {
@Id
@Column(name = "id")
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid", strategy = "uuid")
private String id;
@OneToOne(targetEntity = TimeSliceEntity.class,
cascade = {CascadeType.DETACH},
fetch = FetchType.EAGER)
@JoinColumn(name = "timme_slice", referencedColumnName = "id")
private TimeSliceEntity timmeSlice;
@Basic
@Column(name = "workday")
private String workday;
@Basic
@Column(name = "engineer_code")
private String engineerCode;
@Basic
@Column(name = "cap_total")
private Long capTotal;
@Basic
@Column(name = "cap_used")
private Long capUsed;
@Basic
@Column(name = "cap_used_travel")
private Long capUsedTravel;
@Basic
@Column(name = "cap_left")
private Long capLeft;
@Basic
@Column(name = "max_duration")
private Long maxDuration;
@Type(type = "json")
@Column(name = "duration_time", columnDefinition = "json")
private List<OccupyInfoDetail> durationTime;
@Basic
@Column(name = "max_duration_type")
private String maxDurationType;
@Basic
@Column(name = "memo")
private String memo;
@Basic
@Column(name = "create_time")
private LocalDateTime createTime;
@Basic
@Column(name = "update_time")
private LocalDateTime updateTime;
public void setId(String id) {
this.id = id;
}
public void setTimmeSlice(TimeSliceEntity timmeSlice) {
this.timmeSlice = timmeSlice;
}
public void setWorkday(String workday) {
this.workday = workday;
}
public void setEngineerCode(String engineerCode) {
this.engineerCode = engineerCode;
}
public void setCapTotal(Long capTotal) {
this.capTotal = capTotal;
}
public void setCapUsed(Long capUsed) {
this.capUsed = capUsed;
}
public void setCapUsedTravel(Long capUsedTravel) {
this.capUsedTravel = capUsedTravel;
}
public void setCapLeft(Long capLeft) {
this.capLeft = capLeft;
}
public void setMaxDuration(Long maxDuration) {
this.maxDuration = maxDuration;
}
public void setDurationTime(List<OccupyInfoDetail> durationTime) {
this.durationTime = durationTime;
}
public void setMaxDurationType(String maxDurationType) {
this.maxDurationType = maxDurationType;
}
public void setMemo(String memo) {
this.memo = memo;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
CapacityEngineerSliceUsedEntity that = (CapacityEngineerSliceUsedEntity) o;
return Objects.equals(id, that.id) && Objects.equals(timmeSlice, that.timmeSlice) && Objects.equals(workday, that.workday) && Objects.equals(engineerCode, that.engineerCode) && Objects.equals(capTotal, that.capTotal) && Objects.equals(capUsed, that.capUsed) && Objects.equals(capUsedTravel, that.capUsedTravel) && Objects.equals(capLeft, that.capLeft) && Objects.equals(maxDuration, that.maxDuration) && Objects.equals(durationTime, that.durationTime) && Objects.equals(maxDurationType, that.maxDurationType) && Objects.equals(memo, that.memo) && Objects.equals(createTime, that.createTime) && Objects.equals(updateTime, that.updateTime);
}
@Override
public int hashCode() {
return Objects.hash(id, timmeSlice, workday, engineerCode, capTotal, capUsed, capUsedTravel, capLeft, maxDuration, durationTime, maxDurationType, memo, createTime, updateTime);
}
}
package com.dituhui.pea.dispatch.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name="capacity_engineer_stat")
public class CapacityEngineerStatEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 日期
*/
private String workday;
/**
* 技术员id
*/
private String engineerCode;
/**
* 总容量(分钟)
*/
private Integer capTotal;
/**
* 已占容量
*/
private Integer capUsed;
/**
* 已占容量-路途
*/
private Integer capUsedTravel;
/**
* 剩余可约容量
*/
private Integer capLeft;
/**
* 已约单量
*/
private Integer orderCount;
/**
* 最大连续时长
*/
private Integer maxDuration;
/**
* 备注
*/
private String memo;
/**
* 创建时间
*/
private LocalDateTime createTime = LocalDateTime.now();
/**
* 更新时间
*/
private LocalDateTime updateTime = LocalDateTime.now();
}
package com.dituhui.pea.dispatch.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* @author zhangx
*/
@Data
@Entity
@Table(name = "engineer_business")
public class EngineerBusinessEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "engineer_code", nullable = false, length = 50)
private String engineerCode;
@Column(name = "work_on", nullable = false, length = 5, columnDefinition = "varchar(5) default '08:00'")
private String workOn;
@Column(name = "work_off", nullable = false, length = 5, columnDefinition = "varchar(5) default '18:00'")
private String workOff;
@Column(name = "max_num", nullable = false)
private int maxNum;
@Column(name = "max_minute", nullable = false)
private int maxMinute;
@Column(name = "max_distance", nullable = false)
private int maxDistance;
@Column(name = "address", nullable = false, length = 50)
private String address;
@Column(name = "x", nullable = false, length = 20)
private String X;
@Column(name = "y", nullable = false, length = 20)
private String Y;
@Column(name = "vehicle", nullable = false, length = 10, columnDefinition = "varchar(10) default '1'")
private String vehicle = "1";
@Column(name = "vehicle_no", nullable = false, length = 10, columnDefinition = "varchar(10) default ''")
private String vehicleNo;
@Column(name = "priority", nullable = false, columnDefinition = "tinyint(4) default '1'")
private int priority;
/**
* 常规出发地,1配件仓,2家庭住址,3工作地址 默认工作地址
*/
@Column(name = "departure", nullable = false, columnDefinition = "tinyint(4) default '3'")
private int departure = 3;
@Column(name = "dispatch_strategy", nullable = false, length = 32, columnDefinition = "varchar(32) default 'CENTER'")
private String dispatchStrategy;
@Column(name = "memo", nullable = false, length = 100, columnDefinition = "varchar(100) default ''")
private String memo;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "create_time", nullable = false, updatable = false, columnDefinition = "timestamp default current_timestamp")
private LocalDateTime createTime = LocalDateTime.now();
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Column(name = "update_time", nullable = false, columnDefinition = "timestamp default current_timestamp on update current_timestamp")
private LocalDateTime updateTime = LocalDateTime.now();
}
package com.dituhui.pea.dispatch.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "map_block_info")
public class MapBlockInfoEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "saas_area_ids", length = 1024)
private String areaIds;
@Column(name = "area_name", length = 50, nullable = false)
private String areaName;
@Column(name = "branch_id", length = 50, nullable = false)
private String branchId;
@Column(name = "group_id", length = 50, nullable = false)
private String groupId;
@Column(name = "team_id", length = 50, nullable = false)
private String teamId;
@Column(name = "city_code", nullable = true)
private String cityCode;
@Column(name = "area_count")
private Long areaCount;
@Column(name = "area_data", nullable = true, columnDefinition = "json")
private String areaData;
@Column(nullable = true)
private Integer type;
@Column(name = "layer_id", length = 50, nullable = false)
private String layerId;
@Column(name = "layer_name", length = 50, nullable = false)
private String layerName;
@Column(name = "saas_layercode", length = 50)
private String saasLayercode;
@Column(name = "saas_layer_id", length = 50)
private String saasLayerId;
@Column(name = "saas_url", length = 512)
private String saasUrl;
@Column(nullable = false)
private Boolean status;
@Column(length = 100, nullable = false)
private String memo;
@Column(name = "create_time", nullable = false, columnDefinition = "datetime DEFAULT CURRENT_TIMESTAMP")
private LocalDateTime createTime;
@Column(name = "update_time", nullable = true, columnDefinition = "datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private LocalDateTime updateTime;
// Getters and Setters
// ...
}
package com.dituhui.pea.dispatch.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Data
@Table(name="pub_params")
public class PubParamsEntity {
/**
* id
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 限定系统
*/
private String catalog;
/**
* 参数组/业务代码
*/
private String biztype;
/**
* 参数名
*/
private String pkey;
/**
* 标题
*/
private String plabel;
/**
* 参数值
*/
private String pvalue;
/**
* 参数解释说明
*/
private String description;
/**
* 创建时间
*/
private LocalDateTime createTime = LocalDateTime.now();
/**
* 更新时间
*/
private LocalDateTime updateTime = LocalDateTime.now();
}
package com.dituhui.pea.dispatch.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
@Data
@Entity
@Table(name = "skill_info")
public class SkillInfoEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "skill_code", length = 32, nullable = false)
private String skillCode;
@Column(length = 20, nullable = false)
private String brand;
@Column(length = 20, nullable = false)
private String type;
@Column(length = 20, nullable = false)
private String skill;
@Column(name = "take_time", nullable = false)
private Integer takeTime;
@Column(name = "take_engineer", nullable = false)
private Integer takeEngineer;
@Column(name = "low_electrician_cert", nullable = false)
private Boolean lowElectricianCert;
@Column(name = "gas_cert", nullable = false)
private Boolean gasCert;
@Column(nullable = false)
private Integer priority;
@Column(name = "skill_group_code", length = 50)
private String skillGroupCode;
@Column(name = "layer_id", length = 32)
private String layerId;
@Column(name = "type_category", length = 50)
private String typeCategory;
@Column(name = "skill_category", length = 50)
private String skillCategory;
@Column(length = 100, nullable = false)
private String memo;
@Column(name = "create_time", nullable = false, columnDefinition = "datetime DEFAULT CURRENT_TIMESTAMP")
private LocalDateTime createTime = LocalDateTime.now();
@Column(name = "update_time", nullable = false, columnDefinition = "datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP")
private LocalDateTime updateTime = LocalDateTime.now();
// Getters and Setters
// ...
}
package com.dituhui.pea.dispatch.entity;
import lombok.Getter;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Objects;
@Getter
@Entity
@Table(name = "time_slice")
public class TimeSliceEntity {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
@Column(name = "id")
private Long id;
@Basic
@Column(name = "type")
private String type;
@Basic
@Column(name = "name")
private String name;
@Basic
@Column(name = "start")
private String start;
@Basic
@Column(name = "end")
private String end;
@Basic
@Column(name = "create_time")
private LocalDateTime createTime;
@Basic
@Column(name = "update_time")
private LocalDateTime updateTime;
public void setId(Long id) {
this.id = id;
}
public void setType(String type) {
this.type = type;
}
public void setName(String name) {
this.name = name;
}
public void setStart(String start) {
this.start = start;
}
public void setEnd(String end) {
this.end = end;
}
public void setCreateTime(LocalDateTime createTime) {
this.createTime = createTime;
}
public void setUpdateTime(LocalDateTime updateTime) {
this.updateTime = updateTime;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TimeSliceEntity that = (TimeSliceEntity) o;
return id == that.id && Objects.equals(type, that.type) && Objects.equals(name, that.name) && Objects.equals(start, that.start) && Objects.equals(end, that.end) && Objects.equals(createTime, that.createTime) && Objects.equals(updateTime, that.updateTime);
}
@Override
public int hashCode() {
return Objects.hash(id, type, name, start, end, createTime, updateTime);
}
}
package com.dituhui.pea.dispatch.quartz;
package com.dituhui.pea.dispatch.quartz.config;
import org.quartz.Job;
import org.quartz.spi.TriggerFiredBundle;
......
package com.dituhui.pea.dispatch.quartz;
package com.dituhui.pea.dispatch.quartz.config;
import org.quartz.spi.JobFactory;
import org.springframework.boot.autoconfigure.quartz.QuartzProperties;
......
package com.dituhui.pea.dispatch.quartz;
package com.dituhui.pea.dispatch.quartz.dispatch;
import com.dituhui.pea.dispatch.service.SchedulerService;
import lombok.extern.slf4j.Slf4j;
......@@ -13,12 +13,14 @@ import javax.annotation.Resource;
/**
* 自动派工任务
* DisallowConcurrentExecution:禁止并发执行多个相同定义的JobDetai
*
* @author RenPing
* @date 2023/11/02
*/
@Component
@Slf4j
@DisallowConcurrentExecution
public class AutoDispatchJob extends QuartzJobBean {
public static final String TEAM_JOB_PREFIX="BOXI_TEAM_";
......
package com.dituhui.pea.dispatch.quartz;
package com.dituhui.pea.dispatch.quartz.dispatch;
import cn.hutool.core.collection.CollectionUtil;
import com.dituhui.pea.dispatch.dao.OrgTeamDao;
import com.dituhui.pea.dispatch.entity.OrgTeamEntity;
import com.dituhui.pea.dispatch.quartz.dispatch.AutoDispatchJob;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Value;
......
package com.dituhui.pea.dispatch.quartz.engineerCapacity;
import com.dituhui.pea.dispatch.common.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
/**
* 工程师容量初始化
*
* @author RenPing
* @date 2023/11/02
*/
@Component
@Slf4j
@DisallowConcurrentExecution
public class InitEngineerCapacityJob extends QuartzJobBean {
public static final String INIT_ENGINEER_JOB_PREFIX = "BOXI_INIT_ENGINEER_CAPACITY_";
@Value("${scheduler.init-engineer-capacity.day-offset-begin}")
private int dayOffsetBegin;
@Value("${scheduler.init-engineer-capacity.day-offset-end}")
private int dayOffsetEnd;
@Autowired
private InitEngineerCapacityScheduler initEngineerCapacityScheduler;
@Override
protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
try {
JobKey jobKey = jobExecutionContext.getJobDetail().getKey();
String name = jobKey.getName();
String branchId = name.substring(INIT_ENGINEER_JOB_PREFIX.length());
long start = System.currentTimeMillis();
log.info(">>> 开始初始化:分部(branchId:{})所有工程师的容量将根据日历表的记录进行计算设置", branchId);
String bdate = DateUtils.formatDate(LocalDate.now().plusDays(dayOffsetBegin));
String edate = DateUtils.formatDate(LocalDate.now().plusDays(dayOffsetEnd));
initEngineerCapacityScheduler.initOneEngineerByDays(bdate, edate, branchId);
long end = System.currentTimeMillis();
log.info(">>> 初始化结束:分部(branchId:{})所有工程师的容量,耗时:{}", branchId, end - start);
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}
\ No newline at end of file
package com.dituhui.pea.dispatch.quartz.engineerCapacity;
import cn.hutool.core.collection.CollectionUtil;
import com.dituhui.pea.dispatch.dao.OrgBranchDao;
import com.dituhui.pea.dispatch.entity.OrgBranchEntity;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;
/**
* 手动触发定时任务
*
* @author RenPing
* @date 2023/11/01
*/
@Component
@Slf4j
public class InitEngineerCapacityListener implements ApplicationListener<ApplicationStartedEvent> {
@Resource
private Scheduler scheduler;
@Autowired
private OrgBranchDao orgBranchDao;
@Value("${scheduler.init-engineer-capacity.cron-expr}")
private String cronExpr;
@Override
public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) {
List<String> branchIds = orgBranchDao.findAll().stream().map(OrgBranchEntity::getBranchId).collect(Collectors.toList());
branchIds.forEach(branchId -> {
String jobName = InitEngineerCapacityJob.INIT_ENGINEER_JOB_PREFIX + branchId;
JobDetail jobDetail = JobBuilder.newJob(InitEngineerCapacityJob.class)
.withIdentity(jobName, jobName)
.storeDurably()
.build();
Trigger trigger = TriggerBuilder.newTrigger()
.forJob(jobDetail)
.withIdentity(jobName, jobName)
.startNow()
.withSchedule(CronScheduleBuilder.cronSchedule(cronExpr))
.build();
try {
scheduler.scheduleJob(jobDetail, CollectionUtil.newHashSet(trigger), true);
} catch (SchedulerException e) {
//log.error(e.getMessage(), e);
}
});
}
}
\ No newline at end of file
package com.dituhui.pea.dispatch.service;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.dispatch.common.OccupyInfoDetail;
import com.dituhui.pea.dispatch.dto.*;
import com.dituhui.pea.dispatch.dto.param.EngineerCalendarResultDTO;
import java.time.LocalDate;
import java.util.List;
public interface EngineerCalendarService {
Result<?> getEngineersCalendar(EngineerCalendarDTO.Request engineerCalendarReq);
Result<?> getCalendarTypeList();
Result<?> getPlanDetail(CalendarDetailDTO.Request reqDTO);
Result<?> updatePlan(String userId, CalendarUpdateDTO.Request reqDTO);
Result<?> deletePlan(String userId, CalendarDeleteDTO.Request reqDTO);
Result<?> batchAddPlan(String userId, CalendarBatAddDTO.Request reqDTO);
Result<?> queryEngineerPlanNum(CalendarQueryNumDTO.Request reqDTO);
Result<?> batchDeletePlan(String userId, CalendarBatDelDTO.Request reqDTO);
/**
* 查询工程师日期范围内的日历事件安排, 返回的内容包括:(多条)开始时间,结束时间,事件代码,事件名称,事件说明
*
* @param engineerCode 工程师编码
* @param startDate 开始日期
* @param endDate 结束日期
* @return 日期范围内的日历, 包含开始时间,结束时间,事件代码,事件名称,事件说明
*/
EngineerCalendarResultDTO queryEngineerCalendar(String engineerCode, LocalDate startDate, LocalDate endDate);
/**
* 获取工程师在指定日期的“非工作”时间安排 包含工作队休息时间和日程表事件记录时间, 其中日程表内事件未与工作队时间判定交集, 实际计算非工作时间时需求并集
*
* @param engineerCode 工程师编号
* @param targetDate 目标日期
* @return 没有交集的事件日程时间段即已占用的时间段
*/
List<OccupyInfoDetail> getEngineerWorkDayCalendar(String engineerCode, LocalDate targetDate);
/**
* 判定工程师指定日期是否在工作队的工作日期
*
* @param teamId 工作队
* @param engineerCode 工程师编号
* @param targetDate 目标日期
* @return 工作队内日期工作时间信息
*/
boolean engineerTeamDateWorkTime(String teamId, String engineerCode, LocalDate targetDate);
/**
* 获取工程师的工作时间窗
*
* @param engineerCode 工程师编号
* @param teamId 工程师所属工作队 (解决一个工程师属多个多工作对情况)
* @param targetDate 目标日期
* @return 时间窗格式
* @apiNote 时间窗格式:[[起始时间段1, 结束时间段1],[起始时间段2, 结束时间段2]] <br/> 时间格式: 从0点开始的分钟数, 如8:00AM 为480
*/
int[][] timeWindows(String engineerCode, String teamId, LocalDate targetDate);
}
package com.dituhui.pea.dispatch.service;
import com.dituhui.pea.dispatch.entity.CapacityEngineerSliceUsedEntity;
import java.util.Collection;
import java.util.List;
public interface EngineerSliceUsedCapacityService {
List<CapacityEngineerSliceUsedEntity> findByWorkdayAndEngineerCode(String workDay, String engineerCode);
List<CapacityEngineerSliceUsedEntity> deleteByWorkdayAndEngineerCode(String workDay, String engineerCode);
List<CapacityEngineerSliceUsedEntity> saveAll(Collection<CapacityEngineerSliceUsedEntity> collection);
}
package com.dituhui.pea.dispatch.service.impl;
import com.dituhui.pea.dispatch.dao.EngineerSliceUsedCapacityDao;
import com.dituhui.pea.dispatch.entity.CapacityEngineerSliceUsedEntity;
import com.dituhui.pea.dispatch.service.EngineerSliceUsedCapacityService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;
import java.util.Collection;
import java.util.List;
@Service
@AllArgsConstructor
public class EngineerSliceUsedCapacityServiceImpl implements EngineerSliceUsedCapacityService {
private final EngineerSliceUsedCapacityDao engineerSliceUsedCapacityDao;
@Override
@Transactional
public List<CapacityEngineerSliceUsedEntity> findByWorkdayAndEngineerCode(String workDay, String engineerCode) {
return engineerSliceUsedCapacityDao.findByWorkdayAndEngineerCode(workDay, engineerCode);
}
@Override
@Transactional
public List<CapacityEngineerSliceUsedEntity> deleteByWorkdayAndEngineerCode(String workDay, String engineerCode) {
return engineerSliceUsedCapacityDao.deleteByWorkdayAndEngineerCode(workDay, engineerCode);
}
@Override
@Transactional
public List<CapacityEngineerSliceUsedEntity> saveAll(Collection<CapacityEngineerSliceUsedEntity> collection) {
return engineerSliceUsedCapacityDao.saveAll(collection);
}
}
......@@ -3,10 +3,31 @@ server:
dispatch:
cron:
expr: 0 19 8-20 * * ?
expr: 0 10 8-22 * * ?
next-day-limit: 2
# expr: 0 */10 8-18 * * ?
scheduler:
init-engineer-capacity:
# 每天22点1次
#cron-expr: 0 0 22 * * ?
cron-expr: 0 29 * * * ?
day-offset-begin: 0
day-offset-end: 14
rewrite-force: true
calc-engineer-capacity:
# 8-20点,每30分钟1次
cron-expr: 0 */30 1-23 * * ?
day-offset-begin: 0
day-offset-end: 14
calc-org-capacity:
# 8-20点,每小时1次
cron-expr: 0 0 1-23 * * ?
day-offset-begin: 0
day-offset-end: 14
spring:
application:
name: project-dispatch
......
......@@ -6,6 +6,26 @@ dispatch:
expr: 0 */30 8-18 * * ?
next-day-limit: 2
scheduler:
init-engineer-capacity:
# 每天22点1次
cron-expr: 0 0 22 * * ?
day-offset-begin: 1
day-offset-end: 20
rewrite-force: true
calc-engineer-capacity:
# 8-20点,每30分钟1次
cron-expr: 0 */30 1-23 * * ?
day-offset-begin: 0
day-offset-end: 20
calc-org-capacity:
# 8-20点,每小时1次
cron-expr: 0 0 1-23 * * ?
day-offset-begin: 0
day-offset-end: 20
spring:
application:
name: project-dispatch
......
......@@ -251,7 +251,7 @@ public class InitEngineerCapacityScheduler {
}
}
@Scheduled(cron = "${scheduler.init-engineer-capacity.cron-expr}")
//@Scheduled(cron = "${scheduler.init-engineer-capacity.cron-expr}")
public void run() {
log.info("开始初始化,所有工程师的容量将根据日历表的记录进行计算设置");
String bdate = DateUtils.formatDate(LocalDate.now().plusDays(dayOffsetBegin));
......
......@@ -75,7 +75,7 @@ scheduler:
init-engineer-capacity:
# 每天22点1次
#cron-expr: 0 0 22 * * ?
cron-expr: 0 32 * * * ?
cron-expr: 0 40 * * * ?
day-offset-begin: 0
day-offset-end: 14
rewrite-force: true
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!