package com.fdkankan.scene.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
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.service.impl.ServiceImpl;
import com.fdkankan.common.constant.*;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.response.ResultData;
import com.fdkankan.fyun.oss.UploadToOssUtil;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisUtil;
import com.fdkankan.scene.bean.SceneJsonBean;
import com.fdkankan.scene.entity.SceneEditControls;
import com.fdkankan.scene.entity.SceneEditInfo;
import com.fdkankan.scene.entity.ScenePro;
import com.fdkankan.scene.factory.FloorLogoHandlerFactory;
import com.fdkankan.scene.factory.FloorPlanHandlerFactory;
import com.fdkankan.scene.factory.MusicHandlerFactory;
import com.fdkankan.scene.factory.ScreenshotHandlerFactory;
import com.fdkankan.scene.mapper.ISceneEditInfoMapper;
import com.fdkankan.scene.service.ISceneEditControlsService;
import com.fdkankan.scene.service.ISceneEditInfoService;
import com.fdkankan.scene.service.ISceneProService;
import com.fdkankan.scene.vo.*;
import com.google.common.collect.Lists;
import com.google.errorprone.annotations.Var;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.Objects;
/**
*
* 服务实现类
*
*
* @author
* @since 2022-01-18
*/
@Service
public class SceneEditInfoServiceImpl extends ServiceImpl implements ISceneEditInfoService {
@Value("${oss.bucket:4dkankan}")
private String bucket;
@Autowired
private ISceneEditControlsService sceneEditControlsService;
@Autowired
private ISceneProService sceneProService;
@Autowired
private UploadToOssUtil uploadToOssUtil;
@Autowired
RedisUtil redisUtil;
@Override
public SceneEditInfoVO saveScene(SceneEditInfoParamVO param) {
ScenePro scenePro = sceneProService.findBySceneNum(param.getNum());
if(Objects.isNull(scenePro)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
SceneEditInfo sceneEditInfoDb = this.getBySceneProId(scenePro.getId());
SceneEditControls sceneEditControlsDb = null;
if(Objects.nonNull(sceneEditInfoDb)){
sceneEditControlsDb = sceneEditControlsService.getBySceneEditId(sceneEditInfoDb.getId());
}
SceneEditInfo sceneEditInfo = BeanUtil.copyProperties(param, SceneEditInfo.class);
sceneEditInfo.setSceneProId(scenePro.getId());
sceneEditInfo.setCreateTime(Calendar.getInstance().getTime());
if(Objects.isNull(sceneEditInfoDb)){
this.save(sceneEditInfo);
}else{
sceneEditInfo.setId(sceneEditInfoDb.getId());
sceneEditInfo.setUpdateTime(Calendar.getInstance().getTime());
this.updateById(sceneEditInfo);
}
if(Objects.nonNull(param.getControls())){
SceneEditControls sceneEditControls = BeanUtil.copyProperties(param.getControls(), SceneEditControls.class);
sceneEditControls.setEditInfoId(sceneEditInfo.getId());
if(Objects.isNull(sceneEditControlsDb)){
sceneEditControlsService.save(sceneEditControls);
}else{
sceneEditControls.setId(sceneEditControlsDb.getId());
sceneEditControlsService.updateById(sceneEditControls);
}
}
SceneEditInfoVO result = BeanUtil.copyProperties(param, SceneEditInfoVO.class);
result.setCreateTime(sceneEditInfo.getCreateTime());
return result;
}
@Override
public SceneEditInfo getBySceneProId(long sceneProId) {
return this.getOne(new LambdaQueryWrapper()
.eq(SceneEditInfo::getTbStatus, TbStatus.VALID.code())
.eq(SceneEditInfo::getSceneProId, sceneProId));
}
@Override
public ResultData publicScene(SceneEditInfoParamVO param) throws Exception {
String sceneNum = param.getNum();
if(StrUtil.isEmpty(sceneNum)){
throw new BusinessException(ErrorCode.PARAM_REQUIRED);
}
//根据场景码查询数据库
ScenePro scenePro = sceneProService.findBySceneNum(sceneNum);
SceneEditInfo sceneEditInfo = this.getBySceneProId(scenePro.getId());
SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
//生成sceneJson
SceneJsonBean sceneJson = BeanUtil.copyProperties(sceneEditInfo, SceneJsonBean.class);
SceneEditControlsVO sceneEditControlsVO = BeanUtil.copyProperties(sceneEditControls, SceneEditControlsVO.class);
sceneJson.setControls(sceneEditControlsVO);
sceneJson.setNum(sceneNum);
if(StrUtil.isNotEmpty(sceneEditInfo.getFloorPlanPath())){
sceneJson.setFloorPlanPaths(sceneEditInfo.getFloorPlanPath().split(","));
sceneJson.setFloorPlanStatus(CommonStatus.YES.code());
}
//处理热点数据,生成hot.json
this.publicHotData(sceneNum, sceneJson);
//上传sceneJson文件
String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH+"scene.json", sceneNum);
uploadToOssUtil.upload(JSON.toJSONBytes(sceneJson), sceneJsonPath);
//sceneJson放入缓存
String key = String.format(RedisKey.SCENE_JSON, sceneNum);
redisUtil.set(key, JSON.toJSONString(sceneJson));
//删除发布数据中的user目录
String publicUserPath = String.format(UploadFilePath.USER_VIEW_PATH, sceneNum);
uploadToOssUtil.deleteFile(publicUserPath);
// String editUserPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum);
//复制编辑目录到发布目录
String editPath = String.format(UploadFilePath.EDIT_PATH, param.getNum());
String viewPath = String.format(UploadFilePath.VIEW_PATH, param.getNum());
uploadToOssUtil.copyFiles(editPath,viewPath);
return ResultData.ok();
}
private void publicHotData(String sceneNum, SceneJsonBean sceneJson) throws IOException {
String hotDataKey = String.format(RedisKey.SCENE_HOT_DATA, sceneNum);
Map hotMap = redisUtil.hmget(hotDataKey);
List hotList = Lists.newArrayList();
hotMap.entrySet().stream().forEach(entry->{
if(StrUtil.isNotEmpty(entry.getValue())){
hotList.add(entry.getValue());
}
});
if(CollUtil.isNotEmpty(hotList)){
JSONArray jsonhots = new JSONArray();
hotList.stream().forEach(hot->{
jsonhots.add(JSONObject.parseObject(hot));
});
String hotJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + "hot.json";
uploadToOssUtil.upload(jsonhots.toString().getBytes(), hotJsonPath);
}
}
@Override
public SceneInfoVO getSceneInfo(@Var SceneInfoParamVO param) {
SceneInfoReqType sceneInfoReqType = SceneInfoReqType.get(param.getReqType());
switch (sceneInfoReqType){
//如果是编辑页面请求,查数据库
case EDIT:
return this.getSceneInfo4Edit(param.getNum());
//如果是查看页面请求,查redis
case VIEW:
return this.getSceneInfo4View(param.getNum());
}
return null;
}
/**
*
编辑页面获取场景详情信息
*
* @author dengsixing
* @date 2022/1/21
* @param num
* @return com.fdkankan.scene.vo.SceneInfoVO
**/
private SceneInfoVO getSceneInfo4Edit(String num){
ScenePro scenePro = sceneProService.findBySceneNum(num);
if(Objects.isNull(scenePro)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
SceneEditInfo sceneEditInfo = this.getBySceneProId(scenePro.getId());
SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
SceneInfoVO sceneInfoVO = BeanUtil.copyProperties(sceneEditInfo, SceneInfoVO.class);
sceneInfoVO.setControls(BeanUtil.copyProperties(sceneEditControls, SceneEditControlsVO.class));
sceneInfoVO.setNum(num);
//生成sceneJson
if(StrUtil.isNotEmpty(sceneEditInfo.getFloorPlanPath())){
sceneInfoVO.setFloorPlanPaths(sceneEditInfo.getFloorPlanPath().split(","));
sceneInfoVO.setFloorPlanStatus(CommonStatus.YES.code());
}
return sceneInfoVO;
}
/**
*
查看页面获取场景详情信息
*
* @author dengsixing
* @date 2022/1/21
* @param num
* @return com.fdkankan.scene.vo.SceneInfoVO
**/
private SceneInfoVO getSceneInfo4View(String num){
String sceneJson = redisUtil.get(String.format(RedisKey.SCENE_JSON, num));
SceneInfoVO sceneInfoVO = null;
//先查询redis
if(StrUtil.isNotEmpty(sceneJson)){
sceneInfoVO = JSON.parseObject(sceneJson, SceneInfoVO.class);
return sceneInfoVO;
}
//如果redis没找到,从scene.json中获取
String objectName = String.format(ConstantFilePath.SCENE_VIEW_DATA_DATA_SCENEJSON, num);
String objectContent = uploadToOssUtil.getObjectContent(bucket, objectName);
if(StrUtil.isEmpty(objectContent))
return null;
sceneInfoVO = JSON.parseObject(objectContent, SceneInfoVO.class);
return sceneInfoVO;
}
@Override
// @Transactional
public ResultData saveUpload(SaveUploadParamVO param) throws Exception {
FileBizType fileBizType = FileBizType.get(param.getBizType());
String num = param.getNum();
String fileInfo = param.getFileInfo();
if(Objects.isNull(fileBizType)){
throw new BusinessException(ErrorCode.FAILURE_CODE_7003);
}
switch (fileBizType){
case MUSIC:
return new MusicHandlerFactory().getHandler().save(num, fileInfo);
case FLOOR_LOGO:
return new FloorLogoHandlerFactory().getHandler().save(num, fileInfo);
case FLOOR_PLAN:
return new FloorPlanHandlerFactory().getHandler().save(num, fileInfo);
case SCREENSHOT:
return new ScreenshotHandlerFactory().getHandler().save(num, fileInfo);
}
return ResultData.ok();
}
@Override
public void upgradeVersionById(Long id) {
this.update(new LambdaUpdateWrapper()
.setSql("version=version+" + 1)
.eq(SceneEditInfo::getId, id));
}
}