liujie
2026-06-09 c96fbe6b0aeb413a17c429133ee6d81d138144b9
xp-robotaxi-maintenance-boot/src/main/java/com/xiaopeng/maintenance/service/impl/XpCruiseCheckInRuleServiceImpl.java
@@ -27,6 +27,8 @@
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRecordService;
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRuleLocationService;
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRuleService;
import com.xiaopeng.maintenance.vo.CruiseCheckInLocationVo;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRuleInfoVo;
import com.xiaopeng.maintenance.vo.XpCruiseCheckInRuleListPage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
@@ -38,6 +40,7 @@
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -62,14 +65,14 @@
    @Resource
    private XpOperationUserClient xpOperationsUserClient;
    @Resource
    private XpCruiseCheckInRuleOperationsUserMapper xpCruiseCheckInRuleOperationsUserMapper;
    @Override
    public AppXpCruiseCheckInRuleVo getMyXpCruiseCheckInRule(Long uid) {
        List<XpCruiseCheckInRule> list = this.list(new LambdaQueryWrapper<XpCruiseCheckInRule>().eq(XpCruiseCheckInRule::getDeleted, 0)
                .last(" and (now() BETWEEN start_time and end_time or cyclic_mode = 1)"));
                .eq(XpCruiseCheckInRule::getOperationsUserId, uid).last(" and (now() BETWEEN start_time and end_time or cyclic_mode = 1)"));
        if(list.isEmpty()){
            return null;
        }
@@ -84,7 +87,8 @@
                .eq(XpCruiseCheckInRuleLocation::getCruiseCheckInRuleId, xpCruiseCheckInRule.getId()));
        long count = xpCruiseCheckInRecordService.count(new LambdaQueryWrapper<XpCruiseCheckInRecord>()
                .eq(XpCruiseCheckInRecord::getCruiseCheckInRuleId, xpCruiseCheckInRule.getId())
                .eq(XpCruiseCheckInRecord::getDeleted, 0).eq(XpCruiseCheckInRecord::getOperationsUserId, uid));
                .eq(XpCruiseCheckInRecord::getDeleted, 0).eq(XpCruiseCheckInRecord::getOperationsUserId, uid)
                .last(" and DATE(check_in_time) = DATE(NOW())"));
        vo.setCheckInPointCount(count1);
        vo.setCheckInPointFinishCount(count);
        vo.setCheckInPointUnFinishCount(count1 - count);
@@ -128,6 +132,7 @@
            vo.setLon(xpCheckLocation.getLocationLon());
            vo.setLat(xpCheckLocation.getLocationLat());
            vo.setAddress(xpCheckLocation.getLocationAddress());
            vo.setOpenRange(xpCheckLocation.getLocationRange());
            appXpCruiseCheckInLocationVos.add(vo);
        }
        return appXpCruiseCheckInLocationVos;
@@ -141,8 +146,15 @@
    @Override
    public Long saveCruiseCheckInRecord(XpCruiseCheckInRecord dto) {
        Long checkLocationId = dto.getCheckLocationId();
        List<XpCruiseCheckInRule> list = this.list(new LambdaQueryWrapper<XpCruiseCheckInRule>().eq(XpCruiseCheckInRule::getDeleted, 0)
                .eq(XpCruiseCheckInRule::getOperationsUserId, dto.getOperationsUserId()).last(" and (now() BETWEEN start_time and end_time or cyclic_mode = 1)"));
        if(list.isEmpty()){
            return null;
        }
        XpCruiseCheckInRule xpCruiseCheckInRule = list.get(0);
        dto.setCruiseCheckInRuleId(xpCruiseCheckInRule.getId());
        XpCruiseCheckInRuleLocation one = xpCruiseCheckInRuleLocationService.getOne(new LambdaQueryWrapper<XpCruiseCheckInRuleLocation>()
                .eq(XpCruiseCheckInRuleLocation::getCheckLocationId, checkLocationId));
                .eq(XpCruiseCheckInRuleLocation::getCheckLocationId, checkLocationId).eq(XpCruiseCheckInRuleLocation::getCruiseCheckInRuleId, dto.getCruiseCheckInRuleId()));
        if(null == one){
            throw new ServiceException("打卡点位不存在", I18nKeyConstant.CHECK_IN_LOCATION_DOES_NOT_EXIST);
        }
