SceneProServiceImpl.java 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228
  1. package com.fdkankan.scene.service.impl;
  2. import cn.hutool.core.collection.CollUtil;
  3. import cn.hutool.core.io.FileUtil;
  4. import cn.hutool.core.util.StrUtil;
  5. import com.alibaba.fastjson.JSON;
  6. import com.alibaba.fastjson.JSONArray;
  7. import com.alibaba.fastjson.JSONObject;
  8. import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
  9. import com.fdkankan.common.constant.ConstantFilePath;
  10. import com.fdkankan.common.constant.ErrorCode;
  11. import com.fdkankan.common.constant.UploadFilePath;
  12. import com.fdkankan.common.exception.BusinessException;
  13. import com.fdkankan.model.utils.ConvertUtils;
  14. import com.fdkankan.redis.constant.RedisKey;
  15. import com.fdkankan.redis.util.RedisClient;
  16. import com.fdkankan.scene.bean.IconBean;
  17. import com.fdkankan.scene.bean.ResultData;
  18. import com.fdkankan.scene.bean.TagBean;
  19. import com.fdkankan.scene.entity.Scene;
  20. import com.fdkankan.scene.entity.SceneEditInfo;
  21. import com.fdkankan.scene.service.FYunFileService;
  22. import com.fdkankan.scene.service.ISceneProService;
  23. import com.fdkankan.scene.service.SceneEditInfoService;
  24. import com.fdkankan.scene.service.SceneService;
  25. import com.fdkankan.scene.vo.*;
  26. import com.google.common.collect.Lists;
  27. import com.google.common.collect.Sets;
  28. import lombok.extern.slf4j.Slf4j;
  29. import org.springframework.beans.factory.annotation.Autowired;
  30. import org.springframework.stereotype.Service;
  31. import org.springframework.transaction.annotation.Transactional;
  32. import javax.annotation.Resource;
  33. import java.io.File;
  34. import java.io.IOException;
  35. import java.nio.charset.StandardCharsets;
  36. import java.util.*;
  37. import java.util.stream.Collectors;
  38. /**
  39. * <p>
  40. * pro场景表 服务实现类
  41. * </p>
  42. *
  43. * @author dengsixing
  44. * @since 2021-12-23
  45. */
  46. @Slf4j
  47. @Service
  48. public class SceneProServiceImpl implements ISceneProService {
  49. // @Value("${fyun.host}")
  50. // private String ossUrlPrefix;
  51. // @Value("${fyun.type}")
  52. // private String fyunType;
  53. // @Value("${main.url}")
  54. // private String mainUrl;
  55. // @Value("${scene.url}")
  56. // private String sceneUrl;
  57. // @Value("${scene.pro.url}")
  58. // private String sceneProUrl;
  59. // @Value("${scene.pro.new.url}")
  60. // private String sceneProNewUrl;
  61. // @Value("${ecs.checkFile.maxTimes:5}")
  62. // private int maxCheckTimes;
  63. // @Value("${ecs.checkFile.waitTime:5000}")
  64. // private int waitTime;
  65. //
  66. @Autowired
  67. private FYunFileService fYunFileService;
  68. // @Autowired
  69. // private RedisLockUtil redisLockUtil;
  70. @Resource
  71. private RedisClient redisClient;
  72. // @Autowired
  73. // private ISceneDataDownloadService sceneDataDownloadService;
  74. // @Autowired
  75. // private ISceneProService sceneProService;
  76. @Autowired
  77. private SceneEditInfoService sceneEditInfoService;
  78. // @Autowired
  79. // private ISceneEditControlsService sceneEditControlsService;
  80. @Autowired
  81. private SceneService scenePlusService;
  82. // @Autowired
  83. // private IScenePlusExtService scenePlusExtService;
  84. // @Autowired
  85. // private ISceneUploadService sceneUploadService;
  86. // @Autowired
  87. // private ISceneAsynOperLogService sceneAsynOperLogService;
  88. @Transactional
  89. @Override
  90. public ResultData saveInitialPage(FileNameAndDataParamVO param) throws Exception{
  91. Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup());
  92. if(scenePlus == null){
  93. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  94. }
  95. SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  96. if(sceneEditInfo == null){
  97. sceneEditInfo = new SceneEditInfo();
  98. sceneEditInfo.setScenePlusId(scenePlus.getId());
  99. sceneEditInfo.setEntry(param.getData());
  100. sceneEditInfoService.save(sceneEditInfo);
  101. }else{
  102. sceneEditInfoService.update(
  103. new LambdaUpdateWrapper<SceneEditInfo>()
  104. .set(SceneEditInfo::getEntry, param.getData())
  105. .setSql("version = version + 1")
  106. .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
  107. }
  108. return ResultData.ok();
  109. }
  110. @Override
  111. public ResultData addOrUpdateTag(SaveTagsParamVO param) throws Exception {
  112. Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup());
  113. if (scenePlus == null)
  114. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  115. this.addOrUpdateHotData(param.getNum(), param.getSubgroup(), param.getHotDataList());
  116. this.addOrUpdateIcons(param.getNum(), param.getSubgroup(), param.getIcons());
  117. //保存数据库
  118. SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  119. sceneEditInfoService.saveTagsToSceneEditInfo(param.getNum(), param.getSubgroup(), sceneEditInfo);
  120. sceneEditInfoService.updateById(sceneEditInfo);
  121. this.publicHotData(param.getNum(), param.getSubgroup());
  122. return ResultData.ok();
  123. }
  124. private void addOrUpdateHotData(String num, Integer subgroup, List<HotParamVO> hotDataList) throws Exception{
  125. Map<String, String> addOrUpdateMap = new HashMap<>();
  126. int i = 0;
  127. for (HotParamVO hotParamVO : hotDataList) {
  128. JSONObject jsonObject = JSON.parseObject(hotParamVO.getHotData());
  129. jsonObject.put("createTime", Calendar.getInstance().getTimeInMillis() + i++);
  130. addOrUpdateMap.put(hotParamVO.getSid(), jsonObject.toJSONString());
  131. }
  132. // this.syncHotFromFileToRedis(num);
  133. //处理新增和修改数据
  134. this.addOrUpdateHotDataHandler(num, subgroup, addOrUpdateMap);
  135. }
  136. private void addOrUpdateIcons(String num, Integer subgroup, Set<String> icons) throws Exception{
  137. if(CollUtil.isEmpty(icons)){
  138. return;
  139. }
  140. // this.syncIconsFromFileToRedis(num);
  141. String key = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup));
  142. redisClient.sSet(key, icons);
  143. }
  144. @Override
  145. public ResultData deleteTag(DeleteHotParamVO param) throws Exception {
  146. Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup());
  147. if (scenePlus == null)
  148. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  149. List<String> deleteSidList = param.getSidList();
  150. //处理删除状态数据
  151. this.deleteHotData(param.getNum(), param.getSubgroup(), deleteSidList);
  152. //删除导览中的热点数据
  153. this.deleteHotDataFromTourJson(param.getNum(), param.getSubgroup(), param.getSidList());
  154. // //写入本地文件,作为备份
  155. // this.writeHotJson(param.getNum());
  156. //保存数据库
  157. SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  158. sceneEditInfoService.saveTagsToSceneEditInfo(param.getNum(), param.getSubgroup(), sceneEditInfo);
  159. sceneEditInfoService.updateById(sceneEditInfo);
  160. this.publicHotData(param.getNum(), param.getSubgroup());
  161. return ResultData.ok();
  162. }
  163. private void deleteHotDataFromTourJson(String num, Integer subgroup, List<String> sidList) throws IOException {
  164. String key = String.format(UploadFilePath.USER_VIEW_PATH, num) + "tour.json";
  165. String tourJson = fYunFileService.getFileContent(key, subgroup);
  166. if(StrUtil.isEmpty(tourJson)){
  167. return;
  168. }
  169. JSONArray jsonArray = JSON.parseArray(tourJson);
  170. if(CollUtil.isEmpty(jsonArray)){
  171. return;
  172. }
  173. jsonArray.stream().forEach(tour->{
  174. JSONObject obj = (JSONObject) tour;
  175. JSONArray itemArra = obj.getJSONArray("list");
  176. itemArra.stream().forEach(item->{
  177. JSONObject itemObj = (JSONObject) item;
  178. String tagId = itemObj.getString("tagId");
  179. if(tagId != null && sidList.contains(tagId)){
  180. itemObj.remove("tagId");
  181. }
  182. });
  183. });
  184. fYunFileService.uploadFile(num, subgroup, jsonArray.toJSONString().getBytes(StandardCharsets.UTF_8), key);
  185. }
  186. @Override
  187. public ResultData deleteIcons(DeleteHotIconParamVO param) throws Exception {
  188. Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup());
  189. if (scenePlus == null)
  190. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  191. List<String> fileNameList = param.getFileNameList();
  192. // this.syncIconsFromFileToRedis(param.getNum());
  193. String key = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(param.getNum(), param.getSubgroup()));
  194. redisClient.setRemove(key, new HashSet<>(fileNameList));
  195. //写入本地文件,作为备份
  196. // this.writeHotJson(param.getNum());
  197. return ResultData.ok();
  198. }
  199. @Override
  200. public ResultData listTags(String num, Integer subgroup) throws Exception{
  201. //保证热点数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
  202. // this.syncHotFromFileToRedis(num);
  203. //保证icons数据安全性,当redis宕机导致icons数据丢失时,可以从文件中读取,恢复到redis
  204. // this.syncIconsFromFileToRedis(num);
  205. JSONObject result = new JSONObject();
  206. //查询缓存是否包含热点数据
  207. String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup));
  208. Map<String, String> allTagsMap = redisClient.hmget(key);
  209. List<JSONObject> tags = Lists.newArrayList();
  210. List<TagBean> tagBeanList = new ArrayList<>();
  211. if(CollUtil.isNotEmpty(allTagsMap)){
  212. allTagsMap.entrySet().stream().forEach(entry -> {
  213. JSONObject jsonObject = JSON.parseObject(entry.getValue());
  214. tagBeanList.add(
  215. TagBean.builder()
  216. .createTime(jsonObject.getLong("createTime"))
  217. .tag(jsonObject).build());
  218. });
  219. //按创建时间倒叙排序
  220. tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed());
  221. //移除createTime字段
  222. tags = tagBeanList.stream().map(tagBean -> {
  223. JSONObject tag = tagBean.getTag();
  224. tag.remove("createTime");
  225. return tag;
  226. }).collect(Collectors.toList());
  227. }
  228. result.put("tags", tags);
  229. //查询缓存是否包含icons
  230. key = String.format(RedisKey.SCENE_HOT_ICONS, RedisKey.getNumStr(num, subgroup));
  231. Set<String> icons = redisClient.sGet(key);
  232. if(icons == null){
  233. icons = Sets.newHashSet();
  234. }
  235. List<String> iconList = this.sortIcons(tags, icons);
  236. result.put("icons", iconList);
  237. return ResultData.ok(result);
  238. }
  239. private List<String> sortIcons(List<JSONObject> tags, Set<String> icons){
  240. //统计使用频次
  241. List<IconBean> iconBeans = Lists.newArrayList();
  242. for (String icon : icons) {
  243. int count = 0;
  244. for (JSONObject tag : tags) {
  245. String sid = tag.getString("icon");
  246. if(StrUtil.isEmpty(sid) || !icon.equals(sid)){
  247. continue;
  248. }
  249. ++count;
  250. }
  251. iconBeans.add(IconBean.builder().icon(icon).count(count).build());
  252. }
  253. //排序
  254. List<String> iconList = iconBeans.stream().sorted(Comparator.comparing(IconBean::getCount).reversed())
  255. .map(item -> {
  256. return item.getIcon();
  257. }).collect(Collectors.toList());
  258. return iconList;
  259. }
  260. private void publicHotData(String sceneNum, Integer subgroup) {
  261. String hotDataKey = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(sceneNum, subgroup));
  262. Map<String, String> hotMap = redisClient.hmget(hotDataKey);
  263. JSONArray tags = new JSONArray();
  264. if(CollUtil.isNotEmpty(hotMap)){
  265. List<TagBean> tagBeanList = hotMap.entrySet().stream().map(entry -> {
  266. JSONObject jsonObject = JSON.parseObject(entry.getValue());
  267. return TagBean.builder()
  268. .createTime(jsonObject.getLong("createTime"))
  269. .tag(jsonObject).build();
  270. }).collect(Collectors.toList());
  271. //按创建时间倒叙排序
  272. tagBeanList.sort(Comparator.comparingLong(TagBean::getCreateTime).reversed());
  273. //移除createTime字段
  274. tagBeanList.stream().forEach(tagBean -> {
  275. tags.add(tagBean.getTag());
  276. });
  277. }
  278. String hotJsonPath = String.format(UploadFilePath.USER_VIEW_PATH, sceneNum) + "hot.json";
  279. fYunFileService.uploadFile(sceneNum, subgroup, tags.toString().getBytes(StandardCharsets.UTF_8), hotJsonPath);
  280. }
  281. //
  282. // /**
  283. // * <p>
  284. // 保证热点数据安全性,当redis宕机导致热点数据丢失时,可以从文件中读取,恢复到redis
  285. // * </p>
  286. // * @author dengsixing
  287. // * @date 2022/3/3
  288. // **/
  289. // private void syncHotFromFileToRedis(String num) throws Exception{
  290. //
  291. // String key = String.format(RedisKey.SCENE_HOT_DATA, num);
  292. // boolean exist = redisUtil.hasKey(key);
  293. // if(exist){
  294. // return;
  295. // }
  296. // String lockKey = String.format(RedisLockKey.LOCK_HOT_DATA_SYNC, num);
  297. // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
  298. // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
  299. // if(!lock){
  300. // throw new BusinessException(ErrorCode.SYSTEM_BUSY);
  301. // }
  302. // try{
  303. // exist = redisUtil.hasKey(key);
  304. // if(exist){
  305. // return;
  306. // }
  307. // String tagsFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "hot.json";
  308. // String tagsData = FileUtils.readUtf8String(tagsFilePath);
  309. // if(StrUtil.isEmpty(tagsData)){
  310. // return;
  311. // }
  312. // JSONObject jsonObject = JSON.parseObject(tagsData);
  313. // JSONArray tagsArr = jsonObject.getJSONArray("tags");
  314. // if(CollUtil.isEmpty(tagsArr)){
  315. // return;
  316. // }
  317. // Map<String, String> map = new HashMap<>();
  318. // for (Object o : tagsArr) {
  319. // JSONObject jo = (JSONObject)o;
  320. // map.put(jo.getString("sid"), jo.toJSONString());
  321. // }
  322. // redisUtil.hmset(key, map);
  323. // }finally {
  324. // redisLockUtil.unlockLua(lockKey, lockVal);
  325. // }
  326. // }
  327. //
  328. // /**
  329. // * <p>
  330. // 保证icons数据安全性,当redis宕机导致icons数据丢失时,可以从文件中读取,恢复到redis
  331. // * </p>
  332. // * @author dengsixing
  333. // * @date 2022/3/3
  334. // **/
  335. // private void syncIconsFromFileToRedis(String num) throws Exception{
  336. //
  337. // String key = String.format(RedisKey.SCENE_HOT_ICONS, num);
  338. // boolean exist = redisUtil.hasKey(key);
  339. // if(exist){
  340. // return;
  341. // }
  342. // String lockKey = String.format(RedisLockKey.LOCK_HOT_ICONS_SYNC, num);
  343. // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
  344. // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
  345. // if(!lock){
  346. // throw new BusinessException(ErrorCode.SYSTEM_BUSY);
  347. // }
  348. // try{
  349. // exist = redisUtil.hasKey(key);
  350. // if(exist){
  351. // return;
  352. // }
  353. // String tagsFilePath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "hot.json";
  354. // String tagsData = FileUtils.readUtf8String(tagsFilePath);
  355. // if(StrUtil.isEmpty(tagsData)){
  356. // return;
  357. // }
  358. // JSONObject jsonObject = JSON.parseObject(tagsData);
  359. // JSONArray iconArr = jsonObject.getJSONArray("icons");
  360. // if(CollUtil.isEmpty(iconArr)){
  361. // return;
  362. // }
  363. // redisUtil.sSet(key, iconArr.toJavaList(String.class).toArray());
  364. // }finally {
  365. // redisLockUtil.unlockLua(lockKey, lockVal);
  366. // }
  367. //
  368. // }
  369. //
  370. // /**
  371. // * <p>
  372. // 热点数据保存
  373. //
  374. // * </p>
  375. // * @author dengsixing
  376. // * @date 2022/3/3
  377. // **/
  378. // private void writeHotJson(String num) throws Exception{
  379. //
  380. // String dataKey = String.format(RedisKey.SCENE_HOT_DATA, num);
  381. // Map<String, String> tagMap = redisUtil.hmget(dataKey);
  382. // List<String> tagList = Lists.newArrayList();
  383. // tagMap.entrySet().stream().forEach(entry->{
  384. // if(StrUtil.isNotEmpty(entry.getValue())){
  385. // tagList.add(entry.getValue());
  386. // }
  387. // });
  388. // JSONObject jsonObject = new JSONObject();
  389. // JSONArray tagJsonArr = new JSONArray();
  390. // if(CollUtil.isNotEmpty(tagList)){
  391. // tagList.stream().forEach(hot->{
  392. // tagJsonArr.add(JSONObject.parseObject(hot));
  393. // });
  394. // }
  395. // jsonObject.put("tags", tagJsonArr);
  396. //
  397. // String iconsKey = String.format(RedisKey.SCENE_HOT_ICONS, num);
  398. // Set<String> iconList = redisUtil.sGet(iconsKey);
  399. // jsonObject.put("icons", iconList);
  400. //
  401. // String hotJsonPath = String.format(ConstantFilePath.SCENE_USER_PATH_V4, num) + "hot.json";
  402. // String lockKey = String.format(RedisLockKey.LOCK_HOT_JSON, num);
  403. // String lockVal = cn.hutool.core.lang.UUID.randomUUID().toString();
  404. // boolean lock = redisLockUtil.lock(lockKey, lockVal, RedisKey.EXPIRE_TIME_1_MINUTE);
  405. // if(!lock){
  406. // return;
  407. // }
  408. // try{
  409. // FileUtils.writeFile(hotJsonPath, jsonObject.toJSONString());
  410. // }finally {
  411. // redisLockUtil.unlockLua(lockKey, lockVal);
  412. // }
  413. // }
  414. private void addOrUpdateHotDataHandler(String num, Integer subgroup, Map<String, String> addOrUpdateMap){
  415. if(CollUtil.isEmpty(addOrUpdateMap))
  416. return;
  417. //数据验证,新增、修改状态,hotdata不能为空
  418. for (String sid : addOrUpdateMap.keySet()) {
  419. String hotData = addOrUpdateMap.get(sid);
  420. if(StrUtil.isEmpty(hotData)){
  421. throw new BusinessException(ErrorCode.FAILURE_CODE_7004);
  422. }
  423. }
  424. //批量写入缓存
  425. String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup));
  426. redisClient.hmset(key, addOrUpdateMap);
  427. }
  428. private void deleteHotData(String num, Integer subgroup, List<String> deleteSidList) throws Exception {
  429. // this.syncHotFromFileToRedis(num);
  430. if(CollUtil.isEmpty(deleteSidList)){
  431. return;
  432. }
  433. //从redis中加载热点数据
  434. String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(num, subgroup));
  435. //从redis中移除热点数据
  436. redisClient.hdel(key, deleteSidList);
  437. }
  438. @Override
  439. public ResultData saveTagsVisible(SaveTagsVisibleParamVO param) throws Exception {
  440. Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup());
  441. if (scenePlus == null ) {
  442. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  443. }
  444. JSONArray visiblePanos = JSONArray.parseArray(param.getData());
  445. //如果redis找不到,就从本地文件中reload
  446. // this.syncHotFromFileToRedis(param.getNum());
  447. //从缓存中获取热点数据,如果为空,抛出异常
  448. String key = String.format(RedisKey.SCENE_HOT_DATA, RedisKey.getNumStr(param.getNum(), param.getSubgroup()));
  449. Map<String, String> map = redisClient.hmget(key);
  450. if (CollUtil.isEmpty(map)) {
  451. throw new BusinessException(ErrorCode.FAILURE_CODE_7005);
  452. }
  453. List<Map.Entry<String, String>> allTags = map.entrySet().stream().filter(item -> {
  454. if (StrUtil.isBlank(item.getValue())) {
  455. return false;
  456. }
  457. return true;
  458. }).collect(Collectors.toList());
  459. if (CollUtil.isEmpty(allTags)) {
  460. throw new BusinessException(ErrorCode.FAILURE_CODE_7005);
  461. }
  462. allTags.stream().forEach(entry->{
  463. JSONObject hot = JSON.parseObject(entry.getValue());
  464. visiblePanos.stream().forEach(item->{
  465. if (hot.getString("sid").equals(((JSONObject) item).getString("sid"))) {
  466. hot.put("visiblePanos", ((JSONObject) item).getJSONArray("value"));
  467. hot.put("isHidden", ((JSONObject) item).getBoolean("isHidden"));
  468. entry.setValue(hot.toJSONString());
  469. }
  470. });
  471. });
  472. //更新版本号
  473. SceneEditInfo editInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  474. sceneEditInfoService.upgradeVersionById(editInfo.getId());
  475. //放入缓存
  476. Map<String, String> finalMap = new HashMap<>();
  477. allTags.stream().forEach(entry->{
  478. finalMap.put(entry.getKey(), entry.getValue());
  479. });
  480. redisClient.hmset(key, finalMap);
  481. //写入本地文件,作为备份,以防redis数据丢失
  482. // this.writeHotJson(param.getNum());
  483. this.publicHotData(param.getNum(), param.getSubgroup());
  484. return ResultData.ok();
  485. }
  486. public static void main(String[] args) {
  487. String tmpDirPath = FileUtil.getTmpDirPath();
  488. System.out.println(tmpDirPath);
  489. }
  490. @Override
  491. public ResultData saveRoam(BaseDataParamVO param) throws Exception {
  492. Scene scenePlus = scenePlusService.getByNum(param.getNum(), param.getSubgroup());
  493. if (scenePlus == null ) {
  494. throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  495. }
  496. JSONArray inputData = JSONObject.parseArray(param.getData());
  497. // String prefix = fileName.substring(fileName.lastIndexOf("."));
  498. //// String path = String.format(ConstantFilePath.SCENE_TMP_PATH_V4, num).concat(UUID.randomUUID().toString()).concat(prefix);
  499. // File tempFile = File.createTempFile(UUID.randomUUID().toString() ,prefix);
  500. //// File tempFile = FileUtil.createTempFile(prefix, true);
  501. // String path = tempFile.getAbsolutePath();
  502. //
  503. //
  504. // String localDataPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, RedisKey.getNumStr(param.getNum(), param.getSubgroup()));
  505. // File directory = new File(localDataPath);
  506. // if (!directory.exists()) {
  507. // directory.mkdirs();
  508. // }
  509. String viewImagesPath = String.format(UploadFilePath.IMG_VIEW_PATH, param.getNum());
  510. //如果是云存储,将vision.modeldata下载到本地,如果是本地存储,场景计算完就已经将这个文件拷贝到编辑目录了存在这个文件了,不需要再下载
  511. // fYunFileService.downloadFile(bucket, viewImagesPath + "vision.modeldata", localDataPath + "vision.modeldata");
  512. //
  513. // //检查vision.modeldata本地是否存在,不存在抛出异常
  514. // File file = new File(localDataPath + "vision.modeldata");
  515. // if(!file.exists()) {
  516. // return ResultData.error(ErrorCode.FAILURE_CODE_5012);
  517. // }
  518. // //将vision.modeldata解压缩至vision.json
  519. // ConvertUtils.convertVisionModelDataToTxt(localDataPath + "vision.modeldata", localDataPath + "vision.json");
  520. // String str = FileUtils.readFile(localDataPath + "vision.json");
  521. String modeldataKey = viewImagesPath + "vision.modeldata";
  522. String tempPath = FileUtil.getTmpDirPath() + UUID.randomUUID() + "/";
  523. String localModeldataPath = fYunFileService.downloadFile(param.getNum(), param.getSubgroup(), modeldataKey, tempPath, "vision.modeldata");
  524. String localVisionTxtPath = tempPath + "vision.txt";
  525. ConvertUtils.convertVisionmodeldataToTxt(localModeldataPath, localVisionTxtPath);
  526. // String str = ConvertUtils.transferVisionUuidToIndex(localVisionTxtPath);
  527. String str = FileUtil.readUtf8String(localVisionTxtPath);
  528. // String str = fYunFileService.getFileContent(viewImagesPath + "vision.txt", param.getSubgroup());
  529. JSONObject json = JSONObject.parseObject(str);
  530. JSONArray panos = json.getJSONArray("sweepLocations");
  531. for (int i = 0; i < panos.size(); ++i) {
  532. JSONObject pano = panos.getJSONObject(i);
  533. for (int j = 0; j < inputData.size(); ++j) {
  534. JSONObject jo = inputData.getJSONObject(j);
  535. String currentPanoId = jo.getString("panoID");
  536. JSONArray visibles = jo.getJSONArray("visibles");
  537. JSONArray visibles3 = jo.getJSONArray("visibles3");
  538. if (pano.getString("uuid").replaceAll("-", "").equals(currentPanoId)) {
  539. pano.put("visibles", visibles);
  540. pano.put("visibles3", visibles3);
  541. }
  542. }
  543. }
  544. // FileUtils.deleteFile(localDataPath + "vision.json");
  545. // FileUtils.deleteFile(localDataPath + "vision.modeldata");
  546. // FileUtils.writeFile(localDataPath + "vision.json", json.toString());
  547. File tempFile = File.createTempFile(UUID.randomUUID().toString(), ".json");
  548. File tempFile2 = File.createTempFile(UUID.randomUUID().toString(), ".txt");
  549. FileUtil.writeUtf8String(json.toString(), tempFile.getAbsolutePath());
  550. ConvertUtils.convertTxtToVisionModelData(tempFile.getAbsolutePath(), tempFile2.getAbsolutePath());
  551. fYunFileService.uploadFile(param.getNum(), param.getSubgroup(), tempFile2.getAbsolutePath(), viewImagesPath + "vision.modeldata");
  552. FileUtil.del(tempFile);
  553. FileUtil.del(tempFile2);
  554. //更新版本号
  555. SceneEditInfo editInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  556. if(Objects.isNull(editInfo)){
  557. editInfo = new SceneEditInfo();
  558. editInfo.setScenePlusId(scenePlus.getId());
  559. sceneEditInfoService.save(editInfo);
  560. }else{
  561. sceneEditInfoService.upgradeVersionAndImgVersionById(editInfo.getId());
  562. //更新scenejson缓存和oss文件版本号
  563. sceneEditInfoService.upgradeSceneJsonVersion(param.getNum(), param.getSubgroup(), editInfo.getVersion() + 1, editInfo.getImgVersion() + 1);
  564. }
  565. return ResultData.ok();
  566. }
  567. //
  568. // @Override
  569. // public void updateUserIdByCameraId(Long userId, Long cameraId) {
  570. // this.update(new LambdaUpdateWrapper<ScenePro>()
  571. // .eq(ScenePro::getCameraId, cameraId)
  572. // .set(ScenePro::getUserId, userId));
  573. // }
  574. //
  575. // @Override
  576. // public ResultData uploadModel(String num, MultipartFile file) throws Exception{
  577. // if(StrUtil.isEmpty(num)){
  578. // throw new BusinessException(ServerCode.PARAM_REQUIRED, "num");
  579. // }
  580. // if(!file.getOriginalFilename().endsWith(".zip")){
  581. // throw new BusinessException(ErrorCode.FAILURE_CODE_7015);
  582. // }
  583. //
  584. // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
  585. // if(scenePlus == null){
  586. // throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  587. // }
  588. //
  589. // //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作
  590. // sceneAsynOperLogService.checkSceneAsynOper(num, null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.MODEL.code());
  591. //
  592. // //清除全景图异步操作记录,防止再次下载的时候请求到旧的压缩包
  593. // sceneAsynOperLogService.cleanLog(num, SceneAsynModuleType.UPLOAD_DOWNLOAD.code(), SceneAsynFuncType.MODEL.code());
  594. //
  595. // ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
  596. // String bucket = scenePlusExt.getYunFileBucket();
  597. //
  598. // if(ModelKind.THREE_D_TILE.code().equals(scenePlusExt.getModelKind())){
  599. // this.buildModel43dtiles(num, bucket, scenePlusExt.getDataSource(), file);
  600. // }else{
  601. // this.buildModel4Dam(num, bucket, scenePlusExt.getDataSource(), scenePlusExt.getBuildType(), file);
  602. // }
  603. //
  604. // return ResultData.ok();
  605. // }
  606. //
  607. //
  608. // /**
  609. // * 老算法(dam)上传模型逻辑
  610. // * @param num
  611. // * @param bucket
  612. // * @param dataSource
  613. // * @param buildType
  614. // * @throws Exception
  615. // */
  616. // private void buildModel4Dam(String num, String bucket, String dataSource, String buildType, MultipartFile file) throws Exception {
  617. // //文件上传的位置可以自定义
  618. // String path = dataSource + "_obj2txt";
  619. // String zipPath = path + "/zip/";
  620. // String filePath = path + "/extras/";
  621. // String resultPath = path + "/results/";
  622. //
  623. // //压缩文件处理:解压缩,解压缩后复制等操作
  624. // this.objAndImgFileHandler(resultPath, filePath, zipPath, file);
  625. //
  626. // //创建data.json
  627. // this.writeDataJson(path);
  628. //
  629. // CompletableFuture.runAsync(() -> {
  630. // SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
  631. // sceneAsynOperLog.setNum(num);
  632. // sceneAsynOperLog.setOperType(SceneAsynOperType.UPLOAD.code());
  633. // sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
  634. // sceneAsynOperLog.setFunc(SceneAsynFuncType.MODEL.code());
  635. // sceneAsynOperLogService.save(sceneAsynOperLog);
  636. // try {
  637. // //调用算法,不同的类型调用不同的算法
  638. // if("V2".equals(buildType)){
  639. // CreateObjUtil.objToTxt(path , "1");
  640. // }
  641. // if("V3".equals(buildType)){
  642. // CreateObjUtil.build3dModel(path , "1");
  643. // }
  644. //
  645. // //算法计算完后,生成压缩文件,上传到oss
  646. // uploadFileofterBuildDamModel(path, filePath, num, bucket);
  647. //
  648. // //更新版本信息
  649. // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
  650. // SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  651. // sceneEditInfoService.update(
  652. // new LambdaUpdateWrapper<SceneEditInfo>()
  653. // .setSql("version = version + 1")
  654. // .setSql("floor_edit_ver = floor_edit_ver + 1")
  655. // .setSql("floor_publish_ver = floor_publish_ver + 1")
  656. // .setSql("img_version = img_version + 1")
  657. // .set(SceneEditInfo::getIsUploadObj, CommonStatus.YES.code())
  658. // .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
  659. //
  660. // sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);
  661. //
  662. // sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
  663. // } catch (Exception e) {
  664. // log.error("上传dam模型,num:" + num, e);
  665. // sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
  666. // }
  667. // sceneAsynOperLogService.updateById(sceneAsynOperLog);
  668. // });
  669. // }
  670. //
  671. // /**
  672. // * 新算法(3dtiles)上传模型逻辑
  673. // * @param num
  674. // * @param bucket
  675. // * @param dataSource
  676. // * @throws Exception
  677. // */
  678. // private void buildModel43dtiles(String num, String bucket, String dataSource, MultipartFile file) throws Exception {
  679. // //文件上传的位置可以自定义
  680. // String path = dataSource + "_obj2Tiles" + File.separator;
  681. // String meshPath = path + "mesh";
  682. // String zipPath = path + "zip" + File.separator;
  683. // String zipFilePath = zipPath + file.getOriginalFilename();
  684. //
  685. //
  686. // //压缩文件处理:解压缩,解压缩后复制等操作
  687. // FileUtil.del(path);
  688. // FileUtil.mkdir(zipPath);
  689. // File zipFile = new File(zipFilePath);
  690. // file.transferTo(zipFile);
  691. // ZipUtil.unzip(zipFilePath, meshPath);
  692. //
  693. // String jsonName = "";
  694. // if(fYunFileService.fileExist(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/floors.json")){
  695. // jsonName = "floors.json";
  696. // }
  697. // if(fYunFileService.fileExist(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/mesh.json")){
  698. // jsonName = "mesh.json";
  699. // }
  700. //
  701. // //检测文件
  702. // String floorsJsonPath = meshPath + File.separator + jsonName;
  703. // if(!FileUtil.exist(floorsJsonPath)){
  704. // throw new BusinessException(ErrorCode.FAILURE_CODE_5068.code(), "json file is not exist!");
  705. // }
  706. // String floorsJsonStr = FileUtil.readUtf8String(floorsJsonPath);
  707. // JSONObject floorsJsonObj = JSON.parseObject(floorsJsonStr);
  708. // JSONArray floorArr = floorsJsonObj.getJSONArray("floors");
  709. // if(CollUtil.isEmpty(floorArr)){
  710. // throw new BusinessException(ErrorCode.FAILURE_CODE_5069.code(), "json content is error");
  711. // }
  712. // Set<String> floorNameSet = new HashSet<>();
  713. // String finalJsonName = jsonName;
  714. // floorArr.stream().forEach(item->{
  715. // JSONObject itemObj = (JSONObject) item;
  716. // //楼层目录是否存在
  717. // String name = itemObj.getString("name");
  718. // if(StrUtil.isEmpty(name) || !FileUtil.exist(meshPath + File.separator + name)){
  719. // throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
  720. // }
  721. // //检测obj文件是否存在
  722. // if("floors.json".equals(finalJsonName)){
  723. // String objPath = itemObj.getString("objPath");
  724. // if(StrUtil.isEmpty(objPath) || !FileUtil.exist(path + objPath)){
  725. // throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
  726. // }
  727. // }else{
  728. // JSONArray lods = itemObj.getJSONArray("lods");
  729. // if(CollUtil.isEmpty(lods)){
  730. // throw new BusinessException(ErrorCode.FAILURE_CODE_5069.code(), "json content is error");
  731. // }
  732. // for (Object lod : lods) {
  733. // JSONObject lodObj = (JSONObject) lod;
  734. // String objPath = lodObj.getString("objPath");
  735. // if(StrUtil.isEmpty(objPath) || !FileUtil.exist(path + objPath)){
  736. // throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
  737. // }
  738. // }
  739. // }
  740. // if(floorNameSet.contains(name)){
  741. // throw new BusinessException(ErrorCode.FAILURE_CODE_5069);
  742. // }
  743. // floorNameSet.add(name);
  744. // });
  745. //
  746. // //读取oss上的floors.jsoon用于校验用户上传的模型楼层数是否一一对应
  747. // String ossFloorsJson = fYunFileService.getFileContent(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/" + jsonName);
  748. // JSONObject orginFloorsJsonObj = JSON.parseObject(ossFloorsJson);
  749. // JSONArray orginFloorArr = orginFloorsJsonObj.getJSONArray("floors");
  750. // Set<String> orginFloorNameSet = orginFloorArr.stream().map(item -> {
  751. // JSONObject itemObj = (JSONObject) item;
  752. // return itemObj.getString("name");
  753. // }).collect(Collectors.toSet());
  754. // if(floorNameSet.size() != orginFloorNameSet.size()){
  755. // throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
  756. // }
  757. // orginFloorNameSet.stream().forEach(orginName->{
  758. // if(!floorNameSet.contains(orginName)){
  759. // throw new BusinessException(ErrorCode.FAILURE_CODE_5070);
  760. // }
  761. // });
  762. //
  763. // SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
  764. // sceneAsynOperLog.setNum(num);
  765. // sceneAsynOperLog.setOperType(SceneAsynOperType.UPLOAD.code());
  766. // sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
  767. // sceneAsynOperLog.setFunc(SceneAsynFuncType.MODEL.code());
  768. // sceneAsynOperLogService.save(sceneAsynOperLog);
  769. // CompletableFuture.runAsync(() -> {
  770. // try {
  771. // //调用算法
  772. // String command = "bash /home/ubuntu/bin/Obj2Tiles.sh " + path;
  773. // log.info("上传3dtiles模型开始, num:{}, targetPath:{}", num, path);
  774. // CreateObjUtil.callshell(command);
  775. // log.info("上传3dtiles模型结束, num:{}, targetPath:{}", num, path);
  776. //
  777. // //检测计算结果
  778. // String tilesPath = path + "3dtiles";
  779. // String tilesetJsonPath = tilesPath + File.separator + "tileset.json";
  780. // boolean success = ComputerUtil.checkComputeCompleted(tilesetJsonPath, maxCheckTimes, waitTime);
  781. // if(!success){
  782. // throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
  783. // }
  784. //
  785. // //删除logs
  786. // FileUtil.del(tilesPath + File.separator + "logs");
  787. //
  788. // //算法计算完后,生成压缩文件,上传到oss
  789. // //上传3dtiles
  790. // fYunFileService.deleteFolder(bucket, String.format(UploadFilePath.IMG_VIEW_PATH, num) + "3dtiles");
  791. // fYunFileService.uploadFileByCommand(bucket, tilesPath, String.format(UploadFilePath.IMG_VIEW_PATH, num) + "3dtiles");
  792. // //上传mesh
  793. // fYunFileService.deleteFolder(bucket, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh");
  794. // fYunFileService.uploadFileByCommand(bucket, meshPath, String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh");
  795. //
  796. // //更新版本信息
  797. // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
  798. // SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  799. // sceneEditInfoService.update(
  800. // new LambdaUpdateWrapper<SceneEditInfo>()
  801. // .setSql("version = version + 1")
  802. // .setSql("floor_edit_ver = floor_edit_ver + 1")
  803. // .setSql("floor_publish_ver = floor_publish_ver + 1")
  804. // .setSql("img_version = img_version + 1")
  805. // .set(SceneEditInfo::getIsUploadObj, CommonStatus.YES.code())
  806. // .eq(SceneEditInfo::getId, sceneEditInfo.getId()));
  807. //
  808. // sceneEditInfoService.upgradeSceneJsonVersion(num, sceneEditInfo.getVersion() + 1, sceneEditInfo.getImgVersion() + 1, bucket);
  809. //
  810. // sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
  811. // } catch (Exception e) {
  812. // log.error("上传全景图报错,num:" + num, e);
  813. // sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
  814. // }
  815. // sceneAsynOperLogService.updateById(sceneAsynOperLog);
  816. // });
  817. //
  818. // }
  819. //
  820. // private void uploadFileofterBuildDamModel(String path, String filePath, String sceneNum, String bucket) throws Exception {
  821. // //因为共享目录有延迟,这里循环检测算法是否计算完毕3次,每次隔五秒
  822. // String uploadJsonPath = path + File.separator + "results" +File.separator+"upload.json";
  823. // boolean exist = ComputerUtil.checkComputeCompleted(uploadJsonPath, maxCheckTimes, waitTime);
  824. // if(!exist){
  825. // throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
  826. // }
  827. // String uploadData = FileUtils.readFile(uploadJsonPath);
  828. // JSONObject uploadJson = null;
  829. // JSONArray array = null;
  830. // if(uploadData!=null) {
  831. // uploadJson = JSONObject.parseObject(uploadData);
  832. // array = uploadJson.getJSONArray("upload");
  833. // }
  834. //
  835. // Map<String,String> map = new HashMap<String,String>();
  836. // JSONObject fileJson = null;
  837. // String fileName = "";
  838. // String imgViewPath = String.format(UploadFilePath.IMG_VIEW_PATH, sceneNum);
  839. // for(int i = 0, len = array.size(); i < len; i++) {
  840. // fileJson = array.getJSONObject(i);
  841. // fileName = fileJson.getString("file");
  842. // //文件不存在抛出异常
  843. // if (!new File(path + File.separator + "results" + File.separator + fileName).exists()) {
  844. // throw new Exception(path + File.separator + "results" + File.separator + fileName + "文件不存在");
  845. // }
  846. //
  847. // //tex文件夹
  848. // if (fileJson.getIntValue("clazz") == 15) {
  849. // map.put(path + File.separator + "results" + File.separator + fileName,
  850. // imgViewPath + ConstantFileName.modelUUID + "_50k_texture_jpg_high1/" + fileName.replace("tex/", ""));
  851. // continue;
  852. // }
  853. // }
  854. //
  855. // String damPath = path + File.separator + "results" +File.separator+ ConstantFileName.modelUUID+"_50k.dam";
  856. // CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", damPath);
  857. // boolean existDam = ComputerUtil.checkComputeCompleted(damPath, 5, 2);
  858. // if(!existDam){
  859. // throw new BusinessException(ErrorCode.FAILURE_CODE_7013);
  860. // }
  861. //// CreateObjUtil.convertDamToLzma(path + File.separator + "results");
  862. //// CreateObjUtil.convertTxtToDam( path + File.separator + "results" +File.separator+"modeldata.txt", path + File.separator + "results" + File.separator+ConstantFileName.modelUUID+"_50k.dam");
  863. //// map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam.lzma", imgViewPath +ConstantFileName.modelUUID+"_50k.dam.lzma");
  864. // map.put(path + File.separator + "results" +File.separator+ConstantFileName.modelUUID+"_50k.dam", imgViewPath+ConstantFileName.modelUUID+"_50k.dam");
  865. //
  866. // String ossMeshPath = String.format(UploadFilePath.DATA_VIEW_PATH, sceneNum) + "mesh";
  867. // //删除oss中的mesh
  868. // fYunFileService.deleteFolder(bucket, ossMeshPath);
  869. // //上传obj相关文件
  870. // List<String> fileNames = FileUtil.listFileNames(filePath);
  871. // fileNames.stream().forEach(name->map.put(filePath + name, ossMeshPath + File.separator + name));
  872. //
  873. // fYunFileService.uploadMulFiles(bucket, map);
  874. // }
  875. //
  876. // private void writeDataJson(String path) throws IOException {
  877. // JSONObject dataJson = new JSONObject();
  878. // dataJson.put("obj2txt", true);
  879. // dataJson.put("split_type", "SPLIT_V6");
  880. // dataJson.put("data_describe", "double spherical");
  881. // dataJson.put("skybox_type", "SKYBOX_V5");
  882. // FileUtils.writeFile(path + "/data.json", dataJson.toString());
  883. // }
  884. //
  885. // private void objAndImgFileHandler(String resultPath, String filePath, String zipPath, MultipartFile file)
  886. // throws Exception {
  887. // FileUtils.delAllFile(resultPath);
  888. // File targetFile = new File(filePath);
  889. // if (!targetFile.exists()) {
  890. // targetFile.mkdirs();
  891. // }else {
  892. // FileUtils.delAllFile(filePath);
  893. // }
  894. //
  895. // targetFile = new File(zipPath);
  896. // if (!targetFile.exists()) {
  897. // targetFile.mkdirs();
  898. // }else {
  899. // FileUtils.delAllFile(zipPath);
  900. // }
  901. //
  902. // targetFile = new File(zipPath + file.getOriginalFilename());
  903. // if(!targetFile.getParentFile().exists()){
  904. // targetFile.getParentFile().mkdirs();
  905. // }
  906. // // 保存压缩包到本地
  907. // if(targetFile.exists())
  908. // {
  909. // FileUtils.deleteFile(zipPath + file.getOriginalFilename());
  910. // }
  911. // file.transferTo(targetFile);
  912. //
  913. // ZipUtil.unzip(zipPath + file.getOriginalFilename(), zipPath + "data/");
  914. //
  915. // //源文件数据,判断是否有多个文件夹,有多个就提示错误,有一个就将文件夹里数据迁移到extras目录,无直接迁移到extras目录
  916. // boolean flag = false;
  917. // //目录名称,如果不为空,则压缩文件第一层是目录
  918. // String targetName = "";
  919. // File dataFile = new File(zipPath + "data/");
  920. // for(File data : dataFile.listFiles()){
  921. // if(data.isDirectory() && flag){
  922. // throw new BusinessException(ErrorCode.FAILURE_CODE_5018);
  923. // }
  924. // if(data.isDirectory() && !flag){
  925. // flag = true;
  926. // targetName = data.getName();
  927. // }
  928. // }
  929. //
  930. // //是否包含obj文件
  931. // boolean objFlag = false;
  932. // //是否包含mtl文件
  933. // boolean mtlFlag = false;
  934. // File[] files = null;
  935. // String dataPath = null;
  936. // if(StrUtil.isEmpty(targetName)){
  937. // files = dataFile.listFiles();
  938. // dataPath = zipPath + "data/";
  939. // }else{
  940. // files = new File(zipPath + "data/" + targetName).listFiles();
  941. // dataPath = zipPath + "data/" + targetName + File.separator;
  942. // }
  943. //
  944. // for(File data : files){
  945. // if(data.isDirectory()){
  946. // throw new BusinessException(ErrorCode.FAILURE_CODE_5018);
  947. // }
  948. //
  949. // if(data.getName().endsWith(".jpg") || data.getName().endsWith(".png")){
  950. // if(!FileUtils.checkFileSizeIsLimit(data.length(), 1.5, "M")){
  951. // throw new BusinessException(ErrorCode.FAILURE_CODE_5020);
  952. // }
  953. // }
  954. // if(data.getName().endsWith(".obj")){
  955. // if(objFlag){
  956. // throw new BusinessException(ErrorCode.FAILURE_CODE_5019);
  957. // }
  958. // if(!data.getName().equals("mesh.obj")){
  959. // throw new BusinessException(ErrorCode.FAILURE_CODE_5060);
  960. // }
  961. // if(!FileUtils.checkFileSizeIsLimit(data.length(), 20, "M")){
  962. // throw new BusinessException(ErrorCode.FAILURE_CODE_5020);
  963. // }
  964. //
  965. // objFlag = true;
  966. // FileUtils.copyFile(dataPath + data.getName(), filePath + "mesh.obj", true);
  967. // continue;
  968. // }
  969. //
  970. // if(data.getName().endsWith(".mtl")){
  971. // mtlFlag = true;
  972. // }
  973. //
  974. // FileUtils.copyFile(dataPath + data.getName(), filePath + data.getName(), true);
  975. // }
  976. //
  977. // //压缩文件中必须有且仅有一个obj和mtl文件,否则抛出异常
  978. // if(!mtlFlag || !objFlag){
  979. // throw new BusinessException(ErrorCode.FAILURE_CODE_5059);
  980. // }
  981. // }
  982. //
  983. // public ResultData downloadModel(String num) throws Exception {
  984. //
  985. // if(StrUtil.isEmpty(num)){
  986. // throw new BusinessException(ErrorCode.PARAM_REQUIRED);
  987. // }
  988. // ScenePlus scenePlus = scenePlusService.getScenePlusByNum(num);
  989. // if(scenePlus == null){
  990. // throw new BusinessException(ErrorCode.FAILURE_CODE_5005);
  991. // }
  992. //
  993. // //查询是否存在等待中的异步操作记录,如果存在,抛出业务异常,终止操作
  994. // sceneAsynOperLogService.checkSceneAsynOper(num,null, SceneAsynModuleType.UPLOAD_DOWNLOAD.code() , SceneAsynFuncType.MODEL.code());
  995. //
  996. // //清除旧的下载记录
  997. // sceneAsynOperLogService.cleanLog(num, SceneAsynModuleType.UPLOAD_DOWNLOAD.code(), SceneAsynFuncType.MODEL.code(), SceneAsynOperType.DOWNLOAD.code());
  998. //
  999. // ScenePlusExt scenePlusExt = scenePlusExtService.getScenePlusExtByPlusId(scenePlus.getId());
  1000. // String bucket = scenePlusExt.getYunFileBucket();
  1001. //
  1002. // SceneEditInfo sceneEditInfo = sceneEditInfoService.getByScenePlusId(scenePlus.getId());
  1003. //
  1004. // //开始异步执行下载全景图压缩包操作
  1005. // CompletableFuture.runAsync(() -> {
  1006. // SceneAsynOperLog sceneAsynOperLog = new SceneAsynOperLog();
  1007. // sceneAsynOperLog.setNum(num);
  1008. // sceneAsynOperLog.setOperType(SceneAsynOperType.DOWNLOAD.code());
  1009. // sceneAsynOperLog.setModule(SceneAsynModuleType.UPLOAD_DOWNLOAD.code());
  1010. // sceneAsynOperLog.setFunc(SceneAsynFuncType.MODEL.code());
  1011. // sceneAsynOperLog.setVersion(sceneEditInfo.getImgVersion());
  1012. // sceneAsynOperLogService.save(sceneAsynOperLog);
  1013. // try {
  1014. //
  1015. // String url = null;
  1016. // if(ModelKind.THREE_D_TILE.code().equals(scenePlusExt.getModelKind())){
  1017. // url = downloadModel43dtiles(num, bucket, scenePlusExt, sceneEditInfo);
  1018. // }else{
  1019. // url = downloadModel4Dam(num, bucket);
  1020. // }
  1021. //
  1022. // sceneAsynOperLog.setState(CommonOperStatus.SUCCESS.code());
  1023. // sceneAsynOperLog.setUrl(url);
  1024. // }catch (Exception e){
  1025. // sceneAsynOperLog.setState(CommonOperStatus.FAILD.code());
  1026. // log.error("下载模型压缩包失败,num:" + num, e);
  1027. // }
  1028. // sceneAsynOperLogService.saveOrUpdate(sceneAsynOperLog);
  1029. // });
  1030. //
  1031. // return ResultData.ok();
  1032. // }
  1033. //
  1034. // @Override
  1035. // public ScenePro getByNum(String num) {
  1036. // return this.getOne(new LambdaQueryWrapper<ScenePro>().eq(ScenePro::getNum, num));
  1037. // }
  1038. //
  1039. // private String downloadModel43dtiles(String num, String bucket, ScenePlusExt scenePlusExt, SceneEditInfo sceneEditInfo){
  1040. //
  1041. // //下载mesh到本地
  1042. // String meshOssPath = String.format(UploadFilePath.DATA_VIEW_PATH, num) + "mesh/";
  1043. // String meshLocalPath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + "mesh";
  1044. // String zipName = num + "_mesh.zip";
  1045. // String zipFilePath = String.format(ConstantFilePath.SCENE_DATA_PATH_V4, num) + zipName;
  1046. // //下载
  1047. // fYunFileService.downloadFileByCommand(bucket, meshLocalPath, meshOssPath);
  1048. // //打包
  1049. // ZipUtil.zip(meshLocalPath,zipFilePath);
  1050. // //上传压缩包
  1051. // fYunFileService.uploadFile(bucket, zipFilePath, "downloads/extras/" + zipName);
  1052. // //删除本地文件
  1053. // FileUtil.del(meshLocalPath);
  1054. // FileUtil.del(zipFilePath);
  1055. // String url = "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
  1056. // return url;
  1057. // }
  1058. //
  1059. // public static void main(String[] args) throws Exception {
  1060. //
  1061. // ConvertUtils.convertVisionModelDataToTxt( "D:\\test\\vision.modeldata", "D:\\test\\vision.json");
  1062. //
  1063. // }
  1064. //
  1065. //
  1066. // private String downloadModel4Dam(String num, String bucket){
  1067. // String localImagePath = String.format(ConstantFilePath.IMAGESBUFFER_FORMAT, num);
  1068. // if(!new File(localImagePath).exists()){
  1069. // new File(localImagePath).mkdirs();
  1070. // }
  1071. //
  1072. // String zipName = num + "_extras.zip";
  1073. // String zipPath = localImagePath + zipName;
  1074. //
  1075. // String dataViewPath = String.format(UploadFilePath.DATA_VIEW_PATH, num);
  1076. // //V3版本去oss下载2048模型
  1077. // String meshPath = String.format(ConstantFilePath.DATABUFFER_FORMAT, num) + "mesh";
  1078. // FileUtils.deleteDirectory(meshPath);
  1079. // fYunFileService.downloadFileByCommand(bucket, meshPath, dataViewPath + "mesh");
  1080. // log.info("meshPath="+meshPath);
  1081. // if(!new File(meshPath).exists() || new File(meshPath).listFiles().length < 1){
  1082. // throw new BusinessException(ErrorCode.FAILURE_CODE_7006);
  1083. // }
  1084. // for(File file : new File(meshPath).listFiles()){
  1085. // if(file.isDirectory()){
  1086. // for (File item : file.listFiles()) {
  1087. // if(item.getName().endsWith(".obj") && !"output.house.obj".equals(item.getName()) &&
  1088. // !"mesh.obj".equals(item.getName())){
  1089. // item.delete();
  1090. // }
  1091. // if(item.getName().endsWith(".mtl") && !"output.house.mtl".equals(item.getName()) &&
  1092. // !"mesh.mtl".equals(item.getName())){
  1093. // item.delete();
  1094. // }
  1095. // }
  1096. // continue;
  1097. // }
  1098. // if(file.getName().endsWith(".obj") && !"output.house.obj".equals(file.getName()) &&
  1099. // !"mesh.obj".equals(file.getName())){
  1100. // file.delete();
  1101. // }
  1102. // if(file.getName().endsWith(".mtl") && !"output.house.mtl".equals(file.getName()) &&
  1103. // !"mesh.mtl".equals(file.getName())){
  1104. // file.delete();
  1105. // }
  1106. // }
  1107. // //打包
  1108. // ZipUtil.zip(meshPath, zipPath);
  1109. // //上传压缩包
  1110. // fYunFileService.uploadFile(bucket, zipPath, "downloads/extras/" + zipName);
  1111. // String url = "downloads/extras/" + zipName + "?t=" + Calendar.getInstance().getTimeInMillis();
  1112. // FileUtil.del(zipPath);
  1113. // return url;
  1114. // }
  1115. //
  1116. // @Override
  1117. // public List<SceneBean> listCleanOrigScene(int cleanOrigMonth) {
  1118. // Date time = Calendar.getInstance().getTime();
  1119. // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -cleanOrigMonth));
  1120. // return this.baseMapper.selectCleanOrigScene(time);
  1121. // }
  1122. //
  1123. // @Override
  1124. // public List<SceneBean> listCleanOss4DeletedScene(int month) {
  1125. // Date time = Calendar.getInstance().getTime();
  1126. // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -month));
  1127. // return this.baseMapper.listCleanOss4DeletedScene(time);
  1128. // }
  1129. //
  1130. // @Override
  1131. // public List<SceneBean> listCleanOss4TestCamera(Set<Long> cameraIds, int month) {
  1132. // Date time = Calendar.getInstance().getTime();
  1133. // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -month));
  1134. // return this.baseMapper.listCleanOss4TestCamera(cameraIds, time);
  1135. // }
  1136. //
  1137. // @Override
  1138. // public List<SceneBean> listColdStorageScene(int cleanOrigMonth) {
  1139. // Date time = Calendar.getInstance().getTime();
  1140. // time = DateUtil.beginOfDay(DateUtil.offset(time, DateField.MONTH, -cleanOrigMonth));
  1141. // return this.baseMapper.selectColdStorageScene(time);
  1142. // }
  1143. }