package com.fdkankan.ucenter.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.SceneConstant;
import com.fdkankan.common.constant.SceneKind;
import com.fdkankan.common.constant.SceneVersionType;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.*;
import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
import com.fdkankan.rabbitmq.util.RabbitMqProducer;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.ucenter.common.OssPath;
import com.fdkankan.ucenter.common.PageInfo;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.ucenter.common.constants.ResultCodeMsg;
import com.fdkankan.ucenter.constant.CameraConstant;
import com.fdkankan.ucenter.constant.LoginConstant;
import com.fdkankan.ucenter.entity.*;
import com.fdkankan.ucenter.httpClient.service.LaserService;
import com.fdkankan.ucenter.mapper.ISceneProMapper;
import com.fdkankan.ucenter.mapper.ISceneUpgradeMapper;
import com.fdkankan.ucenter.service.*;
import com.fdkankan.ucenter.util.DateUserUtil;
import com.fdkankan.ucenter.util.SceneResourcePath;
import com.fdkankan.ucenter.vo.ResponseScene;
import com.fdkankan.ucenter.vo.request.RequestScene;
import com.fdkankan.ucenter.vo.request.SceneParam;
import com.fdkankan.ucenter.vo.response.*;
import java.io.File;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
/**
*
* pro场景表 服务实现类
*
*
* @author
* @since 2022-07-04
*/
@Service
@Slf4j
public class SceneProServiceImpl extends ServiceImpl implements ISceneProService {
@Autowired
private IUserService userService;
@Autowired
private ISceneCooperationService sceneCooperationService;
@Autowired
private IScenePlusService scenePlusService;
@Autowired
private ISceneService sceneService;
@Autowired
private LaserService fdkkLaserService;
@Autowired
private FYunFileServiceInterface fYunFileService;
@Autowired
private IUserIncrementService userIncrementService;
@Autowired
private IIncrementTypeService incrementTypeService;
@Autowired
private IScenePlusExtService scenePlusExtService;
@Autowired
private ISceneEditInfoService sceneEditInfoService;
@Autowired
private ICameraDetailService cameraDetailService;
@Autowired
ICameraService cameraService;
@Autowired
private IFolderService folderService;
@Autowired
private IFolderSceneService folderSceneService;
@Autowired
private ISceneCopyLogService sceneCopyLogService;
@Autowired
private IScene3dNumService scene3dNumService;
@Autowired
private ISceneProEditService sceneProEditService;
@Autowired
private SceneCommonService sceneCommonService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private ISceneUpgradeMapper sceneUpgradeMapper;
@Autowired
private IInnerService innerService;
@Autowired
LaserService laserService;
@Autowired
private FYunFileServiceInterface fYunFileServiceInterface;
@Autowired
ISceneDelLogService sceneDelLogService;
@Value("${scene.pro.url}")
private String sceneProUrl;
@Value("${scene.pro.new.url}")
private String sceneProNewUrl;
@Value("${queue.modeling.obj.modeling-pre}")
private String queueObjModelingPre;
@Autowired
private RabbitMqProducer mqProducer;
@Autowired
ICameraTypeService cameraTypeService;
@Override
public HashMap findSceneNumber(String token) {
User user = userService.getByUserName(JwtUtil.getUsername(token));
SceneNumVo sceneNumVoKk = getSceneNumVoByType(Arrays.asList(1,2,12,13,14), user.getId());
Integer oldNum = sceneService.getCountByUserId(user.getId());
sceneNumVoKk.setSceneNum( oldNum + sceneNumVoKk.getSceneNum());
sceneNumVoKk.setTotalNum(oldNum + sceneNumVoKk.getTotalNum());
SceneNumVo sceneNumVoKj = getSceneNumVoByType(Collections.singletonList(3), user.getId());
SceneNumVo sceneNumVoSS = fdkkLaserService.getLaserSceneNumByUser(token,4);
SceneNumVo sceneNumVoSSObj = getSceneNumVoByObjType(Arrays.asList(4), user.getId());
SceneNumVo sceneNumVoSG = fdkkLaserService.getLaserSceneNumByUser(token,5);
SceneNumVo sceneNumVoSGObj = getSceneNumVoByObjType(Arrays.asList(5), user.getId());
SceneNumVo sceneNumVoE57 = fdkkLaserService.getLaserSceneNumByUser(token,57);
SceneNumVo sceneNumVoE57Obj = getSceneNumVoByObjType(Arrays.asList(57), user.getId());
HashMap hashMap = new HashMap<>();
hashMap.put("kk",sceneNumVoKk);
hashMap.put("kJ",sceneNumVoKj);
hashMap.put("SS",sceneNumVoSS);
hashMap.put("SS_OBJ",sceneNumVoSSObj);
hashMap.put("SG",sceneNumVoSG);
hashMap.put("SG_OBJ",sceneNumVoSGObj);
hashMap.put("e57",sceneNumVoE57);
hashMap.put("e57_OBJ",sceneNumVoE57Obj);
return hashMap;
}
private SceneNumVo getSceneNumVoByType(List sceneSourceList, Long userId){
SceneNumVo sceneNumVo = new SceneNumVo();
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ScenePro::getUserId, userId);
queryWrapper.in(ScenePro::getSceneSource, sceneSourceList);
queryWrapper.eq(ScenePro::getIsUpgrade, 0);
Integer sceneNum = Math.toIntExact(this.count(queryWrapper));
Long count = scenePlusService.getCountByUserId(userId,sceneSourceList);
sceneNumVo.setCooperationSceneNum(sceneCooperationService.getCooperationSceneNum(userId,sceneSourceList));
sceneNumVo.setSceneNum(sceneNum + count);
sceneNumVo.setTotalNum(sceneNumVo.getSceneNum() + sceneNumVo.getCooperationSceneNum());
return sceneNumVo;
}
private SceneNumVo getSceneNumVoByObjType(List sceneSourceList, Long userId){
SceneNumVo sceneNumVo = new SceneNumVo();
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(ScenePro::getUserId, userId);
queryWrapper.in(ScenePro::getSceneSource, sceneSourceList);
queryWrapper.eq(ScenePro::getIsUpgrade, 0);
queryWrapper.eq(ScenePro::getIsObj,1);
Integer sceneNum = Math.toIntExact(this.count(queryWrapper));
List scenePlusList = scenePlusService.getCountByUserIdAndSceneSource(userId,sceneSourceList,1);
long plusCount = scenePlusList.size();
Long cooperNum = sceneCooperationService.getCooperationSceneNum(userId, sceneSourceList);
sceneNumVo.setCooperationSceneNum(cooperNum);
sceneNumVo.setSceneNum(sceneNum + plusCount);
sceneNumVo.setTotalNum(sceneNumVo.getSceneNum() + sceneNumVo.getCooperationSceneNum());
return sceneNumVo;
}
@Override
public HashMap findSceneNumByCameraIds(List cameraIdList) {
HashMap map = new HashMap<>();
List result = this.getBaseMapper().findSceneProNumByCameraIds(cameraIdList);
List result2 = this.getBaseMapper().findScenePlusNumByCameraIds(cameraIdList);
result.forEach(entity ->map.put(entity.getId(),entity));
for (GroupByCount groupByCount : result2) {
if (map.get(groupByCount.getId()) != null) {
Long totalCount = map.get(groupByCount.getId()).getCount() + groupByCount.getCount();
String lastTime = DateUserUtil.getLastTime(map.get(groupByCount.getId()).getLastTime(), groupByCount.getLastTime());
groupByCount.setCount(totalCount);
groupByCount.setLastTime(lastTime);
}
map.put(groupByCount.getId(),groupByCount);
}
return map;
}
public void lockOrUnLockBySpace(Long cameraId){
CameraDetail cameraDetail = cameraDetailService.getByCameraId(cameraId);
this.lockOrUnLockBySpace(cameraDetail,cameraId);
}
@Override
public void lockOrUnLockBySpace(CameraDetail cameraDetail, Long cameraId) {
List voList = this.getSimpleSceneVo(cameraDetail);
if(voList .size() <=0){
return;
}
CameraType cameraType = cameraTypeService.getByCameraType(cameraDetail.getType());
Long totalSpace = cameraDetailService.getTotalSpaceByCameraId(cameraDetail);
Long usedSpace = 0L;
//获取未被封存的场景容量
List spaceList = voList.stream().filter(entity -> entity.getPayStatus() == 1).map(SimpleSceneVo::getSpace).collect(Collectors.toList());
if("SP".equals(cameraDetail.getUnit())){
usedSpace = (long) spaceList.size();
}
if("GB".equals(cameraDetail.getUnit())){
for (Long aLong : spaceList) {
usedSpace += aLong;
}
}
//计算时间倒序
List sceneVos = voList.stream().sorted(Comparator.comparing(SimpleSceneVo::getCreateTime).reversed()).collect(Collectors.toList());
if(totalSpace == -1){ // 无限容量 全部解封
sceneVos = sceneVos.stream().filter(e -> e.getPayStatus() !=1).collect(Collectors.toList());
lockOrUnLockScenes(sceneVos,1,cameraType);
return;
}
//按计算完成时间由新到旧封存
//按计算完成时间由旧到新解封
//payStatus 1解封,-2封存
List lockedIds = new ArrayList<>();
if(usedSpace > totalSpace){
sceneVos = sceneVos.stream().filter(entity -> entity.getPayStatus() ==1).collect(Collectors.toList());
Long space = getSceneLockedIds(lockedIds, sceneVos, usedSpace - totalSpace,cameraDetail.getUnit());
log.info("lockOrUnLockBySpace---cameraId:{},totalSpace:{},useSpace{},space:{},payStatus:{}", cameraId,totalSpace,usedSpace,space,-2);
lockOrUnLockScenes(lockedIds,-2,cameraType);
return;
}
if(usedSpace < totalSpace){ //使用容量小于总容量,解封
sceneVos = sceneVos.stream().filter(entity -> entity.getPayStatus() !=1).collect(Collectors.toList());
CollectionUtil.reverse(sceneVos);
Long space = getSceneUnLockedIds(lockedIds, sceneVos, totalSpace - usedSpace,cameraDetail.getUnit());
log.info("lockOrUnLockBySpace---cameraId:{},totalSpace:{},useSpace{},space:{},payStatus:{}", cameraId,totalSpace,usedSpace,space,1);
lockOrUnLockScenes(lockedIds,1,cameraType);
}
}
private void lockOrUnLockScenes(List sceneVos, Integer payStatus,CameraType cameraType){
List v3NumList = sceneVos.stream().filter(e ->"v3".equals(e.getVersion())).map(SimpleSceneVo::getNum).collect(Collectors.toList());
List v4NumList = sceneVos.stream().filter(e ->"v4".equals(e.getVersion())).map(SimpleSceneVo::getNum).collect(Collectors.toList());
List panoNumList = sceneVos.stream().filter(e ->"v4".equals(e.getVersion()) && e.getLocation() != null && e.getLocation() == 7).map(SimpleSceneVo::getNum).collect(Collectors.toList());
lockOrUnLockScenes(v3NumList,v4NumList,payStatus,cameraType.getIsLaser(),panoNumList);
}
private Long getSceneUnLockedIds(List lockedIds ,List list,Long beyondSpace,String unit){
Long space = 0L;
if (list != null && list.size() > 0){
for (SimpleSceneVo scenePro : list){
Long sceneSpace = scenePro.getSpace()== null ? 0 : scenePro.getSpace();
if("SP".equals(unit)){
sceneSpace = 1L;
}
if (space + sceneSpace > beyondSpace){
break;
}
space += sceneSpace;
lockedIds.add(scenePro);
}
}
return space;
}
private Long getSceneLockedIds(List lockedIds ,List list,Long beyondSpace,String unit){
Long space = 0L;
if (list != null && list.size() > 0){
for (SimpleSceneVo scenePro : list){
Long sceneSpace = scenePro.getSpace()== null ? 0 : scenePro.getSpace();
if("SP".equals(unit)){
sceneSpace = 1L;
}
space += sceneSpace;
lockedIds.add(scenePro);
if (space >= beyondSpace){
break;
}
}
}
return space;
}
// payStatus 为 -2 封存,为 1 解封
@Override
public void lockOrUnLockScenes( List v3NumList,List v4NumList,Integer payStatus,Integer isLaser,List panoNumList) {
if(!v3NumList.isEmpty()){
LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(ScenePro::getPayStatus,payStatus)
.eq(ScenePro::getIsUpgrade,0)
.in(ScenePro::getNum,v3NumList);
this.update(updateWrapper);
}
if(!v4NumList.isEmpty()){
LambdaUpdateWrapper updatePlusWrapper = new LambdaUpdateWrapper<>();
updatePlusWrapper.set(ScenePlus::getPayStatus,payStatus)
.in(ScenePlus::getNum,v4NumList);
scenePlusService.update(updatePlusWrapper);
}
this.updateOssStatus(v3NumList,v4NumList,payStatus);
List numList = new ArrayList<>();
numList.addAll(v3NumList);
numList.addAll(v4NumList);
if(isLaser == 1){
//激光系统相机
//1:场景被删 0:计算中 1计算失败 2计算成功 3封存 4重算中'
if(!numList.isEmpty()){
laserService.updateStatus(numList,payStatus);
}
}
if(panoNumList != null && !panoNumList.isEmpty()){
laserService.updatePanoStatus(numList,payStatus);
}
}
/**
* 修改oss status.json中 payStatus
*/
private void updateOssStatus(List v3NumList ,List v4NumList , Integer payStatus) {
if(!v3NumList.isEmpty()){
v3NumList.forEach(e ->this.updateOssStatus(String.format(OssPath.v3_statusPath,e),payStatus,e));
}
if(!v4NumList.isEmpty()){
v4NumList.forEach(e ->this.updateOssStatus(String.format(OssPath.v4_statusPath,e),payStatus,e));
}
}
/**
* 从oss中获取文件,并重写,上传替换
*/
public void updateOssStatus(String path,Integer payStatus,String num) {
String localStatusPath = String.format(OssPath.localStatusPath,num);
try {
if(!fYunFileService.fileExist(path)){
return;
}
String data = fYunFileService.getFileContent(path);
if(StringUtils.isBlank(data)){
return;
}
JSONObject jsonObject = JSONObject.parseObject(data);
jsonObject.put("payStatus",payStatus);
String json = JSONUtil.toJsonStr(jsonObject);
FileUtils.writeFile(localStatusPath ,json);
log.info("updateOssStatus--localPath:{},ossPath:{},payStatus:{}",localStatusPath,path,payStatus);
fYunFileService.uploadFile(localStatusPath,path);
}catch (Exception e){
log.info("updateOssStatus--localPath:{},ossPath:{},payStatus:{}",localStatusPath,path,payStatus,e);
}finally {
if(new File(localStatusPath).getParentFile().exists()){
FileUtil.del( new File(localStatusPath).getParentFile());
}
}
}
@Override
public List getListByCameraId(Long cameraId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ScenePro::getCameraId,cameraId)
.eq(ScenePro::getIsUpgrade,0);
return this.list(wrapper);
}
@Override
public void bindOrUnCamera(List cameraIds, Long userId) {
if(cameraIds.size() >0){
LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
wrapper.in(ScenePro::getCameraId,cameraIds)
.eq(ScenePro::getIsUpgrade,0)
.set(ScenePro::getUserId,userId);
this.update(wrapper);
}
}
@Override
public List getListByCameraIds(List cameraIds) {
if(cameraIds.size() >0){
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(ScenePro::getCameraId,cameraIds)
.eq(ScenePro::getIsUpgrade,0);
return this.list(wrapper);
}
return new ArrayList<>();
}
@Override
public List getListByNums(List numList) {
if(numList.size() >0){
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(ScenePro::getNum,numList)
.eq(ScenePro::getIsUpgrade,0);
return this.list(wrapper);
}
return new ArrayList<>();
}
@Override
public Long getCountByUserId(Long userId, List> resourceList) {
if(resourceList.size() >0){
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ScenePro::getUserId,userId);
wrapper.eq(ScenePro::getIsUpgrade,0);
wrapper.in(ScenePro::getSceneSource,resourceList);
return this.count(wrapper);
}
return 0L;
}
@Override
public Long getCountByUserId(Long id, Integer cameraType) {
return this.getBaseMapper().getCountByUserId(id,cameraType);
}
@Override
public void deleteByIds(List sceneIds,Long userId) {
if(sceneIds.size() >0){
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(ScenePro::getId,sceneIds)
.eq(ScenePro::getIsUpgrade,0);
List proList = this.list(wrapper);
LambdaQueryWrapper plusWr = new LambdaQueryWrapper<>();
plusWr.in(ScenePlus::getId,sceneIds);
List plusList = scenePlusService.list(plusWr);
this.deleteByList(proList,plusList,userId,null);
}
}
@Override
public Page pageListAndFolder(Page