package com.lqkj.link.module.zone.service; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import com.lqkj.link.module.authority.domain.UserInfo; import com.lqkj.link.module.authority.repository.UserInfoRepository; import com.lqkj.link.module.zone.domain.*; import com.lqkj.link.module.zone.repository.GeomInfoRepository; import com.lqkj.link.module.zone.repository.ModelInfoRepository; import com.lqkj.link.module.zone.repository.ZoneInfoRepository; import com.lqkj.link.util.Unzipper; import org.apache.commons.lang3.StringUtils; import org.locationtech.jts.geom.Coordinate; import org.locationtech.jts.geom.GeometryFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.File; import java.nio.file.Files; import java.nio.file.Paths; import java.util.*; import java.util.stream.Collectors; @Service public class ZoneInfoService { private final ZoneInfoRepository zoneInfoRepository; private final UserInfoRepository userInfoRepository; private final GeomInfoRepository geomInfoRepository; private final ModelInfoRepository modelInfoRepository; public ZoneInfoService(ZoneInfoRepository zoneInfoRepository, UserInfoRepository userInfoRepository, GeomInfoRepository geomInfoRepository, ModelInfoRepository modelInfoRepository) { this.zoneInfoRepository = zoneInfoRepository; this.userInfoRepository = userInfoRepository; this.geomInfoRepository = geomInfoRepository; this.modelInfoRepository = modelInfoRepository; } public Page pageQueryTemplate(String zoneName, Integer page, Integer pageSize) { Pageable pageable = PageRequest.of(page, pageSize); return zoneInfoRepository.pageQueryTemplate(zoneName, pageable); } @Transactional public Map saveTemplate(ZoneInfo zoneInfo) { Map result = new HashMap<>(); if ((zoneInfo.getZoneId() != null && zoneInfoRepository.hasSameTemplateNameWithoutOne(zoneInfo.getZoneName(), zoneInfo.getZoneId())) || (zoneInfo.getZoneId() == null && zoneInfoRepository.hasSameTemplateName(zoneInfo.getZoneName()))) { result.put("msg", "模板名称不能重复!"); return result; } zoneInfo.setUpdateTime(new Date()); if (zoneInfo.getZoneId() == null) { zoneInfo.setShareCount(0); zoneInfo.setViewCount(0); zoneInfo.setTemplateUse(0); } ZoneInfo zoneInfo1 = zoneInfoRepository.save(zoneInfo); try { if (StringUtils.isNotBlank(zoneInfo.getTemplateFilePath())) { // 清除元素与模型 geomInfoRepository.deleteAllByZoneId(zoneInfo1.getZoneId()); modelInfoRepository.deleteAllByTemplateIds(Collections.singletonList(zoneInfo1.getZoneId())); // 解压压缩文件 // 文件目录格式: // --geom.json // --models // ----model1.fbx 模型1文件 // ----model2.fbx 模型2文件 // ----model1.json 模型1材质 // ----model2.json 模型2材质 // // geom.json文件总json格式: // { // "init": { // "rotation": { // "x": 0, // "y": 0, // "z": 0, // "w": 0 // }, // "translation": { // "x": 0, // "y": 0, // "z": 0 // }, // "scale3D": { // "x": 0, // "y": 0, // "z": 0 // } // }, // "models": [ // { // "modelPath": "model1.fbx", // "location": [ // { // "rotation": { // "x": 0, // "y": 0, // "z": 0, // "w": 0 // }, // "translation": { // "x": 0, // "y": 0, // "z": 0 // }, // "scale3D": { // "x": 0, // "y": 0, // "z": 0 // } // } // ] // } // ] // } Unzipper.unZipFiles(new File("." + zoneInfo.getTemplateFilePath()), "./upload/template/" + zoneInfo1.getZoneId() + "/"); String geomJsonString = Files.readString(Paths.get("./upload/template/" + zoneInfo1.getZoneId() + "/geom.json")); TemplateGeom templateGeom = JSON.parseObject(geomJsonString, TemplateGeom.class); zoneInfo1.setInitLocation(templateGeom.getInit()); zoneInfoRepository.save(zoneInfo1); List templateInfoList = templateGeom.getModels(); String modelFolderPath = "./upload/template/" + zoneInfo1.getZoneId() + "/models"; File modelFolder = new File(modelFolderPath); List list = new ArrayList<>(); File[] models = modelFolder.listFiles(); assert models != null; for (File model : models) { if (model.isFile()) { String modelFileName = model.getName(); if (modelFileName.endsWith(".fbx")) { String modelPath = "/upload/template/" + zoneInfo1.getZoneId() + "/models/"; if (modelFileName.matches(".*[\u4e00-\u9fa5]+.*")) { // 如果包含中文,重命名 String newFileName =UUID.randomUUID() + ".fbx"; modelPath += newFileName; boolean rename = model.renameTo(new File("." + modelPath)); System.out.println(rename); // 材质文件也需要重命名 File oldMaterialFile = new File("." + "/upload/template/" + zoneInfo1.getZoneId() + "/models/" + modelFileName.replace(".fbx", ".json")); if (oldMaterialFile.exists()) { File newMaterialFile = new File("." + "/upload/template/" + zoneInfo1.getZoneId() + "/models/" + newFileName.replace(".fbx", ".json")); rename = oldMaterialFile.renameTo(newMaterialFile); System.out.println(rename); } } else { modelPath += modelFileName; } list.add(new ModelInfo(null, null, modelFileName.substring(0, modelFileName.lastIndexOf(".")).toLowerCase(), null, null, null, modelPath, null, null, zoneInfo1.getZoneId())); } } } List modelInfoList = modelInfoRepository.saveAll(list); Map modelPathIdMap = modelInfoList .stream() .collect(Collectors.toMap(ModelInfo::getModelName, ModelInfo -> ModelInfo)); List geomInfoList = new ArrayList<>(); GeometryFactory geometryFactory = new GeometryFactory(); int j = 1; for (TemplateInfo templateInfo : templateInfoList) { String modelName = templateInfo.getModelPath().substring(0, templateInfo.getModelPath().lastIndexOf(".")).toLowerCase(); ModelInfo modelInfo = modelPathIdMap.get(modelName); for (int i = 0; i < templateInfo.getLocation().size(); i++) { JSONObject trans = templateInfo.getLocation().get(i); GeomInfo geomInfo = new GeomInfo(); geomInfo.setGeomId(zoneInfo1.getZoneId() + "_" + j); geomInfo.setModelId(modelInfo.getModelId()); geomInfo.setGeomName(modelInfo.getModelName()); geomInfo.setZoneId(zoneInfo1.getZoneId()); geomInfo.setLocking(false); geomInfo.setTrans(trans); JSONObject pointObject = trans.getJSONObject("translation"); geomInfo.setGeom(geometryFactory.createPoint(new Coordinate( Double.parseDouble(pointObject.get("x").toString()), Double.parseDouble(pointObject.get("y").toString()), Double.parseDouble(pointObject.get("z").toString())))); j++; geomInfoList.add(geomInfo); } } geomInfoRepository.saveAll(geomInfoList); } } catch (Exception e) { modelInfoRepository.deleteAllByTemplateIds(Collections.singletonList(zoneInfo1.getZoneId())); zoneInfoRepository.delete(zoneInfo1); result.put("msg", "模板压缩文件解压失败!"); return result; } result.put("zone", zoneInfo1); return result; } @Transactional public void deleteTemplate(List zoneIds) { zoneInfoRepository.deleteAllByIdInBatch(zoneIds); modelInfoRepository.deleteAllByTemplateIds(zoneIds); } public List autoCompleteMyWork(String userCode, String keyword) { return zoneInfoRepository .autoCompleteMyWork(userCode, keyword) .stream() .map(v -> (String) v.get("name")) .toList(); } public List autoCompleteResource(String keyword, Integer searchType) { return zoneInfoRepository .autoCompleteResource(keyword, searchType) .stream() .map(v -> (String) v.get("name")) .toList(); } public List autoCompleteAudit(String keyword, Integer searchType) { return zoneInfoRepository .autoCompleteAudit(keyword, searchType) .stream() .map(v -> (String) v.get("name")) .toList(); } public Page myWork(String userCode, String name, Integer page, Integer pageSize) { Pageable pageable = PageRequest.of(page, pageSize); return zoneInfoRepository.pageQueryMyWork(userCode, name, pageable); } public Page> resourceCenter(String name, Integer searchType, Integer page, Integer pageSize) { Pageable pageable = PageRequest.of(page, pageSize); return zoneInfoRepository.pageQueryResourceCenter(name, searchType, pageable); } public Page> auditCenter(String name, Integer searchType, Integer page, Integer pageSize) { Pageable pageable = PageRequest.of(page, pageSize); return zoneInfoRepository.auditCenter(name, searchType, pageable); } @Transactional public String share(Integer zoneId, String userCode) { String shareCode = UUID.randomUUID().toString(); zoneInfoRepository.share(zoneId, userCode, shareCode); return shareCode; } @Transactional public void view(Integer zoneId, String userCode) { zoneInfoRepository.view(zoneId, userCode); } @Transactional public String rename(Integer zoneId, String newName, String userCode) { if (zoneInfoRepository.hasSameNameWithUser(newName, userCode, zoneId)) { return "不能与已有作品重名!"; } zoneInfoRepository.rename(newName, zoneId); return null; } public String deleteWork(Integer zoneId, String userCode) { if(!zoneInfoRepository.existsById(zoneId)){ return "该作品不存在!"; } if (!zoneInfoRepository.isAuthor(zoneId, userCode)) { return "您不是该作品的作者!"; } if (zoneInfoRepository.canBeDeleteWithAuthStatus(zoneId)) { return "不能删除正在审核或已发布的作品!"; } zoneInfoRepository.deleteById(zoneId); return null; } @Transactional public Map create(String name, Integer templateId, String userCode) { Map result = new HashMap<>(); UserInfo userInfo = userInfoRepository.findByUserCode(userCode); if (zoneInfoRepository.existsByZoneNameAndUserId(name, userInfo.getUserId())) { result.put("msg", "不能与已有作品重名!"); return result; } ZoneInfo template = null; if (templateId != null) { template = zoneInfoRepository.findById(templateId).get(); } ZoneInfo zoneInfo = new ZoneInfo(null, userInfo.getUserId(), name, template == null ? null : template.getInitLocation(), template == null ? null : template.getThumbnail(), 0, new Date(), 0, 0, null, null, 0); ZoneInfo newInfo = zoneInfoRepository.save(zoneInfo); if (templateId != null) { GeometryFactory geometryFactory = new GeometryFactory(); if (geomInfoRepository.hasGeom(templateId)) { List geomInfoList = geomInfoRepository.findAllByZoneId(templateId); List list = new ArrayList<>(); for (GeomInfo geomInfo : geomInfoList) { String geomId = geomInfo.getGeomId(); String newId = newInfo.getZoneId() + "_" + geomId.split("_")[1]; GeomInfo newGeom = JSON.parseObject(JSON.toJSONString(geomInfo), GeomInfo.class); newGeom.setGeomId(newId); newGeom.setZoneId(newInfo.getZoneId()); newGeom.setTrans(geomInfo.getLocation()); JSONObject pointObject = geomInfo.getLocation().getJSONObject("translation"); newGeom.setGeom(geometryFactory.createPoint(new Coordinate( Double.parseDouble(pointObject.get("x").toString()), Double.parseDouble(pointObject.get("y").toString()), Double.parseDouble(pointObject.get("z").toString())))); newGeom.setLocking(false); list.add(newGeom); } geomInfoRepository.saveAll(list); } // 模板使用次数+1 zoneInfoRepository.addTemplateUse(templateId); } result.put("zone", newInfo); return result; } public void saveThumbnail(Integer zoneId, String thumbnailPath) { ZoneInfo zoneInfo = zoneInfoRepository.findById(zoneId).get(); zoneInfo.setThumbnail(thumbnailPath); zoneInfoRepository.save(zoneInfo); } public JSONObject readTrans(Integer zoneId) { return zoneInfoRepository.findById(zoneId).get().getInitLocation(); } }