package com.fdkankan.scene.service.impl;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.model.constants.ConstantFilePath;
import com.fdkankan.common.constant.ErrorCode;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.web.response.ResultData;
import com.fdkankan.model.utils.CreateObjUtil;
import com.fdkankan.common.util.DateUtil;
import com.fdkankan.common.util.FileUtils;
import com.fdkankan.fyun.face.FYunFileServiceInterface;
import com.fdkankan.rabbitmq.util.RabbitMqProducer;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.constant.RedisLockKey;
import com.fdkankan.redis.util.RedisLockUtil;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.scene.bean.RequestRebuildVedioScene;
import com.fdkankan.scene.bean.RequestSceneCooperation;
import com.fdkankan.scene.entity.Camera;
import com.fdkankan.scene.entity.CameraDetail;
import com.fdkankan.scene.entity.PicSceneProgress;
import com.fdkankan.scene.entity.Scene;
import com.fdkankan.scene.entity.SceneCooperation;
import com.fdkankan.scene.entity.ScenePlus;
import com.fdkankan.scene.entity.ScenePlusExt;
import com.fdkankan.scene.entity.ScenePro;
import com.fdkankan.scene.entity.SceneProEdit;
import com.fdkankan.scene.entity.SceneResource;
import com.fdkankan.scene.entity.User;
import com.fdkankan.scene.entity.UserIncrement;
import com.fdkankan.scene.entity.VideoSceneProgress;
import com.fdkankan.scene.mapper.ISceneMapper;
import com.fdkankan.scene.service.ICameraDetailService;
import com.fdkankan.scene.service.ICameraService;
import com.fdkankan.scene.service.IPicSceneProgressService;
import com.fdkankan.scene.service.ISceneCooperationService;
import com.fdkankan.scene.service.IScenePlusExtService;
import com.fdkankan.scene.service.IScenePlusService;
import com.fdkankan.scene.service.ISceneProEditService;
import com.fdkankan.scene.service.ISceneProService;
import com.fdkankan.scene.service.ISceneResourceService;
import com.fdkankan.scene.service.ISceneService;
import com.fdkankan.scene.service.IUserIncrementService;
import com.fdkankan.scene.service.IUserService;
import com.fdkankan.scene.service.IVideoSceneProgressService;
import com.fdkankan.web.user.SSOUser;
import java.io.File;
import java.util.*;
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.stereotype.Service;
import org.springframework.util.ObjectUtils;
/**
*
* TODO
*
*
* @author dengsixing
* @since 2022/7/4
**/
@Slf4j
@Service
public class SceneServiceImpl extends ServiceImpl implements ISceneService {
@Autowired
private ISceneProService sceneProService;
@Autowired
private ICameraService cameraService;
@Autowired
private IUserIncrementService userIncrementService;
@Autowired
private ICameraDetailService cameraDetailService;
@Autowired
private IUserService userService;
@Autowired
private ISceneCooperationService sceneCooperationService;
@Autowired
private ISceneResourceService sceneResourceService;
@Autowired
private ISceneProEditService sceneProEditService;
@Autowired
private RedisUtil redisUtil;
@Autowired
private RedisLockUtil redisLockUtil;
@Autowired
private IScenePlusService scenePlusService;
@Autowired
private IScenePlusExtService scenePlusExtService;
@Autowired
private FYunFileServiceInterface fYunFileService;
@Autowired
private IVideoSceneProgressService videoSceneProgressService;
@Autowired
private IPicSceneProgressService picSceneProgressService;
@Autowired
private RabbitMqProducer rabbitMqProducer;
@Value("${queue.modeling.queue-video-a}")
private String queueVideoA;
@Value("${queue.modeling.queue-pic-a}")
private String queuePicA;
@Value("${expected-time}")
private String expectedTime;
@Value("${scene.expired.month:#{null}}")
private Integer expiredMonth;
@Override
public ResultData isLogin(String num, SSOUser ssoUser) throws Exception {
if(Objects.isNull(ssoUser)){
throw new BusinessException(ErrorCode.FAILURE_CODE_3004);
}
// 解密获得username,用于和数据库进行对比
String username = ssoUser.getUserName();
ScenePro sceneProEntity = sceneProService.findBySceneNum(num);
if(sceneProEntity == null){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
if(sceneProEntity.getPayStatus() != 1){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
if(sceneProEntity.getStatus() != 1 && sceneProEntity.getStatus() != -2){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
JSONObject jsonObject = new JSONObject();
//判断本地资源是否已本删除,如果已删除,前端根据字段值为true提示用户不能使用某些功能,需要重算
Date algorithmTime = sceneProEntity.getCreateTime();
jsonObject.put("sourceExpired", false);
if (!ObjectUtils.isEmpty(expiredMonth) && com.fdkankan.common.util.DateUtil.delay(algorithmTime, expiredMonth, Calendar.MONTH).before(new Date())) {
jsonObject.put("sourceExpired", true);
}
List exclude = new ArrayList<>();
SceneResource excludeEntity = new SceneResource();
excludeEntity.setKeyWord("data");
exclude.add(excludeEntity);
Camera camera = cameraService.findByChildName(username);
jsonObject.put("exclude", exclude);
jsonObject.put("include", new ArrayList<>());
jsonObject.put("company", null);
ResultData result = ResultData.ok(jsonObject);
//判断该场景是否属于增值权益
boolean isIncrement = false;
//获取该相机是否有权益
boolean isExpired = false;
Camera sceneCamera = cameraService.getById(sceneProEntity.getCameraId());
if(sceneCamera != null){
UserIncrement userIncrementEntity = userIncrementService.findByCameraId(sceneCamera.getId());
if(userIncrementEntity != null){
if( userIncrementEntity.getIsExpired().intValue() == 0){
isIncrement = true;
}
if(userIncrementEntity.getIsExpired().intValue() == 1){
isExpired = true;
}
}else{
try {
Date date = DateUtil.string2Date("2021-09-09 00:00:00",null);
//非07批次的放开
String pc = sceneCamera.getSnCode().substring(0,2);
if(!pc.equals("07") ){
if(sceneCamera.getCreateTime()!=null && date.after(sceneCamera.getCreateTime())){
isIncrement = true;
isExpired = false;
}
}
}catch (Exception e){
e.printStackTrace();
}
}
}
jsonObject.put("isExpired", isExpired );
jsonObject.put("isIncrement", isIncrement);
//判断过期时间
Date date = DateUtil.string2Date(expectedTime,null);
jsonObject.put("isTransition",DateUtil.isBeforeNow2(date));
if(camera != null){
if(!sceneProEntity.getCameraId().equals(camera.getId())){
throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
}
CameraDetail cameraDetailEntity = cameraDetailService.findByCameraId(camera.getId());
if(cameraDetailEntity.getCompanyId() != null){
if(cameraDetailEntity.getCompanyId().longValue() == 1 || cameraDetailEntity.getCompanyId().longValue() == 14){
jsonObject.put("exclude", new ArrayList<>());
jsonObject.put("company", cameraDetailEntity.getCompanyId().longValue());
}
}
return result;
}
User user = userService.findByUserName(username);
if("18750226207".equals(username)){
log.info("18750226207该账号默认超级管理员,可以操作所有场景");
}
else if(user == null || sceneProEntity.getUserId() == null || user.getId().longValue() != sceneProEntity.getUserId().longValue()){
log.info("user:" + user.getId() + ",scene:" + sceneProEntity.getUserId());
List list =
sceneCooperationService.list(
new LambdaQueryWrapper()
.eq(SceneCooperation::getSceneNum, num));
if(list != null && list.size() > 0){
if(list.get(0).getUserId().longValue() != user.getId().longValue()){
throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
}
}else {
throw new BusinessException(ErrorCode.FAILURE_CODE_5014);
}
}
if(sceneProEntity.getCameraId() != null){
camera = cameraService.getById(sceneProEntity.getCameraId());
if(camera != null){
CameraDetail cameraDetail = cameraDetailService.findByCameraId(camera.getId());
if(cameraDetail.getCompanyId() != null){
if(cameraDetail.getCompanyId().longValue() == 1 || cameraDetail.getCompanyId().longValue() == 14){
jsonObject.put("exclude", new ArrayList<>());
jsonObject.put("company", cameraDetail.getCompanyId().longValue());
}
}
}
}
//权限控制完后判断若是协作账号,获取协作权限
SceneCooperation sceneCooperation = sceneCooperationService.getByNum(num);
//若数据为空表示可操作全部资源
if(sceneCooperation == null || sceneCooperation.getUserId().longValue() != ssoUser.getId().longValue()){
return result;
}
if(sceneProEntity.getUserId()!= null && sceneCooperation.getUserId()!= null &&
sceneProEntity.getUserId().equals(sceneCooperation.getUserId())){
return result;
}
jsonObject.put("include", sceneResourceService.findByCooperationId(sceneCooperation.getId()));
return result;
}
@Override
public ResultData sceneResourceBySceneNum(RequestSceneCooperation cooperation, SSOUser ssoUser) throws Exception {
if(StrUtil.isEmpty(cooperation.getSceneNum())){
throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
}
// 解密获得username,用于和数据库进行对比
String username = ssoUser.getUserName();
Camera cameraEntity = cameraService.findByChildName(username);
if(cameraEntity != null){
return ResultData.ok();
}
SceneCooperation sceneCooperation = sceneCooperationService.getByNum(cooperation.getSceneNum());
//若数据为空表示可操作全部资源
if(sceneCooperation == null || sceneCooperation.getUserId().longValue() != ssoUser.getId().longValue()){
return ResultData.ok();
}
ScenePro scenePro = sceneProService.findBySceneNum(cooperation.getSceneNum());
if(scenePro != null && scenePro.getUserId() == sceneCooperation.getUserId().longValue()){
return ResultData.ok();
}
return ResultData.ok(sceneResourceService.findByCooperationId(sceneCooperation.getId()));
}
@Override
public ResultData getVoiceSound(String sceneNum) throws Exception {
if(StringUtils.isEmpty(sceneNum)){
throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
}
ScenePro sceneProEntity = sceneProService.findBySceneNum(sceneNum);
if(sceneProEntity == null){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
SceneProEdit editEntity = sceneProEditService.findBySceneProId(sceneProEntity.getId());
return ResultData.ok(editEntity.getScreencapVoiceSoundsync());
}
@Override
public ResultData updateViewCount(String sceneNum) {
String key = RedisKey.SCENE_VISIT_CNT;
if(!redisUtil.hHasKey(key, sceneNum)){
String lockKey = String.format(RedisLockKey.LOCK_SCENE_VISIT_CNT, sceneNum);
boolean lock = redisLockUtil.lock(lockKey, RedisKey.EXPIRE_TIME_10_MINUTE);
if(!lock){
return ResultData.ok();
}
try {
String cnt = redisUtil.hget(key, sceneNum);
if(StrUtil.isEmpty(cnt)){
//标记是否找到了场景,如果找到就不往下找
boolean getScene = false;
Integer viewCount = null;
ScenePlus scenePlus = scenePlusService.getByNum(sceneNum);
if(Objects.nonNull(scenePlus)){
ScenePlusExt scenePlusExt = scenePlusExtService.getByScenePlusId(scenePlus.getId());
viewCount = scenePlusExt.getViewCount();
getScene = true;
}
if(!getScene){
ScenePro scenePro = sceneProService.findBySceneNum(sceneNum);
if(Objects.nonNull(scenePro)){
viewCount = scenePro.getViewCount();
getScene = true;
}
}
if(!getScene){
Scene scene = this.findByNum(sceneNum);
if(Objects.nonNull(scene)){
viewCount = scene.getViewCount();
getScene = true;
}
}
if(!getScene){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
redisUtil.hset(key, sceneNum, Objects.isNull(viewCount) ? "0" : String.valueOf(viewCount));
}
}finally {
redisLockUtil.unlockLua(lockKey);
}
}
redisUtil.hincr(key, sceneNum, 1);
return ResultData.ok();
}
@Override
public Scene findByNum(String num) {
return this.getOne(new LambdaQueryWrapper().eq(Scene::getNum, num));
}
@Override
public ResultData rebuildVideoScene(RequestRebuildVedioScene requestRebuildVedioScene)
throws Exception {
if(StrUtil.isEmpty(requestRebuildVedioScene.getSceneNum()) || StrUtil.isEmpty(requestRebuildVedioScene.getPanoId())){
throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
}
String num = requestRebuildVedioScene.getSceneNum();
ScenePro sceneProEntity = sceneProService.findBySceneNum(num);
Scene scene = null;
String path = "";
if(sceneProEntity == null){
scene = this.findByNum(requestRebuildVedioScene.getSceneNum());
if(scene == null){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}else {
path = ConstantFilePath.BUILD_MODEL_PATH + scene.getDataSource().split("/")[scene.getDataSource().split("/").length - 2];
}
}else {
path = sceneProEntity.getDataSource();
}
//先从备份文件下拉取
fYunFileService.downloadFileByCommand(sceneProEntity.getDataSource() + "_rv" + File.separator + "videoback_temp",
"video/video" +sceneProEntity.getNum() + File.separator + "back" + File.separator);
String backpathtemp = sceneProEntity.getDataSource() + "_rv" + File.separator + "videoback_temp";
File fileback = new File(backpathtemp);
File[] filebackList = fileback.listFiles();
if(filebackList.length<=0){
String backpath = sceneProEntity.getDataSource() + "_rv" + File.separator + "videoback";
log.info("------------------" + backpath);
File file = new File(backpath);
//验证video 文件夹下是否有备份
fYunFileService.downloadFileByCommand(sceneProEntity.getDataSource() + "_rv" + File.separator + "videoback", "video/video" +sceneProEntity.getNum() + File.separator);
String name = "";
Map map = new HashMap();
file = new File(backpath);
File[] fileList = file.listFiles();
if(fileList.length>0){
for(File f:fileList){
name = f.getName();
log.info("file name :" + name);
map.put(sceneProEntity.getDataSource() + "_rv" + File.separator + "videoback" + File.separator + name,
"video/video" +sceneProEntity.getNum() + File.separator + "back" + File.separator + name);
}
}
//上传
log.info("上传内容 ===== + " + map);
fYunFileService.uploadMulFiles(map);
FileUtils.deleteDirectory(backpathtemp);
}
//更新旧记录
videoSceneProgressService.updateProgressRec(requestRebuildVedioScene);
//往文件中写入值
JSONObject reObject = new JSONObject();
JSONObject Object = new JSONObject();
Object.put("name",requestRebuildVedioScene.getPanoId());
Object.put("x",requestRebuildVedioScene.getX());
Object.put("y",requestRebuildVedioScene.getY());
Object.put("width",requestRebuildVedioScene.getW());
Object.put("height",requestRebuildVedioScene.getH());
JSONArray arrayRe = new JSONArray();
arrayRe.add(Object);
reObject.put("required_videos",arrayRe);
JSONObject hdrObject = new JSONObject();
if(StringUtils.isNotEmpty(sceneProEntity.getVideos())){
JSONObject object = JSONObject.parseObject(sceneProEntity.getVideos());
if(object.containsKey("data")){
JSONArray array = new JSONArray();
array = (JSONArray) object.get("data");
arrayRe = new JSONArray();
if(array.size()>0){
for(int i = 0; i < array.size(); i++) {
JSONObject obj = (JSONObject) array.get(i);
Object = new JSONObject();
Object.put("name",(String) obj.get("id"));
Object.put("value",(String) obj.get("value"));
Object.put("fov",(String) obj.get("blend_fov"));
arrayRe.add(Object);
}
hdrObject.put("hdr_param",arrayRe);
}
}
}else{
hdrObject.put("hdr_param","{}");
}
//重新计算时需要删除文件夹,否知使用缓存
log.info("开始清除result");
FileUtils.delAllFile(path + File.separator + "results");
log.info("清除result结束");
String fileId = path.split("/")[path.split("/").length - 2];
log.info("fileId:" + fileId);
String parametr = "";
parametr += sceneProEntity.getNum() + ":;" +
requestRebuildVedioScene.getPanoId();
long start = System.currentTimeMillis();
VideoSceneProgress videoSceneProgressEntity = new VideoSceneProgress();
videoSceneProgressEntity.setSceneCode(sceneProEntity.getNum());
videoSceneProgressEntity.setVideoName(requestRebuildVedioScene.getPanoId());
videoSceneProgressEntity.setDataSource(sceneProEntity.getDataSource());
videoSceneProgressEntity.setRebuildResult(2);
videoSceneProgressEntity.setDataSource(sceneProEntity.getDataSource());
videoSceneProgressEntity.setRebuildQueueStartTime(new Date());
videoSceneProgressEntity.setHdrParam(hdrObject.toJSONString());
videoSceneProgressEntity.setRebuildParam(reObject.toJSONString());
videoSceneProgressService.save(videoSceneProgressEntity);
rabbitMqProducer.sendByWorkQueue(queueVideoA, parametr);
return ResultData.ok("视频场景计算中");
}
@Override
public ResultData rebuildPicScene(RequestRebuildVedioScene requestRebuildVedioScene) throws Exception {
if(StrUtil.isEmpty(requestRebuildVedioScene.getSceneNum())){
throw new BusinessException(ErrorCode.FAILURE_CODE_3001);
}
String num = requestRebuildVedioScene.getSceneNum();
ScenePro sceneProEntity = sceneProService.findBySceneNum(num);
String path = "";
if(sceneProEntity == null){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
path = sceneProEntity.getDataSource();
PicSceneProgress picSceneProgress = picSceneProgressService.findrebuildVideoProgressDetail(num,null);
if(!ObjectUtils.isEmpty(picSceneProgress) && (picSceneProgress.getRebuildResult() == 2 || picSceneProgress.getRebuildResult() == 3)){
return ResultData.error(ErrorCode.FAILURE_CODE_5035);
}
//更新旧记录
picSceneProgressService.updateProgressRec(requestRebuildVedioScene);
//重新计算时需要删除文件夹,否知使用缓存
log.info("开始清除result");
FileUtils.delAllFile(path + File.separator + "results");
log.info("清除result结束");
String fileId = path.split("/")[path.split("/").length - 2];
log.info("fileId:" + fileId);
PicSceneProgress picSceneProgressEntity = new PicSceneProgress();
picSceneProgressEntity.setSceneCode(sceneProEntity.getNum());
picSceneProgressEntity.setVideoName(requestRebuildVedioScene.getPanoId());
picSceneProgressEntity.setDataSource(sceneProEntity.getDataSource());
picSceneProgressEntity.setRebuildResult(2);
picSceneProgressEntity.setDataSource(sceneProEntity.getDataSource());
picSceneProgressEntity.setRebuildQueueStartTime(new Date());
picSceneProgressEntity.setRebuildParam(JSONObject.toJSONString(requestRebuildVedioScene));
picSceneProgressService.save(picSceneProgressEntity);
String parametr = picSceneProgressEntity.getId()+"";
rabbitMqProducer.sendByWorkQueue(queuePicA, parametr);
return ResultData.ok("图片场景计算中");
}
}