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 cn.hutool.json.JSONUtil; 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.common.util.FileUtils; import com.fdkankan.fyun.constant.StorageType; 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.entity.SceneProExt; 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.ISceneProExtService; 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.prefix.ali}") private String prefixAli; @Value("${upload.type}") private String type; @Value("${oss.bucket:4dkankan}") private String bucket; @Autowired private ISceneEditControlsService sceneEditControlsService; @Autowired private ISceneProService sceneProService; @Autowired private UploadToOssUtil uploadToOssUtil; @Autowired RedisUtil redisUtil; @Autowired private ISceneProExtService sceneProExtService; @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(",")); } //处理热点数据,生成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(",")); } 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 ResultData saveCad(BaseDataParamVO param) throws Exception { String num = param.getNum(); ScenePro scenePro = sceneProService.findBySceneNum(num); if(Objects.isNull(scenePro)) throw new BusinessException(ErrorCode.FAILURE_CODE_5005); String editDataPath = String.format(UploadFilePath.DATA_EDIT_PATH, num); String editUserPath = String.format(UploadFilePath.USER_EDIT_PATH, num); String localDataPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, num); JSONObject fileInfoJson = JSON.parseObject(param.getData()); String floors = fileInfoJson.getString("floors"); String cadInfo = fileInfoJson.getString("cadInfo"); String floorJsonData = fileInfoJson.getString("floorJsonData"); String filePaths = fileInfoJson.getString("filePaths"); Byte reSet = fileInfoJson.getByte("reset"); String filePathStr = null; //如果floors不为空,只需要根据对应楼层id修改楼层名称 if(StrUtil.isNotEmpty(floors)){ //从编辑目录中下载floorplan_cad.json、floorplan_user.json到本地 String floorCadUrl = prefixAli + editDataPath + "floorplan_cad.json?t=" + System.currentTimeMillis(); String floorUserUrl = prefixAli + editUserPath + "floorplan_user.json?t=" + System.currentTimeMillis(); //如果是云存储,将vision.modeldata下载到本地,如果是本地存储,场景计算完就已经将这个文件拷贝到编辑目录了存在这个文件了,不需要再下载 if(!StorageType.LOCAL.code().equals(this.type)){// TODO: 2022/2/15 这里有可能有问题,可能还需要考虑本地部署的情况 FileUtils.downLoadFromUrl(floorCadUrl, "floorplan_cad.json", localDataPath); FileUtils.downLoadFromUrl(floorUserUrl, "floorplan_user.json", localDataPath); } String floorCadStr = FileUtils.readFile(localDataPath + "floorplan_cad.json"); if(StrUtil.isNotEmpty(floorCadStr)){ JSONObject floorCadJson = this.updateFloorName(floors, floorCadStr); FileUtils.writeFile(localDataPath + "floorplan_cad.json", floorCadJson.toString()); uploadToOssUtil.upload(localDataPath + "floorplan_cad.json", editDataPath+"floorplan_cad.json"); } String floorUserStr = FileUtils.readFile(localDataPath + "floorplan_user.json"); if(StrUtil.isNotEmpty(floorUserStr)) { JSONObject floorUserJson = this.updateFloorName(floors, floorUserStr); FileUtils.writeFile(localDataPath + "floorplan_user.json", floorUserJson.toString()); uploadToOssUtil.upload(localDataPath + "floorplan_user.json",editUserPath + "floorplan_user.json"); } }else{ //户型图文件路径 if(StrUtil.isNotEmpty(filePaths)){ cn.hutool.json.JSONArray filePathsArrs = JSONUtil.parseArray(filePaths); List filePathsList = filePathsArrs.toList(String.class); StringBuilder filePathBuilder = new StringBuilder(); filePathsList.parallelStream().forEach(path -> { filePathBuilder.append(",").append(path); }); filePathStr = filePathBuilder.substring(1); } //上传houst_floor.json文件 FileUtils.writeFile(localDataPath + "floorplan_user.json", floorJsonData); uploadToOssUtil.upload(localDataPath + "floorplan_user.json", editUserPath + "floorplan_user.json"); } //写入数据库 Byte floorPlanUser = null; if(StrUtil.isNotEmpty(floorJsonData)){ floorPlanUser = CommonStatus.YES.code(); } if(CommonStatus.YES.code().equals(reSet)){ floorPlanUser = CommonStatus.NO.code(); } SceneEditInfo sceneEditInfoDb = this.getBySceneProId(scenePro.getId()); if(Objects.nonNull(sceneEditInfoDb)){ LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper() .setSql("version=version+" + 1) .eq(SceneEditInfo::getId, sceneEditInfoDb.getId()); if(StrUtil.isNotEmpty(filePathStr)){ updateWrapper.set(SceneEditInfo::getFloorPlanPath, filePathStr); } if(StrUtil.isNotEmpty(cadInfo)){ updateWrapper.set(SceneEditInfo::getCadInfo, cadInfo); } if(floorPlanUser != null){ updateWrapper.set(SceneEditInfo::getFloorPlanUser, floorPlanUser); } this.update(updateWrapper); }else{ sceneEditInfoDb = new SceneEditInfo(); sceneEditInfoDb.setSceneProId(scenePro.getId()); sceneEditInfoDb.setFloorPlanPath(filePathStr); sceneEditInfoDb.setCadInfo(cadInfo); sceneEditInfoDb.setFloorPlanUser(floorPlanUser); this.save(sceneEditInfoDb); } return ResultData.ok(); } private JSONObject updateFloorName(String sourceFloors, String targeFloors){ JSONArray sourceFloorsJson = JSON.parseArray(sourceFloors); JSONObject targeFloorsJson = JSONObject.parseObject(targeFloors); JSONArray array = targeFloorsJson.getJSONArray("floors"); for (int i = 0; i < array.size(); ++i) { JSONObject targetFloor = array.getJSONObject(i); int targetId = targetFloor.getIntValue("id"); for (int j = 0; j < sourceFloorsJson.size(); ++j) { JSONObject floor = sourceFloorsJson.getJSONObject(j); int id = floor.getIntValue("id"); String name = floor.getString("name"); if (targetId != id) continue; targetFloor.put("name", name); } } return targeFloorsJson; } @Override public void upgradeVersionById(Long id) { this.update(new LambdaUpdateWrapper() .setSql("version=version+" + 1) .eq(SceneEditInfo::getId, id)); } }