SceneProServiceImpl.java 52 KB

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