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 f1b13ca2
authored
Nov 07, 2023
by
刘鑫
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(工程师工作时间窗) :时间窗格式:[[起始时间段1, 结束时间段1],[起始时间段2, 结束时间段2]] <br/> 时间格式: 从0点开始的分钟数, 如8:00AM 为480
1 parent
ea051d6f
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
168 additions
and
1 deletions
project-order/src/main/java/com/dituhui/pea/order/common/CapacityUtils.java
project-order/src/main/java/com/dituhui/pea/order/controller/TestController.java
project-order/src/main/java/com/dituhui/pea/order/service/EngineerCalendarService.java
project-order/src/main/java/com/dituhui/pea/order/service/impl/EngineerCalendarServiceImpl.java
project-order/src/test/java/com/dituhui/pea/order/common/CapacityUtilsTest.java
project-order/src/main/java/com/dituhui/pea/order/common/CapacityUtils.java
View file @
f1b13ca
...
...
@@ -179,6 +179,31 @@ public class CapacityUtils {
.
distinct
().
collect
(
Collectors
.
toList
());
}
public
static
List
<
OccupyInfoDetail
>
intervalTime
(
LocalDateTime
startTime
,
LocalDateTime
endTime
,
List
<
OccupyInfoDetail
>
timeUnitList
)
{
timeUnitList
=
calculateUnion
(
timeUnitList
);
timeUnitList
.
sort
(
Comparator
.
comparing
(
OccupyInfo:
:
getBeginTime
));
int
uniSize
=
0
;
LocalDateTime
currentStart
=
startTime
;
ArrayList
<
OccupyInfoDetail
>
result
=
new
ArrayList
<>();
while
(
uniSize
<
timeUnitList
.
size
())
{
OccupyInfoDetail
timeUnit
=
timeUnitList
.
get
(
uniSize
);
//当前开始时间 < 时间片开始, 空闲时间为 当前开始时间, 时间片开始时间
if
(
currentStart
.
isBefore
(
timeUnit
.
getBeginTime
()))
{
OccupyInfoDetail
resultUnit
=
new
OccupyInfoDetail
(
currentStart
,
timeUnit
.
getBeginTime
());
result
.
add
(
resultUnit
);
}
currentStart
=
timeUnit
.
getEndTime
();
if
(
uniSize
+
1
==
timeUnitList
.
size
()
&&
currentStart
.
isBefore
(
endTime
))
{
OccupyInfoDetail
resultUnit
=
new
OccupyInfoDetail
(
currentStart
,
endTime
);
result
.
add
(
resultUnit
);
}
uniSize
+=
1
;
}
return
result
;
}
/**
* 定义一个方法,接受一个OccupyInfoDetail列表,返回它们的并集列表
* 1. 将所有时间片按照开始时间从小到大排序。
...
...
project-order/src/main/java/com/dituhui/pea/order/controller/TestController.java
View file @
f1b13ca
package
com
.
dituhui
.
pea
.
order
.
controller
;
import
com.dituhui.pea.common.Result
;
import
com.dituhui.pea.order.dto.param.CapacityQueryDTO
;
import
com.dituhui.pea.order.service.impl.BeanRemoteServiceImpl
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.springframework.validation.annotation.Validated
;
import
org.springframework.web.bind.annotation.GetMapping
;
import
org.springframework.web.bind.annotation.PostMapping
;
import
org.springframework.web.bind.annotation.RequestBody
;
import
org.springframework.web.bind.annotation.RequestMapping
;
import
org.springframework.web.bind.annotation.RestController
;
import
java.time.LocalDate
;
import
java.time.LocalTime
;
//TODO 仅用于联通测试
@RestController
...
...
@@ -16,7 +23,7 @@ import org.springframework.web.bind.annotation.RestController;
@Slf4j
public
class
TestController
{
private
final
BeanRemoteServiceImpl
beanRemoteServiceImpl
;
private
final
com
.
dituhui
.
pea
.
order
.
service
.
CapacityQueryService
CapacityQueryService
;
@GetMapping
(
"/test"
)
public
Result
<?>
test
()
{
...
...
@@ -29,4 +36,18 @@ public class TestController {
return
beanRemoteServiceImpl
.
serviceOrgList
();
}
@PostMapping
(
"/capacity/test"
)
public
Result
<?>
capacityQuery1
()
{
CapacityQueryDTO
.
Service
service
=
new
CapacityQueryDTO
.
Service
();
service
.
setBrand
(
"博世/西门子以及其他品牌"
);
service
.
setProductType
(
"洗碗机"
);
service
.
setServiceType
(
"标准维修"
);
CapacityQueryDTO
.
Segment
segment
=
CapacityQueryService
.
queryCapacityByTeam
(
"1689896351243501568"
,
service
,
LocalDate
.
now
(),
LocalTime
.
of
(
15
,
0
),
LocalTime
.
of
(
16
,
0
));
return
Result
.
success
(
segment
);
}
}
project-order/src/main/java/com/dituhui/pea/order/service/EngineerCalendarService.java
View file @
f1b13ca
...
...
@@ -60,4 +60,15 @@ public interface EngineerCalendarService {
* @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
);
}
project-order/src/main/java/com/dituhui/pea/order/service/impl/EngineerCalendarServiceImpl.java
View file @
f1b13ca
...
...
@@ -611,6 +611,57 @@ public class EngineerCalendarServiceImpl implements EngineerCalendarService {
return
workDay
.
contains
(
String
.
valueOf
(
dayOfWeek
));
}
@Override
public
int
[][]
timeWindows
(
String
engineerCode
,
String
teamId
,
LocalDate
targetDate
)
{
EngineerInfoEntity
engineerInfoEntity
=
engineerInfoDao
.
selectEngineerByEngineerCodeAndTeamId
(
engineerCode
,
teamId
);
if
(
Objects
.
isNull
(
engineerInfoEntity
))
{
return
new
int
[
0
][];
}
OrgTeamEntity
e
=
orgTeamDao
.
getByTeamId
(
teamId
);
List
<
String
>
workDay
=
List
.
of
(
e
.
getWorkdays
().
split
(
","
));
final
int
dayOfWeek
=
targetDate
.
getDayOfWeek
().
getValue
();
if
(!
workDay
.
contains
(
String
.
valueOf
(
dayOfWeek
)))
{
return
new
int
[
0
][];
}
//是工作日, 取当前天的日历事件
EngineerBusinessEntity
businessEntity
=
engineerBusinessDao
.
getByEngineerCode
(
engineerCode
);
LocalDateTime
workStartTime
=
DateUtils
.
localDateTimeFromStr
(
String
.
format
(
"%s %s:00"
,
targetDate
,
businessEntity
.
getWorkOn
()));
LocalDateTime
workEndTime
=
DateUtils
.
localDateTimeFromStr
(
String
.
format
(
"%s %s:00"
,
targetDate
,
businessEntity
.
getWorkOff
()));
final
LocalDateTime
minDate
=
LocalDateTime
.
MIN
;
List
<
OccupyInfoDetail
>
configs
=
getEngineerWorkDayCalendar
(
engineerCode
,
targetDate
);
if
(
CollectionUtils
.
isEmpty
(
configs
))
{
return
new
int
[][]{{(
int
)
Duration
.
between
(
workStartTime
,
minDate
).
abs
().
toMinutes
(),
(
int
)
Duration
.
between
(
workEndTime
,
minDate
).
abs
().
toMinutes
()}};
}
// 多个休息时间不存在交集
List
<
OccupyInfoDetail
>
usedTimeInfo
=
configs
.
stream
()
.
map
(
t
->
{
OccupyInfoDetail
usedTime
=
new
OccupyInfoDetail
();
usedTime
.
setBeginTime
(
t
.
getBeginTime
());
usedTime
.
setEndTime
(
t
.
getEndTime
());
return
usedTime
;
}).
collect
(
Collectors
.
toList
());
//工作时间与时间时间并集求差集
List
<
OccupyInfoDetail
>
result
=
CapacityUtils
.
intervalTime
(
workStartTime
,
workEndTime
,
usedTimeInfo
);
if
(
CollectionUtils
.
isEmpty
(
result
))
{
return
new
int
[
0
][];
}
int
[][]
ints
=
new
int
[
result
.
size
()][
2
];
for
(
int
i
=
0
;
i
<
result
.
size
();
i
++)
{
OccupyInfoDetail
occupy
=
result
.
get
(
i
);
int
start
=
(
int
)
Duration
.
between
(
occupy
.
getBeginTime
(),
minDate
).
abs
().
toMinutes
();
int
end
=
(
int
)
Duration
.
between
(
occupy
.
getEndTime
(),
minDate
).
abs
().
toMinutes
();
ints
[
i
][
0
]
=
start
;
ints
[
i
][
1
]
=
end
;
}
return
ints
;
}
private
EngineerCalendarDTO
.
Calendar
getEmptyCalendar
(
String
teamId
,
String
date
)
{
// 初始化一天的日历
EngineerCalendarDTO
.
Calendar
calendar
=
new
EngineerCalendarDTO
.
Calendar
();
...
...
project-order/src/test/java/com/dituhui/pea/order/common/CapacityUtilsTest.java
View file @
f1b13ca
...
...
@@ -4,6 +4,7 @@ import org.junit.jupiter.api.Assertions;
import
org.junit.jupiter.api.Test
;
import
org.junit.jupiter.api.extension.ExtendWith
;
import
org.mockito.junit.jupiter.MockitoExtension
;
import
org.springframework.util.CollectionUtils
;
import
java.time.Duration
;
import
java.time.LocalDate
;
...
...
@@ -16,6 +17,64 @@ import java.util.List;
public
class
CapacityUtilsTest
{
@Test
public
void
testIntervalTime
()
{
LocalDateTime
fixedStart
=
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
0
));
LocalDateTime
fixedEnd
=
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
18
,
0
));
ArrayList
<
OccupyInfoDetail
>
test
=
new
ArrayList
<>();
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
0
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
25
))));
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
25
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
45
))));
List
<
OccupyInfoDetail
>
occupyInfoDetails
=
CapacityUtils
.
intervalTime
(
fixedStart
,
fixedEnd
,
test
);
Assertions
.
assertEquals
(
1
,
occupyInfoDetails
.
size
());
test
.
clear
();
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
0
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
25
))));
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
29
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
45
))));
occupyInfoDetails
=
CapacityUtils
.
intervalTime
(
fixedStart
,
fixedEnd
,
test
);
Assertions
.
assertEquals
(
2
,
occupyInfoDetails
.
size
());
test
.
clear
();
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
0
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
45
))));
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
10
,
30
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
12
,
0
))));
occupyInfoDetails
=
CapacityUtils
.
intervalTime
(
fixedStart
,
fixedEnd
,
test
);
Assertions
.
assertEquals
(
3
,
occupyInfoDetails
.
size
());
test
.
clear
();
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
0
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
45
))));
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
16
,
30
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
18
,
0
))));
occupyInfoDetails
=
CapacityUtils
.
intervalTime
(
fixedStart
,
fixedEnd
,
test
);
Assertions
.
assertEquals
(
2
,
occupyInfoDetails
.
size
());
test
.
clear
();
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
0
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
18
,
0
))));
occupyInfoDetails
=
CapacityUtils
.
intervalTime
(
fixedStart
,
fixedEnd
,
test
);
Assertions
.
assertTrue
(
CollectionUtils
.
isEmpty
(
occupyInfoDetails
));
test
.
clear
();
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
7
,
0
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
45
))));
test
.
add
(
new
OccupyInfoDetail
(
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
16
,
30
)),
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
18
,
0
))));
occupyInfoDetails
=
CapacityUtils
.
intervalTime
(
fixedStart
,
fixedEnd
,
test
);
Assertions
.
assertEquals
(
1
,
occupyInfoDetails
.
size
());
}
@Test
public
void
testMaxRemainBlock
()
{
LocalDateTime
sliceStart
=
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
8
,
0
));
LocalDateTime
sliceEnd
=
LocalDateTime
.
of
(
LocalDate
.
now
(),
LocalTime
.
of
(
9
,
0
));
...
...
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