package com.fdkankan.scene.service.impl;
import cn.hutool.extra.spring.SpringUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.fdkankan.common.constant.*;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.JwtUtil;
import com.fdkankan.model.constants.UploadFilePath;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.scene.bean.SceneJsonBean;
import com.fdkankan.scene.config.FdkkLaserConfig;
import com.fdkankan.scene.config.ServiceConfig;
import com.fdkankan.scene.entity.*;
import com.fdkankan.scene.mapper.ISceneDownloadLogMapper;
import com.fdkankan.scene.oss.OssUtil;
import com.fdkankan.scene.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.scene.vo.DownloadVO;
import com.fdkankan.scene.vo.SceneDownloadParamVO;
import com.fdkankan.web.bean.DownLoadProgressBean;
import com.fdkankan.web.response.ResultData;
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 java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
*
* 服务实现类
*
*
* @author
* @since 2023-03-06
*/
@Service
@Slf4j
public class SceneDownloadLogServiceImpl extends ServiceImpl implements ISceneDownloadLogService {
private static String keyFormat = "touch:scene:download:num:%s";
@Value("${download.config.public-url}")
private String publicUrl;
@Autowired
private IScenePlusService scenePlusService;
@Autowired
private ISceneEditInfoService sceneEditInfoService;
@Autowired
private OssUtil ossUtil;
@Autowired
private RedisUtil redisUtil;
@Autowired
private ServiceConfig serviceConfig;
@Autowired
private IScenePlusExtService scenePlusExtService;
@Autowired
private ISceneService sceneService;
@Autowired
private FdkkLaserConfig fdkkLaserConfig;
public static void main(String[] args) {
String lang = null;
System.out.println("123123".equals(lang));
}
@Override
public ResultData downOfflineScene(String num, String lang, String resultPath) {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
String bucket = scenePlusExt.getYunFileBucket();
Scene scene = sceneService.getBySceneCode(num);
String mapping = scene.getMapping();
Map result = new HashMap<>();
String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH+"scene.json", num);
String sceneJson = ossUtil.getFileContent(bucket, sceneJsonPath);
SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
int version = sceneJsonBean.getVersion();
redisUtil.set(String.format(keyFormat, num), "1");
SceneDownloadLog sceneDownloadLog = this.getOne(
new LambdaQueryWrapper()
.eq(SceneDownloadLog::getSceneNum, num)
.orderByDesc(SceneDownloadLog::getId)
.last("limit 1"));
boolean download = false;//是否需要生成
if(Objects.nonNull(sceneDownloadLog)){
if(sceneDownloadLog.getStatus() == 0){
result.put("status", 0);
return ResultData.ok(result);
}
if(version == sceneDownloadLog.getSceneVersion() && lang.equals(sceneDownloadLog.getLang())){
String url=this.publicUrl+":"+fdkkLaserConfig.getLaserPort()+"/" + mapping +sceneDownloadLog.getDownloadUrl();
result.put("status", 2);
result.put("url",url);
String key=String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4,num);
DownLoadProgressBean progress = new DownLoadProgressBean(sceneDownloadLog.getDownloadUrl(),100, SceneDownloadProgressStatus.DOWNLOAD_SUCCESS.code());
redisUtil.set(key, JSONUtil.toJsonStr(progress));
return ResultData.ok(result);
}else{
result.put("status", 3);
download = true;
}
}else{
result.put("status", 1);
download = true;
}
if(download){
//清除之前的下载记录
this.remove(new LambdaQueryWrapper().eq(SceneDownloadLog::getSceneNum, num));
//写入新的记录
sceneDownloadLog = new SceneDownloadLog();
sceneDownloadLog.setSceneNum(num);
sceneDownloadLog.setSceneVersion(version);
sceneDownloadLog.setSysVersion("v4");
sceneDownloadLog.setLang(lang);
sceneDownloadLog.setDownloadUrl(resultPath);
this.save(sceneDownloadLog);
Map params = new HashMap<>(2);
params.put("type","local");
params.put("num",num);
params.put("lang", lang);
params.put("resultPath", resultPath);
redisUtil.lRightPush(RedisKey.SCENE_DOWNLOADS_TASK_V4, JSONObject.toJSONString(params));
}
return ResultData.ok(result);
}
@Override
public ResultData downloadProcess(String num) {
String key=String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4,num);
DownLoadProgressBean downLoadProgressBean = new DownLoadProgressBean();
if (!redisUtil.hasKey(key)){
return ResultData.ok(downLoadProgressBean);
}
String processStr = redisUtil.get(key);
log.info("downloadProcess-processStr-{}",processStr);
downLoadProgressBean = JSONObject.parseObject(processStr, DownLoadProgressBean.class);
if (downLoadProgressBean.getStatus()== 1002){
final Scene scene = sceneService.getBySceneCode(num);
//写库
update(
new LambdaUpdateWrapper()
.eq(SceneDownloadLog::getSceneNum,num)
.set(SceneDownloadLog::getDownloadUrl,downLoadProgressBean.getUrl())
.set(SceneDownloadLog::getStatus,1)
);
downLoadProgressBean.setUrl(this.publicUrl+":"+fdkkLaserConfig.getLaserPort()+ "/" + scene.getMapping() +downLoadProgressBean.getUrl());
}
return ResultData.ok(downLoadProgressBean);
}
@Override
public ResultData downloadUpDateStatus(String num) {
redisUtil.del(String.format(keyFormat, num));
redisUtil.del(String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4,num));
return ResultData.ok();
}
@Override
public ResultData downOfflineSceneCheck(String num, String lang) {
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
Scene scene = sceneService.getBySceneCode(num);
String mapping = scene.getMapping();
Map result = new HashMap<>();
SceneDownloadLog sceneDownloadLog = this.getOne(
new LambdaQueryWrapper()
.eq(SceneDownloadLog::getSceneNum, num)
.orderByDesc(SceneDownloadLog::getId)
.last("limit 1"));
String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH+"scene.json", num);
String sceneJson = ossUtil.getFileContent(scenePlusExt.getYunFileBucket(), sceneJsonPath);
SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
int version = sceneJsonBean.getVersion();
if(Objects.nonNull(sceneDownloadLog) && sceneDownloadLog.getStatus() == 1 && version == sceneDownloadLog.getSceneVersion() && lang.equals(sceneDownloadLog.getLang())){
String url=this.publicUrl+":"+fdkkLaserConfig.getLaserPort()+"/" + mapping +sceneDownloadLog.getDownloadUrl();
result.put("status", 2);
result.put("url",url);
}else{
result.put("status", 1);
}
return ResultData.ok(result);
}
@Override
public Map downOfflineSceneDetail(SceneDownloadParamVO param) {
String num = param.getSceneCode();
// String lang = param.getLang();
Map result = new HashMap<>();
result.put("rebuildOffline", true);
SceneDownloadLog sceneDownloadLog = this.getOne(
new LambdaQueryWrapper()
.eq(SceneDownloadLog::getSceneNum, num)
// .eq(SceneDownloadLog::getLang, lang)
.last("limit 1"));
if(Objects.isNull(sceneDownloadLog)){//如果没有记录,则没有生成过
result.put("status", -1);
return result;
}
Integer status = sceneDownloadLog.getStatus();
//成功或者失败,直接返回
if(status == DownloadStatus.SUCCESS.code() || status == DownloadStatus.FAILD.code()){
result.put("status", status);
result.put("path", sceneDownloadLog.getDownloadUrl());
if(status == DownloadStatus.SUCCESS.code()){//如果是成功,需要匹配版本号,如果版本号不一致,需要返回需要重新生成表示
result.put("rebuildOffline", this.rebuildOffline(sceneDownloadLog));
result.put("buildOfflineEndTime", sceneDownloadLog.getUpdateTime());
}
return result;
}
//下载中,从redis中获取下载进度,并根据状态更新数据库
String key=String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4,num);
if (!redisUtil.hasKey(key)){
result.put("status", DownloadStatus.DOWNLOADING.code());
result.put("percent", 0);
return result;
}
DownLoadProgressBean downLoadProgressBean = new DownLoadProgressBean();
String processStr = redisUtil.get(key);
downLoadProgressBean = JSONObject.parseObject(processStr, DownLoadProgressBean.class);
if (downLoadProgressBean.getStatus()== 1002){//下载成功,更新数据库表
//写库
sceneDownloadLog.setStatus(DownloadStatus.SUCCESS.code());
sceneDownloadLog.setDownloadUrl(downLoadProgressBean.getUrl());
sceneDownloadLog.setUpdateTime(new Date());
this.updateById(sceneDownloadLog);
// final Scene scene = sceneService.getBySceneCode(num);
// downLoadProgressBean.setUrl(this.publicUrl+":"+fdkkLaserConfig.getLaserPort()+ "/" + scene.getMapping() +downLoadProgressBean.getUrl());
result.put("status", DownloadStatus.SUCCESS.code());
result.put("percent", 100);
result.put("rebuildOffline", this.rebuildOffline(sceneDownloadLog));
result.put("path", downLoadProgressBean.getUrl());
result.put("buildOfflineEndTime", sceneDownloadLog.getUpdateTime());
return result;
}
if(downLoadProgressBean.getStatus()== 1003){//下载失败,更新数据库表
//写库
sceneDownloadLog.setStatus(DownloadStatus.FAILD.code());
sceneDownloadLog.setUpdateTime(new Date());
this.updateById(sceneDownloadLog);
result.put("status", DownloadStatus.SUCCESS.code());
result.put("percent", downLoadProgressBean.getPercent());
return result;
}
//下载中
result.put("status", DownloadStatus.DOWNLOADING.code());
result.put("percent", downLoadProgressBean.getPercent());
return result;
}
private boolean rebuildOffline(SceneDownloadLog sceneDownloadLog){
String num = sceneDownloadLog.getSceneNum();
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
String bucket = scenePlusExt.getYunFileBucket();
String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH+"scene.json", num);
String sceneJson = ossUtil.getFileContent(bucket, sceneJsonPath);
SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
int version = sceneJsonBean.getVersion();
if(version != sceneDownloadLog.getSceneVersion()){
return true;
}
return false;
}
@Override
public ResultData downloadScene(SceneDownloadParamVO param) {
String num = param.getSceneCode();
String lang = param.getLang();
String resultPath = param.getDir();
ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
String bucket = scenePlusExt.getYunFileBucket();
Scene scene = sceneService.getBySceneCode(num);
String mapping = scene.getMapping();
Map result = new HashMap<>();
String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH+"scene.json", num);
String sceneJson = ossUtil.getFileContent(bucket, sceneJsonPath);
SceneJsonBean sceneJsonBean = JSON.parseObject(sceneJson, SceneJsonBean.class);
int version = sceneJsonBean.getVersion();
// redisUtil.set(String.format(keyFormat, num), "1");
String key=String.format(RedisKey.PREFIX_DOWNLOAD_PROGRESS_V4,num);
redisUtil.del(key);
//清除之前的下载记录
this.remove(new LambdaQueryWrapper().eq(SceneDownloadLog::getSceneNum, num));
//写入新的记录
SceneDownloadLog sceneDownloadLog = new SceneDownloadLog();
sceneDownloadLog.setSceneNum(num);
sceneDownloadLog.setSceneVersion(version);
sceneDownloadLog.setSysVersion("v4");
sceneDownloadLog.setLang(param.getLang());
sceneDownloadLog.setDownloadUrl(resultPath);
this.save(sceneDownloadLog);
Map params = new HashMap<>(2);
params.put("type","local");
params.put("num",num);
params.put("lang", lang);
params.put("resultPath", resultPath);
redisUtil.lRightPush(RedisKey.SCENE_DOWNLOADS_TASK_V4, JSONObject.toJSONString(params));
return ResultData.ok(result);
}
}