Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
yangxiujun
/
paidan_demo
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit a32bf84c
authored
Nov 10, 2023
by
huangjinxin
Browse files
Options
Browse Files
Download
Plain Diff
Merge remote-tracking branch 'origin/develop' into develop
2 parents
cf594427
077e2451
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
84 additions
and
25 deletions
project-dispatch/src/main/java/com/dituhui/pea/dispatch/constraint/DispatchConstraintProvider.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/entity/OrderInfo.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/quartz/engineerCapacity/InitEngineerCapacityScheduler.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/SchedulerServiceImpl.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/SolveServiceImpl.java
project-dispatch/src/main/resources/application-dev.yaml
project-dispatch/src/main/resources/logback-spring.xml
project-dispatch/src/main/java/com/dituhui/pea/dispatch/constraint/DispatchConstraintProvider.java
View file @
a32bf84
...
...
@@ -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
());
}
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/entity/OrderInfo.java
View file @
a32bf84
...
...
@@ -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
;
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/quartz/engineerCapacity/InitEngineerCapacityScheduler.java
View file @
a32bf84
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
);
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/SchedulerServiceImpl.java
View file @
a32bf84
...
...
@@ -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
;
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/SolveServiceImpl.java
View file @
a32bf84
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
);
});
...
...
project-dispatch/src/main/resources/application-dev.yaml
View file @
a32bf84
...
...
@@ -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
:
...
...
project-dispatch/src/main/resources/logback-spring.xml
View file @
a32bf84
...
...
@@ -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
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment