From 88c31d4fdc5245a1c7c23fb84dbed70b7371132f Mon Sep 17 00:00:00 2001 From: Jerry Yan <792602257@qq.com> Date: Sat, 8 Nov 2025 15:04:50 +0800 Subject: [PATCH] =?UTF-8?q?feat(printer):=E4=BC=98=E5=8C=96=E4=BA=BA?= =?UTF-8?q?=E8=84=B8=E6=A0=B7=E6=9C=AC=E4=BD=BF=E7=94=A8=E9=80=BB=E8=BE=91?= =?UTF-8?q?=E5=B9=B6=E5=A2=9E=E5=BC=BA=E6=99=AF=E5=8C=BA=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 useSample 接口返回类型为 FaceRecognizeResp - 增加根据样本ID和类型查询来源实体的逻辑 - 在景区列表查询中添加参数校验和异常处理 - 完善景区信息处理流程,增加设备数量统计 -优化景区距离计算与筛选逻辑 - 增加人脸匹配后自动添加照片到用户相册的功能 - 添加 XML 映射文件中新的查询语句实现 --- .../mobile/AppPrinterController.java | 3 +- .../com/ycwl/basic/mapper/SourceMapper.java | 2 + .../mobile/impl/AppScenicServiceImpl.java | 114 ++++++++++++------ .../basic/service/printer/PrinterService.java | 3 +- .../printer/impl/PrinterServiceImpl.java | 9 +- src/main/resources/mapper/SourceMapper.xml | 5 + 6 files changed, 96 insertions(+), 40 deletions(-) diff --git a/src/main/java/com/ycwl/basic/controller/mobile/AppPrinterController.java b/src/main/java/com/ycwl/basic/controller/mobile/AppPrinterController.java index b45e38ff..ddc8671d 100644 --- a/src/main/java/com/ycwl/basic/controller/mobile/AppPrinterController.java +++ b/src/main/java/com/ycwl/basic/controller/mobile/AppPrinterController.java @@ -2,6 +2,7 @@ package com.ycwl.basic.controller.mobile; import com.ycwl.basic.annotation.IgnoreToken; import com.ycwl.basic.model.jwt.JwtInfo; +import com.ycwl.basic.model.mobile.face.FaceRecognizeResp; import com.ycwl.basic.model.pc.printer.resp.MemberPrintResp; import com.ycwl.basic.model.pc.printer.resp.PrinterResp; import com.ycwl.basic.model.printer.req.FromSourceReq; @@ -37,7 +38,7 @@ public class AppPrinterController { } @PostMapping("/useSample/{sampleId}") - public ApiResponse useSample(@PathVariable("sampleId") Long sampleId) throws IOException { + public ApiResponse useSample(@PathVariable("sampleId") Long sampleId) throws IOException { JwtInfo worker = JwtTokenUtil.getWorker(); return ApiResponse.success(printerService.useSample(worker.getUserId(), sampleId)); } diff --git a/src/main/java/com/ycwl/basic/mapper/SourceMapper.java b/src/main/java/com/ycwl/basic/mapper/SourceMapper.java index f398d054..4c8c3c35 100644 --- a/src/main/java/com/ycwl/basic/mapper/SourceMapper.java +++ b/src/main/java/com/ycwl/basic/mapper/SourceMapper.java @@ -105,4 +105,6 @@ public interface SourceMapper { * @return 影响行数 */ int addFromZTSource(SourceEntity source); + + SourceEntity getBySampleIdAndType(Long faceSampleId, Integer type); } diff --git a/src/main/java/com/ycwl/basic/service/mobile/impl/AppScenicServiceImpl.java b/src/main/java/com/ycwl/basic/service/mobile/impl/AppScenicServiceImpl.java index 117e1a0d..4805f576 100644 --- a/src/main/java/com/ycwl/basic/service/mobile/impl/AppScenicServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/mobile/impl/AppScenicServiceImpl.java @@ -220,58 +220,98 @@ public class AppScenicServiceImpl implements AppScenicService { @Override public List scenicListByLnLa(ScenicIndexVO scenicIndexVO) { + // 参数校验 + if (scenicIndexVO == null) { + log.warn("scenicListByLnLa 接收到空参数"); + return Collections.emptyList(); + } + if (scenicIndexVO.getLatitude() == null || scenicIndexVO.getLongitude() == null) { + log.warn("scenicListByLnLa 缺少必要的经纬度参数, latitude={}, longitude={}", + scenicIndexVO.getLatitude(), scenicIndexVO.getLongitude()); + return Collections.emptyList(); + } + // 从 scenicRepository 获取所有景区(1000个) ScenicReqQuery query = new ScenicReqQuery(); query.setPageNum(1); query.setPageSize(1000); List scenicList = scenicRepository.list(query); - + + if (scenicList == null || scenicList.isEmpty()) { + log.info("未查询到任何景区数据"); + return Collections.emptyList(); + } + List list = new ArrayList<>(); - + // 为每个景区获取详细信息(包含经纬度) for (ScenicV2DTO scenicDTO : scenicList) { try { + // ID 格式校验 + if (StringUtils.isBlank(scenicDTO.getId())) { + log.warn("景区 ID 为空,跳过该景区"); + continue; + } + // 获取景区详细信息(包含经纬度) ScenicEntity scenicEntity = scenicRepository.getScenic(Long.parseLong(scenicDTO.getId())); - if (scenicEntity != null && scenicEntity.getLatitude() != null && scenicEntity.getLongitude() != null) { - // 计算距离 - BigDecimal distance = calculateDistance( - scenicIndexVO.getLatitude(), - scenicIndexVO.getLongitude(), - scenicEntity.getLatitude(), - scenicEntity.getLongitude() - ); - - // 根据距离和范围筛选景区 - if (scenicEntity.getRadius() != null && - distance.compareTo(scenicEntity.getRadius().multiply(BigDecimal.valueOf(1_000L))) < 0) { - - // 转换为 ScenicAppVO - ScenicAppVO scenicAppVO = new ScenicAppVO(); - scenicAppVO.setId(scenicEntity.getId()); - scenicAppVO.setName(scenicEntity.getName()); - scenicAppVO.setPhone(scenicEntity.getPhone()); - scenicAppVO.setIntroduction(scenicEntity.getIntroduction()); - scenicAppVO.setCoverUrl(scenicEntity.getCoverUrl()); - scenicAppVO.setLongitude(scenicEntity.getLongitude()); - scenicAppVO.setLatitude(scenicEntity.getLatitude()); - scenicAppVO.setRadius(scenicEntity.getRadius()); - scenicAppVO.setProvince(scenicEntity.getProvince()); - scenicAppVO.setCity(scenicEntity.getCity()); - scenicAppVO.setArea(scenicEntity.getArea()); - scenicAppVO.setAddress(scenicEntity.getAddress()); - scenicAppVO.setDistance(distance); - scenicAppVO.setDeviceNum(deviceRepository.getAllDeviceByScenicId(scenicEntity.getId()).size()); - - list.add(scenicAppVO); - } + if (scenicEntity == null) { + log.warn("景区详情查询失败, scenicId={}", scenicDTO.getId()); + continue; } + + if (scenicEntity.getLatitude() == null || scenicEntity.getLongitude() == null) { + log.warn("景区缺少经纬度信息, scenicId={}, scenicName={}", + scenicEntity.getId(), scenicEntity.getName()); + continue; + } + + // 计算距离 + BigDecimal distance = calculateDistance( + scenicIndexVO.getLatitude(), + scenicIndexVO.getLongitude(), + scenicEntity.getLatitude(), + scenicEntity.getLongitude() + ); + + // 根据距离和范围筛选景区 + if (scenicEntity.getRadius() != null && + distance.compareTo(scenicEntity.getRadius().multiply(BigDecimal.valueOf(1_000L))) < 0) { + + // 转换为 ScenicAppVO + ScenicAppVO scenicAppVO = new ScenicAppVO(); + scenicAppVO.setId(scenicEntity.getId()); + scenicAppVO.setName(scenicEntity.getName()); + scenicAppVO.setPhone(scenicEntity.getPhone()); + scenicAppVO.setIntroduction(scenicEntity.getIntroduction()); + scenicAppVO.setCoverUrl(scenicEntity.getCoverUrl()); + scenicAppVO.setLongitude(scenicEntity.getLongitude()); + scenicAppVO.setLatitude(scenicEntity.getLatitude()); + scenicAppVO.setRadius(scenicEntity.getRadius()); + scenicAppVO.setProvince(scenicEntity.getProvince()); + scenicAppVO.setCity(scenicEntity.getCity()); + scenicAppVO.setArea(scenicEntity.getArea()); + scenicAppVO.setAddress(scenicEntity.getAddress()); + scenicAppVO.setDistance(distance); + + // 获取设备数量 + List devices = deviceRepository.getAllDeviceByScenicId(scenicEntity.getId()); + scenicAppVO.setDeviceNum(devices != null ? devices.size() : 0); + + list.add(scenicAppVO); + } + } catch (NumberFormatException e) { + log.error("景区 ID 格式错误,无法转换为 Long 类型, scenicId={}, error={}", + scenicDTO.getId(), e.getMessage()); } catch (Exception e) { - // 单个景区获取失败,继续处理下一个 - continue; + log.error("处理景区信息时发生异常, scenicId={}, error={}", + scenicDTO != null ? scenicDTO.getId() : "unknown", e.getMessage(), e); } } - + + log.info("根据经纬度筛选景区完成, 输入坐标=({}, {}), 符合条件的景区数量={}", + scenicIndexVO.getLatitude(), scenicIndexVO.getLongitude(), list.size()); + return list; } diff --git a/src/main/java/com/ycwl/basic/service/printer/PrinterService.java b/src/main/java/com/ycwl/basic/service/printer/PrinterService.java index 5258c6dd..6014075e 100644 --- a/src/main/java/com/ycwl/basic/service/printer/PrinterService.java +++ b/src/main/java/com/ycwl/basic/service/printer/PrinterService.java @@ -1,5 +1,6 @@ package com.ycwl.basic.service.printer; +import com.ycwl.basic.model.mobile.face.FaceRecognizeResp; import com.ycwl.basic.model.mobile.order.PriceObj; import com.ycwl.basic.model.pc.printer.entity.PrinterEntity; import com.ycwl.basic.model.pc.printer.resp.MemberPrintResp; @@ -56,7 +57,7 @@ public interface PrinterService { void setUserIsBuyItem(Long memberId, Long id, Long orderId); - Object useSample(Long userId, Long sampleId); + FaceRecognizeResp useSample(Long userId, Long sampleId); void autoAddPhotosToPreferPrint(Long faceId); } \ No newline at end of file diff --git a/src/main/java/com/ycwl/basic/service/printer/impl/PrinterServiceImpl.java b/src/main/java/com/ycwl/basic/service/printer/impl/PrinterServiceImpl.java index 44f9302b..fc6e7c6f 100644 --- a/src/main/java/com/ycwl/basic/service/printer/impl/PrinterServiceImpl.java +++ b/src/main/java/com/ycwl/basic/service/printer/impl/PrinterServiceImpl.java @@ -752,9 +752,10 @@ public class PrinterServiceImpl implements PrinterService { } @Override - public Object useSample(Long userId, Long sampleId) { + public FaceRecognizeResp useSample(Long userId, Long sampleId) { // 1. 查询 faceSample 获取其 URL FaceSampleEntity faceSample = faceSampleMapper.getEntity(sampleId); + SourceEntity sourceEntity = sourceMapper.getBySampleIdAndType(sampleId, 2); if (faceSample == null) { throw new BaseException("人脸样本不存在"); } @@ -807,6 +808,12 @@ public class PrinterServiceImpl implements PrinterService { resp.setScenicId(scenicId); faceService.matchFaceId(faceId); autoAddPhotosToPreferPrint(faceId); + List userPhotoList = getUserPhotoList(userId, scenicId, faceId); + boolean noneMatch = userPhotoList.stream() + .noneMatch(item -> Strings.CI.equals(item.getOrigUrl(), sourceEntity.getUrl())); + if (noneMatch) { + addUserPhoto(userId, scenicId, sourceEntity.getUrl(), faceId); + } return resp; } diff --git a/src/main/resources/mapper/SourceMapper.xml b/src/main/resources/mapper/SourceMapper.xml index ce051acc..0bd0aa81 100644 --- a/src/main/resources/mapper/SourceMapper.xml +++ b/src/main/resources/mapper/SourceMapper.xml @@ -354,4 +354,9 @@ inner join member_source ms on s.id = ms.source_id where ms.face_id = #{faceId} and s.type = 2 +