feat(positioning): 实现人员定位状态管理功能

dev
zhaokai 2026-08-01 10:44:54 +08:00
parent 061f052080
commit 1b26af67e7
6 changed files with 96 additions and 13 deletions

View File

@ -116,7 +116,7 @@ public class AreaQueryExe {
} }
private void countPerson(List<AreaStatAccumulator> areas, BiCompanyOnlinePersonCO person) { private void countPerson(List<AreaStatAccumulator> areas, BiCompanyOnlinePersonCO person) {
if (person == null || person.getLon() == null || person.getLat() == null) { if (!biPersonLocationProvider.isOnline(person) || person.getLon() == null || person.getLat() == null) {
return; return;
} }
for (AreaStatAccumulator area : areas) { for (AreaStatAccumulator area : areas) {

View File

@ -1,6 +1,9 @@
package com.zcloud.personnel.positioning.command.query; package com.zcloud.personnel.positioning.command.query;
import com.alibaba.cola.dto.PageResponse;
import com.zcloud.personnel.positioning.dto.PositionPersonPageQry;
import com.zcloud.personnel.positioning.dto.clientobject.BiCompanyOnlinePersonCO; import com.zcloud.personnel.positioning.dto.clientobject.BiCompanyOnlinePersonCO;
import com.zcloud.personnel.positioning.dto.clientobject.PositionPersonCO;
import com.zcloud.personnel.positioning.persistence.dataobject.BiPersonPositionUserDO; import com.zcloud.personnel.positioning.persistence.dataobject.BiPersonPositionUserDO;
import com.zcloud.personnel.positioning.persistence.repository.UserRepository; import com.zcloud.personnel.positioning.persistence.repository.UserRepository;
import lombok.Data; import lombok.Data;
@ -27,8 +30,12 @@ import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
public class BiPersonLocationProvider { public class BiPersonLocationProvider {
private static final Logger LOGGER = LoggerFactory.getLogger(BiPersonLocationProvider.class); private static final Logger LOGGER = LoggerFactory.getLogger(BiPersonLocationProvider.class);
private static final int PAGE_SIZE = 10000;
private static final String STATUS_ONLINE = "ONLINE";
private static final String STATUS_OFFLINE = "OFFLINE";
private final UserRepository userRepository; private final UserRepository userRepository;
private final PositionPersonQueryExe positionPersonQueryExe;
public List<BiCompanyOnlinePersonCO> listCompanyOnlinePersons(String corpinfoId, public List<BiCompanyOnlinePersonCO> listCompanyOnlinePersons(String corpinfoId,
String corpinfoName, String corpinfoName,
@ -51,13 +58,56 @@ public class BiPersonLocationProvider {
return result; return result;
} }
public boolean isOnline(BiCompanyOnlinePersonCO person) {
return person != null && STATUS_ONLINE.equalsIgnoreCase(person.getLocationStatus());
}
private List<ThirdPartyPersonLocation> loadThirdPartyPersonLocations(String corpinfoId, private List<ThirdPartyPersonLocation> loadThirdPartyPersonLocations(String corpinfoId,
String corpinfoName, String corpinfoName,
String corpCode) { String corpCode) {
LOGGER.info("TODO 待接入第三方人员定位接口corpinfoId={}corpinfoName={}corpCode={}", LOGGER.info("开始调用企业人员定位查询corpinfoId={}corpinfoName={}corpCode={}",
corpinfoId, corpinfoName, corpCode); corpinfoId, corpinfoName, corpCode);
// TODO 后续只在这里接入第三方接口根据企业id获取在线人员、经纬度、定位时间、人员唯一标识。 List<ThirdPartyPersonLocation> result = new ArrayList<>();
return Collections.emptyList(); int pageIndex = 1;
int totalCount = Integer.MAX_VALUE;
while (result.size() < totalCount) {
PositionPersonPageQry qry = new PositionPersonPageQry();
qry.setCorpinfoId(corpinfoId);
qry.setPageIndex(pageIndex);
qry.setPageSize(PAGE_SIZE);
PageResponse<PositionPersonCO> page = positionPersonQueryExe.list(qry);
if (page == null || page.getData() == null || page.getData().isEmpty()) {
break;
}
totalCount = page.getTotalCount();
for (PositionPersonCO row : page.getData()) {
result.add(toThirdPartyPersonLocation(row));
}
if (page.getData().size() < PAGE_SIZE) {
break;
}
pageIndex++;
}
LOGGER.info("企业人员定位查询完成corpinfoId={},人员状态数量={}", corpinfoId, result.size());
return result;
}
private ThirdPartyPersonLocation toThirdPartyPersonLocation(PositionPersonCO row) {
ThirdPartyPersonLocation location = new ThirdPartyPersonLocation();
location.setUserId(row.getUserId());
location.setUsername(row.getLocalStaffNo());
location.setPersonName(row.getStaffName());
location.setStaffNo(row.getLocalStaffNo());
location.setMobileNo(row.getMobileNo());
location.setIdCardNo(row.getIdCardNo());
location.setTerminalNo(row.getTerminalNo());
location.setLocationStatus(normalizeStatus(row.getLocationStatus()));
location.setLocationStatusName(row.getLocationStatusName());
location.setLocationName(firstText(row.getCurrentLocation(), row.getLastLocationName()));
location.setLastLocationTime(row.getLastLocationTime());
location.setLon(row.getLon());
location.setLat(row.getLat());
return location;
} }
private Map<String, BiPersonPositionUserDO> buildUserMap(String corpinfoId) { private Map<String, BiPersonPositionUserDO> buildUserMap(String corpinfoId) {
@ -95,6 +145,9 @@ public class BiPersonLocationProvider {
co.setInternalEmployee(user != null); co.setInternalEmployee(user != null);
co.setPersonType(user == null ? "TEMP" : "INTERNAL"); co.setPersonType(user == null ? "TEMP" : "INTERNAL");
co.setTerminalNo(location.getTerminalNo()); co.setTerminalNo(location.getTerminalNo());
co.setLocationStatus(location.getLocationStatus());
co.setLocationStatusName(firstText(location.getLocationStatusName(),
STATUS_ONLINE.equalsIgnoreCase(location.getLocationStatus()) ? "在线" : "离线"));
co.setCurrentLocation(location.getLocationName()); co.setCurrentLocation(location.getLocationName());
co.setLastLocationTime(location.getLastLocationTime()); co.setLastLocationTime(location.getLastLocationTime());
co.setLon(location.getLon()); co.setLon(location.getLon());
@ -120,6 +173,10 @@ public class BiPersonLocationProvider {
return user; return user;
} }
private String normalizeStatus(String status) {
return STATUS_ONLINE.equalsIgnoreCase(status) ? STATUS_ONLINE : STATUS_OFFLINE;
}
private String firstText(String... values) { private String firstText(String... values) {
if (values == null) { if (values == null) {
return null; return null;
@ -141,6 +198,8 @@ public class BiPersonLocationProvider {
private String mobileNo; private String mobileNo;
private String idCardNo; private String idCardNo;
private String terminalNo; private String terminalNo;
private String locationStatus;
private String locationStatusName;
private String locationName; private String locationName;
private Long lastLocationTime; private Long lastLocationTime;
private BigDecimal lon; private BigDecimal lon;

View File

@ -255,8 +255,8 @@ public class PersonnelPositioningBiQueryExe {
private BiPortPersonVehicleStatCO buildPortPersonVehicleStat(Integer portArea, String portName) { private BiPortPersonVehicleStatCO buildPortPersonVehicleStat(Integer portArea, String portName) {
int personCount = 0; int personCount = 0;
for (BiCorpInfoDO corpInfo : biRepository.listPersonPositionCompanies(null, portArea)) { for (BiCorpInfoDO corpInfo : biRepository.listPersonPositionCompanies(null, portArea)) {
personCount += biPersonLocationProvider.listCompanyOnlinePersons( personCount += countOnlinePersonsOne(biPersonLocationProvider.listCompanyOnlinePersons(
corpInfo.getCorpinfoId(), corpInfo.getCorpName(), corpInfo.getCode()).size(); corpInfo.getCorpinfoId(), corpInfo.getCorpName(), corpInfo.getCode()));
} }
BiPortPersonVehicleStatCO co = new BiPortPersonVehicleStatCO(); BiPortPersonVehicleStatCO co = new BiPortPersonVehicleStatCO();
co.setPortArea(portArea); co.setPortArea(portArea);
@ -277,7 +277,7 @@ public class PersonnelPositioningBiQueryExe {
BiCompanyPersonPositionCO co = new BiCompanyPersonPositionCO(); BiCompanyPersonPositionCO co = new BiCompanyPersonPositionCO();
co.setCorpinfoId(corpInfo.getCorpinfoId()); co.setCorpinfoId(corpInfo.getCorpinfoId());
co.setCorpinfoName(corpInfo.getCorpName()); co.setCorpinfoName(corpInfo.getCorpName());
co.setPersonCount(personList.size()); co.setPersonCount(countOnlinePersonsOne(personList));
co.setVehicleCount(0); co.setVehicleCount(0);
result.add(co); result.add(co);
} }
@ -354,7 +354,7 @@ public class PersonnelPositioningBiQueryExe {
co.setPersonName(user.getPersonName()); co.setPersonName(user.getPersonName());
co.setCorpinfoId(user.getCorpinfoId()); co.setCorpinfoId(user.getCorpinfoId());
co.setCorpinfoName(user.getCorpinfoName()); co.setCorpinfoName(user.getCorpinfoName());
if (location == null) { if (!biPersonLocationProvider.isOnline(location)) {
co.setOnlineStatus("OFFLINE"); co.setOnlineStatus("OFFLINE");
co.setOnlineStatusName("离线"); co.setOnlineStatusName("离线");
return co; return co;
@ -442,8 +442,12 @@ public class PersonnelPositioningBiQueryExe {
List<CorpInfoView> corpInfos = queryCompanyOnlineCorpInfos(query); List<CorpInfoView> corpInfos = queryCompanyOnlineCorpInfos(query);
List<BiCompanyOnlinePersonCO> personList = new ArrayList<>(); List<BiCompanyOnlinePersonCO> personList = new ArrayList<>();
for (CorpInfoView corpInfo : corpInfos) { for (CorpInfoView corpInfo : corpInfos) {
personList.addAll(biPersonLocationProvider.listCompanyOnlinePersons( for (BiCompanyOnlinePersonCO person : biPersonLocationProvider.listCompanyOnlinePersons(
corpInfo.corpinfoId, corpInfo.corpName, corpInfo.code)); corpInfo.corpinfoId, corpInfo.corpName, corpInfo.code)) {
if (biPersonLocationProvider.isOnline(person)) {
personList.add(person);
}
}
} }
personList.sort((left, right) -> { personList.sort((left, right) -> {
long leftTime = left.getLastLocationTime() == null ? 0L : left.getLastLocationTime(); long leftTime = left.getLastLocationTime() == null ? 0L : left.getLastLocationTime();
@ -464,6 +468,19 @@ public class PersonnelPositioningBiQueryExe {
return co; return co;
} }
private int countOnlinePersonsOne(List<BiCompanyOnlinePersonCO> personList) {
int count = 0;
if (personList == null) {
return count;
}
for (BiCompanyOnlinePersonCO person : personList) {
if (biPersonLocationProvider.isOnline(person)) {
count++;
}
}
return count;
}
private List<CorpInfoView> queryCompanyOnlineCorpInfos(BiCompanyOnlinePersonQry qry) { private List<CorpInfoView> queryCompanyOnlineCorpInfos(BiCompanyOnlinePersonQry qry) {
if (qry.getCorpinfoId() != null) { if (qry.getCorpinfoId() != null) {
CorpInfoView corpInfo = queryCorpInfoById(String.valueOf(qry.getCorpinfoId())); CorpInfoView corpInfo = queryCorpInfoById(String.valueOf(qry.getCorpinfoId()));

View File

@ -41,6 +41,12 @@ public class BiCompanyOnlinePersonCO extends ClientObject {
@ApiModelProperty(value = "终端号", name = "terminalNo") @ApiModelProperty(value = "终端号", name = "terminalNo")
private String terminalNo; private String terminalNo;
@ApiModelProperty(value = "定位状态 ONLINE在线 OFFLINE离线", name = "locationStatus")
private String locationStatus;
@ApiModelProperty(value = "定位状态名称", name = "locationStatusName")
private String locationStatusName;
@ApiModelProperty(value = "当前位置", name = "currentLocation") @ApiModelProperty(value = "当前位置", name = "currentLocation")
private String currentLocation; private String currentLocation;

View File

@ -4,6 +4,7 @@ import lombok.Data;
@Data @Data
public class BiCorpInfoDO { public class BiCorpInfoDO {
private String corpinfoId; private String corpinfoId;
private String corpName; private String corpName;
private String code; private String code;

View File

@ -2,7 +2,7 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zcloud.personnel.positioning.persistence.mapper.PersonnelPositioningBiMapper"> <mapper namespace="com.zcloud.personnel.positioning.persistence.mapper.PersonnelPositioningBiMapper">
<sql id="corpInfoSelect"> <sql id="corpInfoSelect">
SELECT corpinfo_id, corp_name, code, address, address_business, address_office, contacts, lr_name, SELECT id,corpinfo_id, corp_name, code, address, address_business, address_office, contacts, lr_name,
corp_type_name, corp_type2_name, corp_type3_name, corp_type4_name, corp_type_name, corp_type2_name, corp_type3_name, corp_type4_name,
longitude, latitude, port_area longitude, latitude, port_area
FROM corp_info WHERE (delete_enum IS NULL OR delete_enum = 'FALSE') FROM corp_info WHERE (delete_enum IS NULL OR delete_enum = 'FALSE')
@ -19,7 +19,7 @@
<select id="listPersonPositionCompanies" resultType="com.zcloud.personnel.positioning.persistence.dataobject.BiCorpInfoDO"> <select id="listPersonPositionCompanies" resultType="com.zcloud.personnel.positioning.persistence.dataobject.BiCorpInfoDO">
<include refid="corpInfoSelect"/> <include refid="corpInfoSelect"/>
<if test="corpinfoId != null and corpinfoId != ''"> <if test="corpinfoId != null and corpinfoId != ''">
AND CAST(corpinfo_id AS CHAR) = CAST(#{corpinfoId} AS CHAR) AND CAST(id AS CHAR) = CAST(#{corpinfoId} AS CHAR)
</if> </if>
<if test="portArea != null"> <if test="portArea != null">
AND port_area = #{portArea} AND port_area = #{portArea}
@ -60,7 +60,7 @@
ORDER BY update_time DESC LIMIT 1 ORDER BY update_time DESC LIMIT 1
</select> </select>
<select id="findCorpById" resultType="com.zcloud.personnel.positioning.persistence.dataobject.BiCorpInfoDO"> <select id="findCorpById" resultType="com.zcloud.personnel.positioning.persistence.dataobject.BiCorpInfoDO">
<include refid="corpInfoSelect"/> AND CAST(corpinfo_id AS CHAR) = CAST(#{corpinfoId} AS CHAR) LIMIT 1 <include refid="corpInfoSelect"/> AND CAST(id AS CHAR) = CAST(#{corpinfoId} AS CHAR) LIMIT 1
</select> </select>
<select id="findCorpByCreditCode" resultType="com.zcloud.personnel.positioning.persistence.dataobject.BiCorpInfoDO"> <select id="findCorpByCreditCode" resultType="com.zcloud.personnel.positioning.persistence.dataobject.BiCorpInfoDO">
<include refid="corpInfoSelect"/> AND code = #{creditCode} LIMIT 1 <include refid="corpInfoSelect"/> AND code = #{creditCode} LIMIT 1