package com.xiaopeng.maintenance.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.xiaopeng.api.model.maintenance.XpCheckLocation;
|
import com.xiaopeng.api.model.maintenance.XpCruiseCheckInRecord;
|
import com.xiaopeng.api.model.maintenance.XpCruiseCheckInRule;
|
import com.xiaopeng.api.model.maintenance.XpCruiseCheckInRuleLocation;
|
import com.xiaopeng.common.core.exception.ServiceException;
|
import com.xiaopeng.common.core.utils.GeodesyUtil;
|
import com.xiaopeng.maintenance.constant.I18nKeyConstant;
|
import com.xiaopeng.maintenance.mapper.XpCruiseCheckInRuleMapper;
|
import com.xiaopeng.maintenance.model.vo.AppXpCruiseCheckInLocationVo;
|
import com.xiaopeng.maintenance.model.vo.AppXpCruiseCheckInRuleVo;
|
import com.xiaopeng.maintenance.model.vo.CheckInMessageVo;
|
import com.xiaopeng.maintenance.model.vo.RealTimePositionVo;
|
import com.xiaopeng.maintenance.service.IXpCheckLocationService;
|
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRecordService;
|
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRuleLocationService;
|
import com.xiaopeng.maintenance.service.IXpCruiseCheckInRuleService;
|
import org.springframework.stereotype.Service;
|
|
import javax.annotation.Resource;
|
import java.math.BigDecimal;
|
import java.time.LocalDateTime;
|
import java.time.ZoneOffset;
|
import java.time.format.DateTimeFormatter;
|
import java.util.ArrayList;
|
import java.util.Collections;
|
import java.util.List;
|
import java.util.Map;
|
import java.util.stream.Collectors;
|
|
|
@Service
|
public class XpCruiseCheckInRuleServiceImpl extends ServiceImpl<XpCruiseCheckInRuleMapper, XpCruiseCheckInRule> implements IXpCruiseCheckInRuleService {
|
|
@Resource
|
private IXpCruiseCheckInRecordService xpCruiseCheckInRecordService;
|
|
@Resource
|
private IXpCruiseCheckInRuleLocationService xpCruiseCheckInRuleLocationService;
|
|
@Resource
|
private IXpCheckLocationService xpCheckLocationService;
|
|
|
|
@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)"));
|
if(list.isEmpty()){
|
return null;
|
}
|
XpCruiseCheckInRule xpCruiseCheckInRule = list.get(0);
|
|
AppXpCruiseCheckInRuleVo vo = new AppXpCruiseCheckInRuleVo();
|
vo.setId(xpCruiseCheckInRule.getId());
|
vo.setCruiseCheckInTaskTime(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " "
|
+ xpCruiseCheckInRule.getStartTime().format(DateTimeFormatter.ofPattern("HH:mm")) + "~"
|
+ xpCruiseCheckInRule.getEndTime().format(DateTimeFormatter.ofPattern("HH:mm")));
|
long count1 = xpCruiseCheckInRuleLocationService.count(new LambdaQueryWrapper<XpCruiseCheckInRuleLocation>()
|
.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));
|
vo.setCheckInPointCount(count1);
|
vo.setCheckInPointFinishCount(count);
|
vo.setCheckInPointUnFinishCount(count1 - count);
|
return vo;
|
}
|
|
|
/**
|
* 获取APP端签到规则位置信息
|
* @param ruleId
|
* @param uid
|
* @return
|
*/
|
@Override
|
public List<AppXpCruiseCheckInLocationVo> getAppXpCruiseCheckInLocation(Integer ruleId, Long uid) {
|
//查询巡游打卡规则和点位关系数据
|
List<XpCruiseCheckInRuleLocation> list = xpCruiseCheckInRuleLocationService.list(new LambdaQueryWrapper<XpCruiseCheckInRuleLocation>()
|
.eq(XpCruiseCheckInRuleLocation::getCruiseCheckInRuleId, ruleId).orderByAsc(XpCruiseCheckInRuleLocation::getSort));
|
//查询打卡点位数据
|
List<XpCheckLocation> xpCheckLocations = xpCheckLocationService.listByIds(list.stream().map(XpCruiseCheckInRuleLocation::getCheckLocationId).collect(Collectors.toList()));
|
List<AppXpCruiseCheckInLocationVo> appXpCruiseCheckInLocationVos = new ArrayList<>();
|
//获取运维人员打卡记录
|
List<XpCruiseCheckInRecord> list1 = xpCruiseCheckInRecordService.list(new LambdaQueryWrapper<XpCruiseCheckInRecord>()
|
.eq(XpCruiseCheckInRecord::getDeleted, 0)
|
.eq(XpCruiseCheckInRecord::getCruiseCheckInRuleId, ruleId)
|
.eq(XpCruiseCheckInRecord::getOperationsUserId, uid)
|
.last(" and DATE_FORMAT(check_in_time, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d"));
|
//构建返回结果
|
for (XpCruiseCheckInRuleLocation xpCruiseCheckInRuleLocation : list) {
|
XpCruiseCheckInRecord xpCruiseCheckInRecord = list1.stream().filter(x -> x.getCheckLocationId().equals(xpCruiseCheckInRuleLocation.getCheckLocationId())).findFirst().orElse(null);
|
XpCheckLocation xpCheckLocation = xpCheckLocations.stream().filter(x -> x.getId().equals(xpCruiseCheckInRuleLocation.getCheckLocationId())).findFirst().orElse(null);
|
AppXpCruiseCheckInLocationVo vo = new AppXpCruiseCheckInLocationVo();
|
vo.setLocationId(xpCruiseCheckInRuleLocation.getCheckLocationId());
|
vo.setTime(xpCruiseCheckInRuleLocation.getStartTime() + "-" + xpCruiseCheckInRuleLocation.getEndTime());
|
vo.setCheckIn(0);
|
if(null != xpCruiseCheckInRecord){
|
vo.setCheckInTime(xpCruiseCheckInRecord.getCheckInTime().format(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
vo.setCheckIn(1);
|
vo.setCheckInResult(xpCruiseCheckInRecord.getCheckInResult());
|
}
|
vo.setLon(xpCheckLocation.getLocationLon());
|
vo.setLat(xpCheckLocation.getLocationLat());
|
vo.setAddress(xpCheckLocation.getLocationAddress());
|
appXpCruiseCheckInLocationVos.add(vo);
|
}
|
return appXpCruiseCheckInLocationVos;
|
}
|
|
|
/**
|
* 运维人员巡游打卡操作
|
* @param dto
|
*/
|
@Override
|
public void saveCruiseCheckInRecord(XpCruiseCheckInRecord dto) {
|
Long checkLocationId = dto.getCheckLocationId();
|
XpCruiseCheckInRuleLocation one = xpCruiseCheckInRuleLocationService.getOne(new LambdaQueryWrapper<XpCruiseCheckInRuleLocation>()
|
.eq(XpCruiseCheckInRuleLocation::getCheckLocationId, checkLocationId));
|
if(null == one){
|
throw new ServiceException("打卡点位不存在", I18nKeyConstant.CHECK_IN_LOCATION_DOES_NOT_EXIST);
|
}
|
XpCruiseCheckInRecord cruiseCheckInRecord = xpCruiseCheckInRecordService.getOne(new LambdaQueryWrapper<XpCruiseCheckInRecord>()
|
.eq(XpCruiseCheckInRecord::getCruiseCheckInRuleId, one.getCruiseCheckInRuleId())
|
.eq(XpCruiseCheckInRecord::getDeleted, 0)
|
.eq(XpCruiseCheckInRecord::getCheckLocationId, checkLocationId)
|
.eq(XpCruiseCheckInRecord::getOperationsUserId, dto.getOperationsUserId())
|
.last(" and DATE_FORMAT(check_in_time, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d')"));
|
if(null != cruiseCheckInRecord){
|
throw new ServiceException("不能重复打卡", I18nKeyConstant.CANNOT_REPEAT_CLOCKING_IN);
|
}
|
dto.setCruiseCheckInRuleId(one.getCruiseCheckInRuleId());
|
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);
|
}
|
dto.setDeleted(false);
|
xpCruiseCheckInRecordService.save(dto);
|
}
|
|
|
|
/**
|
* 运维端实时上传位置信息,返回提醒消息
|
* @param dto
|
* @return
|
*/
|
@Override
|
public CheckInMessageVo uploadRealTimePosition(RealTimePositionVo dto, Long uid) {
|
List<XpCruiseCheckInRuleLocation> list = xpCruiseCheckInRuleLocationService.list(new LambdaQueryWrapper<XpCruiseCheckInRuleLocation>()
|
.eq(XpCruiseCheckInRuleLocation::getCruiseCheckInRuleId, dto.getId())
|
.orderByAsc(XpCruiseCheckInRuleLocation::getSort));
|
if(list.isEmpty()){
|
return null;
|
}
|
//查找即将需要到达的打卡点位
|
XpCruiseCheckInRecord cruiseCheckInRecord = xpCruiseCheckInRecordService.getOne(new LambdaQueryWrapper<XpCruiseCheckInRecord>()
|
.eq(XpCruiseCheckInRecord::getCruiseCheckInRuleId, dto.getId())
|
.eq(XpCruiseCheckInRecord::getDeleted, 0)
|
.eq(XpCruiseCheckInRecord::getOperationsUserId, uid)
|
.last(" and DATE_FORMAT(check_in_time, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d') order by check_in_time desc limit 1"));
|
XpCruiseCheckInRuleLocation cruiseCheckInRuleLocation = null;
|
//没有打卡的情况,用第一个打卡点位
|
if(null == cruiseCheckInRecord){
|
cruiseCheckInRuleLocation = list.get(0);
|
}else{
|
Long checkLocationId = cruiseCheckInRecord.getCheckLocationId();
|
for (int i = 0; i < list.size(); i++) {
|
Long checkLocationId1 = list.get(i).getCheckLocationId();
|
if(checkLocationId.equals(checkLocationId1) && i < list.size() - 1){
|
cruiseCheckInRuleLocation = list.get(i + 1);
|
break;
|
}
|
}
|
}
|
//没有需要打卡的点位,则返回空数据
|
if(null == cruiseCheckInRuleLocation){
|
return null;
|
}
|
|
//先判断当前定位是否到达打卡点位附近,在范围内则返回打卡消息
|
XpCheckLocation xpCheckLocation = xpCheckLocationService.getById(cruiseCheckInRuleLocation.getCheckLocationId());
|
if(null == xpCheckLocation){
|
return null;
|
}
|
|
CheckInMessageVo vo = new CheckInMessageVo();
|
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.setMessageType(1);
|
vo.setCheckLocationId(cruiseCheckInRuleLocation.getCheckLocationId());
|
return vo;
|
}
|
//判断时间小于10分钟首次触发和小于3分钟再次触发
|
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime endTime = now.withHour(Integer.parseInt(cruiseCheckInRuleLocation.getEndTime().split(":")[0]))
|
.withMinute(Integer.parseInt(cruiseCheckInRuleLocation.getEndTime().split(":")[1]))
|
.withSecond(0);
|
long time = endTime.toEpochSecond(ZoneOffset.of("+8")) - now.toEpochSecond(ZoneOffset.of("+8"));
|
if((time <= 10 * 60 && time > 10 * 50) || (time <= 3 * 60 && time > 3 * 50)){
|
vo.setMessageType(2);
|
vo.setCheckLocationId(cruiseCheckInRuleLocation.getCheckLocationId());
|
vo.setMessage(time > 10 * 50 ? "距离打卡超时还有10分钟,请尽快前往打卡点" : "距离打卡超时还有3分钟,请尽快前往打卡点");
|
return vo;
|
}
|
return null;
|
}
|
|
|
/**
|
* 获取巡游打卡详情
|
* @param ruleId
|
* @param locationId
|
* @param uid
|
* @return
|
*/
|
@Override
|
public XpCruiseCheckInRecord getCruiseCheckInRecordInfo(Integer ruleId, Long locationId, Long uid) {
|
return xpCruiseCheckInRecordService.getOne(new LambdaQueryWrapper<XpCruiseCheckInRecord>()
|
.eq(XpCruiseCheckInRecord::getCruiseCheckInRuleId, ruleId)
|
.eq(XpCruiseCheckInRecord::getCheckLocationId, locationId)
|
.eq(XpCruiseCheckInRecord::getDeleted, 0)
|
.eq(XpCruiseCheckInRecord::getOperationsUserId, uid)
|
.last(" and DATE_FORMAT(check_in_time, '%Y-%m-%d') = DATE_FORMAT(NOW(), '%Y-%m-%d')"));
|
}
|
}
|