package com.fdkankan.fusion.service.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fdkankan.fusion.common.PageInfo;
import com.fdkankan.fusion.common.util.*;
import com.fdkankan.fusion.common.FilePath;
import com.fdkankan.fusion.common.ResultCode;
import com.fdkankan.fusion.entity.*;
import com.fdkankan.fusion.exception.BusinessException;
import com.fdkankan.fusion.mapper.IModelMapper;
import com.fdkankan.fusion.request.ModelPram;
import com.fdkankan.fusion.response.SceneVo;
import com.fdkankan.fusion.service.ICaseNumService;
import com.fdkankan.fusion.service.ICaseService;
import com.fdkankan.fusion.service.IFusionNumService;
import com.fdkankan.fusion.service.IModelService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fdkankan.redis.util.RedisUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
/**
*
* 服务实现类
*
*
* @author
* @since 2022-08-03
*/
@Service
public class ModelServiceImpl extends ServiceImpl implements IModelService {
@Autowired
UploadToOssUtil uploadToOssUtil;
@Autowired
UploadService uploadService;
@Autowired
ICaseNumService caseNumService;
@Autowired
ICaseService caseService;
@Autowired
IFusionNumService fusionNumService;
@Autowired
RedisUtil redisUtil;
@Value("${local.obj_path}")
private String OBJ_PATH;
@Value("${local.glb_path}")
private String GLB_PATH;
@Value("${upload.query-path}")
private String queryPath;
@Override
public Model uploadObj(MultipartFile file, String username) throws Exception {
if(file.isEmpty()){
throw new BusinessException(ResultCode.UPLOAD_FILE_NO_EXIST);
}
if(file.getSize()>10 * 1024 * 1024 * 100){
throw new BusinessException(ResultCode.UPLOAD_FILE_TO_LONG);
}
//获取文件名
String fileName = file.getOriginalFilename();
if(StringUtils.isEmpty(fileName)){
throw new BusinessException(ResultCode.UPLOAD_FILE_NO_EXIST);
}
if(com.fdkankan.fusion.common.util.StringUtils.isChinese(fileName)){
throw new BusinessException(ResultCode.UPLOAD_FILE_CHINA_NAME);
}
if(fileName.length() >50){
throw new BusinessException(ResultCode.UPLOAD_FILE_NAME_TO_LONG);
}
if(!fileName.toLowerCase().endsWith(".zip")){
throw new BusinessException(ResultCode.UPLOAD_FILE_TYPE_ERROR);
}
//获取文件后缀名
String modelName = fileName.substring(0,fileName.lastIndexOf("."));
Model model = new Model();
model.setModelTitle(modelName);
model.setModelSize(FileWriterUtil.setFileSize(file.getSize()));
model.setUserName(username);
this.save(model);
redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"0");
fileName = UUID.randomUUID().toString().replace("-","") +".zip";
File newObjFile = null;
File objPathFile = null;
String objPath = String.format(OBJ_PATH , "modelId_"+model.getModelId()) ;
newObjFile = new File(objPath +"/" + fileName);
if(!newObjFile.getParentFile().exists()){
newObjFile.mkdirs();
}
file.transferTo(newObjFile);
if(fileName.toLowerCase().endsWith(".zip")){
ShellUtil.unZip(newObjFile.getPath(),objPath);
}
objPathFile = new File(objPath );
if(!objPathFile.isDirectory()){
setCreateStatus(model,-1);
throw new BusinessException(ResultCode.UPLOAD_FILE_TYPE_ERROR);
}
List fileList = new ArrayList<>();
FileWriterUtil.getCanRunList(fileList,objPathFile);
if(fileList.size() != 1){
setCreateStatus(model,-1);
throw new BusinessException(ResultCode.UPLOAD_FILE_MSG_ERROR);
}
File file1 = fileList.get(0);
if(file1 == null){
setCreateStatus(model,-1);
throw new BusinessException(ResultCode.UPLOAD_FILE_OBJ_ERROR);
}
if(com.fdkankan.fusion.common.util.StringUtils.isChinese(file1.getName())){
setCreateStatus(model,-1);
throw new BusinessException(ResultCode.UPLOAD_FILE_CHINA_NAME);
}
redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"20");
runThread(file1,objPath,model,newObjFile,objPathFile,this);
return model;
}
private void setCreateStatus(Model model,Integer status){
model.setCreateStatus(status);
this.saveOrUpdate(model);
redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),status.toString());
}
private void runThread(File file1,String objPath,Model model,File newObjFile,File objPathFile,IModelService modelService){
new Thread() {
@Override
public void run() {
File mntFile = null;
try {
String glbOssPath = String.format(FilePath.GLB_OSS_PATH, model.getModelId());
String name = file1.getName();
if(name.contains("obj") || name.contains("OBJ")){
glbOssPath = glbOssPath.replace("mesh.glb",file1.getName().replace("obj","glb"));
model.setModelDateType("obj");
model.setModelType("glb");
OBJToGLBUtil.objToGlb(objPath,name, file1.getPath().replace("obj","glb"));
redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"65");
uploadToOssUtil.uploadOss(file1.getPath(),glbOssPath);
}
if(name.contains(".ply")){
model.setModelDateType("ply");
model.setModelType("ply");
}
if(name.contains(".las")){
model.setModelDateType("las");
model.setModelType("las");
}
if("las".equals(model.getModelType()) || "ply".equals(model.getModelType()) ){
mntFile = OBJToGLBUtil.lasOrPlyToBin(file1);
glbOssPath = mntFile.getPath().replace("/mnt/","")+"/webcloud";
redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"65");
uploadToOssUtil.uploadFileOss(mntFile );
}
model.setModelObjUrl(objPath);
model.setModelGlbUrl(queryPath + glbOssPath);
model.setCreateStatus(1); //上传成功
modelService.saveOrUpdate(model);
}catch (Exception e){
model.setCreateStatus(-1);
modelService.saveOrUpdate(model);
redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"-1");
}finally {
if(newObjFile!=null){
FileUtil.del(newObjFile);
}
if(objPathFile!=null){
FileUtil.del(objPathFile);
}
if(mntFile!=null){
FileUtil.del(mntFile.getParentFile());
}
redisUtil.set(RedisKeyUtil.modelUpload+model.getModelId(),"100");
}
}
}.start();
}
@Override
public PageInfo pageList(ModelPram param, String token) {
String username = JwtUtil.getUsername(token);
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Model::getUserName,username);
wrapper.eq(Model::getType,3);
if(param.getStatus()!=null){ //参数2为成功,数据库中成功为1
wrapper.eq(Model::getCreateStatus,param.getStatus() == 2 ? 1 :param.getStatus());
}
if(StringUtils.isNotBlank(param.getModelTitle())){
wrapper.like(Model::getModelTitle,param.getModelTitle());
}
wrapper.orderByDesc(Model::getCreateTime);
Page page = this.page(new Page<>(param.getPageNum(),param.getPageSize()),wrapper);
for (Model model : page.getRecords()) {
if(model.getType() == 3 && StringUtils.isEmpty(model.getNum())) {
model.setNum(model.getModelId().toString());
}
}
return PageInfo.PageInfo(page);
}
@Override
public void delete(Integer modelId) {
List caseNumEntityList = caseNumService.getByNum(modelId.toString());
List fusionNumList = fusionNumService.getByNum(modelId.toString());
if(caseNumEntityList.size() >0 || fusionNumList.size() >0){
StringBuilder title = new StringBuilder();
List caseIdIds = caseNumEntityList.parallelStream().map(CaseNumEntity::getCaseId).collect(Collectors.toList());
if(caseIdIds.size() >0){
List list = caseService.getByIds(caseIdIds);
List collect = list.parallelStream().map(CaseEntity::getCaseTitle).collect(Collectors.toList());
for (String str : collect) {
title.append(str).append(",");
}
if(title.length()>0){
title.delete(title.length()-1,title.length());
}
}
throw new BusinessException(ResultCode.CASE_USE.code, String.format(ResultCode.CASE_USE.msg,title));
}
Model model = this.getById(modelId);
if(model == null ){
throw new BusinessException(ResultCode.MODEL_NOT_EXIST);
}
this.removeById(modelId);
fusionNumService.deleteByModelId(modelId);
if(StringUtils.isNotBlank(model.getModelGlbUrl())){
uploadService.deleteOssUrl(model.getModelGlbUrl());
}
}
@Override
public List getListByNum(List numList) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(Model::getNum,numList);
return this.list(wrapper);
}
@Override
public List getListByModelIds(List modelIds) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(Model::getModelId,modelIds);
return this.list(wrapper);
}
@Override
public List getListByModelIdStrs(List numList) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(Model::getModelId,numList);
wrapper.orderByDesc(Model::getCreateTime);
return this.list(wrapper);
}
@Override
public void deleteByNum(List numList) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.in(Model::getNum,numList);
this.remove(wrapper);
}
@Override
public List getByUserName(String username) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Model::getUserName,username)
.eq(Model::getType,3);
return this.list(wrapper);
}
@Override
public Model getIsNullNewByNum(String num) {
LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>();
wrapper.eq(Model::getNum,num);
Model model = this.getOne(wrapper);
if(model == null){
model = new Model();
}
return model;
}
@Override
public Object getInfo(Integer modelId) {
Model model = this.getById(modelId);
if(model == null){
throw new BusinessException(ResultCode.SCENE_NOT_EXIST);
}
SceneVo sceneVo = new SceneVo();
BeanUtils.copyProperties(model,sceneVo);
return sceneVo;
}
@Override
public String uploadObjProgress(Integer modelId) {
String redisKey = RedisKeyUtil.modelUpload+modelId;
if(redisUtil.hasKey(redisKey)){
return redisUtil.get(redisKey);
}
return "0";
}
}