dengsixing 1 năm trước cách đây
mục cha
commit
3ad24aa79e

+ 10 - 4
pom.xml

@@ -74,11 +74,17 @@
     </dependency>
 
     <dependency>
-      <groupId>com.fdkankan</groupId>
-      <artifactId>4dkankan-utils-rabbitmq</artifactId>
-      <version>3.0.0-SNAPSHOT</version>
+      <groupId>org.springframework.boot</groupId>
+      <artifactId>spring-boot-starter-amqp</artifactId>
+      <version>2.3.12.RELEASE</version>
     </dependency>
 
+<!--    <dependency>-->
+<!--      <groupId>com.fdkankan</groupId>-->
+<!--      <artifactId>4dkankan-utils-rabbitmq</artifactId>-->
+<!--      <version>3.0.0-SNAPSHOT</version>-->
+<!--    </dependency>-->
+
     <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
@@ -161,7 +167,7 @@
 <!--      </plugin>-->
 <!--    </plugins>-->
 
-    <finalName>4dkankan-center-convert</finalName>
+    <finalName>model</finalName>
 
     <plugins>
       <plugin>

+ 66 - 0
src/main/java/com/fdkankan/modeldemo/entity/SceneConvertLog.java

@@ -0,0 +1,66 @@
+package com.fdkankan.modeldemo.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import java.util.Date;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ *
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-07-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("T_SCENE_CONVERT_LOG")
+public class SceneConvertLog extends Model<SceneConvertLog> {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.AUTO)
+    private String id;
+
+    @TableField("STATION_CODE")
+    private String stationCode;
+
+    @TableField("ENTITY_ID")
+    private String entityId;
+
+    /**
+     * 0-失败,1-成功
+     */
+    @TableField("STATUS")
+    private String status;
+
+    @TableField("CREATE_TIME")
+    private Date createTime;
+
+    /**
+     * 备注
+     */
+    @TableField("REMARK")
+    private String remark;
+
+    /**
+     * 耗时
+     */
+    @TableField("TIME_CONSUMING")
+    private String timeConsuming;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 7 - 5
src/main/java/com/fdkankan/modeldemo/generator/MappingGeneratorOracle.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.generator.config.GlobalConfig;
 import com.baomidou.mybatisplus.generator.config.PackageConfig;
 import com.baomidou.mybatisplus.generator.config.StrategyConfig;
 import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
+import com.baomidou.mybatisplus.generator.config.rules.DateType;
 import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
 import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
 
