|
|
@@ -0,0 +1,274 @@
|
|
|
+package com.fdkankan.deploy.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.io.FileUtil;
|
|
|
+import cn.hutool.core.util.ZipUtil;
|
|
|
+import cn.hutool.http.HttpUtil;
|
|
|
+import com.alibaba.fastjson.JSON;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.fdkankan.common.util.DateExtUtil;
|
|
|
+import com.fdkankan.deploy.bean.SceneDeployBean;
|
|
|
+import com.fdkankan.deploy.entity.Scene;
|
|
|
+import com.fdkankan.deploy.mapper.SceneMapper;
|
|
|
+import com.fdkankan.deploy.service.SceneService;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import com.fdkankan.web.response.ResultData;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import net.lingala.zip4j.core.ZipFile;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletRequest;
|
|
|
+import java.io.File;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.*;
|
|
|
+import java.util.function.Function;
|
|
|
+import java.util.regex.Matcher;
|
|
|
+import java.util.regex.Pattern;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * <p>
|
|
|
+ * 服务实现类
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author
|
|
|
+ * @since 2025-11-05
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+public class SceneServiceImpl extends ServiceImpl<SceneMapper, Scene> implements SceneService {
|
|
|
+ @Value("${scene.download.waiting-path}")
|
|
|
+ private String waitingFilePath;
|
|
|
+ @Value("${scene.download.zip-dir}")
|
|
|
+ private String zipDir;
|
|
|
+ @Value("${scene.deploy.kankan}")
|
|
|
+ private String delpoyKankan;
|
|
|
+ @Value("${scene.deploy.laser}")
|
|
|
+ private String delpoyLaser;
|
|
|
+ @Value("${scene.download.completed-file}")
|
|
|
+ private String completedFile;
|
|
|
+ @Value("${scene.download.fail-file}")
|
|
|
+ private String failFile;
|
|
|
+ @Value("${scene.list-file-path}")
|
|
|
+ private String listFilePath;
|
|
|
+ private static final String pattern = "^\\[\\d{2}:\\d{2}:\\d{2}\\]";
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData receive(Map<String, Object> params) {
|
|
|
+
|
|
|
+ String num = (String)params.get("num");
|
|
|
+
|
|
|
+ String waitingFileName = Calendar.getInstance().getTimeInMillis() + "-" + num + ".txt";
|
|
|
+
|
|
|
+ FileUtil.mkParentDirs(waitingFilePath + waitingFileName);
|
|
|
+ FileUtil.writeUtf8String(JSON.toJSONString(params), FileUtil.file(waitingFilePath + waitingFileName));
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void donloadAndDeploy() {
|
|
|
+ FileUtil.mkdir(waitingFilePath);
|
|
|
+ List<String> waitingFileList = FileUtil.listFileNames(waitingFilePath);
|
|
|
+ if(CollUtil.isEmpty(waitingFileList)){
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String fileName = waitingFileList.stream().sorted(Comparator.comparing(String::toString)).collect(Collectors.toList()).get(0);
|
|
|
+ String taskStr = FileUtil.readUtf8String(waitingFilePath + fileName);
|
|
|
+ try {
|
|
|
+ JSONObject taskObj = JSON.parseObject(taskStr);
|
|
|
+ String num = taskObj.getString("num");
|
|
|
+ String downloadUrl = taskObj.getString("downloadUrl");
|
|
|
+ String zipType = taskObj.getString("zipType");
|
|
|
+ String title = taskObj.getString("title");
|
|
|
+ int version = taskObj.getIntValue("version");
|
|
|
+
|
|
|
+ String zipPath = zipDir + FileUtil.getPrefix(fileName) + "/";
|
|
|
+ String zipFilePath = zipPath + num + ".zip";
|
|
|
+ FileUtil.mkParentDirs(zipFilePath);
|
|
|
+ HttpUtil.downloadFile(downloadUrl, zipFilePath);
|
|
|
+ ZipUtil.unzip(zipFilePath);
|
|
|
+
|
|
|
+ if("kankan".equals(zipType)){
|
|
|
+ FileUtil.copy(zipPath + num+ "/wwwroot/scene_view_data/" + num, delpoyKankan, true);
|
|
|
+ }else{
|
|
|
+ FileUtil.copy(zipPath + num + "/www/" + num, delpoyLaser, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ //写入部署清单文件
|
|
|
+ SceneDeployBean deployBean = SceneDeployBean.builder()
|
|
|
+ .num(num).title(title).sceneType(zipType).calcTime(DateExtUtil.format(new Date(), DateExtUtil.dateStyle8))
|
|
|
+ .syncTime(DateExtUtil.format(new Date(), DateExtUtil.dateStyle8)).build();
|
|
|
+ this.writeListJson(deployBean);
|
|
|
+
|
|
|
+ //部署完毕后写入已下载任务,删除待下载任务
|
|
|
+ FileUtil.mkParentDirs(completedFile);
|
|
|
+ FileUtil.appendUtf8String(JSON.toJSONString(taskObj) + "\n", completedFile);
|
|
|
+
|
|
|
+ }catch (Exception e){
|
|
|
+ log.error("部署失败,task:{}", taskStr, e);
|
|
|
+ FileUtil.mkParentDirs(failFile);
|
|
|
+ FileUtil.appendUtf8String(taskStr + "\n", failFile);
|
|
|
+ } finally {
|
|
|
+ FileUtil.del(waitingFilePath + fileName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private synchronized void writeListJson(SceneDeployBean deployBean){
|
|
|
+
|
|
|
+ Map<String, SceneDeployBean> sceneMap = null;
|
|
|
+ if(FileUtil.exist(listFilePath)){
|
|
|
+ String listStr = FileUtil.readUtf8String(listFilePath);
|
|
|
+ List<SceneDeployBean> sceneDeployBeans = JSON.parseArray(listStr, SceneDeployBean.class);
|
|
|
+ if(CollUtil.isNotEmpty(sceneDeployBeans)){
|
|
|
+ sceneMap = sceneDeployBeans.stream().collect(Collectors.toMap(SceneDeployBean::getKey, Function.identity()));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(CollUtil.isEmpty(sceneMap)){
|
|
|
+ sceneMap = new HashMap<>();
|
|
|
+ }
|
|
|
+
|
|
|
+ sceneMap.put(deployBean.getNum() + "-" + deployBean.getSceneType(), deployBean);
|
|
|
+
|
|
|
+ Collection<SceneDeployBean> values = sceneMap.values();
|
|
|
+
|
|
|
+ FileUtil.writeUtf8String(JSON.toJSONString(values), listFilePath);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ResultData receive2(HttpServletRequest request) throws Exception {
|
|
|
+ String id = request.getParameter("id");
|
|
|
+ String action = request.getParameter("action");
|
|
|
+ String fileName = request.getParameter("fileName");
|
|
|
+ String num = request.getParameter("num");
|
|
|
+ String zipPath = zipDir + id + "/";
|
|
|
+ String zipFilePath = zipPath.concat(fileName);
|
|
|
+
|
|
|
+ if("upload".equals(action)){
|
|
|
+ InputStream ins = request.getPart("file").getInputStream();
|
|
|
+ FileUtil.mkParentDirs(zipFilePath);
|
|
|
+ FileUtil.writeFromStream(ins,zipFilePath);
|
|
|
+ }else{
|
|
|
+ ZipFile zipFile = new ZipFile(new File(zipFilePath));
|
|
|
+ zipFile.extractAll(zipPath);
|
|
|
+ String zipType = request.getParameter("zipType");
|
|
|
+ String title = request.getParameter("title");
|
|
|
+ int computeTime = Integer.valueOf(request.getParameter("computeTime"));
|
|
|
+ if("kankan".equals(zipType)){
|
|
|
+ FileUtil.copy(zipPath + num, delpoyKankan, true);
|
|
|
+ }else{
|
|
|
+ FileUtil.copy(zipPath + num, delpoyLaser, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ //重写日志文件
|
|
|
+ this.reWriteLog(num, zipPath + num + "/console.log", computeTime);
|
|
|
+
|
|
|
+ //写入部署清单文件
|
|
|
+ SceneDeployBean deployBean = SceneDeployBean.builder()
|
|
|
+ .num(num).title(title).sceneType(zipType).calcTime(DateExtUtil.format(new Date(), DateExtUtil.dateStyle8))
|
|
|
+ .syncTime(DateExtUtil.format(new Date(), DateExtUtil.dateStyle8)).build();
|
|
|
+ this.writeListJson(deployBean);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ResultData.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Value("${scene.log.path}")
|
|
|
+ private String sceneLogPath;
|
|
|
+
|
|
|
+ private void reWriteLog(String num, String logPath, int time){
|
|
|
+ List<String> strings = FileUtil.readLines(logPath, StandardCharsets.UTF_8);
|
|
|
+ Date endTime = Calendar.getInstance().getTime();
|
|
|
+ Date startTime = DateUtil.offsetSecond(endTime, -time);
|
|
|
+ int flag = strings.size()/time;
|
|
|
+ int skipIndex = time/(strings.size()%time);
|
|
|
+ if(time%(strings.size()%time) != 0){
|
|
|
+ skipIndex++;
|
|
|
+ }
|
|
|
+ String targetLog = String.format(sceneLogPath, num);
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
+ int index = 1;
|
|
|
+
|
|
|
+ int count = 0;
|
|
|
+ for (String str : strings) {
|
|
|
+ if(this.checkStartWithTime(str)){
|
|
|
+ list.add("[" + DateExtUtil.format(startTime, DateExtUtil.dateStyle2) + "]" + str.substring(10));
|
|
|
+ }else{
|
|
|
+ list.add(str);
|
|
|
+ }
|
|
|
+ if(count == 0){
|
|
|
+ if(index%flag==0){
|
|
|
+ if(index%skipIndex != 0){
|
|
|
+ startTime = DateUtil.offsetSecond(startTime, 1);
|
|
|
+ }else{
|
|
|
+ count = (++index)%skipIndex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else{
|
|
|
+ if(count-- == 0){
|
|
|
+ startTime = DateUtil.offsetSecond(startTime, 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ index++;
|
|
|
+ }
|
|
|
+
|
|
|
+ FileUtil.writeUtf8Lines(list, targetLog);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public static void main(String[] args) throws Exception{
|
|
|
+// net.lingala.zip4j.core.ZipFile zipFile = new ZipFile(new File("D:\\test\\KJ-t-WypZvHxCR4X.zip"));
|
|
|
+// zipFile.extractAll("D:\\test\\");
|
|
|
+// FileUtils.unZip("D:\\test\\aa\\KJ-t-WypZvHxCR4X.zip", "D:\\test\\aa\\");
|
|
|
+// List<String> strings = FileUtil.readLines("D:\\test\\console.log", StandardCharsets.UTF_8);
|
|
|
+// int time = 20 * 60;
|
|
|
+// Date endTime = Calendar.getInstance().getTime();
|
|
|
+// Date startTime = DateUtil.offsetSecond(endTime, -time);
|
|
|
+// System.out.println("开始时间:" + DateExtUtil.format(startTime, DateExtUtil.dateStyle2));
|
|
|
+// System.out.println("结束时间:" + DateExtUtil.format(endTime, DateExtUtil.dateStyle2));
|
|
|
+// int flag = strings.size()/time;
|
|
|
+// int test = time/(strings.size()%time);
|
|
|
+// if(time%(strings.size()%time) != 0){
|
|
|
+// test++;
|
|
|
+// }
|
|
|
+// String targetLog = "D:\\test\\aaa.log";
|
|
|
+// List<String> list = new ArrayList<>();
|
|
|
+// int index = 1;
|
|
|
+//
|
|
|
+// for (String str : strings) {
|
|
|
+// if(checkStartWithTime(str)){
|
|
|
+// list.add("[" + DateExtUtil.format(startTime, DateExtUtil.dateStyle2) + "]" + str.substring(10));
|
|
|
+// }else{
|
|
|
+// list.add(str);
|
|
|
+// }
|
|
|
+// if(index%flag==0){
|
|
|
+// if(index%test != 0){
|
|
|
+// startTime = DateUtil.offsetSecond(startTime, 1);
|
|
|
+// }
|
|
|
+// }
|
|
|
+//
|
|
|
+// index++;
|
|
|
+//
|
|
|
+// }
|
|
|
+//
|
|
|
+// FileUtil.writeUtf8Lines(list, targetLog);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ public boolean checkStartWithTime(String content){
|
|
|
+ Pattern r = Pattern.compile(pattern);
|
|
|
+ Matcher m = r.matcher(content);
|
|
|
+ if (m.find()) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|