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 dd8f43dd
authored
Nov 13, 2023
by
chamberone
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'develop' of
https://zhangguoping@gitlab.dituhui.com/bsh/project/pr…
…oject.git into develop
2 parents
8f969e73
99e48267
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
227 additions
and
16 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/EngineerInfoDao.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 @
dd8f43d
...
...
@@ -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 @
dd8f43d
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 @
dd8f43d
...
...
@@ -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
;
...
...
@@ -266,10 +269,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/EngineerInfoDao.java
View file @
dd8f43d
...
...
@@ -71,7 +71,7 @@ public interface EngineerInfoDao extends JpaRepository<EngineerInfoEntity, Integ
" LEFT JOIN engineer_info ei ON esg.engineer_code = ei.engineer_code\n"
+
" LEFT JOIN org_team_engineer ote ON ote.engineer_code = ei.engineer_code \n"
+
" WHERE si.brand = :brand AND si.type= :productType AND si.skill = :skill \n"
+
" AND ote.team_id = :teamId AND ote.status = 1"
,
nativeQuery
=
true
)
" AND ote.team_id = :teamId AND ote.status = 1
AND esg.status = 1
"
,
nativeQuery
=
true
)
Set
<
EngineerInfoEntity
>
listByBrandAndTypeAndSkillAndTeamId
(
@Param
(
"brand"
)
String
brand
,
@Param
(
"productType"
)
String
productType
,
@Param
(
"skill"
)
String
skill
,
@Param
(
"teamId"
)
String
teamId
);
...
...
project-order/src/main/java/com/dituhui/pea/order/dao/EngineerSkillGroupDao.java
View file @
dd8f43d
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 AND esg.status = 1"
,
nativeQuery
=
true
)
List
<
EngineerSkillGroupEntity
>
getEngineerSkillGroup
(
String
engineerCode
);
}
project-order/src/main/java/com/dituhui/pea/order/dao/OrderInfoDao.java
View file @
dd8f43d
...
...
@@ -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 @
dd8f43d
...
...
@@ -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 @
dd8f43d
...
...
@@ -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 @
dd8f43d
package
com
.
dituhui
.
pea
.
order
.
service
.
impl
;
import
com.dituhui.pea.common.BusinessException
;
import
com.dituhui.pea.enums.StatusCodeEnum
;
import
com.dituhui.pea.order.common.SaasUtils
;
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.MapBlockInfoDao
;
import
com.dituhui.pea.order.dao.OrderInfoDao
;
import
com.dituhui.pea.order.dao.OrgGroupDao
;
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.MapBlockInfoEntity
;
import
com.dituhui.pea.order.entity.OrderInfoEntity
;
import
com.dituhui.pea.order.entity.OrgGroupEntity
;
import
com.dituhui.pea.order.enums.OrderFlowEnum
;
import
com.dituhui.pea.order.service.PeaOuterAPIService
;
import
com.dituhui.pea.pojo.fendan.FendanDTO
;
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,11 +49,36 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
*/
private
final
OrgGroupDao
orgGroupDao
;
private
final
OrderInfoDao
orderInfoDao
;
private
final
EngineerSkillGroupDao
engineerSkillGroupDao
;
private
final
SaasUtils
saasUtils
;
private
final
MapBlockInfoDao
mapBlockInfoDao
;
@Override
public
EstimateDTO
.
VisitResult
estimateVisitService
(
String
brand
,
String
productType
,
String
serviceType
,
Location
clientLocation
)
{
//TODO 走分单逻辑获取对应的工作队信息
String
teamId
=
"team_suzhou_001"
;
//1:根据经纬度分单获取面
FendanDTO
fendanDTO
=
new
FendanDTO
();
final
String
addressLongLat
=
clientLocation
.
getLongitude
()
+
","
+
clientLocation
.
getLatitude
();
fendanDTO
.
setXy
(
addressLongLat
);
List
<
SaasUtils
.
BlockInfo
>
blockInfoList
=
saasUtils
.
queryBlocksByXy
(
fendanDTO
);
if
(
blockInfoList
.
isEmpty
())
{
throw
new
BusinessException
(
StatusCodeEnum
.
FENDAN_AREA_UNMATCHED
.
getDesc
());
}
//2:根据查询出区划匹配分站信息
List
<
String
>
blockIds
=
blockInfoList
.
stream
().
map
(
SaasUtils
.
BlockInfo
::
getBlockId
).
distinct
().
collect
(
Collectors
.
toList
());
Set
<
MapBlockInfoEntity
>
mapBlockInBlockIdsList
=
new
HashSet
<>();
//区划所在范围所有工作队
for
(
String
blockId
:
blockIds
)
{
List
<
MapBlockInfoEntity
>
mapBlockInfoEntities
=
mapBlockInfoDao
.
findByAreaIdsLike
(
"%"
+
blockId
+
"%"
);
mapBlockInBlockIdsList
.
addAll
(
mapBlockInfoEntities
);
}
//分站、网点ID
List
<
String
>
teamIdList
=
mapBlockInBlockIdsList
.
stream
().
map
(
MapBlockInfoEntity:
:
getTeamId
).
distinct
()
.
collect
(
Collectors
.
toList
());
//走分单逻辑获取对应的工作队信息
final
String
teamId
=
teamIdList
.
get
(
0
);
OrgGroupEntity
orgGroupEntity
=
orgGroupDao
.
queryGroupByTeam
(
teamId
);
//获取分站出站点(仓库点)
Location
outboundLocation
=
new
Location
();
...
...
@@ -51,8 +91,10 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
visitResult
.
setGroupName
(
orgGroupEntity
.
getGroupName
());
visitResult
.
setGroupLocation
(
outboundLocation
);
visitResult
.
setDestination
(
clientLocation
);
//TODO 里程估计调用
visitResult
.
setDistance
(
0
);
// 里程估计调用
double
distance
=
Stapial4jUtil
.
getDistance
(
outboundLocation
.
getLongitude
(),
outboundLocation
.
getLatitude
(),
clientLocation
.
getLongitude
(),
clientLocation
.
getLatitude
())
*
1000
;
visitResult
.
setDistance
((
int
)
distance
);
return
visitResult
;
...
...
@@ -60,16 +102,42 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
@Override
public
Order
orderIncreaseQuery
(
String
engineerCode
,
Location
location
,
Integer
idleDuration
)
{
OrderInfoEntity
sss
=
orderInfoDao
.
findTopBySkillAndAppointmentStatus
(
"标准安装"
,
OrderFlowEnum
.
INIT
.
name
());
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
());
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
()));
...
...
@@ -81,8 +149,35 @@ public class PeaOuterAPIServiceImpl implements PeaOuterAPIService {
orderLocation
.
setLongitude
(
Double
.
parseDouble
(
sss
.
getX
()));
orderLocation
.
setLatitude
(
Double
.
parseDouble
(
sss
.
getY
()));
order
.
setLocation
(
orderLocation
);
return
order
;
}).
collect
(
Collectors
.
toList
());
}
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