package com.fd.controller;
import com.fd.constant.Command;
import com.fd.constant.MsgCode;
import com.fd.constant.TypeCode;
import com.fd.dto.PageDto;
import com.fd.dto.MyQueue;
import com.fd.entity.FileEntity;
import com.fd.entity.FileSchedule;
import com.fd.entity.OutputFileEntity;
import com.fd.server.CmdServer;
import com.fd.server.FileServer;
import com.fd.server.ModelServer;
import com.fd.util.FileUtils;
import com.fd.util.R;
import com.fd.util.RegexUtils;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.PostConstruct;
import java.io.File;
import java.util.Date;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
/**
* Created by Owen on 2019/11/12 0012 9:40
*
* 3D模型数据
*/
@Log4j2
@RequestMapping("api/fdModel")
@RestController
public class FdModelController {
@Value("${input.file.path}")
private String INPUT_FILE_PATH;
@Value("${output.file.path}")
private String OUTPUT_FILE_PATH;
@Autowired
private FileServer fileServer;
@Autowired
private CmdServer cmdServer;
@Autowired
private ModelServer modelServer;
// 队列
BlockingQueue queue = new LinkedBlockingQueue(5);
BlockingQueue modelQueue = new LinkedBlockingQueue(5);
private static AtomicInteger count = new AtomicInteger();
/**
* 初始化队列
*
* @return
*/
@PostConstruct
private void init() {
new Thread(new modelSliceConsumerThread(modelQueue)).start();
}
/**
* 消费队列
*/
public class modelSliceConsumerThread implements Runnable{
private BlockingQueue queue;
private boolean isRun = true;
public modelSliceConsumerThread(BlockingQueue queue){
this.queue = queue;
}
@Override
public void run() {
log.warn("run modelSliceConsumerThread");
while (true) {
try {
MyQueue data = queue.poll(2, TimeUnit.SECONDS);
if (data != null) {
log.info("消费者,拿到队列中的数据data:" + data.toString());
Integer integer = cmdServer.exeCmdModelSlice(data.getStr());
OutputFileEntity obj = data.getOutputFile();
if (integer != 0) {
log.info("error command exeCmdModelSlice");
// 如果命令运行失败,删除刚才创建的实体类
// o:代表切片失败
obj.setStatus(0);
modelServer.save(obj);
return;
}
}
// Thread.sleep(4000);
} catch (InterruptedException e) {
// isRun = false;
e.printStackTrace();
}
}
}
}
@ApiOperation("上传3D模型数据,只能上传zip文件")
@PostMapping(value = "upload", consumes = {"multipart/form-data"})
private R upload(@RequestParam("file") MultipartFile file) {
log.info("run upload");
// 文件名全名
String fileName = file.getOriginalFilename();
// 文件是否包含中文字符
if (RegexUtils.regexChinese(fileName)) {
return new R(51005, MsgCode.E51005);
}
String s = StringUtils.substringAfterLast(fileName, ".");
if (!"zip".equals(s)) {
return new R(50007, MsgCode.E50007);
}
FileEntity entity = modelServer.findByFileName(fileName);
if (entity != null) {
return new R(51006, MsgCode.E51006);
}
return modelServer.uploadBigFile(file);
}
@ApiOperation("解压zip文件")
@GetMapping("unzip/{fileId}/")
private R fileUnzip(@PathVariable("fileId") Long fileId) {
log.info("run fileUnzip: {}", fileId);
// FileEntity entity = fileServer.findById(fileId);
OutputFileEntity entity = modelServer.findById(fileId);
FileEntity uploadFiel = fileServer.findById(entity.getUploadId());
String outputPath = OUTPUT_FILE_PATH + "unzip";
FileUtils.createDir(outputPath);
boolean unzip = FileUtils.unzip(uploadFiel.getFileUrl(), outputPath);
if (!unzip) {
log.info("zip error: {}", MsgCode.E51001);
return new R(50001, MsgCode.E51001);
}
String fileName = StringUtils.substringBeforeLast(entity.getFileName(), ".");
entity.setStatus(4);
entity.setUpdateTime(new Date());
entity.setUnZipPath(outputPath + File.separator + fileName);
entity = modelServer.save(entity);
return new R(200, entity);
}
@ApiOperation("获取3D模型数据列表")
@PostMapping(value = "list")
private R list(@RequestBody PageDto param) {
// log.info("run list");
return modelServer.findByType(TypeCode.FILE_TYPE_MODEL, param);
}
/**
* 删除文件
*/
@ApiOperation("删除文件")
@GetMapping("delete/{fileId}/")
private R deleteFile(@PathVariable("fileId") Long fileId) {
log.info("run deleteFile: {}", fileId);
return modelServer.deleteById(fileId);
}
@ApiOperation("倾斜摄影数据切片")
@GetMapping("command/osgb/{fileId}/")
private R cmdModelSlice(@PathVariable("fileId") Long fileId) {
log.info("run cmdModelSlice: {}", fileId);
// FileEntity entity = fileServer.findById(fileId);
OutputFileEntity entity = modelServer.findById(fileId);
String fileName = StringUtils.substringBeforeLast(entity.getFileName(), ".");
String outputPath = OUTPUT_FILE_PATH + "model";
FileUtils.createDir(outputPath);
outputPath = outputPath + File.separator + fileName;
// 传入的是目录
String cmd = Command.MODEL_SLICE_OSGB;
cmd = cmd.replace("@inputFile", entity.getUnZipPath());
cmd = cmd.replace("@outputFile", outputPath);
log.info("cmd: {}", cmd);
// 命令产生的是文件夹
entity.setStatus(5);
entity.setUpdateTime(new Date());
entity.setSlicePath(outputPath);
entity = modelServer.save(entity);
// 把数据放入队列中
MyQueue data = new MyQueue();
data.setOutputFile(entity);
data.setStr(cmd);
try {
modelQueue.offer(data, 1, TimeUnit.SECONDS);
log.info("入队成功");
} catch (InterruptedException e) {
e.printStackTrace();
}
return new R(200, entity);
}
@ApiOperation("移动数据到服务器上")
@GetMapping("move/{fileId}/")
private R moveFile(@PathVariable("fileId") Long fileId) {
log.info("run moveFile: {}", fileId);
return modelServer.moveFileToServer(fileId);
}
}