@@ -44,20 +45,20 @@ public class MappingGeneratorOracle {
 	 * 总包名,后续生成的 Mapper,Service 等将在该包下生成子包
 	 * </p>
 	 */
-	private static final String PACKAGE = "com.fdkankan.project.tieta";
+	private static final String PACKAGE = "com.fdkankan.modeldemo";
 	/**
 	 * JDBC URL 说明: url地址前需要加上@,否则会报错
 	 */
 
-	private static final String JDBC_URL = "jdbc:oracle:thin:@//8.135.106.227:1521/helowin";
+	private static final String JDBC_URL = "jdbc:oracle:thin:@//10.180.41.39:1521/resdb";
 	/**
 	 * 数据库账户
 	 */
-	private static final String DB_USERNAME = "FDKK";
+	private static final String DB_USERNAME = "RES_VR";
 	/**
 	 * 数据库账户密码
 	 */
-	private static final String DB_PASSWORD = "qawsed@123.";
+	private static final String DB_PASSWORD = "IDCqawsed@123.";
 
 	/**
 	 * 执行即可生成代码 需要添加 freemarker 依赖 <dependency> <groupId>org.freemarker</groupId>
@@ -102,6 +103,7 @@ public class MappingGeneratorOracle {
 		globalConfig.setActiveRecord(true);
 		// 设置 ID 类型
 		globalConfig.setIdType(IdType.AUTO);
+		globalConfig.setDateType(DateType.ONLY_DATE);
 //		// 生成基本 Swagger2 文档
 //		globalConfig.setSwagger2(true);
 		// 开启二级缓存
@@ -139,7 +141,7 @@ public class MappingGeneratorOracle {
 		// TODO 填写表前缀、表字段前缀,生成代码时去除字段前缀
 		strategyConfig.setTablePrefix("t_");
 		strategyConfig.setFieldPrefix("a_", "c_", "e_", "f_", "p_", "r_", "t_", "tf_");
-		strategyConfig.setInclude("t_test");
+		strategyConfig.setInclude("T_FULLPHOTO_FILEINDEX");
 		return strategyConfig;
 	}
 

+ 16 - 0
src/main/java/com/fdkankan/modeldemo/mapper/SceneConvertLogMapper.java

@@ -0,0 +1,16 @@
+package com.fdkankan.modeldemo.mapper;
+
+import com.fdkankan.modeldemo.entity.SceneConvertLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-07-02
+ */
+public interface SceneConvertLogMapper extends BaseMapper<SceneConvertLog> {
+
+}

+ 175 - 23
src/main/java/com/fdkankan/modeldemo/mq/ConvertListener.java

@@ -1,19 +1,26 @@
 package com.fdkankan.modeldemo.mq;
 
+import cn.hutool.core.date.TimeInterval;
+import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.img.ImgUtil;
 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.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.fdkankan.modeldemo.bean.SceneEditControlsBean;
 import com.fdkankan.modeldemo.bean.SceneJsonBean;
 import com.fdkankan.modeldemo.constant.Constant;
 import com.fdkankan.modeldemo.entity.Scene;
+import com.fdkankan.modeldemo.entity.SceneConvertLog;
 import com.fdkankan.modeldemo.entity.SceneFileMapping;
+import com.fdkankan.modeldemo.service.SceneConvertLogService;
 import com.fdkankan.modeldemo.service.SceneFileMappingService;
 import com.fdkankan.modeldemo.service.SceneService;
 import com.fdkankan.modeldemo.utils.ConvertUtil;
 import com.fdkankan.modeldemo.utils.FdfsUtil;
+import com.fdkankan.modeldemo.utils.HttpUtilExt;
 import com.rabbitmq.client.Channel;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.amqp.core.Message;
@@ -23,7 +30,10 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;
+import java.io.File;
 import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+import java.util.Date;
 import java.util.Map;
 import java.util.Objects;
 
@@ -39,6 +49,8 @@ import java.util.Objects;
 @Component
 public class ConvertListener{
 
+    public final static String baseZipPath = "/mnt/scene/convert/";
+
     @Autowired
     private ConvertUtil convertUtil;
     @Resource
@@ -48,37 +60,154 @@ public class ConvertListener{
     @Autowired
     private SceneService sceneService;
 
+    @Autowired
+    private SceneConvertLogService sceneConvertLogService;
+
+//    @RabbitListener(
+//            queuesToDeclare = @Queue(Constant.QUEUE_SCENE_CONVERT),
+//            concurrency = "1"
+//    )
+//    public void buildObjScenePreHandler(Channel channel, Message message) throws Exception {
+//        String roomId = null;
+//        try {
+//            String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+//            log.info("msg:{}", msg);
+//            JSONObject jsonObject = JSON.parseObject(msg);
+//            //roomId
+//            roomId = jsonObject.getString("roomId");
+//            String zipUrl = jsonObject.getString("zipUrl");
+//            String zipName = FileUtil.getName(zipUrl);
+//            String dirName = FileUtil.getPrefix(zipName);
+//            log.info("zipUrl:{}", zipUrl);
+//            //下载压缩包
+//            String baseZipPath = "/mnt/scene/convert/";
+//            FileUtil.mkdir(baseZipPath);
+//            HttpUtil.downloadFile(zipUrl, baseZipPath);
+////            FileUtil.copy(zipUrl, baseZipPath, true);
+//
+//            String localZipPath = baseZipPath + zipName;
+//            ZipUtil.unzip(localZipPath, baseZipPath);
+//
+//            String targetPath = "/oss/4dkankan/scene_view_data/" + roomId + "/";
+//            String dataSource = baseZipPath + dirName + "/";
+//            Map<String, String> uploadFileMap = convertUtil.convert(dataSource, roomId);
+//            String finalRoomId = roomId;
+//            uploadFileMap.keySet().stream().forEach(key->{
+//
+//                SceneFileMapping sceneFileMapping = sceneFileMappingService.getByNumAndKey(finalRoomId, key);
+//                if(Objects.isNull(sceneFileMapping)){
+//                    sceneFileMapping = new SceneFileMapping();
+//                }
+//                Map<String, String> mapping = fdfsUtil.uploadFile(uploadFileMap.get(key));
+//                sceneFileMapping.setNum(finalRoomId);
+//                sceneFileMapping.setFileid(mapping.get("file_id"));
+//                sceneFileMapping.setUrl(mapping.get("http_url"));
+//                sceneFileMapping.setKey(key);
+//                sceneFileMappingService.saveOrUpdate(sceneFileMapping);
+//            });
+//
+//        }catch (Exception e){
+//            log.error("convert fail, roomId:{}", roomId, e);
+//        }
+//
+//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+//
+//
+//    }
+
     @RabbitListener(
-            queuesToDeclare = @Queue(Constant.QUEUE_SCENE_CONVERT),
+            queuesToDeclare = @Queue(Constant.QUEUE_SCENE_CONVERT + "-2"),
             concurrency = "1"
     )
     public void buildObjScenePreHandler(Channel channel, Message message) throws Exception {
-        String roomId = null;
+        //开始急事
+        TimeInterval timeInterval = new TimeInterval();
+        timeInterval.start();
+
+        String stationCode = null;
+        String entityId = null;
+        JSONArray fileList = null;
+        SceneConvertLog sceneConvertLog = new SceneConvertLog();
+        String dataSource = null;
         try {
             String msg = new String(message.getBody(), StandardCharsets.UTF_8);
             log.info("msg:{}", msg);
             JSONObject jsonObject = JSON.parseObject(msg);
-            //roomId
-            roomId = jsonObject.getString("roomId");
-            String zipUrl = jsonObject.getString("zipUrl");
-            String zipName = FileUtil.getName(zipUrl);
-            String dirName = FileUtil.getPrefix(zipName);
-            log.info("zipUrl:{}", zipUrl);
-            //下载压缩包
-            String baseZipPath = "/mnt/scene/convert/";
-            FileUtil.mkdir(baseZipPath);
-            HttpUtil.downloadFile(zipUrl, baseZipPath);
-//            FileUtil.copy(zipUrl, baseZipPath, true);
-
-            String localZipPath = baseZipPath + zipName;
-            ZipUtil.unzip(localZipPath, baseZipPath);
-
-            String targetPath = "/oss/4dkankan/scene_view_data/" + roomId + "/";
-            String dataSource = baseZipPath + dirName + "/";
-            Map<String, String> uploadFileMap = convertUtil.convert(dataSource, roomId);
-            String finalRoomId = roomId;
-            uploadFileMap.keySet().stream().forEach(key->{
+            stationCode = jsonObject.getString("stationCode");
+            entityId = jsonObject.getString("entityId");
+            fileList = jsonObject.getJSONArray("fileList");
+
+            sceneConvertLog.setStationCode(stationCode);
+            sceneConvertLog.setEntityId(entityId);
+            sceneConvertLog.setCreateTime(new Date());
+
+            //校验文件是否齐全
+            boolean exists512 = fileList.stream().anyMatch(v -> {
+                JSONObject obj = (JSONObject) v;
+                return "1".equals(obj.getString("fileType"));
+            });
 
+            boolean exists4k = fileList.stream().anyMatch(v -> {
+                JSONObject obj = (JSONObject) v;
+                return "2".equals(obj.getString("fileType"));
+            });
+
+            boolean exists8k = fileList.stream().anyMatch(v -> {
+                JSONObject obj = (JSONObject) v;
+                return "3".equals(obj.getString("fileType"));
+            });
+
+
+            dataSource = baseZipPath + stationCode + "_" + entityId + "/";
+            String imagePath = dataSource + "images/";
+            String dataPath = dataSource + "data/";
+            String meshPath = dataPath + "mesh/";
+            String image512Path = imagePath + "512/";
+            String image4kPath = imagePath + "4k/";
+            String image8kPath = imagePath + "8k/";
+            FileUtil.mkdir(image512Path);
+            FileUtil.mkdir(image4kPath);
+
+            fileList.parallelStream().forEach(o->{
+                JSONObject obj = (JSONObject) o;
+                String fileName = obj.getString("fileName");
+                String fileType = obj.getString("fileType");
+                String fileUrl = obj.getString("fileUrl");
+                if("7".equals(fileType)){//vision.txt
+                    HttpUtilExt.downloadFileAndCheck(fileUrl, imagePath + fileName, 3000);
+                }
+                if("1".equals(fileType)){//512图
+                    HttpUtilExt.downloadFileAndCheck(fileUrl, image512Path + fileName, 30000);
+                }
+                if("2".equals(fileType)){//4k图
+                    HttpUtilExt.downloadFileAndCheck(fileUrl, image4kPath + fileName, 30000);
+                    if(!exists512){
+                        ImgUtil.scale(new File(image4kPath + fileName), new File(image512Path + fileName), 0.125f);
+                    }
+                }
+                if(!exists4k){//如果资源中没有4k,需要用8k图做一下像素压缩
+                    if("3".equals(fileType)){
+                        HttpUtilExt.downloadFileAndCheck(fileUrl, image8kPath + fileName, 30000);
+                        ImgUtil.scale(new File(image8kPath + fileName),new File(image4kPath + fileName), 0.5f);
+                        if(!exists512){
+                            ImgUtil.scale(new File(image8kPath + fileName),new File(image512Path + fileName), 0.0625f);
+                        }
+                    }
+                }
+                if("11".equals(fileType)){//mesh.obj
+                    HttpUtilExt.downloadFileAndCheck(fileUrl, meshPath + fileName, 300000);
+                }
+                if("5".equals(fileType)){//floorplan.json
+                    HttpUtilExt.downloadFileAndCheck(fileUrl, dataPath + fileName, 3000);
+                }
+                if("12".equals(fileType)){//scene.json
+                    HttpUtilExt.downloadFileAndCheck(fileUrl, dataPath + fileName, 3000);
+                }
+            });
+
+            Map<String, String> uploadFileMap = convertUtil.convert(dataSource, entityId);
+            String finalRoomId = entityId;
+            uploadFileMap.keySet().parallelStream().forEach(key->{
                 SceneFileMapping sceneFileMapping = sceneFileMappingService.getByNumAndKey(finalRoomId, key);
                 if(Objects.isNull(sceneFileMapping)){
                     sceneFileMapping = new SceneFileMapping();
@@ -91,12 +220,35 @@ public class ConvertListener{
                 sceneFileMappingService.saveOrUpdate(sceneFileMapping);
             });
 
+            sceneConvertLog.setStatus("1");
+
         }catch (Exception e){
-            log.error("convert fail, roomId:{}", roomId, e);
+            log.error("convert fail, stationCode:{}, roomId:{}", stationCode, entityId, e);
+            sceneConvertLog.setStatus("0");
+            sceneConvertLog.setRemark(ExceptionUtil.stacktraceToString(e, 4000));
+        }
+
+        if(dataSource != null){
+            FileUtil.del(dataSource);
+            FileUtil.del(dataSource.substring(0, dataSource.lastIndexOf("/")) + "_obj2txt");
         }
 
+        sceneConvertLog.setTimeConsuming(String.valueOf(timeInterval.intervalSecond()));
+        sceneConvertLogService.save(sceneConvertLog);
+
         channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+    }
 
+//    public boolean checkNead8kPic(JSONArray array){
+//        array.stream().findFirst().stream().anyMatch()
+//
+//
+//
+//    }
 
+    public static void main(String[] args) {
+        String dataSource = "110106908000001067_001102050200000038732428/";
+        System.out.println(dataSource.substring(0, dataSource.lastIndexOf("/") -1) + "_obj2txt");
     }
+
 }

+ 16 - 0
src/main/java/com/fdkankan/modeldemo/service/SceneConvertLogService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.modeldemo.service;
+
+import com.fdkankan.modeldemo.entity.SceneConvertLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-07-02
+ */
+public interface SceneConvertLogService extends IService<SceneConvertLog> {
+
+}

+ 20 - 0
src/main/java/com/fdkankan/modeldemo/service/impl/SceneConvertLogServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.modeldemo.service.impl;
+
+import com.fdkankan.modeldemo.entity.SceneConvertLog;
+import com.fdkankan.modeldemo.mapper.SceneConvertLogMapper;
+import com.fdkankan.modeldemo.service.SceneConvertLogService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author dsx
+ * @since 2024-07-02
+ */
+@Service
+public class SceneConvertLogServiceImpl extends ServiceImpl<SceneConvertLogMapper, SceneConvertLog> implements SceneConvertLogService {
+
+}

+ 8 - 4
src/main/java/com/fdkankan/modeldemo/utils/ConvertUtil.java

@@ -1,6 +1,7 @@
 package com.fdkankan.modeldemo.utils;
 
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.StrUtil;
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
@@ -101,7 +102,7 @@ public class ConvertUtil {
 
         //压缩成dam
         String damKey = imgViewPath + "tieta.dam";
-        String damPath = obj2TxtPath + File.separator + "results" +File.separator + "tieta.dam";
+        String damPath = obj2TxtPath + File.separator + "results" +File.separator + "dam.txt";
         CreateObjUtil.convertTxtToDam( obj2TxtPath + File.separator + "results" +File.separator+"modeldata.txt", damPath);
         map.put(damKey, damPath);
 
@@ -145,8 +146,8 @@ public class ConvertUtil {
 //            FileUtil.copy(sourcePath + "images/vision.txt", targetImagePath + "/vision.txt", true);
 
         //生成vison.modeldata
-        CreateObjUtil.convertTxtToVisionmodeldata(sourcePath + "images/vision.txt", sourcePath + "images/vision.modeldata");
-        map.put(imgViewPath + "vision.modeldata", sourcePath + "images/vision.modeldata");
+        CreateObjUtil.convertTxtToVisionmodeldata(sourcePath + "images/vision.txt", sourcePath + "images/visionmodeldata.txt");
+        map.put(imgViewPath + "vision.modeldata", sourcePath + "images/visionmodeldata.txt");
 
         //生成场景标题
         String title = this.getTitle(num, sourcePath);
@@ -196,7 +197,10 @@ public class ConvertUtil {
         String sceneJsonStr = FileUtil.readUtf8String(sceneJsonPath);
         JSONObject jsonObject = JSON.parseObject(sceneJsonStr);
         String title = jsonObject.getString("title");
-        return Objects.isNull(title) ? roomId : title;
+        if(StrUtil.isEmpty(title)){
+            return roomId;
+        }
+        return title;
     }
 
     public static void writeDataJson(String path){

+ 45 - 14
src/main/java/com/fdkankan/modeldemo/utils/CreateObjUtil.java

@@ -29,22 +29,34 @@ public class CreateObjUtil {
 //		System.out.println("输入目标文件路径:");
 //		String targetPath = scanner.next();
 
-		String type = args[0];//类型(1-vision.txt转为vision.modeldata, 2-modeldata.txt转为tieta.dam)
-		String srcPath = args[1];//源文件目录(需要提前源文件放到此目录中再调用方法)
-		String targetPath = args[2];//目标文件路径(目录,转换后文件会放到此目录中,文件名固定为vision.modeldata或tieta.dam)
-
-		if(type.equals("1")){
-			String srcFileName = "vision.txt";
-			String targetFileName = "vision.modeldata";
-			CreateObjUtil.convertTxtToVisionmodeldata(srcPath.concat(File.separator).concat(srcFileName),targetPath.concat(File.separator).concat(targetFileName));
-		}
-		if(type.equals("2")){
-			String srcFileName = "modeldata.txt";
-			String targetFileName = "tieta.dam";
-			CreateObjUtil.convertTxtToDam(srcPath.concat(File.separator).concat(srcFileName),targetPath.concat(File.separator).concat(targetFileName));
-		}
+//		String type = args[0];//类型(1-vision.txt转为vision.modeldata, 2-modeldata.txt转为tieta.dam)
+//		String srcPath = args[1];//源文件目录(需要提前源文件放到此目录中再调用方法)
+//		String targetPath = args[2];//目标文件路径(目录,转换后文件会放到此目录中,文件名固定为vision.modeldata或tieta.dam)
+//
+//		if(type.equals("1")){
+//			String srcFileName = "vision.txt";
+//			String targetFileName = "vision.modeldata";
+//			CreateObjUtil.convertTxtToVisionmodeldata(srcPath.concat(File.separator).concat(srcFileName),targetPath.concat(File.separator).concat(targetFileName));
+//		}
+//		if(type.equals("2")){
+//			String srcFileName = "modeldata.txt";
+//			String targetFileName = "tieta.dam";
+//			CreateObjUtil.convertTxtToDam(srcPath.concat(File.separator).concat(srcFileName),targetPath.concat(File.separator).concat(targetFileName));
+//		}
 
 //		scanner.close();
+
+//		String srcFileName1 = "D:\\test\\tieta\\110106908000001067_001102050200000038732428\\modeldata.txt";
+//		String srcFileName2 = "D:\\test\\tieta\\110115908000001104_000102050000000000079651\\modeldata.txt";
+//		String srcFileName3 = "D:\\test\\tieta\\111401500010001724_500102050000000000285799\\modeldata.txt";
+//		String targetFileName1 = "D:\\test\\tieta\\110106908000001067_001102050200000038732428\\tieta.dam";
+//		String targetFileName2 = "D:\\test\\tieta\\110115908000001104_000102050000000000079651\\tieta.dam";
+//		String targetFileName3 = "D:\\test\\tieta\\111401500010001724_500102050000000000285799\\tieta.dam";
+//		CreateObjUtil.convertTxtToDam(srcFileName1,targetFileName1);
+//		CreateObjUtil.convertTxtToDam(srcFileName2,targetFileName2);
+//		CreateObjUtil.convertTxtToDam(srcFileName3,targetFileName3);
+
+		CreateObjUtil.convertTxtToVisionmodeldata("C:\\Users\\dsx\\Desktop\\vsion.txt", "C:\\Users\\dsx\\Desktop\\vsion.modeldata");
 	}
 
 	/**
@@ -164,6 +176,25 @@ public class CreateObjUtil {
 				visiblesArr[i] = uuidIndexMap.get(visibles.get(i));
 			}
 			sweepLocationObj.put("visibles", visiblesArr);
+
+			if(sweepLocationObj.containsKey("visibles2")){
+				JSONArray visibles2 =  sweepLocationObj.getJSONArray("visibles2");
+				int[] visiblesArr2 = new int[visibles2.size()];
+				for(int i = 0; i < visibles2.size(); i++){
+					visiblesArr2[i] = uuidIndexMap.get(visibles2.get(i));
+				}
+				sweepLocationObj.put("visibles2", visiblesArr2);
+			}
+
+			if(sweepLocationObj.containsKey("visibles3")){
+				JSONArray visibles3 =  sweepLocationObj.getJSONArray("visibles3");
+				int[] visiblesArr3 = new int[visibles3.size()];
+				for(int i = 0; i < visibles3.size(); i++){
+					visiblesArr3[i] = uuidIndexMap.get(visibles3.get(i));
+				}
+				sweepLocationObj.put("visibles3", visiblesArr3);
+			}
+
 		}
 		return JSON.toJSONString(visionJson);
 	}

+ 3 - 0
src/main/java/com/fdkankan/modeldemo/utils/FdfsUtil.java

@@ -5,6 +5,7 @@ import cn.hutool.http.HttpRequest;
 import cn.hutool.http.HttpResponse;
 import com.alibaba.fastjson.JSON;
 import com.fdkankan.modeldemo.bean.TietaResBean;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Component;
 
@@ -14,6 +15,7 @@ import java.util.HashMap;
 import java.util.Map;
 
 @Component
+@Slf4j
 public class FdfsUtil {
 
     @Value("${fdfs.address}")
@@ -60,6 +62,7 @@ public class FdfsUtil {
         HttpRequest httpRequest = HttpRequest.post(address.concat(api_uploadFile)).form(test).addHeaders(headers).timeout(60000);
         HttpResponse res = httpRequest.execute();
         String resBody = res.body();
+        log.info("upload file response : {}", resBody);
         res.close();
         TietaResBean<Map<String, String>> tietaResBean = JSON.parseObject(resBody, TietaResBean.class);
         String code = tietaResBean.getCode();

+ 25 - 0
src/main/java/com/fdkankan/modeldemo/utils/HttpUtilExt.java

@@ -0,0 +1,25 @@
+package com.fdkankan.modeldemo.utils;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.http.HttpUtil;
+import lombok.extern.slf4j.Slf4j;
+import net.sf.jsqlparser.statement.create.table.Index;
+
+import java.io.File;
+
+@Slf4j
+public class HttpUtilExt extends HttpUtil {
+
+    public static void downloadFileAndCheck(String url, String localPath, int timeout){
+        int times = 0;
+        do {
+            downloadFile(url, new File(localPath), timeout);
+            if(FileUtil.exist(localPath) && FileUtil.size(new File(localPath)) > 0){
+                return;
+            }
+            times++;
+        }while (times < 5);
+        throw new RuntimeException("文件下载失败,url=" + url + ",localPath=" + localPath);
+    }
+
+}

+ 40 - 0
src/main/java/com/fdkankan/rabbitmq/callback/ProducerCallback.java

@@ -0,0 +1,40 @@
+package com.fdkankan.rabbitmq.callback;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.connection.CorrelationData;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/19
+ **/
+@Slf4j
+@Component
+public class ProducerCallback implements RabbitTemplate.ConfirmCallback,RabbitTemplate.ReturnCallback {
+
+    //confirms模式:无论exchange投递消息是成功或是失败,都会返回ack,我们可以根据返回的ack是成功还是失败,做相应的业务处理
+    @Override
+    public void confirm(CorrelationData correlationData, boolean ack, String cause) {
+        String messageId = correlationData.getId();
+        //投递成功
+        if(ack){
+            log.info("消息投递成功,id:{}", messageId);
+            return;
+        }
+        //投递失败
+        log.error("消息投递失败,id:{},失败原因:{}", messageId, cause);
+    }
+
+    //return模式:只有exchange投递消息失败时,才会执行回调函数,来做一些相应的业务处理
+    @Override
+    public void returnedMessage(Message returnedMessage, int replyCode, String replyText, String exchange, String routingKey) {
+        log.info("消息从Exchange路由到Queue失败: exchange: {}, route: {}, replyCode: {}, replyText: {}, message: {}", exchange, routingKey, replyCode, replyText, returnedMessage);
+
+    }
+}

+ 119 - 0
src/main/java/com/fdkankan/rabbitmq/config/RabbitMqConfig.java

@@ -0,0 +1,119 @@
+package com.fdkankan.rabbitmq.config;
+
+import com.fdkankan.rabbitmq.callback.ProducerCallback;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.rabbit.connection.ConnectionFactory;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.annotation.Resource;
+
+@Configuration
+@Slf4j
+public class RabbitMqConfig {
+
+//    @Resource
+//    private QueueConfig queueConfig;
+//    @Resource
+//    private ExchangeConfig exchangeConfig;
+    /**
+     * 连接工厂
+     */
+    @Resource
+    private ConnectionFactory connectionFactory;
+
+    @Resource
+    private ProducerCallback producerCallback;
+
+    /**
+     * 指定序列化转换器,否则mq消息存进去
+     * @return
+     */
+    @Bean
+    public Jackson2JsonMessageConverter messageConverter(){
+        return new Jackson2JsonMessageConverter();
+    }
+
+
+    /**
+     * 将消息队列和交换机进行绑定,指定路由
+     */
+//    @Bean
+//    public Binding bindingDirect() {
+//        return BindingBuilder.bind(queueConfig.easyQueue()).to(exchangeConfig.directExchange()).with(RabbitMQConstant.ROUTING_KEY_EASY);
+//    }
+//
+//    @Bean
+//    public Binding bindingWork() {
+//        return BindingBuilder.bind(queueConfig.workQueue()).to(exchangeConfig.workExchange()).with(RabbitMQConstant.ROUTING_KEY_WORK);
+//    }
+//
+//    @Bean
+//    public Binding bindingTopic() {
+//        return BindingBuilder.bind(queueConfig.topicQueue()).to(exchangeConfig.topicExchange()).with(RabbitMQConstant.ROUTING_KEY_TOPIC_FIRST);
+//    }
+//
+//    @Bean
+//    public Binding bindingTopicSecond() {
+//        return BindingBuilder.bind(queueConfig.topicQueueSecond()).to(exchangeConfig.topicExchange()).with(RabbitMQConstant.ROUTING_KEY_TOPIC_SECOND);
+//    }
+//
+//    @Bean
+//    public Binding bindingFanout() {
+//        return BindingBuilder.bind(queueConfig.fanoutQueue()).to(exchangeConfig.fanoutExchange());
+//    }
+//
+//    @Bean
+//    public Binding bindingFanoutSecond() {
+//        return BindingBuilder.bind(queueConfig.fanoutQueueSecond()).to(exchangeConfig.fanoutExchange());
+//    }
+
+    /** ======================== 定制一些处理策略 =============================*/
+
+    /**
+     * 定制化amqp模版
+     * <p>
+     * Rabbit MQ的消息确认有两种。
+     * <p>
+     * 一种是消息发送确认:这种是用来确认生产者将消息发送给交换机,交换机传递给队列过程中,消息是否成功投递。
+     * 发送确认分两步:一是确认是否到达交换机,二是确认是否到达队列
+     * <p>
+     * 第二种是消费接收确认:这种是确认消费者是否成功消费了队列中的消息。
+     */
+    @Bean
+    public RabbitTemplate rabbitTemplate(Jackson2JsonMessageConverter messageConverter) {
+        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
+
+        rabbitTemplate.setMessageConverter(messageConverter);
+
+        // 消息发送失败返回到队列中, yml需要配置 publisher-returns: true
+//        rabbitTemplate.setMandatory(true);
+
+        /**
+         * 使用该功能需要开启消息确认,yml需要配置 publisher-confirm-type: correlated:表示消息成功到达Broker后触发ConfirmCalllBack回调
+         * 通过实现ConfirmCallBack接口,用于实现消息发送到交换机Exchange后接收ack回调
+         * correlationData  消息唯一标志
+         * ack              确认结果
+         *
+         * cause            失败原因
+         */
+        rabbitTemplate.setConfirmCallback(producerCallback);
+
+        /**
+         * 使用该功能需要开启消息返回确认,yml需要配置 publisher-returns: true
+         * 通过实现ReturnCallback接口,如果消息从交换机发送到对应队列失败时触发
+         * message    消息主体 message
+         * replyCode  消息主体 message
+         * replyText  描述
+         * exchange   消息使用的交换机
+         * routingKey 消息使用的路由键
+         */
+//        rabbitTemplate.setReturnCallback(new ProducerCallback());
+
+
+        return rabbitTemplate;
+    }
+
+}

+ 112 - 0
src/main/java/com/fdkankan/rabbitmq/util/RabbitMqProducer.java

@@ -0,0 +1,112 @@
+package com.fdkankan.rabbitmq.util;
+
+import cn.hutool.json.JSONObject;
+import com.rabbitmq.client.AMQP.Queue.DeclareOk;
+import com.rabbitmq.client.Channel;
+import lombok.Data;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.amqp.rabbit.connection.CorrelationData;
+import org.springframework.amqp.rabbit.core.ChannelCallback;
+import org.springframework.amqp.rabbit.core.RabbitTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.UUID;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/19
+ **/
+@Component
+@Data
+public class RabbitMqProducer {
+
+    private Logger log = LoggerFactory.getLogger(this.getClass().getName());
+
+//    @Autowired
+//    ModelingQueueConfig modelingQueueConfig;
+
+    @Autowired
+    private RabbitTemplate rabbitTemplate;
+
+    /**
+     * 工作队列模式发送消息
+     * @param queue 队列名
+     * @param content 载荷
+     */
+    public void sendByWorkQueue(String queue, Object content){
+        String messageId = UUID.randomUUID().toString();
+        log.info("开始发送Mq消息,messageId:{},消息队列:{},消息内容:{}",messageId, queue, new JSONObject(content).toString());
+        rabbitTemplate.convertAndSend(queue, content, message -> {
+            message.getMessageProperties().setMessageId(messageId);
+            return message;
+        }, new CorrelationData(messageId));
+    }
+    /**
+     * 工作队列模式发送消息
+     * @param exchange 交换机
+     * @param queue 队列名
+     * @param content 载荷
+     */
+    public void sendByWorkQueue(String exchange,String queue, Object content){
+        String messageId = UUID.randomUUID().toString();
+        log.info("开始发送Mq消息,messageId:{},消息队列:{},消息内容:{}",messageId, queue, new JSONObject(content).toString());
+        rabbitTemplate.convertAndSend(exchange,queue, content, message -> {
+            message.getMessageProperties().setMessageId(messageId);
+            return message;
+        }, new CorrelationData(messageId));
+    }
+    /**
+     * 工作队列模式发送带优先级消息
+     * @param queue 队列名
+     * @param content 载荷
+     * @param priority 优先级,正整数,值越大优先级越高,当值大于队列设置的最大优先级时,效果等同于最大优先级
+     */
+    public void sendByWorkQueue(String queue, Object content, Integer priority){
+        String messageId = UUID.randomUUID().toString();
+        log.info("开始发送Mq消息,messageId:{},消息队列:{},消息内容:{}",messageId, queue, new JSONObject(content).toString());
+        rabbitTemplate.convertAndSend(queue, content, message -> {
+            message.getMessageProperties().setMessageId(messageId);
+            message.getMessageProperties().setPriority(priority);
+            return message;
+        }, new CorrelationData(messageId));
+    }
+
+    /**
+     * 获取队列未被消费的消息数量
+     * @return
+     */
+    public int getMessageCount(String queueName) {
+        DeclareOk declareOk = rabbitTemplate.execute(new ChannelCallback<DeclareOk>() {
+            public DeclareOk doInRabbit(Channel channel) throws Exception {
+                return channel.queueDeclarePassive(queueName);
+            }
+        });
+
+        return declareOk.getMessageCount();
+    }
+
+    /**
+     * 工作队列模式发送消息到多个队列
+     * @param queue 队列名
+     * @param content 载荷
+     */
+    public void sendByWorkToQueues(Object content, String... queues){
+        for (String queue : queues) {
+            String messageId = UUID.randomUUID().toString();
+            log.info("开始发送Mq消息,messageId:{},消息队列:{},消息内容:{}",messageId, queue, new JSONObject(content).toString());
+            rabbitTemplate.convertAndSend(queue, content, message -> {
+                message.getMessageProperties().setMessageId(messageId);
+                return message;
+            }, new CorrelationData(messageId));
+        }
+    }
+
+
+
+}

+ 2 - 1
src/main/resources/application-test.yml

@@ -27,7 +27,8 @@ fdfs:
   api:
     getSignature: /ChinatowerFileService/getSignature
     uploadFile: /ChinatowerFileService/uploadFile/
-
+server:
+  port: 8081
 
 
 

+ 1 - 1
src/main/resources/logback-spring.xml

@@ -7,7 +7,7 @@
 
 	<contextName>logback</contextName>
 	<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->
-	<property name="log.path" value="/mnt/backend/4dkankan/convert/logs" />
+	<property name="log.path" value="/mnt/docker/4dkankan/model/logs" />
 
 	<!-- 彩色日志 -->
 	<!-- 彩色日志依赖的渲染类 -->

+ 22 - 0
src/main/resources/mapper/SceneConvertLogMapper.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fdkankan.modeldemo.mapper.SceneConvertLogMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.fdkankan.modeldemo.entity.SceneConvertLog">
+        <id column="ID" property="id" />
+        <result column="STATION_CODE" property="stationCode" />
+        <result column="ENTITY_ID" property="entityId" />
+        <result column="STATUS" property="status" />
+        <result column="CREATE_TIME" property="createTime" />
+        <result column="REMARK" property="remark" />
+        <result column="TIME_CONSUMING" property="timeConsuming" />
+
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        ID, STATION_CODE, ENTITY_ID, STATUS, CRAETE_TIME, REMARK
+    </sql>
+
+</mapper>