feat(sync): 优化大华平台人员车辆同步功能

dev_km_logs
zhaokai 2026-08-14 18:02:17 +08:00
parent d1f59044db
commit 4943b36c0b
19 changed files with 606 additions and 142 deletions

View File

@ -72,16 +72,16 @@ archives:
keepAliveSeconds: 60
message:
template:
firstLevelApplyReceiveAudit: MS000152
closedAreaApplyReceiveAudit: MS000153
firstLevelApplyReceiveCarAudit: MS000154
firstLevelApplyReceiveCarAuditReject: MS000155
firstLevelPersonReceiveAudit: MS000156
firstLevelPersonReceiveAuditReject: MS000157
closedAreaApplyReceiveCarAudit: MS000158
closedAreaApplyReceiveCarAuditReject: MS000159
closedAreaPersonReceiveAudit: MS000160
closedAreaPersonReceiveAuditReject: MS000161
firstLevelApplyReceiveAudit: MS000117
closedAreaApplyReceiveAudit: MS000118
firstLevelApplyReceiveCarAudit: MS000119
firstLevelApplyReceiveCarAuditReject: MS000120
firstLevelPersonReceiveAudit: MS000121
firstLevelPersonReceiveAuditReject: MS000122
closedAreaApplyReceiveCarAudit: MS000123
closedAreaApplyReceiveCarAuditReject: MS000124
closedAreaPersonReceiveAudit: MS000125
closedAreaPersonReceiveAuditReject: MS000126
file:
upload:
url: http://192.168.192.201:8992/file/uploadFiles2/

View File

