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 7de5cbdd
authored
Nov 13, 2023
by
刘鑫
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(申请加单): 申请加单除排除一家多单和需要配件逻辑
1 parent
d856f1fb
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
210 additions
and
28 deletions
project-order/pom.xml
project-order/src/main/java/com/dituhui/pea/order/common/Stapial4jUtil.java
project-order/src/main/java/com/dituhui/pea/order/controller/PeaApiController.java
project-order/src/main/java/com/dituhui/pea/order/dao/EngineerSkillGroupDao.java
project-order/src/main/java/com/dituhui/pea/order/dao/OrderInfoDao.java
project-order/src/main/java/com/dituhui/pea/order/entity/SkillGroupEntity.java
project-order/src/main/java/com/dituhui/pea/order/service/PeaOuterAPIService.java
project-order/src/main/java/com/dituhui/pea/order/service/impl/PeaOuterAPIServiceImpl.java
project-order/pom.xml
View file @
7de5cbd
...
...
@@ -82,6 +82,11 @@
<artifactId>
geodesy
</artifactId>
<version>
1.1.3
</version>
</dependency>
<dependency>
<groupId>
org.locationtech.spatial4j
</groupId>
<artifactId>
spatial4j
</artifactId>
<version>
0.8
</version>
</dependency>
<dependency>
<groupId>
org.springframework.boot
</groupId>
...
...
project-order/src/main/java/com/dituhui/pea/order/common/Stapial4jUtil.java
0 → 100644
View file @
7de5cbd
package
com
.
dituhui
.
pea
.
order
.
common
;
import
org.locationtech.spatial4j.context.SpatialContext
;
import
org.locationtech.spatial4j.distance.DistanceUtils
;
import
org.locationtech.spatial4j.shape.Rectangle
;
/**
* 计算外接正方形坐标 以及距离
*/
public
final
class
Stapial4jUtil
{
private
static
final
SpatialContext
SPATIAL_CONTEXT
=
SpatialContext
.
GEO
;
/**
* 利用开源库计算外接正方形坐标
*
* @param distance 距离,单位km
* @param userLng 当前经度
* @param userLat 当前纬度
* @return
*/
public
static
Rectangle
getRectangle
(
double
distance
,
double
userLng
,
double
userLat
)
{
return
SPATIAL_CONTEXT
.
getDistCalc
()
.
calcBoxByDistFromPt
(
SPATIAL_CONTEXT
.
makePoint
(
userLng
,
userLat
),
distance
*
DistanceUtils
.
KM_TO_DEG
,
SPATIAL_CONTEXT
,
null
);
}
/***
* 球面中,两点间的距离(第三方库方法)
*
* @param longitude 经度1
* @param latitude 纬度1
* @param userLng 经度2
* @param userLat 纬度2
* @return 返回距离,单位km
*/
public
static
double
getDistance
(
double
longitude
,
double
latitude
,
double
userLng
,
double
userLat
)
{
return
SPATIAL_CONTEXT
.
calcDistance
(
SPATIAL_CONTEXT
.
makePoint
(
userLng
,
userLat
),
SPATIAL_CONTEXT
.
makePoint
(
longitude
,
latitude
))
*
DistanceUtils
.
DEG_TO_KM
;
}
/**
* 工具类私有化构造方法, 不允许外部调用
*/
private
Stapial4jUtil
()
{
}
}
project-order/src/main/java/com/dituhui/pea/order/controller/PeaApiController.java
View file @
7de5cbd
...
...
@@ -23,7 +23,10 @@ import com.dituhui.pea.order.service.OrderCreateService;
import
com.dituhui.pea.order.service.OrderInfoService
;
import
com.dituhui.pea.order.service.PeaOuterAPIService
;
import
com.fasterxml.jackson.annotation.JsonFormat
;
import
lombok.AllArgsConstructor
;
import
lombok.Getter
;
import
lombok.RequiredArgsConstructor
;
import
lombok.Setter
;
import
org.apache.commons.lang3.StringUtils
;
import
org.springframework.beans.factory.annotation.Autowired
;
import
org.springframework.format.annotation.DateTimeFormat
;
...
...
@@ -245,10 +248,24 @@ public class PeaApiController {
* @apiNote 技术员发起申请,根据技术员当前位置和空闲时间段,返回附近的n张尚未分配,且不需要备件的工单,技术员逐条顺序联系客户确认
*/
@PostMapping
(
"/order/increase/query"
)
public
Result
<
Order
>
orderIncrease
(
@Validated
@RequestBody
EngineerOrderParam
requestParam
)
{
public
Result
<
Order
Result
>
orderIncrease
(
@Validated
@RequestBody
EngineerOrderParam
requestParam
)
{
return
Result
.
success
(
peaOuterAPIService
.
orderIncreaseQuery
(
requestParam
.
getEngineerCode
(),
requestParam
.
getLocation
(),
requestParam
.
getIdleDuration
()));
List
<
Order
>
orders
=
peaOuterAPIService
.
orderIncreaseQuery
(
requestParam
.
getEngineerCode
(),
requestParam
.
getLocation
(),
requestParam
.
getIdleDuration
());
return
Result
.
success
(
new
OrderResult
(
orders
));
}
/**
* 申请加单返回值
*/
@Setter
@Getter
@AllArgsConstructor
class
OrderResult
{
/**
* 待处理工单列表
*/
private
List
<
Order
>
orders
;
}
/**
...
...
project-order/src/main/java/com/dituhui/pea/order/dao/EngineerSkillGroupDao.java
View file @
7de5cbd
package
com
.
dituhui
.
pea
.
order
.
dao
;
import
com.dituhui.pea.order.entity.EngineerSkillGroupEntity
;
import
com.dituhui.pea.order.entity.SkillGroupEntity
;
import
org.springframework.data.jpa.repository.JpaRepository
;
import
org.springframework.data.jpa.repository.Query
;
import
org.springframework.stereotype.Repository
;
import
java.util.List
;
...
...
@@ -20,4 +22,14 @@ public interface EngineerSkillGroupDao extends JpaRepository<EngineerSkillGroupE
List
<
EngineerSkillGroupEntity
>
findBySkillGroupCode
(
String
skillGroupCode
);
List
<
EngineerSkillGroupEntity
>
findBySkillGroupCodeAndStatus
(
String
skillGroupCode
,
boolean
status
);
/**
* 工程师绑定的技能组
*
* @param engineerCode 工程师代码
* @return 工程师技能组信息
*/
@Query
(
value
=
"SELECT esg.* FROM engineer_skill_group esg LEFT JOIN skill_group sg ON sg.skill_group_code = esg.skill_group_code \n"
+
" WHERE esg.engineer_code = :engineerCode"
,
nativeQuery
=
true
)
List
<
EngineerSkillGroupEntity
>
getEngineerSkillGroup
(
String
engineerCode
);
}
project-order/src/main/java/com/dituhui/pea/order/dao/OrderInfoDao.java
View file @
7de5cbd
...
...
@@ -7,6 +7,7 @@ import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import
org.springframework.data.jpa.repository.Query
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.util.List
;
public
interface
OrderInfoDao
extends
JpaRepository
<
OrderInfoEntity
,
Long
>,
JpaSpecificationExecutor
<
OrderInfoEntity
>
{
...
...
@@ -50,4 +51,30 @@ public interface OrderInfoDao extends JpaRepository<OrderInfoEntity, Long>, JpaS
*/
@Query
(
value
=
"SELECT * FROM order_info oi WHERE (engineer_code = :engineerCode OR engineer_code_sub =:engineerCode) AND dt = :targetDate"
,
nativeQuery
=
true
)
List
<
OrderInfoEntity
>
getEngineerDateOrder
(
String
engineerCode
,
String
targetDate
);
/**
* 获取矩形范围内的工单
*
* @param maxLongitude 矩形中最大的经度
* @param minLongitude 矩形中最小的经度
* @param maxLatitude 矩形中最大的经度
* @param minLatitude 矩形中最小的经度
* @return 矩形范围内的工单
*/
@Query
(
value
=
"SELECT * FROM order_info oi WHERE CONVERT(oi.x, decimal(18,8)) < :maxLongitude AND CONVERT(oi.x, decimal(18,8)) >= :minLongitude "
+
" AND CONVERT(oi.y, decimal(18,8)) < :maxLatitude AND CONVERT(oi.y, decimal(18,8)) >= :minLatitude"
,
nativeQuery
=
true
)
List
<
OrderInfoEntity
>
getRectangleOrder
(
Double
maxLongitude
,
Double
minLongitude
,
Double
maxLatitude
,
Double
minLatitude
);
/**
* 查询指定时间后满足技能要求 且未分配的工单信息
*
* @param skillGroupCode 技能组信息
* @param dateTime 时间
* @return 满足条件的工单信息
*/
@Query
(
value
=
"SELECT oi.* FROM skill_info si LEFT JOIN order_info oi ON oi.brand = si.brand AND oi.type = si.type AND oi.skill = si.skill "
+
" WHERE si.skill_group_code = :skillGroupCode AND oi.expect_time_begin >= :dateTime "
+
" AND (appointment_status = 'INIT' AND order_status != 'CANCELED') "
,
nativeQuery
=
true
)
List
<
OrderInfoEntity
>
getSkillGroupOrder
(
String
skillGroupCode
,
LocalDateTime
dateTime
);
}
project-order/src/main/java/com/dituhui/pea/order/entity/SkillGroupEntity.java
View file @
7de5cbd
...
...
@@ -2,7 +2,12 @@ package com.dituhui.pea.order.entity;
import
lombok.Data
;
import
javax.persistence.*
;
import
javax.persistence.Column
;
import
javax.persistence.Entity
;
import
javax.persistence.GeneratedValue
;
import
javax.persistence.GenerationType
;
import
javax.persistence.Id
;
import
javax.persistence.Table
;
import
java.time.LocalDateTime
;
@Data
...
...
@@ -23,7 +28,7 @@ public class SkillGroupEntity {
@Column
(
length
=
50
,
nullable
=
false
)
private
String
description
;
@Column
(
length
=
20
,
nullable
=
false
)
@Column
(
name
=
"category"
,
length
=
20
,
nullable
=
false
)
private
String
category
;
@Column
(
length
=
100
,
nullable
=
false
)
...
...
project-order/src/main/java/com/dituhui/pea/order/service/PeaOuterAPIService.java
View file @
7de5cbd
...
...
@@ -33,7 +33,7 @@ public interface PeaOuterAPIService {
* @param idleDuration 空闲时长 至少空闲多久以上,单位:分钟
* @return 不需要的备件且符合条件的多个未分配工单
*/
Order
orderIncreaseQuery
(
String
engineerCode
,
Location
location
,
Integer
idleDuration
);
List
<
Order
>
orderIncreaseQuery
(
String
engineerCode
,
Location
location
,
Integer
idleDuration
);
OrderDTO
.
AppointResult
engineerCode
(
String
engineerCode
,
LocalDate
localDate
);
...
...
project-order/src/main/java/com/dituhui/pea/order/service/impl/PeaOuterAPIServiceImpl.java
View file @
7de5cbd
package
com
.
dituhui
.
pea
.
order
.
service
.
impl
;
import
com.dituhui.pea.common.BusinessException
;
import
com.dituhui.pea.order.common.Stapial4jUtil
;
import
com.dituhui.pea.order.common.jackson.DateUtil
;
import
com.dituhui.pea.order.dao.EngineerSkillGroupDao
;
import
com.dituhui.pea.order.dao.OrderInfoDao
;
import
com.dituhui.pea.order.dao.OrgGroupDao
;
import
com.dituhui.pea.order.dao.SkillGroupDao
;
import
com.dituhui.pea.order.dto.param.EstimateDTO
;
import
com.dituhui.pea.order.dto.param.Location
;
import
com.dituhui.pea.order.dto.param.Order
;
import
com.dituhui.pea.order.dto.param.OrderDTO
;
import
com.dituhui.pea.order.entity.EngineerSkillGroupEntity
;
import
com.dituhui.pea.order.entity.OrderInfoEntity
;
import
com.dituhui.pea.order.entity.OrgGroupEntity
;
import
com.dituhui.pea.order.en
ums.OrderFlowEnum
;
import
com.dituhui.pea.order.en
tity.SkillGroupEntity
;
import
com.dituhui.pea.order.service.PeaOuterAPIService
;
import
lombok.RequiredArgsConstructor
;
import
lombok.extern.slf4j.Slf4j
;
import
org.apache.commons.collections4.CollectionUtils
;
import
org.locationtech.spatial4j.shape.Rectangle
;
import
org.springframework.stereotype.Service
;
import
java.math.BigDecimal
;
import
java.time.LocalDate
;
import
java.time.LocalDateTime
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Objects
;
import
java.util.Optional
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
/**
...
...
@@ -34,6 +46,7 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
*/
private
final
OrgGroupDao
orgGroupDao
;
private
final
OrderInfoDao
orderInfoDao
;
private
final
EngineerSkillGroupDao
engineerSkillGroupDao
;
@Override
public
EstimateDTO
.
VisitResult
estimateVisitService
(
String
brand
,
String
productType
,
String
serviceType
,
Location
clientLocation
)
{
...
...
@@ -60,29 +73,82 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
@Override
public
Order
orderIncreaseQuery
(
String
engineerCode
,
Location
location
,
Integer
idleDuration
)
{
OrderInfoEntity
sss
=
orderInfoDao
.
findTopBySkillAndAppointmentStatus
(
"标准安装"
,
OrderFlowEnum
.
INIT
.
name
());
Order
order
=
new
Order
();
order
.
setOrderId
(
sss
.
getOrderId
());
order
.
setName
(
sss
.
getName
());
order
.
setPhone
(
sss
.
getPhone
());
order
.
setBrand
(
sss
.
getBrand
());
order
.
setProductType
(
sss
.
getType
());
order
.
setFaultDescribe
(
sss
.
getFaultDescribe
());
order
.
setExpectTimeBegin
(
DateUtil
.
toDate
(
sss
.
getExpectTimeBegin
()));
order
.
setExpectTimeEnd
(
DateUtil
.
toDate
(
sss
.
getExpectTimeEnd
()));
order
.
setApplyNote
(
sss
.
getApplyNote
());
public
List
<
Order
>
orderIncreaseQuery
(
String
engineerCode
,
Location
location
,
Integer
idleDuration
)
{
//查询工程师所有技能组
List
<
EngineerSkillGroupEntity
>
skillGroups
=
engineerSkillGroupDao
.
getEngineerSkillGroup
(
engineerCode
);
if
(
CollectionUtils
.
isEmpty
(
skillGroups
))
{
throw
new
BusinessException
(
"当前工程师未配置技能信息"
);
}
LocalDateTime
targetTime
=
LocalDateTime
.
now
();
Set
<
OrderInfoEntity
>
orderList
=
new
HashSet
<>();
//查询符合条件(技能、)的工单
for
(
EngineerSkillGroupEntity
skillGroup
:
skillGroups
)
{
final
String
groupCode
=
skillGroup
.
getSkillGroupCode
();
List
<
OrderInfoEntity
>
skillGroupOrder
=
orderInfoDao
.
getSkillGroupOrder
(
groupCode
,
targetTime
);
orderList
.
addAll
(
skillGroupOrder
);
}
//TODO 排除一家多台、需要配件工单
//每分钟0.3167 KM, 每小时19KM
//查询 地址范围内工单(过滤掉所需耗时大于空闲时长的工单), 范围根据空闲时长计算
double
speed
=
0.3167
;
double
distance
=
speed
*
idleDuration
;
List
<
OrderInfoEntity
>
infoEntities
=
nearBySearch
(
distance
,
location
.
getLongitude
(),
location
.
getLatitude
(),
orderList
);
infoEntities
=
Optional
.
ofNullable
(
infoEntities
).
orElse
(
Collections
.
emptyList
())
.
stream
()
//过滤掉所需耗时大于空闲时长的工单
.
filter
(
order
->
order
.
getTakeTime
()
<=
idleDuration
)
.
collect
(
Collectors
.
toList
());
Location
orderLocation
=
new
Location
();
orderLocation
.
setAddress
(
sss
.
getAddress
());
orderLocation
.
setLongitude
(
Double
.
parseDouble
(
sss
.
getX
()));
orderLocation
.
setLatitude
(
Double
.
parseDouble
(
sss
.
getY
()));
order
.
setLocation
(
orderLocation
);
return
infoEntities
.
stream
().
map
(
sss
->
{
Order
order
=
new
Order
();
order
.
setOrderId
(
sss
.
getOrderId
());
order
.
setName
(
sss
.
getName
());
order
.
setPhone
(
sss
.
getPhone
());
order
.
setBrand
(
sss
.
getBrand
());
order
.
setProductType
(
sss
.
getType
());
order
.
setServiceType
(
sss
.
getSkill
());
order
.
setTakeTime
(
sss
.
getTakeTime
());
order
.
setFaultDescribe
(
sss
.
getFaultDescribe
());
order
.
setExpectTimeBegin
(
DateUtil
.
toDate
(
sss
.
getExpectTimeBegin
()));
order
.
setExpectTimeEnd
(
DateUtil
.
toDate
(
sss
.
getExpectTimeEnd
()));
order
.
setApplyNote
(
sss
.
getApplyNote
());
Location
orderLocation
=
new
Location
();
orderLocation
.
setAddress
(
sss
.
getAddress
());
orderLocation
.
setLongitude
(
Double
.
parseDouble
(
sss
.
getX
()));
orderLocation
.
setLatitude
(
Double
.
parseDouble
(
sss
.
getY
()));
order
.
setLocation
(
orderLocation
);
return
order
;
}).
collect
(
Collectors
.
toList
());
}
return
order
;
public
List
<
OrderInfoEntity
>
nearBySearch
(
double
distance
,
double
userLng
,
double
userLat
,
Set
<
OrderInfoEntity
>
orderList
)
{
//1 获取外切正方形最大最小经纬度
Rectangle
rectangle
=
Stapial4jUtil
.
getRectangle
(
distance
,
userLng
,
userLat
);
BigDecimal
maxX
=
BigDecimal
.
valueOf
(
rectangle
.
getMaxX
());
BigDecimal
minX
=
BigDecimal
.
valueOf
(
rectangle
.
getMinX
());
BigDecimal
minY
=
BigDecimal
.
valueOf
(
rectangle
.
getMinY
());
BigDecimal
maxY
=
BigDecimal
.
valueOf
(
rectangle
.
getMaxY
());
//2.获取位置在正方形内的所有工单
List
<
OrderInfoEntity
>
rectangleOrder
=
new
ArrayList
<>(
orderList
);
rectangleOrder
=
rectangleOrder
.
stream
().
filter
(
order
->
{
//过滤满足距离要求的工单
BigDecimal
longitude
=
new
BigDecimal
(
order
.
getX
());
BigDecimal
latitude
=
new
BigDecimal
(
order
.
getY
());
return
(
longitude
.
compareTo
(
maxX
)
<
0
&&
longitude
.
compareTo
(
minX
)
>=
0
)
&&
(
latitude
.
compareTo
(
maxY
)
<
0
&&
latitude
.
compareTo
(
minY
)
>=
0
);
}
)
//3.剔除半径超过指定距离的多余工单
.
filter
(
a
->
Stapial4jUtil
.
getDistance
(
Double
.
parseDouble
(
a
.
getX
()),
Double
.
parseDouble
(
a
.
getY
()),
userLng
,
userLat
)
<=
distance
)
.
collect
(
Collectors
.
toList
());
return
rectangleOrder
;
}
@Override
...
...
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