@@ -159,10 +171,12 @@
        dto.setCheckInTime(LocalDateTime.now());
        dto.setCheckInResult(1);
        //判断当前打卡时间是否超过限定时间
        Integer endTime = Integer.valueOf(one.getEndTime().replace(":", ""));
        Integer nowTime = Integer.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmm")));
        if(nowTime > endTime){
            dto.setCheckInResult(2);
        if(StringUtils.isNotEmpty(one.getEndTime())){
            Integer endTime = Integer.valueOf(one.getEndTime().replace(":", ""));
            Integer nowTime = Integer.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmm")));
            if(nowTime > endTime){
                dto.setCheckInResult(2);
            }
        }
        dto.setDeleted(false);
        xpCruiseCheckInRecordService.save(dto);
@@ -220,12 +234,8 @@
        Map<String, Double> distance = GeodesyUtil.getDistance(xpCheckLocation.getLocationLon() + "," + xpCheckLocation.getLocationLat(), dto.getLongitude() + "," + dto.getLatitude());
        if(xpCheckLocation.getLocationRange().compareTo(new BigDecimal(distance.get("WGS84"))) >= 0){
            vo.setIsInRange(true);
            Boolean read = redisService.getCacheObject("CHECK_IN_SCOPE:" + xpCheckLocation.getId());
            if(null == read || !read){
                vo.setMessageType(2);
                vo.setCheckLocationId(cruiseCheckInRuleLocation.getCheckLocationId());
                redisService.setCacheObject("CHECK_IN_SCOPE:" + xpCheckLocation.getId(), true, 1L, TimeUnit.HOURS);
            }
            vo.setMessageType(2);
            vo.setCheckLocationId(cruiseCheckInRuleLocation.getCheckLocationId());
            return vo;
        }
        //判断时间小于10分钟首次触发和小于3分钟再次触发
@@ -279,12 +289,16 @@
            List<XpOperationsUser> data = xpOperationsUserClient.getByPhoneNumber(dto.getPhoneNumber()).getData();
            ids.addAll(data.stream().map(XpOperationsUser::getId).collect(Collectors.toList()));
        }
        if(!list().isEmpty()){
            List<XpCruiseCheckInRuleOperationsUser> operationsUserId = xpCruiseCheckInRuleOperationsUserMapper.selectList(new QueryWrapper<XpCruiseCheckInRuleOperationsUser>().in("operations_user_id", ids));
            List<Integer> ruleIds = operationsUserId.stream().map(XpCruiseCheckInRuleOperationsUser::getCruiseCheckInRuleId).collect(Collectors.toList());
            dto.setIds(ruleIds);
        List<XpCruiseCheckInRuleListPage> xpCruiseCheckInRuleListPage = this.baseMapper.getXpCruiseCheckInRuleListPage(pageInfo, dto.getName(), ids);
        for (XpCruiseCheckInRuleListPage cruiseCheckInRuleListPage : xpCruiseCheckInRuleListPage) {
            long count = xpCruiseCheckInRuleLocationService.count(new LambdaQueryWrapper<XpCruiseCheckInRuleLocation>()
                    .eq(XpCruiseCheckInRuleLocation::getCruiseCheckInRuleId, cruiseCheckInRuleListPage.getId()));
            cruiseCheckInRuleListPage.setPointNum(count);
            XpOperationsUser xpOperationsUser = xpOperationsUserClient.queryById(cruiseCheckInRuleListPage.getOperationsUserId()).getData();
            cruiseCheckInRuleListPage.setUserName(xpOperationsUser.getNickName());
            cruiseCheckInRuleListPage.setPhone(xpOperationsUser.getPhoneNumber());
            cruiseCheckInRuleListPage.setRoleName(xpOperationsUser.getRoleName());
        }
        List<XpCruiseCheckInRuleListPage> xpCruiseCheckInRuleListPage = this.baseMapper.getXpCruiseCheckInRuleListPage(pageInfo, dto);
        return xpCruiseCheckInRuleListPage;
    }
