package com.xiaopeng.maintenance.service.impl;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.xiaopeng.api.feignClient.account.XpOperationUserClient;
|
import com.xiaopeng.api.feignClient.account.XpOperationsUserClient;
|
import com.xiaopeng.api.model.account.XpOperationsUser;
|
import com.xiaopeng.api.model.maintenance.*;
|
import com.xiaopeng.common.core.exception.ServiceException;
|
import com.xiaopeng.common.core.utils.GeodesyUtil;
|
import com.xiaopeng.common.core.utils.StringUtils;
|
import com.xiaopeng.common.redis.service.RedisService;
|
import com.xiaopeng.maintenance.constant.I18nKeyConstant;
|
import com.xiaopeng.maintenance.dto.XpCruiseCheckInRuleDto;
|
import com.xiaopeng.maintenance.dto.XpCruiseCheckInRuleListPageDto;
|
import com.xiaopeng.maintenance.mapper.XpCruiseCheckInRuleMapper;
|
import com.xiaopeng.maintenance.mapper.XpCruiseCheckInRuleOperationsUserMapper;
|
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 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;
|
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.concurrent.TimeUnit;
|
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;
|
@Autowired
|
private RedisService redisService;
|
|
@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)"));
|
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)
|
.last(" and DATE(check_in_time) = DATE(NOW())"));
|
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(check_in_time) = DATE(NOW())"));
|
//构建返回结果
|
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 Long 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(check_in_time) = DATE(NOW())"));
|
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);
|
return dto.getId();
|
}
|
|
|
|
/**
|
* 运维端实时上传位置信息,返回提醒消息
|
* @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(check_in_time) = DATE(NOW()) 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();
|
vo.setIsInRange(false);
|
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);
|
}
|
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(1);
|
vo.setCheckLocationId(cruiseCheckInRuleLocation.getCheckLocationId());
|
vo.setMessage(time > 10 * 50 ? "距离打卡超时还有10分钟,请尽快前往打卡点" : "距离打卡超时还有3分钟,请尽快前往打卡点");
|
return vo;
|
}
|
return vo;
|
}
|
|
|
/**
|
* 获取巡游打卡详情
|
* @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(check_in_time) = DATE(NOW())"));
|
}
|
|
|
/**
|
* 获取巡游打卡规则列表
|
* @param pageInfo
|
* @param dto
|
* @return
|
*/
|
@Override
|
public List<XpCruiseCheckInRuleListPage> getXpCruiseCheckInRuleListPage(Page<XpCruiseCheckInRuleListPage> pageInfo, XpCruiseCheckInRuleListPageDto dto) {
|
List<Long> ids = new ArrayList<>();
|
if(StringUtils.isNotEmpty(dto.getUserName())){
|
List<XpOperationsUser> data = xpOperationsUserClient.listByName(dto.getUserName()).getData();
|
ids.addAll(data.stream().map(XpOperationsUser::getId).collect(Collectors.toList()));
|
}
|
if(StringUtils.isNotEmpty(dto.getPhoneNumber())){
|
List<XpOperationsUser> data = xpOperationsUserClient.getByPhoneNumber(dto.getPhoneNumber()).getData();
|
ids.addAll(data.stream().map(XpOperationsUser::getId).collect(Collectors.toList()));
|
}
|
if(!ids.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);
|
return xpCruiseCheckInRuleListPage;
|
}
|
|
|
/**
|
* 新增巡游打卡规则
|
* @param dto
|
*/
|
@Override
|
public void addXpCruiseCheckInRule(XpCruiseCheckInRuleDto dto) {
|
XpCruiseCheckInRule one = this.getOne(new QueryWrapper<XpCruiseCheckInRule>().like("name", dto.getName()).eq("is_deleted", 0));
|
if(null != one){
|
throw new ServiceException("巡游打卡规则名称已存在");
|
}
|
XpCruiseCheckInRule xpCruiseCheckInRule = new XpCruiseCheckInRule();
|
BeanUtils.copyProperties(dto, xpCruiseCheckInRule);
|
xpCruiseCheckInRule.setDeleted(false);
|
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 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);
|
return info;
|
}
|
}
|