Kaynağa Gözat

v4.3.0代码同步

dengsixing 2 yıl önce
ebeveyn
işleme
ddf7194329

+ 6 - 0
pom.xml

@@ -87,6 +87,12 @@
         </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-test</artifactId>
             <scope>test</scope>

+ 18 - 2
src/main/java/com/fdkankan/scene/controller/SceneEditController.java

@@ -3,6 +3,7 @@ package com.fdkankan.scene.controller;
 import com.fdkankan.common.constant.ErrorCode;
 import com.fdkankan.common.constant.SceneInfoReqType;
 import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.scene.service.IDownloadTourVideoService;
 import com.fdkankan.web.response.ResultData;
 import com.fdkankan.scene.annotation.CheckPermit;
 import com.fdkankan.scene.service.ISceneEditInfoService;
@@ -57,6 +58,9 @@ import org.springframework.web.multipart.MultipartFile;
 @RequestMapping("/service/scene/edit")
 public class SceneEditController extends BaseController {
 
+    @Value("${spring.profiles.active}")
+    private String env;
+
     @Autowired
     private ISceneProService sceneProService;
     @Autowired
@@ -65,8 +69,9 @@ public class SceneEditController extends BaseController {
     private ISceneUploadService sceneUploadService;
     @Autowired
     private ISceneEditService sceneEditService;
-    @Value("${spring.profiles.active}")
-    private String env;
+    @Autowired
+    private IDownloadTourVideoService downloadTourVideoService;
+
 
     /**
      * <p>
@@ -645,6 +650,17 @@ public class SceneEditController extends BaseController {
         return sceneEditService.deleteTour(param);
     }
 
+    @PostMapping(value = "/tour/video/upload")
+    public ResultData uploadTourVideo(@RequestParam("num") String num, @RequestParam("file") MultipartFile file) throws Exception {
+        downloadTourVideoService.uploadTourVideo(num, file);
+        return null;
+    }
+
+    @PostMapping(value = "/tour/video/download")
+    public ResultData downloadTourVideo(@RequestParam("num") String num) throws Exception {
+        return downloadTourVideoService.downloadTourVideo(num);
+    }
+
     /**
      * <p>
      添加马赛克

+ 87 - 0
src/main/java/com/fdkankan/scene/entity/DownloadTourVideo.java

@@ -0,0 +1,87 @@
+package com.fdkankan.scene.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.util.Date;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 导览视频转换记录表
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+@Getter
+@Setter
+@TableName("t_download_tour_video")
+public class DownloadTourVideo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 场景码
+     */
+    @TableField("num")
+    private String num;
+
+    /**
+     * 视频转换状态(0-等待中,1-成功,2-失败)
+     */
+    @TableField("state")
+    private Integer state;
+
+    /**
+     * 转换失败原因
+     */
+    @TableField("reason")
+    private String reason;
+
+    /**
+     * 文件名称
+     */
+    @TableField("file_name")
+    private String fileName;
+
+    /**
+     * 本地临时文件地址
+     */
+    @TableField("local_path")
+    private String localPath;
+
+    /**
+     * 导览视频目录地址
+     */
+    @TableField("download_path")
+    private String downloadPath;
+
+    /**
+     * 创建时间
+     */
+    @TableField("create_time")
+    private Date createTime;
+
+    /**
+     * 修改时间
+     */
+    @TableField("update_time")
+    private Date updateTime;
+
+    /**
+     * A-有效,I-无效
+     */
+    @TableField("rec_status")
+    @TableLogic(value = "A", delval = "I")
+    private String recStatus;
+
+
+}

+ 58 - 131
src/main/java/com/fdkankan/scene/listener/RabbitMqListener.java

@@ -1,131 +1,58 @@
-package com.fdkankan.scene.listener;//package com.fdkankan.scene.listener;
-//
-//import com.alibaba.fastjson.JSONObject;
-//import com.fdkankan.rabbitmq.bean.BuildSceneCallMessage;
-//import com.fdkankan.rabbitmq.bean.BuildSceneFailDTMqMessage;
-//import com.fdkankan.rabbitmq.bean.BuildSceneResultMqMessage;
-//import com.fdkankan.scene.service.IBuildSceneDTService;
-//import com.fdkankan.scene.service.IBuildScenePostService;
-//import com.fdkankan.scene.service.IBuildScenePreService;
-//import com.fdkankan.scene.service.impl.BuildSceneDTServiceImpl;
-//import com.rabbitmq.client.Channel;
-//import java.nio.charset.StandardCharsets;
-//import lombok.extern.slf4j.Slf4j;
-//import org.springframework.amqp.core.Message;
-//import org.springframework.amqp.rabbit.annotation.Queue;
-//import org.springframework.amqp.rabbit.annotation.RabbitListener;
-//import org.springframework.beans.factory.annotation.Autowired;
-//import org.springframework.beans.factory.annotation.Value;
-//import org.springframework.stereotype.Component;
-//
-///**
-// * <p>
-// * TODO
-// * </p>
-// *
-// * @author dengsixing
-// * @since 2022/4/19
-// **/
-//@Slf4j
-//@Component
-//public class RabbitMqListener {
-//    @Value("${queue.modeling.modeling-pre}")
-//    private String queueModelingPre;
-//    @Value("${queue.modeling.modeling-post}")
-//    private String queueModelingPost;
-//    @Value("${queue.modeling.modeling-dt}")
-//    private String queueModelingDt;
-//
-//    @Autowired
-//    IBuildScenePreService buildScenePreService;
-//    @Autowired
-//    IBuildScenePostService buildScenePostService;
-//    @Autowired
-//    IBuildSceneDTService buildSceneDTService;
-//
-//
-//
-//    /**
-//     * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
-//     * queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),  如果队列不不存在会自动创建队列
-//     * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
-//     */
-////    @RabbitListener(
-////        queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),
-////        concurrency = "1"
-////    )
-////    public void receiveMessageDsx(Channel channel, Message message) throws Exception {
-////        channel.queueDeclare();
-////        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-////        log.info("开始消费消息-" + msg + "-" + Thread.currentThread().getId());
-////        Thread.sleep(5000L);
-////        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-////        log.info("结束消息-" + Thread.currentThread().getId());
-////    }
-//
-//
-//    /**
-//     * 场景计算前置资源准备处理
-//     * @param channel
-//     * @param message
-//     * @throws Exception
-//     */
-//    @RabbitListener(
-//        queuesToDeclare = @Queue("${queue.modeling.modeling-pre}"),
-//        concurrency = "${maxThread.modeling.modeling-pre}"
-//    )
-//    public void buildScenePreHandler(Channel channel, Message message) throws Exception {
-//        Object correlation = message.getMessageProperties().getHeader("spring_returned_message_correlation");
-//        String correlationId = (String) correlation;
-//        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-//        log.info("场景计算资源准备开始,队列名:{},id:{},消息体:{}", queueModelingPre, correlationId, msg);
-//        BuildSceneCallMessage buildSceneMessage = JSONObject.parseObject(msg, BuildSceneCallMessage.class);
-//        Thread.sleep(2000L);
-//        buildScenePreService.buildScenePre(buildSceneMessage);
-//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-//    }
-//
-//    /**
-//     * 场景计算后置结果处理
-//     * @param channel
-//     * @param message
-//     * @throws Exception
-//     */
-//    @RabbitListener(
-//        queuesToDeclare = @Queue("${queue.modeling.modeling-post}"),
-//        concurrency = "${maxThread.modeling.modeling-post}"
-//    )
-//    public void buildScenePostHandler(Channel channel, Message message) throws Exception {
-//        Object correlation = message.getMessageProperties().getHeader("spring_returned_message_correlation");
-//        String correlationId = (String) correlation;
-//        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-//        log.info("场景计算结果处理开始,队列名:{},id:{},消息体:{}", queueModelingPost, correlationId, msg);
-//        BuildSceneResultMqMessage resultMessage = JSONObject.parseObject(msg, BuildSceneResultMqMessage.class);
-//        Thread.sleep(2000L);
-//        buildScenePostService.buildScenePost(resultMessage);
-//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-//    }
-//
-//    /**
-//     * 场景计算发送钉钉消息
-//     * @param channel
-//     * @param message
-//     * @throws Exception
-//     */
-//    @RabbitListener(
-//        queuesToDeclare = @Queue("${queue.modeling.modeling-dt}"),
-//        concurrency = "${maxThread.modeling.modeling-dt}"
-//    )
-//    public void buildSceneDTHandler(Channel channel, Message message) throws Exception {
-//        Object correlation = message.getMessageProperties().getHeader("spring_returned_message_correlation");
-//        String correlationId = (String) correlation;
-//        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
-//        log.info("发送钉钉消息处理,队列名:{},id:{},消息体:{}", queueModelingDt, correlationId, msg);
-//        BuildSceneFailDTMqMessage dtMessage = JSONObject.parseObject(msg, BuildSceneFailDTMqMessage.class);
-//        buildSceneDTService.handFail(dtMessage.getReason(), dtMessage.getServerPath(),
-//            dtMessage.getNum(), dtMessage.getHostName(), BuildSceneDTServiceImpl.contentExt);
-//        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
-//    }
-//
-//
-//}
+package com.fdkankan.scene.listener;
+
+import com.alibaba.fastjson.JSON;
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import com.fdkankan.scene.service.IDownloadTourVideoService;
+import com.rabbitmq.client.Channel;
+import java.nio.charset.StandardCharsets;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.amqp.core.Message;
+import org.springframework.amqp.rabbit.annotation.Queue;
+import org.springframework.amqp.rabbit.annotation.RabbitListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/4/19
+ **/
+@Slf4j
+@Component
+public class RabbitMqListener {
+
+    @Value("${queue.scene.transfer-tour-video}")
+    private String downloadTourVideoQueue;
+
+    @Autowired
+    private IDownloadTourVideoService downloadTourVideoService;
+
+
+
+
+    /**
+     * 开启了手动确认模式,如果没有手动确认,消费者不会重试,当服务重启时会再次消费,因为rabbitmq认为你还没有处理完你的业务
+     * queuesToDeclare = @Queue("${queue.modeling.modeling-test}"),  如果队列不不存在会自动创建队列
+     * concurrency = "3"    设置消费线程数,每个线程每次只拉取一条消息消费
+     */
+    @RabbitListener(
+        queuesToDeclare = @Queue("${queue.scene.transfer-tour-video}")
+    )
+    public void transferTourVideo(Channel channel, Message message) throws Exception {
+        String correlation = (String)message.getMessageProperties().getHeader("spring_returned_message_correlation");
+        String msg = new String(message.getBody(), StandardCharsets.UTF_8);
+        log.info("开始消费消息,id:{},queue:{},content:{}", correlation, downloadTourVideoQueue, msg);
+        DownloadTourVideo downloadTourVideo = JSON.parseObject(msg, DownloadTourVideo.class);
+        downloadTourVideoService.transferTourVideo(downloadTourVideo);
+        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
+        log.info("结束消费消息,id:{}", correlation);
+    }
+
+
+
+
+}

+ 18 - 0
src/main/java/com/fdkankan/scene/mapper/IDownloadTourVideoMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.scene.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 导览视频转换记录表 Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+@Mapper
+public interface IDownloadTourVideoMapper extends BaseMapper<DownloadTourVideo> {
+
+}

+ 28 - 0
src/main/java/com/fdkankan/scene/service/IDownloadTourVideoService.java

@@ -0,0 +1,28 @@
+package com.fdkankan.scene.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import com.fdkankan.web.response.ResultData;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * <p>
+ * 导览视频转换记录表 服务类
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+public interface IDownloadTourVideoService extends IService<DownloadTourVideo> {
+
+    DownloadTourVideo getWaitingByNum(String num);
+
+    void removeByNum(String num);
+
+    ResultData uploadTourVideo(String num, MultipartFile file) throws Exception;
+
+    void transferTourVideo(DownloadTourVideo downloadTourVideo);
+
+    ResultData downloadTourVideo(String num);
+
+}

+ 145 - 0
src/main/java/com/fdkankan/scene/service/impl/DownloadTourVideoServiceImpl.java

@@ -0,0 +1,145 @@
+package com.fdkankan.scene.service.impl;
+
+import cn.hutool.core.exceptions.ExceptionUtil;
+import cn.hutool.core.lang.UUID;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.common.constant.ErrorCode;
+import com.fdkankan.common.exception.BusinessException;
+import com.fdkankan.fyun.face.FYunFileServiceInterface;
+import com.fdkankan.model.constants.ConstantFilePath;
+import com.fdkankan.model.constants.UploadFilePath;
+import com.fdkankan.model.utils.CreateObjUtil;
+import com.fdkankan.rabbitmq.util.RabbitMqProducer;
+import com.fdkankan.scene.entity.DownloadTourVideo;
+import com.fdkankan.scene.mapper.IDownloadTourVideoMapper;
+import com.fdkankan.scene.service.IDownloadTourVideoService;
+import com.fdkankan.scene.vo.DownloadTourVideoVO;
+import com.fdkankan.web.response.ResultData;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+import lombok.SneakyThrows;
+import org.apache.http.HttpHeaders;
+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;
+
+/**
+ * <p>
+ * 导览视频转换记录表 服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2022-10-12
+ */
+@Service
+public class DownloadTourVideoServiceImpl extends ServiceImpl<IDownloadTourVideoMapper, DownloadTourVideo> implements IDownloadTourVideoService {
+
+    @Value("${queue.scene.transfer-tour-video}")
+    private String downloadTourVideoQueue;
+    @Value("${upload.type}")
+    private String type;
+    @Value("${fyun.bucket:4dkankan}")
+    private String bucket;
+
+    @Autowired
+    private RabbitMqProducer rabbitMqProducer;
+    @Autowired
+    private FYunFileServiceInterface fYunFileService;
+
+
+    @Override
+    public DownloadTourVideo getWaitingByNum(String num) {
+        return this.getOne(
+            new LambdaQueryWrapper<DownloadTourVideo>().eq(DownloadTourVideo::getNum, num)
+                .eq(DownloadTourVideo::getState, 0));
+    }
+
+    @Override
+    public void removeByNum(String num) {
+        this.remove(new LambdaQueryWrapper<DownloadTourVideo>().eq(DownloadTourVideo::getNum, num));
+    }
+
+    @Override
+    public ResultData uploadTourVideo(String num, MultipartFile file) throws Exception {
+
+        //查询是否有任务正在执行,如果有,直接返回
+        DownloadTourVideo waiting = this.getWaitingByNum(num);
+        if(Objects.nonNull(waiting)){
+            throw new BusinessException(ErrorCode.FAILURE_CODE_5064);
+        }
+
+        String uuid = UUID.randomUUID().toString();
+        String fileName = file.getOriginalFilename();
+        String extName = cn.hutool.core.io.FileUtil.extName(fileName);
+        String tempFileName = uuid + "." + extName;
+        String srcPath = ConstantFilePath.SCENE_V4_PATH + num + "/tour/" + tempFileName;
+        File tempFile = new File(srcPath);
+        if(!tempFile.getParentFile().exists()){
+            tempFile.getParentFile().mkdirs();
+        }
+        file.transferTo(tempFile);
+
+        //先将旧纪录置为无效
+        this.removeByNum(num);
+
+        //写入新记录
+        DownloadTourVideo downloadTourVideo = new DownloadTourVideo();
+        downloadTourVideo.setNum(num);
+        downloadTourVideo.setFileName(fileName);
+        downloadTourVideo.setLocalPath(srcPath);
+        this.save(downloadTourVideo);
+
+        //发送mq
+        rabbitMqProducer.sendByWorkQueue(downloadTourVideoQueue, downloadTourVideo);
+
+        return ResultData.ok();
+    }
+
+    @Override
+    public void transferTourVideo(DownloadTourVideo downloadTourVideo) {
+
+        String destPath = null;
+        try {
+            String destFileName = UUID.randomUUID().toString() + ".mp4";
+            destPath = ConstantFilePath.SCENE_V4_PATH + downloadTourVideo.getNum() + "tour/" + destFileName;
+            File destFile = new File(destPath);
+            if(!destFile.getParentFile().exists()){
+                destFile.getParentFile().mkdir();
+            }
+            String srcPath = downloadTourVideo.getLocalPath();
+            CreateObjUtil.formatMp4(srcPath, destPath);
+            //上传到oss
+            String ossPath = String.format(UploadFilePath.DOWNLOADS_TOUR_VIDEO, downloadTourVideo.getNum()) + downloadTourVideo.getFileName();
+            Map<String, String> headers = new HashMap<>();
+            headers.put(HttpHeaders.CONTENT_TYPE, "application/octet-stream");
+            fYunFileService.uploadFile(bucket, destPath, ossPath, headers);
+            downloadTourVideo.setDownloadPath(ossPath);
+            downloadTourVideo.setState(1);
+            this.updateById(downloadTourVideo);
+        }catch (Exception e) {
+            log.error("导览视频转换失败,num:" + downloadTourVideo.getNum() + "源路径:" + downloadTourVideo.getLocalPath(), e);
+            downloadTourVideo.setReason(ExceptionUtil.stacktraceToString(e, 3000));
+            downloadTourVideo.setState(2);
+            this.updateById(downloadTourVideo);
+        }
+
+    }
+
+    @Override
+    public ResultData downloadTourVideo(String num) {
+        DownloadTourVideoVO result = new DownloadTourVideoVO();
+        DownloadTourVideo downloadTourVideo = this.getOne(new LambdaQueryWrapper<DownloadTourVideo>().eq(DownloadTourVideo::getNum, num));
+        if(Objects.isNull(downloadTourVideo)){
+            result.setStatus(0);
+        }else{
+            result.setStatus(1);
+            result.setTransferStatus(downloadTourVideo.getState());
+            result.setPath(downloadTourVideo.getDownloadPath());
+        }
+        return ResultData.ok(result);
+    }
+}

+ 6 - 5
src/main/java/com/fdkankan/scene/service/impl/SceneEditServiceImpl.java

@@ -117,6 +117,12 @@ public class SceneEditServiceImpl implements ISceneEditService {
         sceneAuthVO.setInclude(new ArrayList<>());
         sceneAuthVO.setCompany(null);
 
+        //判断本地资源是否已本删除,如果已删除,前端根据字段值为true提示用户不能使用某些功能,需要重算
+        Date algorithmTime = scenePlusExt.getAlgorithmTime() == null ? scenePlus.getCreateTime() : scenePlusExt.getAlgorithmTime();
+        if (com.fdkankan.common.util.DateUtil.delay(algorithmTime, 3, Calendar.DAY_OF_MONTH).before(new Date())) {
+            sceneAuthVO.setSourceExpired(true);
+        }
+
         //判断该场景是否属于增值权益
         boolean isVip = false;
         //获取该相机是否有权益
@@ -218,11 +224,6 @@ public class SceneEditServiceImpl implements ISceneEditService {
 
         sceneAuthVO.setInclude(sceneResourceService.findByCooperationId(sceneCooperation.getId()));
 
-        //判断本地资源是否已本删除,如果已删除,前端根据字段值为true提示用户不能使用某些功能,需要重算
-        if (com.fdkankan.common.util.DateUtil.delay(scenePlusExt.getAlgorithmTime(), 3, Calendar.DAY_OF_MONTH).before(new Date())) {
-            sceneAuthVO.setSourceExpired(true);
-        }
-
         return sceneAuthVO;
     }
 

+ 21 - 0
src/main/java/com/fdkankan/scene/vo/DownloadTourVideoVO.java

@@ -0,0 +1,21 @@
+package com.fdkankan.scene.vo;
+
+import lombok.Data;
+
+/**
+ * <p>
+ * TODO
+ * </p>
+ *
+ * @author dengsixing
+ * @since 2022/10/13
+ **/
+@Data
+public class DownloadTourVideoVO {
+
+    private Integer status;
+    private Integer transferStatus;
+    private String path;
+
+
+}

+ 4 - 0
src/main/resources/bootstrap-test.yml

@@ -24,6 +24,10 @@ spring:
           - data-id: common-fyun-config.yaml
             group: DEFAULT_GROUP
             refresh: true
+
+          - data-id: common-rabbitmq-config.yaml
+            group: DEFAULT_GROUP
+            refresh: true
       discovery:
         namespace: ${spring.cloud.nacos.namespace}