@@ -299,19 +313,105 @@
        if(null != one){
            throw new ServiceException("巡游打卡规则名称已存在");
        }
        // 校验同一运维人员是否已存在有效规则(未删除且非循环模式或时间在有效期内)
        long count = countByAnyOperationsUserId(dto.getRelationId(), null);
        if (count > 0) {
            throw new ServiceException("该运维人员已存在有效的巡游打卡规则");
        }
        XpCruiseCheckInRule xpCruiseCheckInRule = new XpCruiseCheckInRule();
        BeanUtils.copyProperties(dto, xpCruiseCheckInRule);
        xpCruiseCheckInRule.setDeleted(false);
        xpCruiseCheckInRule.setOperationsUserId(dto.getRelationId());
        this.save(xpCruiseCheckInRule);
        dto.getPoints().forEach(s->{
            s.setCruiseCheckInRuleId(xpCruiseCheckInRule.getId());
        });
        xpCruiseCheckInRuleLocationService.saveBatch(dto.getPoints());
        Long relationId = dto.getRelationId();
    }
        XpCruiseCheckInRuleOperationsUser xpCruiseCheckInRuleOperationsUser = new XpCruiseCheckInRuleOperationsUser();
        xpCruiseCheckInRuleOperationsUser.setCruiseCheckInRuleId(xpCruiseCheckInRule.getId());
        xpCruiseCheckInRuleOperationsUser.setOperationsUserId(relationId);
        xpCruiseCheckInRuleOperationsUserMapper.insert(xpCruiseCheckInRuleOperationsUser);
    /**
     * 编辑巡游打卡规则
     * @param dto
     */
    @Override
    public void updateXpCruiseCheckInRule(XpCruiseCheckInRuleDto dto) {
        XpCruiseCheckInRule one = this.getOne(new QueryWrapper<XpCruiseCheckInRule>().like("name", dto.getName()).ne("id", dto.getId()).eq("is_deleted", 0));
        if(null != one){
            throw new ServiceException("巡游打卡规则名称已存在");
        }
        // 校验同一运维人员是否已存在有效规则(未删除且非循环模式或时间在有效期内)
        long count = countByAnyOperationsUserId(dto.getRelationId(), dto.getId());
        if (count > 0) {
            throw new ServiceException("该运维人员已存在有效的巡游打卡规则");
        }
        XpCruiseCheckInRule xpCruiseCheckInRule = new XpCruiseCheckInRule();
        BeanUtils.copyProperties(dto, xpCruiseCheckInRule);
        xpCruiseCheckInRule.setDeleted(false);
        xpCruiseCheckInRule.setOperationsUserId(dto.getRelationId());
        this.updateById(xpCruiseCheckInRule);
        // 移除原来的id
        xpCruiseCheckInRuleLocationService.remove(new LambdaQueryWrapper<XpCruiseCheckInRuleLocation>().eq(XpCruiseCheckInRuleLocation::getCruiseCheckInRuleId, xpCruiseCheckInRule.getId()));
        dto.getPoints().forEach(s->{
            s.setCruiseCheckInRuleId(xpCruiseCheckInRule.getId());
        });
        xpCruiseCheckInRuleLocationService.saveBatch(dto.getPoints());
    }
    /**
     * 获取打卡规则详情
     * @param id
     * @return
     */
    @Override
    public XpCruiseCheckInRuleInfoVo getXpCruiseCheckInRuleInfo(Integer id) {
        XpCruiseCheckInRuleInfoVo info = new XpCruiseCheckInRuleInfoVo();
        XpCruiseCheckInRule byId = this.getById(id);
        BeanUtils.copyProperties(byId, info);
        List<XpCruiseCheckInRuleLocation> list = xpCruiseCheckInRuleLocationService.list(new QueryWrapper<XpCruiseCheckInRuleLocation>().eq("cruise_check_in_rule_id", id));
        List<XpCheckLocation> xpCheckLocations = xpCheckLocationService.listByIds(list.stream().map(XpCruiseCheckInRuleLocation::getCheckLocationId).collect(Collectors.toList()));
        List<CruiseCheckInLocationVo> collect = list.stream().map(locationList -> {
            CruiseCheckInLocationVo vo = new CruiseCheckInLocationVo();
            vo.setAddress(xpCheckLocations.stream().filter(xpCheckLocation -> xpCheckLocation.getId().equals(locationList.getCheckLocationId())).findFirst().get().getLocationAddress());
            vo.setCheckRange(xpCheckLocations.stream().filter(xpCheckLocation -> xpCheckLocation.getId().equals(locationList.getCheckLocationId())).findFirst().get().getLocationRange());
            vo.setCheckTime(StringUtils.isNotEmpty(locationList.getStartTime()) ? locationList.getStartTime() + "~" + locationList.getEndTime() : "不限");
            return vo;
        }).collect(Collectors.toList());
        info.setLocationList(collect);
        List<XpOperationsUser> xpOperationsUser = xpOperationsUserClient.queryByIds(byId.getOperationsUserId()).getData();
        if(null != xpOperationsUser){
            info.setOperationsUser(xpOperationsUser.stream().map(XpOperationsUser::getNickName).collect(Collectors.toList()));
        }
        return info;
    }
    private long countByAnyOperationsUserId(String relationId, Integer excludeRuleId) {
        if (StringUtils.isEmpty(relationId)) {
            return 0;
        }
        List<String> relationIds = Arrays.stream(relationId.split(","))
                .map(String::trim)
                .filter(StringUtils::isNotEmpty)
                .collect(Collectors.toList());
        if (relationIds.isEmpty()) {
            return 0;
        }
        LambdaQueryWrapper<XpCruiseCheckInRule> queryWrapper = new LambdaQueryWrapper<XpCruiseCheckInRule>()
                .eq(XpCruiseCheckInRule::getDeleted, false)
                .and(wrapper -> {
                    wrapper.apply("find_in_set({0}, operations_user_id)", relationIds.get(0));
                    for (int i = 1; i < relationIds.size(); i++) {
                        wrapper.or().apply("find_in_set({0}, operations_user_id)", relationIds.get(i));
                    }
                });
        if (excludeRuleId != null) {
            queryWrapper.ne(XpCruiseCheckInRule::getId, excludeRuleId);
        }
        return this.count(queryWrapper);
    }
}