@ -10,6 +10,7 @@ import com.zcloud.primeport.domain.gateway.MkmjGateGateway;
import com.zcloud.primeport.domain.gateway.PersonApplyGateway;
import com.zcloud.gbscommon.dahua.cmd.DaHuaPersonSyncCmd;
import com.zcloud.primeport.domain.model.PersonApplyE;
import com.zcloud.primeport.domain.model.PersonMessageE;
import com.zcloud.primeport.domain.model.XgfApplyPersonE;
import com.zcloud.primeport.dto.PersonApplyUpdateCmd;
import com.zcloud.primeport.dto.XgfPersonApplyAddCmd;
@ -136,6 +137,42 @@ public class DaHuaPersonSyncExe {
checkPersonSyncResult(daHuaGateway.syncPerson(syncCmd), name);
}
public void syncRelatedPartyAuthorization(Integer mkmjPermission, PersonApplyE person,
PersonMessageE personMessage) {
if (person == null) {
throw new BizException("相关方人员申请记录不存在");
}
String paperNumber = decodeUserCard(person.getUserCard());
Long dahuaPersonId = daHuaGateway.findPersonIdByPaperNumber(paperNumber);
if (Integer.valueOf(2).equals(mkmjPermission)) {
if (dahuaPersonId != null) {
checkResult(daHuaGateway.deletePerson(Collections.singletonList(dahuaPersonId), null),
"删除大华人员失败");
}
return;
}
if (!Integer.valueOf(1).equals(mkmjPermission)) {
throw new BizException("进出港权限只能是有权限或无权限");
}
if (personMessage == null) {
throw new BizException("未找到相关方人员访问时间");
}
if (personMessage.getVisitStartTime() == null || personMessage.getVisitEndTime() == null) {
throw new BizException("相关方人员访问时间不能为空");
}
DaHuaPersonSyncCmd syncCmd = buildSyncCmd(dahuaPersonId, person.getEmployeePersonUserName(),
paperNumber, person.getUserPhone(), person.getUserFaceUrl(),
personMessage.getVisitStartTime(), personMessage.getVisitEndTime());
Map<String, Object> result;
if (dahuaPersonId == null) {
syncCmd.setId(daHuaGateway.generatePersonId());
result = daHuaGateway.syncPerson(syncCmd);
} else {
result = daHuaGateway.updatePerson(syncCmd);
}
checkPersonSyncResult(result, person.getEmployeePersonUserName());
}
private List<String> parseAuthAreaCodes(String gateLevelAuthArea) {
if (gateLevelAuthArea == null || gateLevelAuthArea.trim().isEmpty()) {
throw new BizException("人员授权范围不能为空");

View File

@ -3,14 +3,11 @@ package com.zcloud.primeport.command;
import com.alibaba.cola.exception.BizException;
import com.alibaba.fastjson.JSON;
import com.zcloud.gbscommon.dahua.cmd.DaHuaCarPageCmd;
import com.zcloud.primeport.domain.enums.VehicleBelongTypeEnum;
import com.zcloud.primeport.domain.gateway.DaHuaGateway;
import com.zcloud.primeport.domain.gateway.VehicleApplyGateway;
import com.zcloud.gbscommon.dahua.cmd.DaHuaCarAddCmd;
import com.zcloud.gbscommon.dahua.cmd.DaHuaTempVehicleSaveCmd;
import com.zcloud.primeport.domain.model.VehicleApplyE;
import com.zcloud.primeport.plan.mjDevice.dto.CarEnum;
import jodd.util.Base64;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@ -64,39 +61,13 @@ public class DaHuaVehicleSyncExe {
}
private void syncVehicle(VehicleApplyE vehicle) {
log.info("同步大华车辆: vehicleApplyId={}, licenceNo={}, vehicleBelongType={}",
log.info("同步大华车辆新增接口: vehicleApplyId={}, licenceNo={}, vehicleBelongType={}",
vehicle.getId(), vehicle.getLicenceNo(), vehicle.getVehicleBelongType());
if (isRelatedPartyVehicle(vehicle)) {
log.info("识别为相关方车辆, 走addCar接口");
syncAddedVehicle(vehicle);
return;
}
String idcard = vehicle.getLsUserIdcard();
String decodedIdcard = null;
if (idcard != null && !idcard.isEmpty()) {
try {
decodedIdcard = Base64.decodeToString(idcard);
} catch (Exception e) {
log.warn("身份证base64解码失败: {}", e.getMessage());
decodedIdcard = idcard;
}
}
if (decodedIdcard != null && !decodedIdcard.isEmpty()) {
log.info("车辆有身份证号, userDahuaId={}", vehicle.getUserDahuaId());
if (vehicle.getUserDahuaId() != null) {
log.info("userDahuaId有值, 走addCar接口, ownerId={}", vehicle.getUserDahuaId());
syncAddedVehicleWithOwnerId(vehicle);
} else {
log.info("userDahuaId没值, 走saveTempVehicle接口");
syncTempVehicle(vehicle);
}
} else {
log.info("车辆无身份证号, 走addCar接口");
syncAddedVehicle(vehicle);
DaHuaCarAddCmd cmd = buildCarCmd(vehicle);
if (vehicle.getUserDahuaId() != null) {
cmd.setOwnerId(vehicle.getUserDahuaId());
}
checkResult(daHuaGateway.addCar(cmd), "新增大华车辆失败");
}
public void syncDeletedVehicles(List<VehicleApplyE> vehicles) {
@ -151,13 +122,7 @@ public class DaHuaVehicleSyncExe {
return;
}
if (Integer.valueOf(2).equals(mkmjPermission)) {
List<VehicleApplyE> existingVehicles = new ArrayList<>();
for (VehicleApplyE vehicle : uniqueVehicles.values()) {
if (existsVehicle(vehicle)) {
existingVehicles.add(vehicle);
}
}
syncDeletedVehicles(existingVehicles);
syncDeletedVehicles(new ArrayList<>(uniqueVehicles.values()));
return;
}
throw new BizException("进出港权限只能是有权限或无权限");
@ -201,32 +166,6 @@ public class DaHuaVehicleSyncExe {
return false;
}
private void syncAddedVehicle(VehicleApplyE vehicle) {
checkResult(daHuaGateway.addCar(buildCarCmd(vehicle)), "新增大华车辆失败");
}
private void syncAddedVehicleWithOwnerId(VehicleApplyE vehicle) {
DaHuaCarAddCmd cmd = buildCarCmd(vehicle);
cmd.setOwnerId(vehicle.getUserDahuaId());
checkResult(daHuaGateway.addCar(cmd), "新增大华车辆失败");
}
private void syncTempVehicle(VehicleApplyE vehicle) {
log.info("同步临时车辆到大华平台: licenceNo={}, vehicleApplyId={}", vehicle.getLicenceNo(), vehicle.getId());
DaHuaTempVehicleSaveCmd cmd = buildTempVehicleCmd(vehicle);
Long personId = cmd.getId();
Map<String, Object> result = daHuaGateway.saveTempVehicle(cmd);
checkResult(result, "同步临时车辆到大华失败");
log.info("临时车辆同步成功: licenceNo={}, personId={}", vehicle.getLicenceNo(), personId);
if (personId != null) {
VehicleApplyE updateVehicle = new VehicleApplyE();
updateVehicle.setId(vehicle.getId());
updateVehicle.setUserDahuaId(personId);
vehicleApplyGateway.update(updateVehicle);
log.info("保存大华人员ID成功: vehicleApplyId={}, userDahuaId={}", vehicle.getId(), personId);
}
}
private DaHuaCarAddCmd buildCarCmd(VehicleApplyE vehicle) {
DaHuaCarAddCmd cmd = new DaHuaCarAddCmd();
cmd.setCarNum(vehicle.getLicenceNo());
@ -237,44 +176,6 @@ public class DaHuaVehicleSyncExe {
return cmd;
}
private DaHuaTempVehicleSaveCmd buildTempVehicleCmd(VehicleApplyE vehicle) {
DaHuaTempVehicleSaveCmd cmd = new DaHuaTempVehicleSaveCmd();
Long personId = daHuaGateway.generatePersonId();
cmd.setId(personId);
cmd.setName(vehicle.getEmployeeVehicleUserName());
String idcard = vehicle.getLsUserIdcard();
if (idcard != null && !idcard.isEmpty()) {
try {
idcard = Base64.decodeToString(idcard);
log.info("身份证base64解码成功: {}", idcard);
} catch (Exception e) {
log.warn("身份证base64解码失败使用原值: {}", e.getMessage());
}
}
cmd.setCode(idcard);
cmd.setPaperType(111);
cmd.setPaperNumber(idcard);
cmd.setPhone(vehicle.getLsUserPhone());
cmd.setService("evo-thirdParty");
cmd.setValidStartTime(vehicle.getVisitStartTime());
cmd.setValidEndTime(vehicle.getVisitEndTime());
cmd.setDepartmentId(1L);
DaHuaTempVehicleSaveCmd.CarItem carItem = new DaHuaTempVehicleSaveCmd.CarItem();
carItem.setCarNum(vehicle.getLicenceNo());
carItem.setCarNumColor(CarEnum.getMenuKeyByPath(vehicle.getLicenceType()));
carItem.setDepartmentId(1L);
carItem.setDepartmentName(vehicle.getVehicleDepartmentName());
cmd.setCars(Collections.singletonList(carItem));
return cmd;
}
private boolean isRelatedPartyVehicle(VehicleApplyE vehicle) {
return vehicle != null
&& VehicleBelongTypeEnum.XGF_VEHICLES.getCode().equals(vehicle.getVehicleBelongType());
}
private boolean hasText(String value) {
return value != null && !value.trim().isEmpty();
}

View File

@ -76,14 +76,14 @@ public class VehicleAuditUpdateExe {
// 审批通过 进行数据对接。
if (cmd.getAuditStatus().equals(2)) {
log.info("审批通过, 开始数据对接");
if (vehicleApplyE1 != null && (vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.TEMP_VEHICLES.getCode()) ||
vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.XGF_VEHICLES.getCode()))) {
log.info("执行车辆对接: {}", vehicleApplyE1.getLicenceNo());
carDockUtil.execute(vehicleApplyE1.getLicenceNo());
} else {
log.info("执行内部车辆对接");
carDockUtil.executeInternalVehicle(vehicleApplyE1);
}
// if (vehicleApplyE1 != null && (vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.TEMP_VEHICLES.getCode()) ||
// vehicleApplyE1.getVehicleBelongType().equals(VehicleBelongTypeEnum.XGF_VEHICLES.getCode()))) {
// log.info("执行车辆对接: {}", vehicleApplyE1.getLicenceNo());
// carDockUtil.execute(vehicleApplyE1.getLicenceNo());
// } else {
// log.info("执行内部车辆对接");
// carDockUtil.executeInternalVehicle(vehicleApplyE1);
// }
log.info("开始同步大华平台");
daHuaVehicleSyncExe.syncApprovedVehicle(cmd.getVehicleApplyId());
log.info("同步大华平台完成");

View File

@ -11,7 +11,10 @@ import com.zcloud.primeport.command.PersonApplyRemoveExe;
import com.zcloud.primeport.command.PersonApplyUpdateExe;
import com.zcloud.primeport.command.query.PersonApplyQueryExe;
import com.zcloud.primeport.domain.gateway.VehicleApplyGateway;
import com.zcloud.primeport.domain.gateway.PersonApplyGateway;
import com.zcloud.primeport.domain.gateway.PersonMessageGateway;
import com.zcloud.primeport.domain.model.PersonApplyE;
import com.zcloud.primeport.domain.model.PersonMessageE;
import com.zcloud.primeport.domain.model.VehicleApplyE;
import com.zcloud.primeport.dto.*;
import com.zcloud.primeport.dto.clientobject.PersonApplyCO;
@ -20,8 +23,13 @@ import com.zcloud.primeport.dto.clientobject.XgfPersonApplyCO;
import com.zcloud.primeport.dto.clientobject.XgfPersonCountCO;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
/**
* web-app
@ -39,6 +47,8 @@ public class PersonApplyServiceImpl implements PersonApplyServiceI {
private final DaHuaPersonSyncExe daHuaPersonSyncExe;
private final DaHuaVehicleSyncExe daHuaVehicleSyncExe;
private final VehicleApplyGateway vehicleApplyGateway;
private final PersonApplyGateway personApplyGateway;
private final PersonMessageGateway personMessageGateway;
@Override
public PageResponse<XgfPersonApplyCO> listPage(PersonApplyPageQry qry) {
@ -124,7 +134,9 @@ public class PersonApplyServiceImpl implements PersonApplyServiceI {
}
private void syncUserVehicles(Long employeeUserId, Integer mkmjPermission) {
List<VehicleApplyE> vehicles = vehicleApplyGateway.listEffectiveByEmployeeUserId(employeeUserId);
List<VehicleApplyE> vehicles = Integer.valueOf(1).equals(mkmjPermission)
? vehicleApplyGateway.listEffectiveByEmployeeUserId(employeeUserId)
: vehicleApplyGateway.listByEmployeeUserId(employeeUserId);
daHuaVehicleSyncExe.syncVehiclesByPermission(vehicles, mkmjPermission);
}
@ -144,9 +156,70 @@ public class PersonApplyServiceImpl implements PersonApplyServiceI {
}
@Override
@Transactional(rollbackFor = Exception.class)
public void xgfPersonAuthorization(PersonAuthCmd cmd) {
if (!Integer.valueOf(1).equals(cmd.getMkmjPermission())
&& !Integer.valueOf(2).equals(cmd.getMkmjPermission())) {
throw new BizException("进出港权限只能是有权限或无权限");
}
PersonApplyE person = personApplyGateway.getPersonById(cmd.getApplyPersonId());
if (person == null) {
throw new BizException("相关方人员申请记录不存在");
}
if (person.getUserPhone() == null || person.getUserPhone().trim().isEmpty()) {
throw new BizException("相关方人员手机号不能为空");
}
List<PersonApplyE> approvedApplications = personApplyGateway.listApprovedByUserPhone(person.getUserPhone());
boolean currentApproved = approvedApplications.stream()
.anyMatch(item -> Objects.equals(item.getId(), person.getId()));
if (!currentApproved) {
throw new BizException("当前相关方人员申请未审批通过");
}
if (Integer.valueOf(1).equals(cmd.getMkmjPermission())) {
if (!personApplyGateway.updateApprovedMkmjPermissionByUserPhone(person.getUserPhone(), 1)) {
throw new BizException("未找到该手机号对应的审批通过申请");
}
approvedApplications.forEach(item -> item.setMkmjPermission(1));
} else {
personApplyUpdateExe.xgfPersonAuthorization(cmd);
approvedApplications.stream()
.filter(item -> Objects.equals(item.getId(), person.getId()))
.forEach(item -> item.setMkmjPermission(2));
}
personApplyUpdateExe.xgfPersonAuthorization(cmd);
List<PersonApplyE> activeApplications = approvedApplications.stream()
.filter(item -> Integer.valueOf(1).equals(item.getMkmjPermission()))
.collect(Collectors.toList());
if (activeApplications.isEmpty()) {
daHuaPersonSyncExe.syncRelatedPartyAuthorization(2, person, null);
return;
}
PersonMessageE mergedMessage = mergeVisitTime(activeApplications);
daHuaPersonSyncExe.syncRelatedPartyAuthorization(1, person, mergedMessage);
}
private PersonMessageE mergeVisitTime(List<PersonApplyE> applications) {
List<PersonMessageE> messages = new ArrayList<>();
for (PersonApplyE application : applications) {
PersonMessageE message = personMessageGateway.getLatestByApplyIdAndUserCard(
application.getXgfApplyPersonId(), application.getUserCard());
if (message == null || message.getVisitStartTime() == null || message.getVisitEndTime() == null) {
throw new BizException("未找到相关方人员完整的访问时间");
}
messages.add(message);
}
PersonMessageE mergedMessage = new PersonMessageE();
mergedMessage.setVisitStartTime(messages.stream()
.map(PersonMessageE::getVisitStartTime)
.filter(Objects::nonNull)
.min(Comparator.naturalOrder())
.orElseThrow(() -> new BizException("相关方人员访问开始时间不能为空")));
mergedMessage.setVisitEndTime(messages.stream()
.map(PersonMessageE::getVisitEndTime)
.filter(Objects::nonNull)
.max(Comparator.naturalOrder())
.orElseThrow(() -> new BizException("相关方人员访问结束时间不能为空")));
return mergedMessage;
}
@Override

View File

@ -66,6 +66,14 @@ public class VehicleApplyServiceImpl implements VehicleApplyServiceI {
@Override
public SingleResponse add(VehicleApplyAddCmd cmd) {
String licenceNo = cmd.getLicenceNo().trim();
cmd.setLicenceNo(licenceNo);
if (existsLicenceNo(licenceNo, null, cmd.getVisitStartTime(), cmd.getVisitEndTime())) {
throw new BizException("该车牌号已存在");
}
if (existsUnfinishedLicenceApplication(licenceNo)) {
throw new BizException("该车牌号存在未结束的车辆申请,请在访问结束时间后重新申请");
}
VehicleApplyE execute = vehicleApplyAddExe.execute(cmd);
return SingleResponse.of(execute);
}
@ -92,17 +100,9 @@ public class VehicleApplyServiceImpl implements VehicleApplyServiceI {
@Override
public Map<String, Object> checkLicenceNo(String licenceNo, Long id) {
QueryWrapper<VehicleApplyDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("licence_no", licenceNo);
queryWrapper.in("vehicle_belong_type", 1,2,3,4,8,9);
queryWrapper.eq("delete_enum", "false");
queryWrapper.ne("audit_flag", 3);
if (id != null) {
queryWrapper.ne("id", id);
}
Map<String, Object> result = new HashMap<>();
result.put("available", true);
if (vehicleApplyRepository.count(queryWrapper) != 0) {
if (existsLicenceNo(licenceNo, id)) {
result.put("available", false);
result.put("availableMessage", "该车牌号已存在");
}
@ -116,6 +116,35 @@ public class VehicleApplyServiceImpl implements VehicleApplyServiceI {
return result;
}
private boolean existsLicenceNo(String licenceNo, Long id) {
return existsLicenceNo(licenceNo, id, null, null);
}
private boolean existsLicenceNo(String licenceNo, Long id, String visitStartTime, String visitEndTime) {
QueryWrapper<VehicleApplyDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("licence_no", licenceNo);
queryWrapper.in("vehicle_belong_type", 1,2,3,4,8,9);
queryWrapper.eq("delete_enum", "false");
queryWrapper.ne("audit_flag", 3);
queryWrapper.eq("expired_expiration", "2");
queryWrapper.le(visitEndTime != null, "visit_start_time", visitEndTime);
queryWrapper.ge(visitStartTime != null, "visit_end_time", visitStartTime);
if (id != null) {
queryWrapper.ne("id", id);
}
return vehicleApplyRepository.count(queryWrapper) != 0;
}
private boolean existsUnfinishedLicenceApplication(String licenceNo) {
QueryWrapper<VehicleApplyDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("licence_no", licenceNo);
queryWrapper.eq("delete_enum", "false");
queryWrapper.ne("audit_flag", AuditEnum.REJECTED.getCode());
queryWrapper.eq("expired_expiration", "2");
queryWrapper.apply("visit_end_time >= CURRENT_DATE");
return vehicleApplyRepository.count(queryWrapper) != 0;
}
@Override
public void inspectCarSave(VehicleApplyInspectAddCmd cmd) {
List<VehicleApplyInspectAddCmd.InspectCar> inspectCarList = cmd.getInspectCarList();

View File

@ -0,0 +1,144 @@
package com.zcloud.primeport.command;
import com.alibaba.cola.exception.BizException;
import com.sun.net.httpserver.HttpServer;
import com.zcloud.gbscommon.dahua.cmd.DaHuaPersonSyncCmd;
import com.zcloud.primeport.domain.gateway.DaHuaGateway;
import com.zcloud.primeport.domain.gateway.MkmjGateGateway;
import com.zcloud.primeport.domain.gateway.PersonApplyGateway;
import com.zcloud.primeport.domain.model.PersonApplyE;
import com.zcloud.primeport.domain.model.PersonMessageE;
import jodd.util.Base64;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class DaHuaRelatedPartyAuthorizationSyncExeTest {
private static final String PAPER_NUMBER = "110101199001011234";
@Mock
private DaHuaGateway daHuaGateway;
@Mock
private PersonApplyGateway personApplyGateway;
@Mock
private MkmjGateGateway mkmjGateGateway;
@Mock
private PersonApplyAddExe personApplyAddExe;
private DaHuaPersonSyncExe syncExe;
private HttpServer imageServer;
@BeforeEach
void setUp() throws IOException {
imageServer = HttpServer.create(new InetSocketAddress("127.0.0.1", 0), 0);
imageServer.createContext("/faces/test.jpg", exchange -> {
byte[] image = new byte[]{(byte) 0xFF, (byte) 0xD8, (byte) 0xFF, (byte) 0xD9};
exchange.sendResponseHeaders(200, image.length);
exchange.getResponseBody().write(image);
exchange.close();
});
imageServer.start();
syncExe = new DaHuaPersonSyncExe(daHuaGateway, personApplyGateway, mkmjGateGateway, personApplyAddExe);
ReflectionTestUtils.setField(syncExe, "fileUrl",
"http://127.0.0.1:" + imageServer.getAddress().getPort());
ReflectionTestUtils.setField(syncExe, "temporaryDepartmentId", 112L);
}
@AfterEach
void tearDown() {
imageServer.stop(0);
}
@Test
void 访() {
when(daHuaGateway.findPersonIdByPaperNumber(PAPER_NUMBER)).thenReturn(null);
when(daHuaGateway.generatePersonId()).thenReturn(1001L);
when(daHuaGateway.syncPerson(any(DaHuaPersonSyncCmd.class))).thenReturn(success());
syncExe.syncRelatedPartyAuthorization(1, person(), personMessage());
ArgumentCaptor<DaHuaPersonSyncCmd> cmd = ArgumentCaptor.forClass(DaHuaPersonSyncCmd.class);
verify(daHuaGateway).syncPerson(cmd.capture());
assertEquals(112L, cmd.getValue().getDepartmentId());
assertEquals("2026-08-01 00:00:00", cmd.getValue().getValidStartTime());
assertEquals("2026-08-31 23:59:59", cmd.getValue().getValidEndTime());
assertEquals(PAPER_NUMBER, cmd.getValue().getPaperNumber());
}
@Test
void () {
when(daHuaGateway.findPersonIdByPaperNumber(PAPER_NUMBER)).thenReturn(1001L);
when(daHuaGateway.updatePerson(any(DaHuaPersonSyncCmd.class))).thenReturn(success());
syncExe.syncRelatedPartyAuthorization(1, person(), personMessage());
ArgumentCaptor<DaHuaPersonSyncCmd> cmd = ArgumentCaptor.forClass(DaHuaPersonSyncCmd.class);
verify(daHuaGateway).updatePerson(cmd.capture());
assertEquals(1001L, cmd.getValue().getId());
verify(daHuaGateway, never()).syncPerson(any(DaHuaPersonSyncCmd.class));
}
@Test
void () {
when(daHuaGateway.findPersonIdByPaperNumber(PAPER_NUMBER)).thenReturn(1001L);
when(daHuaGateway.deletePerson(Collections.singletonList(1001L), null)).thenReturn(success());
syncExe.syncRelatedPartyAuthorization(2, person(), null);
verify(daHuaGateway).deletePerson(Collections.singletonList(1001L), null);
verify(daHuaGateway, never()).syncPerson(any(DaHuaPersonSyncCmd.class));
verify(daHuaGateway, never()).updatePerson(any(DaHuaPersonSyncCmd.class));
}
@Test
void 访() {
when(daHuaGateway.findPersonIdByPaperNumber(PAPER_NUMBER)).thenReturn(null);
BizException exception = assertThrows(BizException.class,
() -> syncExe.syncRelatedPartyAuthorization(1, person(), null));
assertEquals("未找到相关方人员访问时间", exception.getMessage());
}
private PersonApplyE person() {
PersonApplyE person = new PersonApplyE();
person.setEmployeePersonUserName("张三");
person.setUserCard(Base64.encodeToString(PAPER_NUMBER));
person.setUserPhone("13000000001");
person.setUserFaceUrl("faces/test.jpg");
return person;
}
private PersonMessageE personMessage() {
PersonMessageE personMessage = new PersonMessageE();
personMessage.setVisitStartTime("2026-08-01");
personMessage.setVisitEndTime("2026-08-31");
return personMessage;
}
private Map<String, Object> success() {
Map<String, Object> result = new HashMap<>();
result.put("passed", true);
return result;
}
}

View File

@ -65,17 +65,15 @@ class DaHuaVehiclePermissionSyncExeTest {
}
@Test
void () {
void () {
VehicleApplyE missingVehicle = vehicle();
missingVehicle.setLicenceNo("冀C54321");
when(daHuaGateway.pageCar(any(DaHuaCarPageCmd.class)))
.thenReturn(vehiclePage(LICENCE_NO))
.thenReturn(vehiclePage(null));
when(daHuaGateway.deleteCar(Collections.singletonList(LICENCE_NO))).thenReturn(success());
when(daHuaGateway.deleteCar(Arrays.asList(LICENCE_NO, "冀C54321"))).thenReturn(success());
syncExe.syncVehiclesByPermission(Arrays.asList(vehicle(), missingVehicle), 2);
verify(daHuaGateway).deleteCar(Collections.singletonList(LICENCE_NO));
verify(daHuaGateway).deleteCar(Arrays.asList(LICENCE_NO, "冀C54321"));
verify(daHuaGateway, never()).pageCar(any(DaHuaCarPageCmd.class));
verify(daHuaGateway, never()).addCar(any(DaHuaCarAddCmd.class));
}

View File

@ -0,0 +1,185 @@
package com.zcloud.primeport.service;
import com.zcloud.primeport.command.DaHuaPersonSyncExe;
import com.zcloud.primeport.command.DaHuaVehicleSyncExe;
import com.zcloud.primeport.command.PersonApplyAddExe;
import com.zcloud.primeport.command.PersonApplyRemoveExe;
import com.zcloud.primeport.command.PersonApplyUpdateExe;
import com.zcloud.primeport.command.query.PersonApplyQueryExe;
import com.zcloud.primeport.domain.gateway.PersonApplyGateway;
import com.zcloud.primeport.domain.gateway.PersonMessageGateway;
import com.zcloud.primeport.domain.gateway.VehicleApplyGateway;
import com.zcloud.primeport.domain.model.PersonApplyE;
import com.zcloud.primeport.domain.model.PersonMessageE;
import com.zcloud.primeport.domain.model.VehicleApplyE;
import com.zcloud.primeport.dto.PersonAuthCmd;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class PersonApplyVehicleQueryTest {
@Mock
private PersonApplyAddExe personApplyAddExe;
@Mock
private PersonApplyUpdateExe personApplyUpdateExe;
@Mock
private PersonApplyRemoveExe personApplyRemoveExe;
@Mock
private PersonApplyQueryExe personApplyQueryExe;
@Mock
private DaHuaPersonSyncExe daHuaPersonSyncExe;
@Mock
private DaHuaVehicleSyncExe daHuaVehicleSyncExe;
@Mock
private VehicleApplyGateway vehicleApplyGateway;
@Mock
private PersonApplyGateway personApplyGateway;
@Mock
private PersonMessageGateway personMessageGateway;
private PersonApplyServiceImpl service;
@BeforeEach
void setUp() {
service = new PersonApplyServiceImpl(personApplyAddExe, personApplyUpdateExe, personApplyRemoveExe,
personApplyQueryExe, daHuaPersonSyncExe, daHuaVehicleSyncExe, vehicleApplyGateway,
personApplyGateway, personMessageGateway);
}
@Test
void () {
List<VehicleApplyE> vehicles = Collections.singletonList(new VehicleApplyE());
when(vehicleApplyGateway.listEffectiveByEmployeeUserId(10L)).thenReturn(vehicles);
ReflectionTestUtils.invokeMethod(service, "syncUserVehicles", 10L, 1);
verify(vehicleApplyGateway).listEffectiveByEmployeeUserId(10L);
verify(vehicleApplyGateway, never()).listByEmployeeUserId(10L);
verify(daHuaVehicleSyncExe).syncVehiclesByPermission(vehicles, 1);
}
@Test
void () {
List<VehicleApplyE> vehicles = Collections.singletonList(new VehicleApplyE());
when(vehicleApplyGateway.listByEmployeeUserId(10L)).thenReturn(vehicles);
ReflectionTestUtils.invokeMethod(service, "syncUserVehicles", 10L, 2);
verify(vehicleApplyGateway).listByEmployeeUserId(10L);
verify(vehicleApplyGateway, never()).listEffectiveByEmployeeUserId(10L);
verify(daHuaVehicleSyncExe).syncVehiclesByPermission(vehicles, 2);
}
@Test
void 访() {
PersonApplyE person = relatedPartyPerson();
PersonApplyE anotherPerson = relatedPartyPerson(21L, 31L, 2);
person.setMkmjPermission(2);
PersonMessageE currentMessage = personMessage("2026-08-10", "2026-08-20");
PersonMessageE anotherMessage = personMessage("2026-08-01", "2026-09-30");
when(personApplyGateway.getPersonById(20L)).thenReturn(person);
when(personApplyGateway.listApprovedByUserPhone("13000000001"))
.thenReturn(Arrays.asList(person, anotherPerson));
when(personApplyGateway.updateApprovedMkmjPermissionByUserPhone("13000000001", 1)).thenReturn(true);
when(personMessageGateway.getLatestByApplyIdAndUserCard(30L, "身份证密文"))
.thenReturn(currentMessage);
when(personMessageGateway.getLatestByApplyIdAndUserCard(31L, "身份证密文"))
.thenReturn(anotherMessage);
PersonAuthCmd cmd = authCmd(1);
service.xgfPersonAuthorization(cmd);
verify(personApplyGateway).updateApprovedMkmjPermissionByUserPhone("13000000001", 1);
verify(personApplyUpdateExe, never()).xgfPersonAuthorization(cmd);
verify(personMessageGateway).getLatestByApplyIdAndUserCard(30L, "身份证密文");
verify(personMessageGateway).getLatestByApplyIdAndUserCard(31L, "身份证密文");
verify(daHuaPersonSyncExe).syncRelatedPartyAuthorization(argThat(permission -> permission == 1),
argThat(item -> item == person), argThat(message ->
"2026-08-01".equals(message.getVisitStartTime())
&& "2026-09-30".equals(message.getVisitEndTime())));
}
@Test
void () {
PersonApplyE person = relatedPartyPerson();
PersonApplyE anotherPerson = relatedPartyPerson(21L, 31L, 1);
PersonMessageE anotherMessage = personMessage("2026-09-01", "2026-10-31");
when(personApplyGateway.getPersonById(20L)).thenReturn(person);
when(personApplyGateway.listApprovedByUserPhone("13000000001"))
.thenReturn(Arrays.asList(personWithPermission(person, 2), anotherPerson));
when(personMessageGateway.getLatestByApplyIdAndUserCard(31L, "身份证密文"))
.thenReturn(anotherMessage);
PersonAuthCmd cmd = authCmd(2);
service.xgfPersonAuthorization(cmd);
verify(personApplyUpdateExe).xgfPersonAuthorization(cmd);
verify(personMessageGateway, never()).getLatestByApplyIdAndUserCard(30L, "身份证密文");
verify(daHuaPersonSyncExe).syncRelatedPartyAuthorization(argThat(permission -> permission == 1),
argThat(item -> item == person), argThat(message ->
"2026-09-01".equals(message.getVisitStartTime())
&& "2026-10-31".equals(message.getVisitEndTime())));
}
@Test
void () {
PersonApplyE person = relatedPartyPerson();
when(personApplyGateway.getPersonById(20L)).thenReturn(person);
when(personApplyGateway.listApprovedByUserPhone("13000000001"))
.thenReturn(Collections.singletonList(personWithPermission(person, 2)));
PersonAuthCmd cmd = authCmd(2);
service.xgfPersonAuthorization(cmd);
verify(personApplyUpdateExe).xgfPersonAuthorization(cmd);
verify(personMessageGateway, never()).getLatestByApplyIdAndUserCard(30L, "身份证密文");
verify(daHuaPersonSyncExe).syncRelatedPartyAuthorization(2, person, null);
}
private PersonApplyE relatedPartyPerson() {
return relatedPartyPerson(20L, 30L, null);
}
private PersonApplyE relatedPartyPerson(Long id, Long applyId, Integer permission) {
PersonApplyE person = new PersonApplyE();
person.setId(id);
person.setXgfApplyPersonId(applyId);
person.setMkmjPermission(permission);
person.setUserCard("身份证密文");
person.setUserPhone("13000000001");
return person;
}
private PersonApplyE personWithPermission(PersonApplyE person, Integer permission) {
person.setMkmjPermission(permission);
return person;
}
private PersonMessageE personMessage(String startTime, String endTime) {
PersonMessageE message = new PersonMessageE();
message.setVisitStartTime(startTime);
message.setVisitEndTime(endTime);
return message;
}
private PersonAuthCmd authCmd(Integer mkmjPermission) {
PersonAuthCmd cmd = new PersonAuthCmd();
cmd.setApplyPersonId(20L);
cmd.setMkmjPermission(mkmjPermission);
return cmd;
}
}

View File

@ -41,6 +41,10 @@ public interface PersonApplyGateway {
PersonApplyE getPersonById(Long id);
List<PersonApplyE> listApprovedByUserPhone(String userPhone);
Boolean updateApprovedMkmjPermissionByUserPhone(String userPhone, Integer mkmjPermission);
XgfApplyPersonE getXgfApplyPersonById(Long id);
}

View File

@ -26,5 +26,7 @@ public interface PersonMessageGateway {
Boolean deletedPersonMessageById(Long id);
Boolean deletedPersonMessageByIds(Long[] id);
PersonMessageE getLatestByApplyIdAndUserCard(Long applyId, String userCard);
}

View File

@ -32,6 +32,8 @@ public interface VehicleApplyGateway {
List<VehicleApplyE> listEffectiveByEmployeeUserId(Long employeeUserId);
List<VehicleApplyE> listByEmployeeUserId(Long employeeUserId);
void updateEvehicleBlockedByLicenceNo(String licenceNo, Integer blockedFlag);
void updateBlackFlag(VehicleApplyE vehicleApplyE);

View File

@ -222,6 +222,21 @@ public class PersonApplyGatewayImpl implements PersonApplyGateway {
return personApplyE;
}
@Override
public List<PersonApplyE> listApprovedByUserPhone(String userPhone) {
List<PersonApplyDO> personApplyDOS = personApplyRepository.listApprovedByUserPhone(userPhone);
return personApplyDOS.stream().map(item -> {
PersonApplyE personApplyE = new PersonApplyE();
BeanUtils.copyProperties(item, personApplyE);
return personApplyE;
}).collect(Collectors.toList());
}
@Override
public Boolean updateApprovedMkmjPermissionByUserPhone(String userPhone, Integer mkmjPermission) {
return personApplyRepository.updateApprovedMkmjPermissionByUserPhone(userPhone, mkmjPermission);
}
@Override
public XgfApplyPersonE getXgfApplyPersonById (Long id) {
XgfApplyPersonDO byId = xgfApplyPersonRepository.getById(id);

View File

@ -1,5 +1,6 @@
package com.zcloud.primeport.gatewayimpl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zcloud.primeport.domain.gateway.PersonMessageGateway;
import com.zcloud.primeport.domain.model.PersonMessageE;
import com.zcloud.primeport.persistence.dataobject.PersonMessageDO;
@ -46,5 +47,22 @@ public class PersonMessageGatewayImpl implements PersonMessageGateway {
public Boolean deletedPersonMessageByIds(Long[] ids) {
return personMessageRepository.removeByIds(Collections.singletonList(ids));
}
@Override
public PersonMessageE getLatestByApplyIdAndUserCard(Long applyId, String userCard) {
QueryWrapper<PersonMessageDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("person_apply_id", applyId);
queryWrapper.eq("user_card", userCard);
queryWrapper.eq("delete_enum", "FALSE");
queryWrapper.orderByDesc("create_time");
queryWrapper.last("LIMIT 1");
PersonMessageDO personMessageDO = personMessageRepository.getOne(queryWrapper);
if (personMessageDO == null) {
return null;
}
PersonMessageE personMessageE = new PersonMessageE();
BeanUtils.copyProperties(personMessageDO, personMessageE);
return personMessageE;
}
}

View File

@ -83,13 +83,24 @@ public class VehicleApplyGatewayImpl implements VehicleApplyGateway {
@Override
public List<VehicleApplyE> listEffectiveByEmployeeUserId(Long employeeUserId) {
return listByEmployeeUserId(employeeUserId, true);
}
@Override
public List<VehicleApplyE> listByEmployeeUserId(Long employeeUserId) {
return listByEmployeeUserId(employeeUserId, false);
}
private List<VehicleApplyE> listByEmployeeUserId(Long employeeUserId, boolean effectiveOnly) {
if (employeeUserId == null) {
return Collections.emptyList();
}
QueryWrapper<VehicleApplyDO> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("employee_vehicle_user_id", employeeUserId);
queryWrapper.eq("expired_expiration", "2");
queryWrapper.in("audit_flag", 2, 4);
if (effectiveOnly) {
queryWrapper.eq("expired_expiration", "2");
queryWrapper.in("audit_flag", 2, 4);
}
queryWrapper.eq("delete_enum", "FALSE");
List<VehicleApplyDO> vehicleList = vehicleApplyRepository.list(queryWrapper);
List<VehicleApplyE> result = new ArrayList<>(vehicleList.size());

View File

@ -10,6 +10,7 @@ import com.zcloud.primeport.persistence.dataobject.XgfApplyPersonDO;
import org.apache.ibatis.annotations.Mapper;
import java.util.Map;
import java.util.List;
import org.apache.ibatis.annotations.Param;
/**
@ -38,5 +39,7 @@ public interface PersonApplyMapper extends BaseMapper<PersonApplyDO> {
int updateMkmjPermission(@Param("id") Long id,
@Param("mkmjPermission") Integer mkmjPermission);
List<PersonApplyDO> listApprovedByUserPhone(@Param("userPhone") String userPhone);
}

View File

@ -3,6 +3,7 @@ package com.zcloud.primeport.persistence.repository;
import com.alibaba.cola.dto.PageResponse;
import com.jjb.saas.framework.repository.repo.BaseRepository;
import com.zcloud.primeport.persistence.dataobject.PersonApplyDO;
import java.util.List;
import java.util.Map;
/**
@ -23,5 +24,9 @@ public interface PersonApplyRepository extends BaseRepository<PersonApplyDO> {
PersonApplyDO xgfPersonPermissionsInfo(Long id);
Boolean updateMkmjPermission(Long id, Integer mkmjPermission);
List<PersonApplyDO> listApprovedByUserPhone(String userPhone);
Boolean updateApprovedMkmjPermissionByUserPhone(String userPhone, Integer mkmjPermission);
}

View File

@ -2,6 +2,7 @@ package com.zcloud.primeport.persistence.repository.impl;
import com.alibaba.cola.dto.PageResponse;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jjb.saas.framework.repository.repo.impl.BaseRepositoryImpl;
@ -15,6 +16,8 @@ import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.Map;
import java.util.List;
import java.util.stream.Collectors;
import com.zcloud.gbscommon.utils.Query;
import com.jjb.saas.framework.repository.common.PageHelper;
@ -83,6 +86,27 @@ public class PersonApplyRepositoryImpl extends BaseRepositoryImpl<PersonApplyMap
return personApplyMapper.updateMkmjPermission(id, mkmjPermission) > 0;
}
@Override
public List<PersonApplyDO> listApprovedByUserPhone(String userPhone) {
return personApplyMapper.listApprovedByUserPhone(userPhone);
}
@Override
public Boolean updateApprovedMkmjPermissionByUserPhone(String userPhone, Integer mkmjPermission) {
List<Long> ids = listApprovedByUserPhone(userPhone).stream()
.map(PersonApplyDO::getId)
.collect(Collectors.toList());
if (ids.isEmpty()) {
return false;
}
UpdateWrapper<PersonApplyDO> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("mkmj_permission", mkmjPermission);
updateWrapper.in("id", ids);
updateWrapper.eq("delete_enum", "FALSE");
update(updateWrapper);
return true;
}
}

View File

@ -140,5 +140,18 @@
AND delete_enum = 'FALSE'
</update>
<select id="listApprovedByUserPhone"
resultType="com.zcloud.primeport.persistence.dataobject.PersonApplyDO">
SELECT pa.*
FROM person_apply pa
INNER JOIN xgf_apply_person xap ON xap.id = pa.xgf_apply_person_id
WHERE pa.user_phone = #{userPhone}
AND pa.delete_enum = 'FALSE'
AND xap.delete_enum = 'FALSE'
AND xap.audit_flag = 2
AND xap.person_belong_type = 3
ORDER BY pa.id DESC
</select>
</mapper>