package com.fdkankan.manage_jp.service.impl;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A;
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.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.constant.SceneConstant;
import com.fdkankan.common.constant.SceneKind;
import com.fdkankan.common.constant.SceneVersionType;
import com.fdkankan.common.util.FileUtils;
import com.fdkankan.common.util.JwtUtil;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.manage_jp.common.OssPath;
import com.fdkankan.manage_jp.common.PageInfo;
import com.fdkankan.manage_jp.common.RedisKeyUtil;
import com.fdkankan.manage_jp.common.ResultCode;
import com.fdkankan.manage_jp.entity.*;
import com.fdkankan.manage_jp.exception.BusinessException;
import com.fdkankan.manage_jp.httpClient.service.LaserService;
import com.fdkankan.manage_jp.mapper.ISceneProMapper;
import com.fdkankan.manage_jp.mapper.ISceneUpgradeMapper;
import com.fdkankan.manage_jp.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.manage_jp.util.GenerateNumUtil;
import com.fdkankan.manage_jp.util.SceneResourcePath;
import com.fdkankan.manage_jp.util.SnowflakeIdGenerator;
import com.fdkankan.manage_jp.vo.request.SceneParam;
import com.fdkankan.manage_jp.vo.response.SceneVo;
import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
import com.fdkankan.rabbitmq.util.RabbitMqProducer;
import com.fdkankan.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.io.File;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;
/**
*
* pro场景表 服务实现类
*
*
* @author
* @since 2022-12-30
*/
@Service
@Slf4j
public class SceneProServiceImpl extends ServiceImpl implements ISceneProService {
@Autowired
IScenePlusService scenePlusService;
@Autowired
LaserService laserService;
@Autowired
ISceneProEditService sceneProEditService;
@Autowired
ICompanyService companyService;
@Autowired
IScenePlusExtService scenePlusExtService;
@Autowired
FYunFileServiceInterface fYunFileServiceInterface;
@Autowired
IScene3dNumService scene3dNumService;
@Autowired
SceneCommonService sceneCommonService;
@Autowired
ITmContractorService tmContractorService;
@Autowired
ITmContractorNumService tmContractorNumService;
@Autowired
IUserRoleService userRoleService;
@Autowired
ITmColdStorageService tmColdStorageService;
@Autowired
private RabbitMqProducer mqProducer;
@Value("${queue.modeling.obj.modeling-pre}")
private String queueObjModelingPre;
@Autowired
private ISceneUpgradeMapper sceneUpgradeMapper;
@Autowired
ISceneCopyLogService sceneCopyLogService;
@Autowired
ICameraDetailService cameraDetailService;
@Autowired
ICameraService cameraService;
@Autowired
IUserService userService;
@Autowired
ISceneMoveLogService sceneMoveLogService;
@Override
public Long getCountByUserIds(List userIds) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(ScenePro::getUserId,userIds);
wrapper.eq(ScenePro::getIsUpgrade,0);
long count = this.count(wrapper);
LambdaQueryWrapper wrapper2 = new LambdaQueryWrapper<>();
wrapper2.in(ScenePlus::getUserId,userIds);
long count2 = scenePlusService.count(wrapper2);
return count + count2;
}
@Override
public void rebindUser(Long fromUserId, Long toUserId) {
LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(ScenePro::getUserId,fromUserId);
wrapper.set(ScenePro::getUserId,toUserId);
this.update(wrapper);
LambdaUpdateWrapper wrapper2 = new LambdaUpdateWrapper<>();
wrapper2.eq(ScenePlus::getUserId,fromUserId);
wrapper2.set(ScenePlus::getUserId,toUserId);
scenePlusService.update(wrapper2);
}
@Override
public Object pageList(SceneParam param, User user) {
Set roleIds = userRoleService.getByUser(user);
List numList = new ArrayList<>();
List cooNumList = new ArrayList<>();
if(!roleIds.contains(5L)){ //平台管理员
param.setCompanyId(user.getCompanyId());
param.setUserId(user.getId());
param.setNeStatus(-2);
if(!roleIds.contains(6L)){
param.setIsDel(false);
param.setIsMain(false);
param.setIsMigrate(false);
}
numList = tmContractorNumService.getNumListByCompanyId(user.getCompanyId());
param.setCooperateSceneCodes(numList);
}
Page page = this.getBaseMapper().pageList(new Page<>(param.getPageNum(),param.getPageSize()),param);
List sceneNumList = page.getRecords().stream().map(SceneVo::getNum).collect(Collectors.toList());
if(!sceneNumList.isEmpty()){
cooNumList = tmContractorNumService.getNumList(sceneNumList);
}
HashMap ssSceneMap = new HashMap<>();
if(param.getType() == 2 || param.getType() == 5){
ssSceneMap = laserService.list(sceneNumList);
}
HashMap coldMap = tmColdStorageService.getByNumList(sceneNumList);
for (SceneVo record : page.getRecords()) {
if(param.getType() == 2 || param.getType() == 5){
JSONObject ssObj = ssSceneMap.get(record.getNum());
if(ssObj!=null){
record.setSceneName(ssObj.getString("title"));
record.setThumb(ssObj.getString("thumb"));
record.setWebSite(ssObj.getString("webSite"));
record.setIsObj(ssObj.getInteger("buildObjStatus"));
record.setViewCount(ssObj.getInteger("viewCount"));
record.setStatus(toFdStatus(ssObj.getInteger("status")));
}else{
record.setStatus(-1);
record.setWebSite(null);
}
}
if(StringUtils.isNotBlank(record.getSceneVersion()) && record.getSceneVersion().equals("v3")){
record.setIsUpgrade(0);
}
record.setIsDel(param.getIsDel());
record.setIsMain(param.getIsMain());
record.setIsDownload(param.getIsDownload());
record.setIsMigrate(param.getIsMigrate());
if(!roleIds.contains(5L) && numList != null && numList.contains(record.getNum())){
record.setIsMain(false);
record.setIsDel(false);
record.setIsDownload(false);
}
if(cooNumList != null && cooNumList.contains(record.getNum())){
record.setIsMigrate(false);
}
if(coldMap.get(record.getNum())!=null){
record.setIsMigrate(false);
}
}
return PageInfo.PageInfo(page);
}
private Integer toFdStatus(Integer status) {
//深时状态,-1:场景被删 0:计算中 1计算失败 2计算成功 3封存 4生成OBJ中
switch (status) {
case 0:
case 4:
return 0;
case 2:
return -2;
case 3:
return -3;
default:
return -1;
}
}
@Override
public ScenePro getByNum(String num) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(ScenePro::getNum,num);
wrapper.eq(ScenePro::getIsUpgrade,0);
List list = this.list(wrapper);
if(list == null || list.size() <=0){
return null;
}
return list.get(0);
}
@Override
public HashMap getByNumList(List numList) {
HashMap map = new HashMap<>();
if(numList == null || numList.isEmpty()){
return map;
}
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(ScenePro::getNum,numList);
wrapper.eq(ScenePro::getIsUpgrade,0);
List list = this.list(wrapper);
list.forEach(e -> map.put(e.getNum(),e));
return map;
}
@Override
public void addDownloadNum(String sceneNum) {
if(StringUtils.isBlank(sceneNum)){
throw new BusinessException(ResultCode.PARAM_ERROR);
}
ScenePro scenePro = this.getByNum(sceneNum);
if(scenePro != null){
SceneProEdit sceneProEditEntity = sceneProEditService.getByProId(scenePro.getId());
if(sceneProEditEntity.getDownloadNum() == null){
sceneProEditEntity.setDownloadNum(1);
}else{
sceneProEditEntity.setDownloadNum(sceneProEditEntity.getDownloadNum() + 1);
}
sceneProEditService.updateById(sceneProEditEntity);
}
}
@Override
public void deleteByNum(String num) {
ScenePro scenePro = this.getByNum(num);
if(scenePro!=null){
this.removeById(scenePro.getId());
this.updateOssStatus(String.format(OssPath.v3_statusPath,scenePro.getNum()),"I");
}
ScenePlus scenePlus = scenePlusService.getByNum(num);
if(scenePlus!=null){
scenePlusService.removeById(scenePlus.getId());
scenePlusExtService.delByPlus(scenePlus.getId());
this.updateOssStatus(String.format(OssPath.v4_statusPath,scenePlus.getNum()),"I");
}
Integer sceneSource = scenePro == null ? scenePlus.getSceneSource() : scenePro.getSceneSource();
if(sceneSource == 4 || sceneSource == 5){
laserService.updateStatus(num,-1);
}
tmContractorNumService.deleteByNum(num);
tmContractorService.checkDel();
}
private void updateOssStatus(String path,String recStatus) {
try {
if(!fYunFileServiceInterface.fileExist(path)){
return;
}
String data = fYunFileServiceInterface.getFileContent(path);
if(StringUtils.isBlank(data)){
return;
}
JSONObject jsonObject = JSONObject.parseObject(data);
jsonObject.put("recStatus",recStatus);
String json = JSONUtil.toJsonStr(jsonObject);
FileUtils.writeFile(OssPath.localStatusPath ,json);
log.info("updateOssStatus--localPath:{},ossPath:{}",OssPath.localStatusPath,path);
fYunFileServiceInterface.uploadFile(OssPath.localStatusPath,path);
}catch (Exception e){
e.printStackTrace();
}finally {
FileUtil.del(OssPath.localStatusPath);
}
}
@Override
public void unbind(Long cameraId,Long userId) {
LambdaUpdateWrapper wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(ScenePro::getCameraId,cameraId);
wrapper.eq(ScenePro::getIsUpgrade,0);
wrapper.set(ScenePro::getUserId,userId);
this.update(wrapper);
}
@Override
public ScenePro copyScene(ScenePro scenePro) {
if(scenePro.getStatus() !=-2){
throw new BusinessException(ResultCode.SCENE_ERROR);
}
String oldNum = scenePro.getNum();
String newNum = sceneCommonService.getNewNum(oldNum);
Long sceneProId = scenePro.getId();
String oldSceneName = scenePro.getSceneName();
scenePro.setNum(newNum);
scenePro.setId(null);
scenePro.setSceneName(scenePro.getSceneName() +"(copy)");
scenePro.setViewCount(0);
scenePro.setThumb(scenePro.getThumb().replaceAll(oldNum,scenePro.getNum()));
scenePro.setWebSite(scenePro.getWebSite().replaceAll(oldNum,scenePro.getNum()));
scenePro.setStatus(0);
this.save(scenePro);
try {
sceneCommonService.v3Async(scenePro,oldNum,newNum,sceneProId,oldSceneName);
}catch (Exception e){
log.error("复制场景失败-sceneNum:{},error:{}",oldNum,e);
scenePro.setStatus(-1);
this.updateById(scenePro);
throw new BusinessException(ResultCode.SCENE_DATA_ERROR);
}
return scenePro;
}
@Override
public void updateTitleByNum(String sceneNum, String sceneNewTitle) {
LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(ScenePro::getNum,sceneNum);
updateWrapper.set(ScenePro::getLaserTitle,sceneNewTitle);
this.update(updateWrapper);
}
@Override
public void generateObjFile(String num) {
ScenePro sceneProEntity = this.getByNum(num);
ScenePlus scenePlusEntity = scenePlusService.getByNum(num);
if(ObjectUtils.isEmpty(sceneProEntity) && ObjectUtils.isEmpty(scenePlusEntity)){
throw new BusinessException(ResultCode.SCENE_NOT_EXIT);
}
List sceneCopyLogs = sceneCopyLogService.getByNewNum(num);
if(sceneCopyLogs!=null && sceneCopyLogs.size()>0){
throw new BusinessException(ResultCode.GENERATE_OBJ_ERROR);
}
String path = null;
ScenePlusExt scenePlusExt = null;
if(scenePlusEntity != null){
scenePlusExt = scenePlusExtService.getByPlusId(scenePlusEntity.getId());
if(scenePlusExt == null){
throw new BusinessException(ResultCode.SCENE_ERROR);
}
path = scenePlusExt.getDataSource();
}else {
path = sceneProEntity.getDataSource();
}
Integer sceneSource = sceneProEntity == null ? scenePlusEntity.getSceneSource() : sceneProEntity.getSceneSource();
if(sceneSource != 4){
throw new BusinessException(ResultCode.GENERATE_OBJ_ERROR_TYPE);
}
laserService.updateBuildObjStatus(num,2);
String ossPath = path.replace("/mnt/data","home")+"/data.fdage";
if(!fYunFileServiceInterface.fileExist(ossPath)){
throw new BusinessException(ResultCode.GENERATE_OBJ_ERROR);
}
// 获取最新的场景名称
JSONObject sceneInfo = laserService.getSceneByNum(num);
if(sceneProEntity == null){
LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
.set(ScenePlus::getSceneStatus, 0)
.set(ScenePlus::getTitle, sceneInfo.getString("title"))
.eq(ScenePlus::getNum, num);
scenePlusService.update(updateWrapper);
LambdaUpdateWrapper plusExtUpdateWrapper = new LambdaUpdateWrapper<>();
plusExtUpdateWrapper
.set(ScenePlusExt::getIsObj, 1)
.eq(ScenePlusExt::getPlusId, scenePlusEntity.getId());
scenePlusExtService.update(plusExtUpdateWrapper);
sendMqMsg(num,scenePlusExt.getAlgorithm(),scenePlusExt.getBuildType(),scenePlusExt.getDataSource());
return;
}
LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper
.set(ScenePro::getStatus, 0)
.set(ScenePro::getIsObj, 1)
.set(ScenePro::getIsUpgrade, 2) // 升级中
.set(ScenePro::getSceneName, sceneInfo.getString("title"))
.eq(ScenePro::getNum, sceneProEntity.getNum());
this.update(updateWrapper);
//同步到scenePlus、scenePlus
//同步到scenePlus、scenePlus
ScenePlus scenePlus = scenePlusService.getByNum(num);
if(Objects.nonNull(scenePlus)){
sceneUpgradeMapper.deleteScenePlus(num);
sceneUpgradeMapper.deleteScenePlusExt(scenePlus.getId());
}
sceneUpgradeMapper.transferScenePlus(num);
scenePlus = scenePlusService.getByNum(num);
String sceneKind = sceneProEntity.getSceneScheme() == 3 ? SceneKind.FACE.code():SceneKind.TILES.code();
sceneUpgradeMapper.transferScenePlusExt(num, scenePlus.getId(), sceneKind);
sendMqMsg(sceneProEntity.getNum(),sceneProEntity.getAlgorithm(),sceneProEntity.getBuildType(),sceneProEntity.getDataSource());
}
public void sendMqMsg(String num ,String algorithm,String buildType,String dataSource) {
log.info("开始发送激光场景生成obj mq消息");
// 发送MQ
BuildSceneCallMessage mqMsg = new BuildSceneCallMessage();
mqMsg.setSceneNum(num);
mqMsg.setAlgorithm(algorithm);
mqMsg.setBuildType(buildType);
mqMsg.setPath(dataSource);
mqProducer.sendByWorkQueue(queueObjModelingPre,mqMsg);
}
@Override
public void move(SceneParam param) {
if(param.getNumList().isEmpty() || param.getCameraId() == null || StringUtils.isBlank(param.getUserName())){
throw new BusinessException(ResultCode.PARAM_ERROR);
}
for (String num : param.getNumList()) {
User user = userService.getByUserName(param.getUserName());
if(user == null || user.getCompanyId() == null){
throw new BusinessException(ResultCode.USER_NOT_EXIST);
}
ScenePlus scenePlus = scenePlusService.getByNum(num);
ScenePro scenePro = this.getByNum(num);
if(scenePlus == null && scenePro == null){
throw new BusinessException(ResultCode.SCENE_NOT_EXIT);
}
Long cameraId = scenePro == null ? scenePlus.getCameraId() : scenePro.getCameraId();
Integer sceneSource = scenePro == null ? scenePlus.getSceneSource() : scenePro.getSceneSource();
Camera oldCamera = cameraService.getById(cameraId);
Camera camera = cameraService.getById(param.getCameraId());
CameraDetail oldCameraDetail = cameraDetailService.getByCameraId(cameraId);
CameraDetail cameraDetail = cameraDetailService.getByCameraId(param.getCameraId());
if(oldCamera == null || oldCameraDetail == null || camera == null || cameraDetail == null){
throw new BusinessException(ResultCode.CAMERA_NOT_EXIST);
}
if(!oldCameraDetail.getType().equals(cameraDetail.getType())){
throw new BusinessException(ResultCode.CAMERA_TYPE_NOT_ERROR);
}
String dataSource = scenePro == null ? null :scenePro.getDataSource();
if(scenePlus !=null){
ScenePlusExt scenePlusExt = scenePlusExtService.getByPlusId(scenePlus.getId());
dataSource = scenePlusExt.getDataSource();
}
scenePlusService.updatePayStatus(num,scenePro == null ?"v4":"v3",scenePro == null?scenePlus.getSceneSource():scenePro.getSceneSource(),1,cameraDetail,user);
scenePlusService.move(num,scenePro == null ?"v4":"v3",cameraDetail,user);
if(sceneSource == 4 || sceneSource == 5){
laserService.move(num, oldCamera.getSnCode(), camera.getSnCode(), user.getId(), dataSource);
}
sceneMoveLogService.saveLog(scenePro,scenePlus,camera.getSnCode(),oldCamera.getSnCode(),dataSource,dataSource, null);
}
}
}