package com.fdkankan.scene.service.impl;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.common.constant.*;
import com.fdkankan.common.exception.BusinessException;
import com.fdkankan.common.util.FileUtils;
import com.fdkankan.redis.constant.RedisKey;
import com.fdkankan.redis.util.RedisClient;
import com.fdkankan.scene.bean.BoxPhotoBean;
import com.fdkankan.scene.bean.ResultData;
import com.fdkankan.scene.bean.SceneJsonBean;
import com.fdkankan.scene.bean.TagBean;
import com.fdkankan.scene.entity.*;
import com.fdkankan.scene.httpclient.CustomHttpClient;
import com.fdkankan.scene.mapper.SceneEditInfoMapper;
import com.fdkankan.scene.service.*;
import com.fdkankan.scene.vo.*;
import com.google.common.collect.Lists;
import org.owasp.esapi.errors.EncodingException;
import org.owasp.esapi.errors.ValidationException;
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 org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
/**
*
* 服务实现类
*
*
* @author
* @since 2024-10-09
*/
@DS("vr")
@Service
public class SceneEditInfoServiceImpl extends ServiceImpl implements SceneEditInfoService {
private final static String SQL_ADD_VERSION = "version=version+";
@Value("${tieta.device-address:#{null}}")
private String deviceAddress;
//
@Autowired
private SceneEditControlsService sceneEditControlsService;
@Resource
private FYunFileService fYunFileService;
@Resource
private RedisClient redisClient;
@Autowired
private SceneEditInfoExtService sceneEditInfoExtService;
@Autowired
private SceneService sceneService;
@Autowired
private SceneFileMappingService sceneFileMappingService;
@Resource
CustomHttpClient customHttpClient;
@Autowired
private SceneAsynOperLogService sceneAsynOperLogService;
@Autowired
private ICommonService commonService;
/**
* 保存场景基础设置
* @param param
* @return com.fdkankan.scene.vo.SceneEditInfoVO
*/
@Transactional
@Override
public SceneEditInfoVO saveScene(SceneEditInfoParamVO param) {
//查询场景主表
Scene scenePlus = sceneService.getByNum(param.getNum(), param.getSubgroup(), param.getUpTimeKey());
//场景不存在返回业务异常:场景为空
if(Objects.isNull(scenePlus)){
throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
}
SceneEditInfo sceneEditInfoDb = this.getByScenePlusId(scenePlus.getId());
SceneEditControls sceneEditControlsDb = null;
if(Objects.nonNull(sceneEditInfoDb)){
sceneEditControlsDb = sceneEditControlsService.getBySceneEditId(sceneEditInfoDb.getId());
}
//用户上传的文件后缀名转小写
this.lowercaseExtName(param);
SceneEditInfo sceneEditInfo = BeanUtil.copyProperties(param, SceneEditInfo.class);
sceneEditInfo.setScenePlusId(scenePlus.getId());
//编辑数据表记录,有则更新,无则插入
if(Objects.isNull(sceneEditInfoDb)){
this.save(sceneEditInfo);
}else{
sceneEditInfo.setId(sceneEditInfoDb.getId());
sceneEditInfo.setVersion(sceneEditInfoDb.getVersion() + 1);
this.updateById(sceneEditInfo);
}
SceneEditInfoExt sceneEditInfoExt = sceneEditInfoExtService.getByEditInfoId(sceneEditInfo.getId());
if(Objects.isNull(sceneEditInfoExt)){
sceneEditInfoExt = new SceneEditInfoExt();
sceneEditInfoExt.setEditInfoId(sceneEditInfo.getId());
sceneEditInfoExt.setScenePlusId(scenePlus.getId());
}
if(Objects.nonNull(param.getSns())){
sceneEditInfoExt.setSnsInfo(JSON.toJSONString(param.getSns()));
}
if(Objects.nonNull(param.getStarted())){
sceneEditInfoExt.setStarted(JSON.toJSONString(param.getStarted()));
}
//更新场景编辑信息扩展表
sceneEditInfoExtService.saveOrUpdate(sceneEditInfoExt);
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);
}
}
scenePlus.setTitle(param.getTitle());
scenePlus.setDescription(param.getDescription());
//更新场景表
sceneService.updateById(scenePlus);
SceneEditInfoVO result = BeanUtil.copyProperties(param, SceneEditInfoVO.class);
result.setCreateTime(sceneEditInfo.getCreateTime());
return result;
}
private void lowercaseExtName(SceneEditInfoParamVO sceneEditInfo){
if(StrUtil.isNotEmpty(sceneEditInfo.getMusic())){
String extName = cn.hutool.core.io.FileUtil.extName(sceneEditInfo.getMusic());
if(StrUtil.isNotEmpty(extName)){
sceneEditInfo.setMusic(sceneEditInfo.getMusic().replace(extName, extName.toLowerCase()));
}
}
if(StrUtil.isNotEmpty(sceneEditInfo.getMusicFile())){
String extName = cn.hutool.core.io.FileUtil.extName(sceneEditInfo.getMusicFile());
if(StrUtil.isNotEmpty(extName)){
sceneEditInfo.setMusicFile(sceneEditInfo.getMusicFile().replace(extName, extName.toLowerCase()));
}
}
}
@Override
public SceneEditInfo getByScenePlusId(long scenePlusId) {
return this.getOne(new LambdaQueryWrapper()
.eq(SceneEditInfo::getScenePlusId, scenePlusId));
}
private void publicFilterData(String num, Integer subgroup, String upTime, Integer cacheKeyHasTime, int filters) throws IOException, EncodingException, ValidationException {
String userEditPath = String.format(UploadFilePath.USER_VIEW_PATH, num);
String fileKey = userEditPath + "filter.json";
if(filters == CommonStatus.NO.code()){
sceneFileMappingService.delByNumAndKey(num, subgroup, upTime, fileKey);
return;
}
String key = String.format(RedisKey.SCENE_filter_DATA, RedisKey.getNumStr(num, subgroup, upTime, cacheKeyHasTime));
List list = redisClient.lGet(key, 0, -1);
JSONArray jsonArray = new JSONArray();
list.stream().forEach(str->jsonArray.add(JSON.parseObject(str)));
fYunFileService.uploadFile(num, subgroup, upTime, JSON.toJSONBytes(jsonArray), userEditPath + "filter.json");
}
@Override
public SceneInfoVO getSceneInfo(String num, Integer subgroup, String upTimeKey, byte reqType) throws Exception{
SceneInfoReqType sceneInfoReqType = SceneInfoReqType.get(reqType);
if(Objects.isNull(subgroup)){
subgroup = 0;
}
SceneInfoVO sceneInfo = null;
switch (sceneInfoReqType){
//如果是编辑页面请求,查数据库
case EDIT:
sceneInfo = this.getSceneInfo4Edit(num, subgroup, upTimeKey);
//俊波要求这两个字段编辑页一定是1
sceneInfo.getControls().setShowDollhouse(CommonStatus.YES.code());
sceneInfo.getControls().setShowFloorplan(CommonStatus.YES.code());
break;
//如果是查看页面请求,查redis
case VIEW:
sceneInfo = this.getSceneInfo4Edit(num, subgroup, upTimeKey);
sceneInfo.setScenePassword(null);
//俊波要求这两个字段查看页一定是0
sceneInfo.getControls().setShowDollhouse(CommonStatus.NO.code());
sceneInfo.getControls().setShowFloorplan(CommonStatus.NO.code());
//查询机房列表
List sceneList = sceneService.listByStationcode(sceneInfo.getStationCode());
List