package com.fdkankan.fusion.service.impl;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fdkankan.fusion.common.FilePath;
import com.fdkankan.fusion.common.ResultCode;
import com.fdkankan.fusion.common.ResultData;
import com.fdkankan.fusion.common.util.*;
import com.fdkankan.fusion.entity.*;
import com.fdkankan.fusion.exception.BusinessException;
import com.fdkankan.fusion.httpClient.client.FdKKClient;
import com.fdkankan.fusion.mapper.ICaseNumMapper;
import com.fdkankan.fusion.request.SceneNumParam;
import com.fdkankan.fusion.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.io.File;
import java.sql.BatchUpdateException;
import java.util.*;
import java.util.stream.Collectors;
/**
*
* 服务实现类
*
*
* @author
* @since 2022-07-27
*/
@Service
@Slf4j
public class CaseNumServiceImpl extends ServiceImpl implements ICaseNumService {
@Autowired
LocalToOssUtil localToOssUtil;
@Value("${upload.query-path}")
private String queryPath;
@Value("${spring.profiles.active}")
private String environment;
@Autowired
IModelService modelService;
@Autowired
IFusionNumService fusionNumService;
@Autowired
ICaseViewService caseViewService;
@Autowired
IFusionMeterService fusionMeterService;
@Autowired
IFusionGuidePathService fusionGuidePathService;
@Autowired
ICaseTagService caseTagService;
@Autowired
ICaseTagPointService caseTagPointService;
@Autowired
ThreadService threadService;
@Autowired
ISceneService sceneService;
@Override
public List getByCaseId(Integer caseId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseNumEntity::getCaseId,caseId);
return this.list(wrapper);
}
@Override
public void addBatch(Integer caseId, List sceneNumParam) {
List addNumList = this.updateByNumList(caseId, sceneNumParam);
if(addNumList == null || addNumList.size()<=0){
return;
}
List newCaseNums = new ArrayList<>();
List modelList = new ArrayList<>();
HashMap> map = new HashMap<>();
for (SceneNumParam numParam : sceneNumParam) {
if(map.get(numParam.getType()) == null){
HashSet set = new HashSet<>(numParam.getNumList());
map.put(numParam.getType(),set);
}else {
map.get(numParam.getType()).addAll(numParam.getNumList());
}
}
for (Integer type : map.keySet()) {
HashSet nulList = map.get(type);
List numList = new ArrayList<>(nulList);
HashSet setNum = new HashSet<>(numList);
for (String num : setNum) {
if(!addNumList.contains(num)){
continue;
}
CaseNumEntity caseNumEntity = new CaseNumEntity();
caseNumEntity.setCaseId(caseId);
caseNumEntity.setNumType(type);
caseNumEntity.setNum(num);
newCaseNums.add(caseNumEntity);
if(type == 3){ //用户上传三维模型跳过
continue;
}
Model model = modelService.getIsNullNewByNum(num,type);
if(model.getModelId() != null && StringUtils.isNotBlank(model.getModelGlbUrl()) && StringUtils.isNotBlank(model.getModelSize())){
continue;
}
model.setModelDateType("obj");
model.setType(type);
model.setModelType("pointcloud"); //深时点云类型
model.setCreateStatus(1);
Scene scene = sceneService.getByNum(num);
if(scene == null){
continue;
}
if(type == 0 || type == 1 || type == 4 || type == 6 || type == 7){ //看看,看见
String mesh3DtilesPath = String.format(FilePath.OBJ_OSS_PATH,num) + "/images/3dtiles/tileset.json";
String sizePath = scene.getWebPath() + String.format(FilePath.OBJ_OSS_PATH,num) + "/images/3dtiles";
if(localToOssUtil.existKey(scene.getWebPath() +mesh3DtilesPath)){
model.setModelDateType("b3dm");
model.setModelType("b3dm");
model.setModelGlbUrl(JSONArray.toJSONString(Arrays.asList(scene.getMapping() +File.separator +mesh3DtilesPath)));
model.setModelSize(FileWriterUtil.setFileSize(localToOssUtil.getSizeCount( sizePath)));
}else {
String meshPath = String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh";
if(localToOssUtil.existKey( scene.getWebPath() +meshPath +"/mesh.obj")){
Long size = localToOssUtil.getSizeCount( scene.getWebPath() +meshPath);
model.setModelSize(FileWriterUtil.setFileSize(size));
model.setModelGlbUrl(JSONArray.toJSONString(Arrays.asList(scene.getMapping()+File.separator + meshPath+"/mesh.obj")));
}else {
List objPaths = new ArrayList<>();
String meshPathjs = String.format(FilePath.OBJ_OSS_PATH, num)+"/data/";
String jsonPath =scene.getWebPath() + meshPath + "/floors.json";
if(!localToOssUtil.existKey(jsonPath)){
jsonPath =scene.getWebPath() + meshPath +"mesh.json";
}
if(localToOssUtil.existKey(jsonPath)){
String objectContent = localToOssUtil.getObjectContent(meshPath + "/floors.json");
JSONObject jsonObject = JSONObject.parseObject(objectContent);
JSONArray floors1 = jsonObject.getJSONArray("floors");
for (Object object : floors1) {
JSONObject jb = (JSONObject) object;
String string = jb.getString("objPath");
objPaths.add(scene.getMapping()+File.separator +meshPathjs + string);
}
model.setModelGlbUrl(JSONArray.toJSONString(objPaths));
Long size = localToOssUtil.getSize(scene.getWebPath() +meshPath);
model.setModelSize(FileWriterUtil.setFileSize(size));
}
}
model.setModelType("obj");
}
}
model.setNum(num);
modelList.add(model);
}
}
if(newCaseNums.size() >0){
this.saveBatch(newCaseNums);
}
if(modelList.size() >0){
modelService.saveOrUpdateBatch(modelList);
}
}
private String getGlbUrl(Integer type, String num,Model model) {
if(type == 0 || type == 1 || type == 4 || type == 6 || type == 7){ //看看,看见
String objPath = String.format(FilePath.OBJ_LOCAL_PATH ,environment,num);
ShellUtil.yunDownload(String.format(FilePath.OBJ_OSS_PATH, num)+"/data/mesh" ,objPath);
List localGlbPaths = new ArrayList<>();
List ossGlbPaths = new ArrayList<>();
File localFile = new File(objPath);
this.toGlB(localFile,localGlbPaths);
Long modelSize = 0L;
if(localGlbPaths.size() >0){
for (String localGlbPath : localGlbPaths) {
String ossGlbPath = localGlbPath.replace(FilePath.LOCAL_BASE_PATH,"fusion/");
localToOssUtil.uploadOss(localGlbPath,ossGlbPath);
if(ossGlbPath.contains("lod_")){
if(ossGlbPath.contains("lod_0")){
ossGlbPaths.add(queryPath +ossGlbPath);
modelSize += localToOssUtil.getSize(ossGlbPath);
}
continue;
}
modelSize += localToOssUtil.getSize(ossGlbPath);
ossGlbPaths.add(queryPath +ossGlbPath);
}
model.setModelSize(FileWriterUtil.setFileSize(modelSize));
FileUtil.del(objPath);
return JSONArray.toJSONString(ossGlbPaths);
}
FileUtil.del(objPath);
}
return null;
}
private void toGlB(File localFile, List localGlbPath) {
File[] files = localFile.listFiles();
for (File file : files) {
if(file.isDirectory()){
toGlB(file,localGlbPath);
}
if(file.getName().contains(".obj")){
String glbPath = OBJToGLBUtil.objToGlb(file.getPath(),file.getPath().replace(".obj",".glb") );
localGlbPath.add(glbPath);
}
}
}
private List updateByNumList(Integer caseId, List sceneNumParam) {
List addList = new ArrayList<>();
HashMap fusionNumHashMap = fusionNumService.getByCaseId(caseId);
HashMap> delMap = new HashMap<>();
for (SceneNumParam param : sceneNumParam) {
Integer type = param.getType();
List numList = param.getNumList();
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseNumEntity::getCaseId,caseId);
wrapper.eq(CaseNumEntity::getNumType,type);
List list = this.list(wrapper);
List hanNumList = list.parallelStream().map(CaseNumEntity::getNum).collect(Collectors.toList());
List delList = new ArrayList<>();
for (String num : hanNumList) {
if(!numList.contains(num)){
delList.add(num);
}
}
for (String num : numList) {
if(!hanNumList.contains(num)){
addList.add(num);
}
}
if(!delList.isEmpty()){
HashMap mapByNum = modelService.getMapByNum(delList);
for (String key : mapByNum.keySet()) {
Model model = mapByNum.get(key);
if(model != null && model.getType().equals(param.getType()) && fusionNumHashMap.containsKey(model.getModelId())){
throw new BusinessException(ResultCode.DEL_NUM_ERROR);
}
}
delMap.put(param.getType(),delList);
}
}
if(!delMap.isEmpty()){
for (Integer type : delMap.keySet()) {
this.deleteByNum(caseId,delMap.get(type),type);
}
}
return addList;
}
@Override
public void deleteByNum(Integer caseId, List delList,Integer type) {
if(delList.size() >0){
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseNumEntity::getCaseId,caseId);
wrapper.eq(CaseNumEntity::getNumType,type);
wrapper.in(CaseNumEntity::getNum,delList);
this.remove(wrapper);
fusionNumService.deleteByNumList(caseId,delList,true,type);
}
}
@Override
public void deleteByCaseId(Integer caseId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseNumEntity::getCaseId,caseId);
this.remove(wrapper);
fusionNumService.deleteByCaseId(caseId);
caseViewService.deleteByCaseId(caseId);
fusionGuidePathService.deleteByCaseId(caseId);
fusionMeterService.deleteByCaseId(caseId);
caseTagService.deletePointByCaseId(caseId);
}
@Override
public HashMap> getTypeMap(Integer caseId) {
List caseNumList = this.getByCaseId(caseId);
HashMap> typeMap = new HashMap<>();
for (CaseNumEntity caseNumEntity : caseNumList) {
List numList ;
if(typeMap.get(caseNumEntity.getNumType()) == null){
numList = new ArrayList<>();
}else {
numList = typeMap.get(caseNumEntity.getNumType());
}
numList.add(caseNumEntity.getNum());
typeMap.put(caseNumEntity.getNumType(),numList);
}
return typeMap;
}
@Override
public List getByNum(String num) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseNumEntity::getNum,num);
return this.list(wrapper);
}
@Override
public void addModeByCaseId(Integer caseId, Integer modelId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseNumEntity::getCaseId,caseId);
wrapper.eq(CaseNumEntity::getNum,modelId);
List list = this.list(wrapper);
if(list.isEmpty()){
CaseNumEntity caseNumEntity = new CaseNumEntity();
caseNumEntity.setCaseId(caseId);
caseNumEntity.setNumType(3);
caseNumEntity.setNum(modelId.toString());
this.save(caseNumEntity);
}
}
@Override
public void deleteByModel(Integer modelId) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(CaseNumEntity::getNum,modelId.toString());
this.remove(wrapper);
modelService.removeById(modelId);
}
@Override
public List getByNumList(List numList) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(CaseNumEntity::getNum,numList);
return this.list(wrapper);
}
@Autowired
ICaseService caseService;
@Override
public HashMap getMapByNumList(List numList) {
HashMap map = new HashMap<>();
if(numList == null || numList.isEmpty()){
return map;
}
List list = this.getByNumList(numList);
Set setIds = list.stream().map(CaseNumEntity::getCaseId).collect(Collectors.toSet());
HashMap caseMap = new HashMap<>();
if(!setIds.isEmpty()){
List cases = caseService.listByIds(setIds);
if(!cases.isEmpty()){
cases.forEach(e -> caseMap.put(e.getCaseId(),e));
}
}
for (CaseNumEntity caseNum : list) {
if(caseMap.get(caseNum.getCaseId()) != null){
map.put(caseNum.getNum() +"_"+ caseNum.getNumType() ,caseMap.get(caseNum.getCaseId()));
}
}
return map;
}
}