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 47ca589f
authored
Jul 07, 2023
by
张晓
Browse files
Options
Browse Files
Download
Plain Diff
初步打通
2 parents
0a9dac80
683fb475
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
234 additions
and
34 deletions
project-dispatch/src/main/java/com/dituhui/pea/dispatch/DispatchServiceApplication.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Customer.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/scheduler/BatchScheduler.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/BatchServiceImpl.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/ExtractServiceImpl.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/application.yaml
project-dispatch/src/test/java/com/dituhui/pea/dispatch/SolveServiceTest.java
project-dispatch/src/main/java/com/dituhui/pea/dispatch/DispatchServiceApplication.java
View file @
47ca589
...
@@ -18,11 +18,13 @@ package com.dituhui.pea.dispatch;
...
@@ -18,11 +18,13 @@ package com.dituhui.pea.dispatch;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.SpringApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.boot.autoconfigure.SpringBootApplication
;
import
org.springframework.scheduling.annotation.EnableScheduling
;
/**
/**
* @author gpzhang
* @author gpzhang
*/
*/
@SpringBootApplication
@SpringBootApplication
@EnableScheduling
public
class
DispatchServiceApplication
{
public
class
DispatchServiceApplication
{
public
static
void
main
(
String
[]
args
)
{
public
static
void
main
(
String
[]
args
)
{
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/pojo/Customer.java
View file @
47ca589
...
@@ -13,7 +13,6 @@ import lombok.Setter;
...
@@ -13,7 +13,6 @@ import lombok.Setter;
* 订单
* 订单
*
*
* @author gpzhang
* @author gpzhang
*
*/
*/
@Setter
@Setter
@Getter
@Getter
...
@@ -166,7 +165,19 @@ public class Customer {
...
@@ -166,7 +165,19 @@ public class Customer {
@Override
@Override
public
String
toString
()
{
public
String
toString
()
{
return
"Customer{"
+
"id="
+
id
+
'}'
;
return
"Customer{"
+
"id="
+
id
+
", code='"
+
code
+
'\''
+
", location="
+
location
+
", startTime="
+
startTime
+
", endTime="
+
endTime
+
", serviceDuration="
+
serviceDuration
+
", requiredSkill='"
+
requiredSkill
+
'\''
+
", technician="
+
technician
.
getCode
()
+
", previousCustomer="
+
((
previousCustomer
!=
null
)
?
previousCustomer
.
getCode
()
:
"null"
)
+
", nextCustomer="
+
((
nextCustomer
!=
null
)
?
nextCustomer
.
getCode
()
:
"null"
)
+
", arrivalTime="
+
arrivalTime
+
", departureTime="
+
((
getDepartureTime
()
!=
null
)?
getDepartureTime
()
:
0
)
+
'}'
;
}
}
}
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/scheduler/BatchScheduler.java
0 → 100644
View file @
47ca589
package
com
.
dituhui
.
pea
.
dispatch
.
scheduler
;
import
com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider
;
import
com.dituhui.pea.dispatch.pojo.Customer
;
import
com.dituhui.pea.dispatch.pojo.DispatchSolution
;
import
com.dituhui.pea.dispatch.pojo.Technician
;
import
com.dituhui.pea.dispatch.service.BatchService
;
import
com.dituhui.pea.dispatch.service.ExtractService
;
import
com.dituhui.pea.dispatch.service.SolveService
;
import
lombok.extern.slf4j.Slf4j
;
import
org.optaplanner.core.api.solver.Solver
;
import
org.optaplanner.core.api.solver.SolverFactory
;
import
org.optaplanner.core.api.solver.SolverJob
;
import
org.optaplanner.core.api.solver.SolverManager
;
import
org.optaplanner.core.config.solver.SolverConfig
;
import
org.optaplanner.core.config.solver.SolverManagerConfig
;
import
org.optaplanner.persistence.jackson.impl.domain.solution.JacksonSolutionFileIO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.stereotype.Component
;
import
org.springframework.scheduling.annotation.Scheduled
;
import
java.io.File
;
import
java.sql.SQLException
;
import
java.time.Duration
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.time.format.DateTimeFormatter
;
import
java.util.Arrays
;
import
java.util.UUID
;
@Slf4j
@Component
public
class
BatchScheduler
{
String
groupId
=
"gsuzhou"
;
int
nextDays
=
3
;
@Autowired
BatchService
batchService
;
@Autowired
SolveService
solveService
;
@Autowired
ExtractService
extractService
;
private
Solver
<
DispatchSolution
>
solver
;
public
BatchScheduler
()
{
SolverConfig
solverConfig
=
new
SolverConfig
().
withSolutionClass
(
DispatchSolution
.
class
);
solverConfig
.
withEntityClassList
(
Arrays
.
asList
(
Technician
.
class
,
Customer
.
class
));
// 这里不能漏掉,否则约束不生效
solverConfig
.
withConstraintProviderClass
(
DispatchConstraintProvider
.
class
);
solverConfig
.
withTerminationSpentLimit
(
Duration
.
ofSeconds
(
20
));
SolverFactory
<
DispatchSolution
>
solverFactory
=
SolverFactory
.
create
(
solverConfig
);
solver
=
solverFactory
.
buildSolver
();
}
/*
* 异步执行任务开始
* */
@Scheduled
(
cron
=
"${dispatch.cron.expr}"
)
public
void
dispatchRun
()
{
log
.
info
(
"dispatchRun group:{}"
,
groupId
);
try
{
for
(
int
i
=
0
;
i
<=
2
;
i
++)
{
String
currDay
=
LocalDate
.
now
().
plusDays
(
i
).
format
(
DateTimeFormatter
.
ISO_LOCAL_DATE
);
log
.
info
(
"dispatchRun begin----- group:{}, day:{}"
,
groupId
,
currDay
);
String
batchNo
=
batchService
.
buildBatchNo
(
groupId
,
currDay
);
UUID
problemId
=
solveService
.
generateProblemId
(
groupId
,
batchNo
);
log
.
info
(
"dispatchRun group:{}, day:{}, batch:{}, problemId:{}"
,
groupId
,
currDay
,
batchNo
,
problemId
);
DispatchSolution
problem
=
solveService
.
prepareSolution
(
groupId
,
batchNo
);
if
(
problem
.
getCustomerList
().
size
()
<=
0
)
{
log
.
info
(
"dispatchRun no order , group:{}, day:{}, batch:{}, problemId:{}, order-size:{}"
,
groupId
,
currDay
,
batchNo
,
problemId
,
problem
.
getCustomerList
().
size
());
continue
;
}
log
.
info
(
"dispatchRun prepare done, group:{}, day:{}, batch:{}, problemId:{}"
,
groupId
,
currDay
,
batchNo
,
problemId
);
DispatchSolution
solution
=
solver
.
solve
(
problem
);
log
.
info
(
"dispatchRun run done, group:{}, day:{}, batch:{}, problemId:{}, score:{}"
,
groupId
,
currDay
,
batchNo
,
problemId
,
solution
.
getScore
().
toShortString
());
this
.
extractService
.
saveAndExtractSolution
(
solution
);
log
.
info
(
"dispatchRun done ------ group:{}, day:{}"
,
groupId
,
currDay
);
JacksonSolutionFileIO
<
DispatchSolution
>
exporter
=
new
JacksonSolutionFileIO
<
DispatchSolution
>(
DispatchSolution
.
class
);
// Set the output file.
exporter
.
write
(
solution
,
new
File
(
"dispatchSolution_%s_%s.json"
.
format
(
groupId
,
currDay
)));
Thread
.
sleep
(
1000
*
5
);
}
}
catch
(
SQLException
e
)
{
log
.
info
(
"error %s"
,
e
);
throw
new
RuntimeException
(
e
);
}
catch
(
InterruptedException
e
)
{
log
.
info
(
"error %s"
,
e
);
throw
new
RuntimeException
(
e
);
}
log
.
info
(
"done"
);
}
// @Scheduled(fixedRate = 1000*10)
public
void
RunLog
()
{
log
.
info
(
"RunLog"
);
}
}
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/BatchServiceImpl.java
View file @
47ca589
...
@@ -54,7 +54,6 @@ public class BatchServiceImpl implements BatchService {
...
@@ -54,7 +54,6 @@ public class BatchServiceImpl implements BatchService {
// 检查给定小组、日期是否有在运行的批次任务,没则返回,没有则创建
// 检查给定小组、日期是否有在运行的批次任务,没则返回,没有则创建
@Transactional
@Transactional
@Override
@Override
public
String
buildBatchNo
(
String
groupId
,
String
day
)
{
public
String
buildBatchNo
(
String
groupId
,
String
day
)
{
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/ExtractServiceImpl.java
View file @
47ca589
package
com
.
dituhui
.
pea
.
dispatch
.
service
.
impl
;
package
com
.
dituhui
.
pea
.
dispatch
.
service
.
impl
;
import
cn.hutool.core.date.DateField
;
import
cn.hutool.core.date.DateTime
;
import
cn.hutool.core.date.DateTime
;
import
cn.hutool.core.date.DateUtil
;
import
cn.hutool.core.date.DateUtil
;
import
com.dituhui.pea.dispatch.dao.*
;
import
com.dituhui.pea.dispatch.dao.*
;
...
@@ -38,8 +39,6 @@ import java.util.stream.Stream;
...
@@ -38,8 +39,6 @@ import java.util.stream.Stream;
public
class
ExtractServiceImpl
implements
ExtractService
{
public
class
ExtractServiceImpl
implements
ExtractService
{
@Autowired
@Autowired
EngineerInfoRepository
engineerInfoRepo
;
EngineerInfoRepository
engineerInfoRepo
;
...
@@ -61,7 +60,7 @@ public class ExtractServiceImpl implements ExtractService {
...
@@ -61,7 +60,7 @@ public class ExtractServiceImpl implements ExtractService {
* 将计算结果回写到dispatch2个表、以及order两个表
* 将计算结果回写到dispatch2个表、以及order两个表
* */
* */
@Override
@Override
public
void
saveAndExtractSolution
(
DispatchSolution
solution
)
throws
RuntimeException
{
public
void
saveAndExtractSolution
(
DispatchSolution
solution
)
throws
RuntimeException
{
String
groupId
=
solution
.
getGroupId
();
String
groupId
=
solution
.
getGroupId
();
String
batchNo
=
solution
.
getBatchNo
();
String
batchNo
=
solution
.
getBatchNo
();
log
.
info
(
"算法结果回写包装方法, groupId:{}, batchNo:{}"
,
groupId
,
batchNo
);
log
.
info
(
"算法结果回写包装方法, groupId:{}, batchNo:{}"
,
groupId
,
batchNo
);
...
@@ -69,6 +68,7 @@ public class ExtractServiceImpl implements ExtractService {
...
@@ -69,6 +68,7 @@ public class ExtractServiceImpl implements ExtractService {
try
{
try
{
this
.
extractDispatchToOrder
(
solution
.
getGroupId
(),
solution
.
getBatchNo
());
this
.
extractDispatchToOrder
(
solution
.
getGroupId
(),
solution
.
getBatchNo
());
}
catch
(
SQLException
e
)
{
}
catch
(
SQLException
e
)
{
log
.
error
(
"算法结果回写包装方法异常, groupId:{}, batchNo:{}"
,
groupId
,
batchNo
,
e
);
throw
new
RuntimeException
(
e
);
throw
new
RuntimeException
(
e
);
}
}
}
}
...
@@ -76,6 +76,7 @@ public class ExtractServiceImpl implements ExtractService {
...
@@ -76,6 +76,7 @@ public class ExtractServiceImpl implements ExtractService {
/**
/**
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
* 将计算结果回写到dispatch_order表(更新补充技术员工号、上门时间)
*/
*/
@Transactional
@Override
@Override
public
void
saveSolutionToDispatch
(
String
groupId
,
String
batchNo
,
DispatchSolution
solution
)
throws
RuntimeException
{
public
void
saveSolutionToDispatch
(
String
groupId
,
String
batchNo
,
DispatchSolution
solution
)
throws
RuntimeException
{
log
.
info
(
"算法结果回写dispatch, groupId:{}, batchNo:{}"
,
groupId
,
batchNo
);
log
.
info
(
"算法结果回写dispatch, groupId:{}, batchNo:{}"
,
groupId
,
batchNo
);
...
@@ -90,14 +91,14 @@ public class ExtractServiceImpl implements ExtractService {
...
@@ -90,14 +91,14 @@ public class ExtractServiceImpl implements ExtractService {
log
.
info
(
"算法结果回写dispatch, step2-开始回写, groupId:{}, batchNo:{}"
,
groupId
,
batchNo
);
log
.
info
(
"算法结果回写dispatch, step2-开始回写, groupId:{}, batchNo:{}"
,
groupId
,
batchNo
);
// 保存当前批次指派结果
// 保存当前批次指派结果
solution
.
getTechnicianList
().
forEach
(
vehicle
->
{
solution
.
getTechnicianList
().
forEach
(
technician
->
{
log
.
info
(
"算法结果回写dispatch, step2.1-按技术员逐个回写, groupId:{}, batchNo:{},
employ
: {}, max-minute:{}, customlist.size:{}"
,
log
.
info
(
"算法结果回写dispatch, step2.1-按技术员逐个回写, groupId:{}, batchNo:{},
technician
: {}, max-minute:{}, customlist.size:{}"
,
groupId
,
batchNo
,
vehicle
.
getId
(),
vehicle
.
getMaxMinute
(),
vehicle
.
getCustomerList
().
size
());
groupId
,
batchNo
,
technician
.
getCode
(),
technician
.
getMaxMinute
(),
technician
.
getCustomerList
().
size
());
AtomicInteger
seq
=
new
AtomicInteger
();
AtomicInteger
seq
=
new
AtomicInteger
();
final
Date
[]
expectBegin
=
{
null
};
vehicle
.
getCustomerList
().
forEach
(
customer
->
{
technician
.
getCustomerList
().
forEach
(
customer
->
{
int
idx
=
seq
.
getAndIncrement
();
int
idx
=
seq
.
getAndIncrement
();
// 统计按8:00开始 +take_time + 20分钟路程向后累积
// 统计按8:00开始 +take_time + 20分钟路程向后累积
...
@@ -106,25 +107,22 @@ public class ExtractServiceImpl implements ExtractService {
...
@@ -106,25 +107,22 @@ public class ExtractServiceImpl implements ExtractService {
DispatchOrder
dOrder
=
optional
.
get
();
DispatchOrder
dOrder
=
optional
.
get
();
if
(
expectBegin
[
0
]
==
null
)
{
expectBegin
[
0
]
=
dOrder
.
getExpectTimeBegin
();
}
LocalDateTime
localExpectBegin
=
LocalDateTime
.
ofInstant
(
expectBegin
[
0
].
toInstant
(),
ZoneId
.
systemDefault
());
// 时间相加操作
// 时间相加操作
LocalDateTime
localEndTime
=
localExpectBegin
.
plusMinutes
(
dOrder
.
getTakeTime
());
// LocalDateTime localExpectBegin = LocalDateTime.ofInstant(expectBegin[0].toInstant(), ZoneId.systemDefault());
Date
end
=
Date
.
from
(
localEndTime
.
atZone
(
ZoneId
.
systemDefault
()).
toInstant
());
// LocalDateTime localEndTime = localExpectBegin.plusMinutes(dOrder.getTakeTime());
// Date end = Date.from(localEndTime.atZone(ZoneId.systemDefault()).toInstant());
log
.
info
(
"算法结果回写dispatch, step3-逐个客户处理, groupId:{}, batchNo:{}, employ: {}, customer:{}, service-duration:{} "
,
log
.
info
(
"算法结果回写dispatch, step3-逐个客户处理, groupId:{}, batchNo:{}, employ: {}, customer:{}, service-duration:{} "
,
groupId
,
batchNo
,
vehicle
.
getId
(),
customer
.
getId
(),
customer
.
getServiceDuration
());
groupId
,
batchNo
,
technician
.
getCode
(),
customer
.
getCode
(),
customer
.
getServiceDuration
());
log
.
info
(
customer
.
toString
());
Date
arriveTime
=
DateUtil
.
beginOfDay
(
dOrder
.
getExpectTimeBegin
()).
offset
(
DateField
.
MINUTE
,
customer
.
getArrivalTime
());
Date
leaveTime
=
DateUtil
.
beginOfDay
(
arriveTime
).
offset
(
DateField
.
MINUTE
,
customer
.
getDepartureTime
());
Object
[]
param
=
{
vehicle
.
getId
(),
idx
,
expectBegin
[
0
],
end
,
groupId
,
batchNo
,
customer
.
getId
()};
Object
[]
param
=
{
technician
.
getCode
(),
idx
,
arriveTime
,
leaveTime
,
groupId
,
batchNo
,
customer
.
getCode
()};
jdbcTemplate
.
update
(
sql
,
param
);
jdbcTemplate
.
update
(
sql
,
param
);
// 再追加20分钟路程时间做为下一次时间的开始
expectBegin
[
0
]
=
Date
.
from
(
localEndTime
.
plusMinutes
(
20
).
atZone
(
ZoneId
.
systemDefault
()).
toInstant
());
}
}
});
});
...
@@ -192,13 +190,14 @@ public class ExtractServiceImpl implements ExtractService {
...
@@ -192,13 +190,14 @@ public class ExtractServiceImpl implements ExtractService {
jdbcTemplate
.
update
(
"update order_request set appointment_status ='ASSIGNED' where order_id =? and appointment_status='NOT_ASSIGNED'"
,
orderId
);
jdbcTemplate
.
update
(
"update order_request set appointment_status ='ASSIGNED' where order_id =? and appointment_status='NOT_ASSIGNED'"
,
orderId
);
}
}
// 会有多次上门情况( pre_status='
dispatch
' and status in ('NOT_ASSIGNED', 'ASSIGNED') ,直接更新,其它情况新增)
// 会有多次上门情况( pre_status='
PRE
' and status in ('NOT_ASSIGNED', 'ASSIGNED') ,直接更新,其它情况新增)
Optional
<
OrderAppointment
>
appointmentOpt
=
orderAppointmentRepo
.
findByOrderId
(
orderId
);
Optional
<
OrderAppointment
>
appointmentOpt
=
orderAppointmentRepo
.
findByOrderId
(
orderId
);
if
(
appointmentOpt
.
isPresent
()
&&
"
dispatch
"
.
equals
(
appointmentOpt
.
get
().
getPreStatus
())
&&
if
(
appointmentOpt
.
isPresent
()
&&
"
PRE
"
.
equals
(
appointmentOpt
.
get
().
getPreStatus
())
&&
(
"NOT_ASSIGNED"
.
equals
(
appointmentOpt
.
get
().
getStatus
())
||
"ASSIGNED"
.
equals
(
appointmentOpt
.
get
().
getStatus
())))
{
(
"NOT_ASSIGNED"
.
equals
(
appointmentOpt
.
get
().
getStatus
())
||
"ASSIGNED"
.
equals
(
appointmentOpt
.
get
().
getStatus
())))
{
OrderAppointment
appointment
=
appointmentOpt
.
get
();
OrderAppointment
appointment
=
appointmentOpt
.
get
();
appointment
.
setStatus
(
"ASSIGNED"
);
appointment
.
setStatus
(
"ASSIGNED"
);
appointment
.
setPreStatus
(
"PRE"
);
appointment
.
setEngineerCode
(
engCode
);
appointment
.
setEngineerCode
(
engCode
);
appointment
.
setEngineerName
(
engName
);
appointment
.
setEngineerName
(
engName
);
appointment
.
setEngineerPhone
(
phone
);
appointment
.
setEngineerPhone
(
phone
);
...
@@ -222,7 +221,7 @@ public class ExtractServiceImpl implements ExtractService {
...
@@ -222,7 +221,7 @@ public class ExtractServiceImpl implements ExtractService {
appointment
.
setIsWorkshop
(
0
);
appointment
.
setIsWorkshop
(
0
);
appointment
.
setExpectStartTime
(
dispatchOrder
.
getTimeBegin
());
appointment
.
setExpectStartTime
(
dispatchOrder
.
getTimeBegin
());
appointment
.
setExpectEndTime
(
dispatchOrder
.
getTimeEnd
());
appointment
.
setExpectEndTime
(
dispatchOrder
.
getTimeEnd
());
appointment
.
setPreStatus
(
"
dispatch
"
);
appointment
.
setPreStatus
(
"
PRE
"
);
appointment
.
setStatus
(
"ASSIGNED"
);
appointment
.
setStatus
(
"ASSIGNED"
);
appointment
.
setMemo
(
""
);
appointment
.
setMemo
(
""
);
appointment
.
setCreateTime
(
LocalDateTime
.
now
());
appointment
.
setCreateTime
(
LocalDateTime
.
now
());
...
...
project-dispatch/src/main/java/com/dituhui/pea/dispatch/service/impl/SolveServiceImpl.java
View file @
47ca589
...
@@ -14,10 +14,14 @@ import lombok.extern.slf4j.Slf4j;
...
@@ -14,10 +14,14 @@ import lombok.extern.slf4j.Slf4j;
import
org.optaplanner.core.api.solver.Solver
;
import
org.optaplanner.core.api.solver.Solver
;
import
org.optaplanner.core.api.solver.SolverFactory
;
import
org.optaplanner.core.api.solver.SolverFactory
;
import
org.optaplanner.core.config.solver.SolverConfig
;
import
org.optaplanner.core.config.solver.SolverConfig
;
import
org.optaplanner.persistence.jackson.impl.domain.solution.JacksonSolutionFileIO
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.core.io.ClassPathResource
;
import
org.springframework.jdbc.core.JdbcTemplate
;
import
org.springframework.jdbc.core.JdbcTemplate
;
import
org.springframework.stereotype.Service
;
import
org.springframework.stereotype.Service
;
import
java.io.File
;
import
java.time.Duration
;
import
java.time.Duration
;
import
java.time.LocalDateTime
;
import
java.time.LocalDateTime
;
import
java.util.*
;
import
java.util.*
;
...
@@ -80,7 +84,6 @@ public class SolveServiceImpl implements SolveService {
...
@@ -80,7 +84,6 @@ public class SolveServiceImpl implements SolveService {
oneDepot
=
new
Depot
(
oneGroup
.
getId
(),
oneGroup
.
getGroupId
(),
deptLocation
,
60
*
8
,
60
*
18
);
oneDepot
=
new
Depot
(
oneGroup
.
getId
(),
oneGroup
.
getGroupId
(),
deptLocation
,
60
*
8
,
60
*
18
);
// customerlist
// customerlist
ArrayList
<
Customer
>
customerList
=
new
ArrayList
<>();
ArrayList
<
Customer
>
customerList
=
new
ArrayList
<>();
dispatchOrderRepo
.
findByGroupIdAndBatchNo
(
groupId
,
batchNo
).
forEach
(
order
->
{
dispatchOrderRepo
.
findByGroupIdAndBatchNo
(
groupId
,
batchNo
).
forEach
(
order
->
{
...
@@ -117,13 +120,13 @@ public class SolveServiceImpl implements SolveService {
...
@@ -117,13 +120,13 @@ public class SolveServiceImpl implements SolveService {
// 距离偏好map
// 距离偏好map
Map
<
String
,
Long
>
preferedLoctionDistanceMap
=
new
HashMap
<
String
,
Long
>();
Map
<
String
,
Long
>
preferedLoctionDistanceMap
=
new
HashMap
<
String
,
Long
>();
customerList
.
forEach
(
customer
->
{
customerList
.
forEach
(
customer
->
{
long
distance
=
distanceCalculator
.
calculateDistance
(
location
,
customer
.
getLocation
());
long
distance
=
distanceCalculator
.
calculateDistance
(
location
,
customer
.
getLocation
());
preferedLoctionDistanceMap
.
put
(
engineer
.
getEngineer
Code
(),
distance
);
preferedLoctionDistanceMap
.
put
(
customer
.
get
Code
(),
distance
);
});
});
Technician
vehicle
=
new
Technician
(
engineer
.
getId
(),
engineer
.
getEngineerCode
(),
Technician
vehicle
=
new
Technician
(
engineer
.
getId
(),
engineer
.
getEngineerCode
(),
engineer
.
getMaxNum
(),
engineer
.
getMaxMinute
(),
engineer
.
getMaxDistance
()
*
1000
,
depot
,
engineer
.
getMaxNum
(),
engineer
.
getMaxMinute
(),
engineer
.
getMaxDistance
()
*
1000
,
depot
,
60
*
8
,
60
*
18
,
Set
.
copyOf
(
skillList
),
preferedLoctionDistanceMap
);
60
*
8
,
60
*
18
,
Set
.
copyOf
(
skillList
),
preferedLoctionDistanceMap
);
technicianList
.
add
(
vehicle
);
technicianList
.
add
(
vehicle
);
});
});
...
@@ -164,6 +167,12 @@ public class SolveServiceImpl implements SolveService {
...
@@ -164,6 +167,12 @@ public class SolveServiceImpl implements SolveService {
DispatchSolution
solution
=
solver
.
solve
(
problem
);
DispatchSolution
solution
=
solver
.
solve
(
problem
);
log
.
info
(
"调用引擎处理-结束, groupId:{}, batchNo:{}, score:{}"
,
groupId
,
batchNo
,
solution
.
getScore
());
log
.
info
(
"调用引擎处理-结束, groupId:{}, batchNo:{}, score:{}"
,
groupId
,
batchNo
,
solution
.
getScore
());
JacksonSolutionFileIO
<
DispatchSolution
>
exporter
=
new
JacksonSolutionFileIO
<
DispatchSolution
>(
DispatchSolution
.
class
);
// Set the output file.
exporter
.
write
(
solution
,
new
File
(
"dispatchSolution.json"
));
return
solution
;
return
solution
;
}
}
...
...
project-dispatch/src/main/resources/application-dev.yaml
View file @
47ca589
server
:
server
:
port
:
8011
port
:
8011
dispatch
:
cron
:
expr
:
0 45 8-18 * * ?
# expr: 0 */10 8-18 * * ?
spring
:
spring
:
application
:
application
:
name
:
project-dispatch
name
:
project-dispatch
jackson
:
default-property-inclusion
:
NON_NULL
# time-zone: GMT+8
date-format
:
yyyy-MM-dd HH:mm:ss
cloud
:
cloud
:
nacos
:
nacos
:
discovery
:
discovery
:
...
@@ -18,7 +27,7 @@ spring:
...
@@ -18,7 +27,7 @@ spring:
enabled
:
false
enabled
:
false
datasource
:
datasource
:
driver-class-name
:
com.mysql.cj.jdbc.Driver
driver-class-name
:
com.mysql.cj.jdbc.Driver
url
:
jdbc:mysql://127.0.0.1:3306/saas_aftersale_test?serverTimezone=
UTC
url
:
jdbc:mysql://127.0.0.1:3306/saas_aftersale_test?serverTimezone=
Asia/Shanghai
username
:
root
username
:
root
password
:
12345678
password
:
12345678
type
:
com.alibaba.druid.pool.DruidDataSource
type
:
com.alibaba.druid.pool.DruidDataSource
...
...
project-dispatch/src/main/resources/application.yaml
View file @
47ca589
server
:
server
:
port
:
8011
port
:
8011
dispatch
:
cron
:
expr
:
0 */30 8-18 * * ?
spring
:
spring
:
application
:
application
:
name
:
project-dispatch
name
:
project-dispatch
jackson
:
default-property-inclusion
:
NON_NULL
# time-zone: GMT+8
date-format
:
yyyy-MM-dd HH:mm:ss
cloud
:
cloud
:
nacos
:
nacos
:
discovery
:
discovery
:
...
@@ -18,7 +26,7 @@ spring:
...
@@ -18,7 +26,7 @@ spring:
enabled
:
false
enabled
:
false
datasource
:
datasource
:
driver-class-name
:
com.mysql.cj.jdbc.Driver
driver-class-name
:
com.mysql.cj.jdbc.Driver
url
:
jdbc:mysql://10.10.0.116:3306/saas_aftersale_test?serverTimezone=
UTC
url
:
jdbc:mysql://10.10.0.116:3306/saas_aftersale_test?serverTimezone=
Asia/Shanghai
username
:
root
username
:
root
password
:
123456
password
:
123456
type
:
com.alibaba.druid.pool.DruidDataSource
type
:
com.alibaba.druid.pool.DruidDataSource
...
...
project-dispatch/src/test/java/com/dituhui/pea/dispatch/SolveServiceTest.java
View file @
47ca589
package
com
.
dituhui
.
pea
.
dispatch
;
package
com
.
dituhui
.
pea
.
dispatch
;
import
com.dituhui.pea.dispatch.constraint.DispatchConstraintProvider
;
import
com.dituhui.pea.dispatch.pojo.Customer
;
import
com.dituhui.pea.dispatch.pojo.DispatchSolution
;
import
com.dituhui.pea.dispatch.pojo.DispatchSolution
;
import
com.dituhui.pea.dispatch.pojo.Technician
;
import
com.dituhui.pea.dispatch.service.ExtractService
;
import
com.dituhui.pea.dispatch.service.SolveService
;
import
com.dituhui.pea.dispatch.service.SolveService
;
import
lombok.extern.slf4j.Slf4j
;
import
lombok.extern.slf4j.Slf4j
;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.Test
;
import
org.optaplanner.core.api.solver.SolverManager
;
import
org.optaplanner.core.config.solver.SolverConfig
;
import
org.optaplanner.core.config.solver.SolverManagerConfig
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
org.springframework.boot.test.context.SpringBootTest
;
import
java.time.Duration
;
import
java.util.Arrays
;
import
java.util.UUID
;
import
static
java
.
lang
.
Thread
.
sleep
;
@Slf4j
@Slf4j
@SpringBootTest
@SpringBootTest
class
SolveServiceTest
{
class
SolveServiceTest
{
...
@@ -15,10 +28,26 @@ class SolveServiceTest {
...
@@ -15,10 +28,26 @@ class SolveServiceTest {
@Autowired
@Autowired
SolveService
solveService
;
SolveService
solveService
;
@Autowired
ExtractService
extractService
;
String
groupId
=
"gsuzhou"
;
String
groupId
=
"gsuzhou"
;
String
batchNo
=
"20230705-1500"
;
String
batchNo
=
"20230705-1500"
;
//@Test
private
SolverManager
<
DispatchSolution
,
UUID
>
solverManager
;
public
SolveServiceTest
()
{
SolverConfig
solverConfig
=
new
SolverConfig
().
withSolutionClass
(
DispatchSolution
.
class
);
solverConfig
.
withEntityClassList
(
Arrays
.
asList
(
Technician
.
class
,
Customer
.
class
));
// 这里不能漏掉,否则约束不生效
solverConfig
.
withConstraintProviderClass
(
DispatchConstraintProvider
.
class
);
solverConfig
.
withTerminationSpentLimit
(
Duration
.
ofSeconds
(
10
));
solverManager
=
SolverManager
.
create
(
solverConfig
,
new
SolverManagerConfig
());
}
@Test
public
void
test1
()
{
public
void
test1
()
{
log
.
info
(
"init"
);
log
.
info
(
"init"
);
...
@@ -29,4 +58,21 @@ class SolveServiceTest {
...
@@ -29,4 +58,21 @@ class SolveServiceTest {
log
.
info
(
"done"
);
log
.
info
(
"done"
);
}
}
@Test
public
void
testAsync
()
throws
InterruptedException
{
log
.
info
(
"testAsync init"
);
UUID
problemId
=
solveService
.
generateProblemId
(
groupId
,
batchNo
);
log
.
info
(
"testAsync problemId:{}"
,
problemId
);
DispatchSolution
problem
=
solveService
.
prepareSolution
(
groupId
,
batchNo
);
solverManager
.
solveAndListen
(
problemId
,
id
->
problem
,
this
.
extractService
::
saveAndExtractSolution
);
sleep
(
10
*
60
*
1000
);
log
.
info
(
"testAsync done"
);
}
}
}
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