SceneEditInfoServiceImpl.java 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. package com.fdkankan.scene.service.impl;
  2. import cn.hutool.core.bean.BeanUtil;
  3. import cn.hutool.core.collection.CollUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import cn.hutool.json.JSONUtil;
  6. import com.alibaba.fastjson.JSON;
  7. import com.alibaba.fastjson.JSONArray;
  8. import com.alibaba.fastjson.JSONObject;
  9. import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
  10. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  11. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  12. import com.fdkankan.common.constant.*;
  13. import com.fdkankan.common.exception.BusinessException;
  14. import com.fdkankan.common.response.ResultData;
  15. import com.fdkankan.common.util.FileUtils;
  16. import com.fdkankan.fyun.constant.StorageType;
  17. import com.fdkankan.fyun.oss.UploadToOssUtil;
  18. import com.fdkankan.redis.constant.RedisKey;
  19. import com.fdkankan.redis.util.RedisUtil;
  20. import com.fdkankan.scene.bean.SceneJsonBean;
  21. import com.fdkankan.scene.entity.SceneEditControls;
  22. import com.fdkankan.scene.entity.SceneEditInfo;
  23. import com.fdkankan.scene.entity.ScenePro;
  24. import com.fdkankan.scene.entity.SceneProExt;
  25. import com.fdkankan.scene.factory.FloorLogoHandlerFactory;
  26. import com.fdkankan.scene.factory.FloorPlanHandlerFactory;
  27. import com.fdkankan.scene.factory.MusicHandlerFactory;
  28. import com.fdkankan.scene.factory.ScreenshotHandlerFactory;
  29. import com.fdkankan.scene.mapper.ISceneEditInfoMapper;
  30. import com.fdkankan.scene.service.ISceneEditControlsService;
  31. import com.fdkankan.scene.service.ISceneEditInfoService;
  32. import com.fdkankan.scene.service.ISceneProExtService;
  33. import com.fdkankan.scene.service.ISceneProService;
  34. import com.fdkankan.scene.vo.*;
  35. import com.google.common.collect.Lists;
  36. import com.google.errorprone.annotations.Var;
  37. import java.util.List;
  38. import java.util.Map;
  39. import java.util.stream.Collectors;
  40. import org.springframework.beans.factory.annotation.Autowired;
  41. import org.springframework.beans.factory.annotation.Value;
  42. import org.springframework.stereotype.Service;
  43. import org.springframework.transaction.annotation.Transactional;
  44. import java.io.BufferedReader;
  45. import java.io.IOException;
  46. import java.io.InputStream;
  47. import java.io.InputStreamReader;
  48. import java.util.Calendar;
  49. import java.util.Objects;
  50. /**
  51. * <p>
  52. * 服务实现类
  53. * </p>
  54. *
  55. * @author
  56. * @since 2022-01-18
  57. */
  58. @Service
  59. public class SceneEditInfoServiceImpl extends ServiceImpl<ISceneEditInfoMapper, SceneEditInfo> implements ISceneEditInfoService {
  60. @Value("${oss.prefix.ali}")
  61. private String prefixAli;
  62. @Value("${upload.type}")
  63. private String type;
  64. @Value("${oss.bucket:4dkankan}")
  65. private String bucket;
  66. @Autowired
  67. private ISceneEditControlsService sceneEditControlsService;
  68. @Autowired
  69. private ISceneProService sceneProService;
  70. @Autowired
  71. private UploadToOssUtil uploadToOssUtil;
  72. @Autowired
  73. RedisUtil redisUtil;
  74. @Autowired
  75. private ISceneProExtService sceneProExtService;
  76. @Override
  77. public SceneEditInfoVO saveScene(SceneEditInfoParamVO param) {
  78. ScenePro scenePro = sceneProService.findBySceneNum(param.getNum());
  79. if(Objects.isNull(scenePro)){
  80. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  81. }
  82. SceneEditInfo sceneEditInfoDb = this.getBySceneProId(scenePro.getId());
  83. SceneEditControls sceneEditControlsDb = null;
  84. if(Objects.nonNull(sceneEditInfoDb)){
  85. sceneEditControlsDb = sceneEditControlsService.getBySceneEditId(sceneEditInfoDb.getId());
  86. }
  87. SceneEditInfo sceneEditInfo = BeanUtil.copyProperties(param, SceneEditInfo.class);
  88. sceneEditInfo.setSceneProId(scenePro.getId());
  89. sceneEditInfo.setCreateTime(Calendar.getInstance().getTime());
  90. if(Objects.isNull(sceneEditInfoDb)){
  91. this.save(sceneEditInfo);
  92. }else{
  93. sceneEditInfo.setId(sceneEditInfoDb.getId());
  94. sceneEditInfo.setUpdateTime(Calendar.getInstance().getTime());
  95. this.updateById(sceneEditInfo);
  96. }
  97. if(Objects.nonNull(param.getControls())){
  98. SceneEditControls sceneEditControls = BeanUtil.copyProperties(param.getControls(), SceneEditControls.class);
  99. sceneEditControls.setEditInfoId(sceneEditInfo.getId());
  100. if(Objects.isNull(sceneEditControlsDb)){
  101. sceneEditControlsService.save(sceneEditControls);
  102. }else{
  103. sceneEditControls.setId(sceneEditControlsDb.getId());
  104. sceneEditControlsService.updateById(sceneEditControls);
  105. }
  106. }
  107. SceneEditInfoVO result = BeanUtil.copyProperties(param, SceneEditInfoVO.class);
  108. result.setCreateTime(sceneEditInfo.getCreateTime());
  109. return result;
  110. }
  111. @Override
  112. public SceneEditInfo getBySceneProId(long sceneProId) {
  113. return this.getOne(new LambdaQueryWrapper<SceneEditInfo>()
  114. .eq(SceneEditInfo::getTbStatus, TbStatus.VALID.code())
  115. .eq(SceneEditInfo::getSceneProId, sceneProId));
  116. }
  117. @Override
  118. public ResultData publicScene(SceneEditInfoParamVO param) throws Exception {
  119. String sceneNum = param.getNum();
  120. if(StrUtil.isEmpty(sceneNum)){
  121. throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  122. }
  123. //根据场景码查询数据库
  124. ScenePro scenePro = sceneProService.findBySceneNum(sceneNum);
  125. SceneEditInfo sceneEditInfo = this.getBySceneProId(scenePro.getId());
  126. SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
  127. //生成sceneJson
  128. SceneJsonBean sceneJson = BeanUtil.copyProperties(sceneEditInfo, SceneJsonBean.class);
  129. SceneEditControlsVO sceneEditControlsVO = BeanUtil.copyProperties(sceneEditControls, SceneEditControlsVO.class);
  130. sceneJson.setControls(sceneEditControlsVO);
  131. sceneJson.setNum(sceneNum);
  132. if(StrUtil.isNotEmpty(sceneEditInfo.getFloorPlanPath())){
  133. sceneJson.setFloorPlanPaths(sceneEditInfo.getFloorPlanPath().split(","));
  134. }
  135. //处理热点数据,生成hot.json
  136. this.publicHotData(sceneNum, sceneJson);
  137. //上传sceneJson文件
  138. String sceneJsonPath = String.format(UploadFilePath.DATA_VIEW_PATH+"scene.json", sceneNum);
  139. uploadToOssUtil.upload(JSON.toJSONBytes(sceneJson), sceneJsonPath);
  140. //sceneJson放入缓存
  141. String key = String.format(RedisKey.SCENE_JSON, sceneNum);
  142. redisUtil.set(key, JSON.toJSONString(sceneJson));
  143. //删除发布数据中的user目录
  144. String publicUserPath = String.format(UploadFilePath.USER_VIEW_PATH, sceneNum);
  145. uploadToOssUtil.deleteFile(publicUserPath);
  146. // String editUserPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum);
  147. //复制编辑目录到发布目录
  148. String editPath = String.format(UploadFilePath.EDIT_PATH, param.getNum());
  149. String viewPath = String.format(UploadFilePath.VIEW_PATH, param.getNum());
  150. uploadToOssUtil.copyFiles(editPath,viewPath);
  151. return ResultData.ok();
  152. }
  153. private void publicHotData(String sceneNum, SceneJsonBean sceneJson) throws IOException {
  154. String hotDataKey = String.format(RedisKey.SCENE_HOT_DATA, sceneNum);
  155. Map<String, String> hotMap = redisUtil.hmget(hotDataKey);
  156. List<String> hotList = Lists.newArrayList();
  157. hotMap.entrySet().stream().forEach(entry->{
  158. if(StrUtil.isNotEmpty(entry.getValue())){
  159. hotList.add(entry.getValue());
  160. }
  161. });
  162. if(CollUtil.isNotEmpty(hotList)){
  163. JSONArray jsonhots = new JSONArray();
  164. hotList.stream().forEach(hot->{
  165. jsonhots.add(JSONObject.parseObject(hot));
  166. });
  167. String hotJsonPath = String.format(UploadFilePath.USER_EDIT_PATH, sceneNum) + "hot.json";
  168. uploadToOssUtil.upload(jsonhots.toString().getBytes(), hotJsonPath);
  169. }
  170. }
  171. @Override
  172. public SceneInfoVO getSceneInfo(@Var SceneInfoParamVO param) {
  173. SceneInfoReqType sceneInfoReqType = SceneInfoReqType.get(param.getReqType());
  174. switch (sceneInfoReqType){
  175. //如果是编辑页面请求,查数据库
  176. case EDIT:
  177. return this.getSceneInfo4Edit(param.getNum());
  178. //如果是查看页面请求,查redis
  179. case VIEW:
  180. return this.getSceneInfo4View(param.getNum());
  181. }
  182. return null;
  183. }
  184. /**
  185. * <p>
  186. 编辑页面获取场景详情信息
  187. * </p>
  188. * @author dengsixing
  189. * @date 2022/1/21
  190. * @param num
  191. * @return com.fdkankan.scene.vo.SceneInfoVO
  192. **/
  193. private SceneInfoVO getSceneInfo4Edit(String num){
  194. ScenePro scenePro = sceneProService.findBySceneNum(num);
  195. if(Objects.isNull(scenePro)){
  196. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  197. }
  198. SceneEditInfo sceneEditInfo = this.getBySceneProId(scenePro.getId());
  199. SceneEditControls sceneEditControls = sceneEditControlsService.getBySceneEditId(sceneEditInfo.getId());
  200. SceneInfoVO sceneInfoVO = BeanUtil.copyProperties(sceneEditInfo, SceneInfoVO.class);
  201. sceneInfoVO.setControls(BeanUtil.copyProperties(sceneEditControls, SceneEditControlsVO.class));
  202. sceneInfoVO.setNum(num);
  203. //生成sceneJson
  204. if(StrUtil.isNotEmpty(sceneEditInfo.getFloorPlanPath())){
  205. sceneInfoVO.setFloorPlanPaths(sceneEditInfo.getFloorPlanPath().split(","));
  206. }
  207. return sceneInfoVO;
  208. }
  209. /**
  210. * <p>
  211. 查看页面获取场景详情信息
  212. * </p>
  213. * @author dengsixing
  214. * @date 2022/1/21
  215. * @param num
  216. * @return com.fdkankan.scene.vo.SceneInfoVO
  217. **/
  218. private SceneInfoVO getSceneInfo4View(String num){
  219. String sceneJson = redisUtil.get(String.format(RedisKey.SCENE_JSON, num));
  220. SceneInfoVO sceneInfoVO = null;
  221. //先查询redis
  222. if(StrUtil.isNotEmpty(sceneJson)){
  223. sceneInfoVO = JSON.parseObject(sceneJson, SceneInfoVO.class);
  224. return sceneInfoVO;
  225. }
  226. //如果redis没找到,从scene.json中获取
  227. String objectName = String.format(ConstantFilePath.SCENE_VIEW_DATA_DATA_SCENEJSON, num);
  228. String objectContent = uploadToOssUtil.getObjectContent(bucket, objectName);
  229. if(StrUtil.isEmpty(objectContent))
  230. return null;
  231. sceneInfoVO = JSON.parseObject(objectContent, SceneInfoVO.class);
  232. return sceneInfoVO;
  233. }
  234. @Override
  235. // @Transactional
  236. public ResultData saveUpload(SaveUploadParamVO param) throws Exception {
  237. FileBizType fileBizType = FileBizType.get(param.getBizType());
  238. String num = param.getNum();
  239. String fileInfo = param.getFileInfo();
  240. if(Objects.isNull(fileBizType)){
  241. throw new BusinessException(ErrorCode.FAILURE_CODE_7003);
  242. }
  243. switch (fileBizType){
  244. case MUSIC:
  245. return new MusicHandlerFactory().getHandler().save(num, fileInfo);
  246. case FLOOR_LOGO:
  247. return new FloorLogoHandlerFactory().getHandler().save(num, fileInfo);
  248. // case FLOOR_PLAN:
  249. // return new FloorPlanHandlerFactory().getHandler().save(num, fileInfo);
  250. case SCREENSHOT:
  251. return new ScreenshotHandlerFactory().getHandler().save(num, fileInfo);
  252. }
  253. return ResultData.ok();
  254. }
  255. @Override
  256. public ResultData saveCad(BaseDataParamVO param) throws Exception {
  257. String num = param.getNum();
  258. ScenePro scenePro = sceneProService.findBySceneNum(num);
  259. if(Objects.isNull(scenePro))
  260. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  261. String editDataPath = String.format(UploadFilePath.DATA_EDIT_PATH, num);
  262. String editUserPath = String.format(UploadFilePath.USER_EDIT_PATH, num);
  263. String localDataPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, num);
  264. JSONObject fileInfoJson = JSON.parseObject(param.getData());
  265. String floors = fileInfoJson.getString("floors");
  266. String cadInfo = fileInfoJson.getString("cadInfo");
  267. String floorJsonData = fileInfoJson.getString("floorJsonData");
  268. String filePaths = fileInfoJson.getString("filePaths");
  269. Byte reSet = fileInfoJson.getByte("reset");
  270. String filePathStr = null;
  271. //如果floors不为空,只需要根据对应楼层id修改楼层名称
  272. if(StrUtil.isNotEmpty(floors)){
  273. //从编辑目录中下载floorplan_cad.json、floorplan_user.json到本地
  274. String floorCadUrl = prefixAli + editDataPath + "floorplan_cad.json?t=" + System.currentTimeMillis();
  275. String floorUserUrl = prefixAli + editUserPath + "floorplan_user.json?t=" + System.currentTimeMillis();
  276. //如果是云存储,将vision.modeldata下载到本地,如果是本地存储,场景计算完就已经将这个文件拷贝到编辑目录了存在这个文件了,不需要再下载
  277. if(!StorageType.LOCAL.code().equals(this.type)){// TODO: 2022/2/15 这里有可能有问题,可能还需要考虑本地部署的情况
  278. FileUtils.downLoadFromUrl(floorCadUrl, "floorplan_cad.json", localDataPath);
  279. FileUtils.downLoadFromUrl(floorUserUrl, "floorplan_user.json", localDataPath);
  280. }
  281. String floorCadStr = FileUtils.readFile(localDataPath + "floorplan_cad.json");
  282. if(StrUtil.isNotEmpty(floorCadStr)){
  283. JSONObject floorCadJson = this.updateFloorName(floors, floorCadStr);
  284. FileUtils.writeFile(localDataPath + "floorplan_cad.json", floorCadJson.toString());
  285. uploadToOssUtil.upload(localDataPath + "floorplan_cad.json", editDataPath+"floorplan_cad.json");
  286. }
  287. String floorUserStr = FileUtils.readFile(localDataPath + "floorplan_user.json");
  288. if(StrUtil.isNotEmpty(floorUserStr)) {
  289. JSONObject floorUserJson = this.updateFloorName(floors, floorUserStr);
  290. FileUtils.writeFile(localDataPath + "floorplan_user.json", floorUserJson.toString());
  291. uploadToOssUtil.upload(localDataPath + "floorplan_user.json",editUserPath + "floorplan_user.json");
  292. }
  293. }else{
  294. //户型图文件路径
  295. if(StrUtil.isNotEmpty(filePaths)){
  296. cn.hutool.json.JSONArray filePathsArrs = JSONUtil.parseArray(filePaths);
  297. List<String> filePathsList = filePathsArrs.toList(String.class);
  298. StringBuilder filePathBuilder = new StringBuilder();
  299. filePathsList.parallelStream().forEach(path -> {
  300. filePathBuilder.append(",").append(path);
  301. });
  302. filePathStr = filePathBuilder.substring(1);
  303. }
  304. //上传houst_floor.json文件
  305. FileUtils.writeFile(localDataPath + "floorplan_user.json", floorJsonData);
  306. uploadToOssUtil.upload(localDataPath + "floorplan_user.json", editUserPath + "floorplan_user.json");
  307. }
  308. //写入数据库
  309. Byte floorPlanUser = null;
  310. if(StrUtil.isNotEmpty(floorJsonData)){
  311. floorPlanUser = CommonStatus.YES.code();
  312. }
  313. if(CommonStatus.YES.code().equals(reSet)){
  314. floorPlanUser = CommonStatus.NO.code();
  315. }
  316. SceneEditInfo sceneEditInfoDb = this.getBySceneProId(scenePro.getId());
  317. if(Objects.nonNull(sceneEditInfoDb)){
  318. LambdaUpdateWrapper<SceneEditInfo> updateWrapper = new LambdaUpdateWrapper<SceneEditInfo>()
  319. .setSql("version=version+" + 1)
  320. .eq(SceneEditInfo::getId, sceneEditInfoDb.getId());
  321. if(StrUtil.isNotEmpty(filePathStr)){
  322. updateWrapper.set(SceneEditInfo::getFloorPlanPath, filePathStr);
  323. }
  324. if(StrUtil.isNotEmpty(cadInfo)){
  325. updateWrapper.set(SceneEditInfo::getCadInfo, cadInfo);
  326. }
  327. if(floorPlanUser != null){
  328. updateWrapper.set(SceneEditInfo::getFloorPlanUser, floorPlanUser);
  329. }
  330. this.update(updateWrapper);
  331. }else{
  332. sceneEditInfoDb = new SceneEditInfo();
  333. sceneEditInfoDb.setSceneProId(scenePro.getId());
  334. sceneEditInfoDb.setFloorPlanPath(filePathStr);
  335. sceneEditInfoDb.setCadInfo(cadInfo);
  336. sceneEditInfoDb.setFloorPlanUser(floorPlanUser);
  337. this.save(sceneEditInfoDb);
  338. }
  339. return ResultData.ok();
  340. }
  341. private JSONObject updateFloorName(String sourceFloors, String targeFloors){
  342. JSONArray sourceFloorsJson = JSON.parseArray(sourceFloors);
  343. JSONObject targeFloorsJson = JSONObject.parseObject(targeFloors);
  344. JSONArray array = targeFloorsJson.getJSONArray("floors");
  345. for (int i = 0; i < array.size(); ++i) {
  346. JSONObject targetFloor = array.getJSONObject(i);
  347. int targetId = targetFloor.getIntValue("id");
  348. for (int j = 0; j < sourceFloorsJson.size(); ++j) {
  349. JSONObject floor = sourceFloorsJson.getJSONObject(j);
  350. int id = floor.getIntValue("id");
  351. String name = floor.getString("name");
  352. if (targetId != id)
  353. continue;
  354. targetFloor.put("name", name);
  355. }
  356. }
  357. return targeFloorsJson;
  358. }
  359. @Override
  360. public void upgradeVersionById(Long id) {
  361. this.update(new LambdaUpdateWrapper<SceneEditInfo>()
  362. .setSql("version=version+" + 1)
  363. .eq(SceneEditInfo::getId, id));
  364. }
  365. }