lyhzzz 10 ヶ月 前
コミット
1a872035aa

+ 6 - 0
pom.xml

@@ -172,6 +172,12 @@
                 <version>1.5.9</version>
             </dependency>
 
+        <dependency>
+            <groupId>com.google.code.gson</groupId>
+            <artifactId>gson</artifactId>
+            <version>2.8.5</version>
+        </dependency>
+
     </dependencies>
 
     <build>

+ 2 - 0
src/main/java/com/fdkankan/fusion/common/FilePath.java

@@ -17,5 +17,7 @@ public class FilePath {
    public final static String VIDEO_LOCAL_PATH = LOCAL_BASE_PATH + "%s/video/merge";
    public final static String OBJ_LOCAL_PATH = LOCAL_BASE_PATH + "%s/model/%s";
 
+   public final static String qj_image_path = "scene_view_data/%s/images/pan/high/";
+
 
 }

+ 3 - 0
src/main/java/com/fdkankan/fusion/common/ResultCode.java

@@ -78,6 +78,9 @@ public enum ResultCode {
     CAMERA_VERSION_STATUS_ERROR(8027, "相机版本状态错误"),
 
 
+    XFYUN_CONFIG_NOT_EXIT(9001, "讯飞配置不存在"),
+    QJ_IMAGE_NOT_EXIT(9002, "全景图不存在"),
+
     ;
 
 

+ 14 - 0
src/main/java/com/fdkankan/fusion/controller/TestController.java

@@ -3,10 +3,14 @@ package com.fdkankan.fusion.controller;
 import cn.hutool.http.HttpUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.dtflys.forest.annotation.Post;
+import com.fdkankan.fusion.common.ResultCode;
 import com.fdkankan.fusion.common.ResultData;
 import com.fdkankan.fusion.common.util.ShellUtil;
+import com.fdkankan.fusion.common.util.UploadToOssUtil;
 import com.fdkankan.fusion.entity.*;
+import com.fdkankan.fusion.exception.BusinessException;
 import com.fdkankan.fusion.service.*;
+import com.fdkankan.fusion.xfyun.XfyunWebSocketListener;
 import com.fdkankan.redis.util.RedisUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.ibatis.annotations.Case;
@@ -104,4 +108,14 @@ public class TestController {
         }
         return ResultData.ok();
     }
+
+    @Autowired
+    IXfyunConfigService xfyunConfigService;
+    @Autowired
+    IXfyunImageService xfyunImageService;
+    @GetMapping("/testXfyun")
+    public ResultData testXfyun(@RequestParam(required = false) String num){
+        XfyunImage xfyunImage = xfyunImageService.getByNum(num);
+        return ResultData.ok(xfyunImage);
+    }
 }

+ 57 - 0
src/main/java/com/fdkankan/fusion/entity/XfyunConfig.java

@@ -0,0 +1,57 @@
+package com.fdkankan.fusion.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 2024-10-22
+ */
+@Getter
+@Setter
+@TableName("t_xfyun_config")
+public class XfyunConfig implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @TableField("host_url")
+    private String hostUrl;
+
+    @TableField("appid")
+    private String appid;
+
+    @TableField("api_secret")
+    private String apiSecret;
+
+    @TableField("api_key")
+    private String apiKey;
+
+    @TableField("df_question")
+    private String dfQuestion;
+
+    @TableField("tb_status")
+    @TableLogic
+    private Integer tbStatus;
+
+    @TableField("create_time")
+    private Date createTime;
+
+    @TableField("update_time")
+    private Date updateTime;
+
+
+}

+ 60 - 0
src/main/java/com/fdkankan/fusion/entity/XfyunImage.java

@@ -0,0 +1,60 @@
+package com.fdkankan.fusion.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 2024-10-22
+ */
+@Getter
+@Setter
+@TableName("t_xfyun_image")
+public class XfyunImage implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**
+     * 场景码
+     */
+    @TableField("num")
+    private String num;
+
+    /**
+     * 图片路径
+     */
+    @TableField("image_url")
+    private String imageUrl;
+
+    /**
+     * 讯飞回复
+     */
+    @TableField("xfyun_answer")
+    private String xfyunAnswer;
+
+    @TableField("tb_status")
+    @TableLogic
+    private Integer tbStatus;
+
+    @TableField("create_time")
+    private Date createTime;
+
+    @TableField("update_time")
+    private Date updateTime;
+
+
+}

+ 1 - 1
src/main/java/com/fdkankan/fusion/generate/AutoGenerate.java

@@ -18,7 +18,7 @@ public class AutoGenerate {
         String path =System.getProperty("user.dir") ;
 
         generate(path,"fusion", getTables(new String[]{
-               "t_case_inquest_criminal"
+               "t_xfyun_config","t_xfyun_image"
         }));
 
 //        generate(path,"goods", getTables(new String[]{

+ 18 - 0
src/main/java/com/fdkankan/fusion/mapper/IXfyunConfigMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.fusion.mapper;
+
+import com.fdkankan.fusion.entity.XfyunConfig;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2024-10-22
+ */
+@Mapper
+public interface IXfyunConfigMapper extends BaseMapper<XfyunConfig> {
+
+}

+ 18 - 0
src/main/java/com/fdkankan/fusion/mapper/IXfyunImageMapper.java

@@ -0,0 +1,18 @@
+package com.fdkankan.fusion.mapper;
+
+import com.fdkankan.fusion.entity.XfyunImage;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author 
+ * @since 2024-10-22
+ */
+@Mapper
+public interface IXfyunImageMapper extends BaseMapper<XfyunImage> {
+
+}

+ 16 - 0
src/main/java/com/fdkankan/fusion/service/IXfyunConfigService.java

@@ -0,0 +1,16 @@
+package com.fdkankan.fusion.service;
+
+import com.fdkankan.fusion.entity.XfyunConfig;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2024-10-22
+ */
+public interface IXfyunConfigService extends IService<XfyunConfig> {
+
+}

+ 17 - 0
src/main/java/com/fdkankan/fusion/service/IXfyunImageService.java

@@ -0,0 +1,17 @@
+package com.fdkankan.fusion.service;
+
+import com.fdkankan.fusion.entity.XfyunImage;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author 
+ * @since 2024-10-22
+ */
+public interface IXfyunImageService extends IService<XfyunImage> {
+
+    XfyunImage getByNum(String num);
+}

+ 20 - 0
src/main/java/com/fdkankan/fusion/service/impl/XfyunConfigServiceImpl.java

@@ -0,0 +1,20 @@
+package com.fdkankan.fusion.service.impl;
+
+import com.fdkankan.fusion.entity.XfyunConfig;
+import com.fdkankan.fusion.mapper.IXfyunConfigMapper;
+import com.fdkankan.fusion.service.IXfyunConfigService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2024-10-22
+ */
+@Service
+public class XfyunConfigServiceImpl extends ServiceImpl<IXfyunConfigMapper, XfyunConfig> implements IXfyunConfigService {
+
+}

+ 78 - 0
src/main/java/com/fdkankan/fusion/service/impl/XfyunImageServiceImpl.java

@@ -0,0 +1,78 @@
+package com.fdkankan.fusion.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.fdkankan.fusion.common.FilePath;
+import com.fdkankan.fusion.common.ResultCode;
+import com.fdkankan.fusion.common.util.ShellUtil;
+import com.fdkankan.fusion.common.util.UploadToOssUtil;
+import com.fdkankan.fusion.entity.XfyunConfig;
+import com.fdkankan.fusion.entity.XfyunImage;
+import com.fdkankan.fusion.exception.BusinessException;
+import com.fdkankan.fusion.mapper.IXfyunImageMapper;
+import com.fdkankan.fusion.service.IXfyunConfigService;
+import com.fdkankan.fusion.service.IXfyunImageService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fdkankan.fusion.xfyun.XfyunWebSocketListener;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author 
+ * @since 2024-10-22
+ */
+@Service
+public class XfyunImageServiceImpl extends ServiceImpl<IXfyunImageMapper, XfyunImage> implements IXfyunImageService {
+
+    @Autowired
+    IXfyunConfigService xfyunConfigService;
+    @Autowired
+    UploadToOssUtil uploadToOssUtil;
+
+    @Override
+    public XfyunImage getByNum(String num) {
+        LambdaQueryWrapper<XfyunImage> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(XfyunImage::getNum,num);
+        List<XfyunImage> list1 = this.list(wrapper);
+        if(!list1.isEmpty()){
+            return list1.get(0);
+        }
+
+        List<XfyunConfig> list = xfyunConfigService.list();
+        if(list.isEmpty()){
+            throw new BusinessException(ResultCode.XFYUN_CONFIG_NOT_EXIT);
+        }
+        XfyunConfig xfyunConfig = list.get(0);
+        String path = String.format(FilePath.qj_image_path,num);
+        List<String> imagePahts = uploadToOssUtil.listKeysFromAli(path);
+        if(imagePahts.isEmpty()){
+            throw new BusinessException(ResultCode.QJ_IMAGE_NOT_EXIT);
+        }
+        int size = imagePahts.size();
+        Integer image = size%2 ==0 ? size/2 : size /2 +1;
+
+        String imageOssPath = path+"/"+image +".jpg";
+        ShellUtil.yunDownload(imageOssPath,FilePath.MNT_BASE_PATH + imageOssPath);
+
+        XfyunWebSocketListener xfyunWebSocketListener = new XfyunWebSocketListener( xfyunConfig.getAppid(), xfyunConfig.getDfQuestion(),FilePath.MNT_BASE_PATH +imageOssPath);
+        String xfyunResult = xfyunWebSocketListener.createXfyunResult(xfyunWebSocketListener, xfyunConfig);
+
+        XfyunImage xfyunImage = new XfyunImage();
+        xfyunImage.setNum(num);
+        xfyunImage.setImageUrl(imageOssPath);
+        xfyunImage.setXfyunAnswer(xfyunResult);
+        this.save(xfyunImage);
+        return xfyunImage;
+    }
+
+    public static void main(String[] args) {
+        int size = 11;
+        Integer image = size%2 ==0 ? size/2 : size /2 +1;
+        System.out.println(image);
+    }
+}

+ 26 - 0
src/main/java/com/fdkankan/fusion/xfyun/ImageUtil.java

@@ -0,0 +1,26 @@
+package com.fdkankan.fusion.xfyun;
+
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public class ImageUtil {
+
+
+    public static byte[] read(String filePath) throws IOException {
+        InputStream in = new FileInputStream(filePath);
+        byte[] data = inputStream2ByteArray(in);
+        in.close();
+        return data;
+    }
+    private static byte[] inputStream2ByteArray(InputStream in) throws IOException {
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024 * 4];
+        int n = 0;
+        while ((n = in.read(buffer)) != -1) {
+            out.write(buffer, 0, n);
+        }
+        return out.toByteArray();
+    }
+}

+ 262 - 0
src/main/java/com/fdkankan/fusion/xfyun/XfyunWebSocketListener.java

@@ -0,0 +1,262 @@
+package com.fdkankan.fusion.xfyun;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.fdkankan.fusion.common.ResultCode;
+import com.fdkankan.fusion.entity.XfyunConfig;
+import com.fdkankan.fusion.exception.BusinessException;
+import com.fdkankan.fusion.mapper.IXfyunConfigMapper;
+import com.fdkankan.fusion.service.IXfyunConfigService;
+import com.google.gson.Gson;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import okhttp3.*;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.PostConstruct;
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Slf4j
+public class XfyunWebSocketListener extends WebSocketListener {
+    private Boolean wsCloseFlag ;
+    private String totalAnswer ;
+    private String appid;
+    private String newQuestion;
+    private String imagePath;
+
+    public XfyunWebSocketListener( String appid, String newQuestion, String imagePath) {
+        this.wsCloseFlag = false;
+        this.totalAnswer = "";
+        this.appid = appid;
+        this.newQuestion = newQuestion;
+        this.imagePath = imagePath;
+    }
+
+    public  String createXfyunResult(XfyunWebSocketListener xfyunWebSocketListener, XfyunConfig xfyunConfig) {
+        try {
+            String authUrl = getAuthUrl(xfyunConfig.getHostUrl(), xfyunConfig.getApiKey(), xfyunConfig.getApiSecret());
+            OkHttpClient client = new OkHttpClient.Builder().build();
+            String url = authUrl.toString().replace("http://", "ws://").replace("https://", "wss://");
+            Request request = new Request.Builder().url(url).build();
+            WebSocket webSocket = client.newWebSocket(request, xfyunWebSocketListener);
+            while (!wsCloseFlag){
+                Thread.sleep(200);
+            }
+
+        }catch (Exception e){
+            log.info("创建XfyunWebSocket失败",e);
+        }
+        return totalAnswer;
+    }
+    class MyThread extends Thread {
+        private WebSocket webSocket;
+
+
+        public MyThread(WebSocket webSocket) {
+            this.webSocket = webSocket;
+        }
+        public void run() {
+            try {
+                JSONObject requestJson = new JSONObject();
+
+                JSONObject header = new JSONObject();  // header参数
+                header.put("app_id", appid);
+                header.put("uid", UUID.randomUUID().toString().substring(0, 10));
+
+                JSONObject parameter = new JSONObject(); // parameter参数
+                JSONObject chat = new JSONObject();
+                chat.put("domain", "image");
+                chat.put("temperature", 0.5);
+                chat.put("max_tokens", 4096);
+                chat.put("auditing", "default");
+                parameter.put("chat", chat);
+
+                JSONObject payload = new JSONObject(); // payload参数
+                JSONObject message = new JSONObject();
+                JSONArray text = new JSONArray();
+
+                RoleContent roleContent = new RoleContent();
+                // 添加图片信息
+                roleContent.role = "user";
+                roleContent.content = Base64.getEncoder().encodeToString(ImageUtil.read(imagePath));
+                roleContent.content_type = "image";
+                text.add(JSON.toJSON(roleContent));
+                // 添加对图片提出要求的信息
+                RoleContent roleContent1 = new RoleContent();
+                roleContent1.role = "user";
+                roleContent1.content = newQuestion;
+                roleContent1.content_type = "text";
+                text.add(JSON.toJSON(roleContent1));
+
+
+                message.put("text", text);
+                payload.put("message", message);
+
+
+                requestJson.put("header", header);
+                requestJson.put("parameter", parameter);
+                requestJson.put("payload", payload);
+                // System.err.println(requestJson); // 可以打印看每次的传参明细
+                webSocket.send(requestJson.toString());
+                // 等待服务端返回完毕后关闭
+                while (true) {
+                    // System.err.println(wsCloseFlag + "---");
+                    Thread.sleep(200);
+                    if (wsCloseFlag) {
+                        break;
+                    }
+                }
+                webSocket.close(1000, "");
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+
+    }
+    @Override
+    public void onOpen(WebSocket webSocket, Response response) {
+        super.onOpen(webSocket, response);
+        MyThread myThread = new MyThread(webSocket);
+        myThread.start();
+    }
+
+    @Override
+    public void onMessage(WebSocket webSocket, String text) {
+        JsonParse myJsonParse = new Gson().fromJson(text, JsonParse.class);
+        if (myJsonParse.header.code != 0) {
+            log.info("发生错误,错误码为:" + myJsonParse.header.code);
+            log.info("本次请求的sid为:" + myJsonParse.header.sid);
+            webSocket.close(1000, "");
+        }
+        List<Text> textList = myJsonParse.payload.choices.text;
+        for (Text temp : textList) {
+            totalAnswer+=temp.content;
+        }
+        if (myJsonParse.header.status == 2) {
+            wsCloseFlag = true;
+           log.info("讯飞回复:"+totalAnswer.toString());
+        }
+    }
+
+    @Override
+    public void onFailure(WebSocket webSocket, Throwable t, Response response) {
+        super.onFailure(webSocket, t, response);
+        try {
+            if (null != response) {
+                int code = response.code();
+                System.out.println("onFailure code:" + code);
+                System.out.println("onFailure body:" + response.body().string());
+                if (101 != code) {
+                    System.out.println("connection failed");
+                    System.exit(0);
+                }
+            }
+        } catch (IOException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+    }
+
+
+    // 鉴权方法
+    public static String getAuthUrl(String hostUrl, String apiKey, String apiSecret) throws Exception {
+        URL url = new URL(hostUrl);
+        // 时间
+        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
+        format.setTimeZone(TimeZone.getTimeZone("GMT"));
+        String date = format.format(new Date());
+        // 拼接
+        String preStr = "host: " + url.getHost() + "\n" +
+                "date: " + date + "\n" +
+                "GET " + url.getPath() + " HTTP/1.1";
+        // System.err.println(preStr);
+        // SHA256加密
+        Mac mac = Mac.getInstance("hmacsha256");
+        SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
+        mac.init(spec);
+
+        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
+        // Base64加密
+        String sha = Base64.getEncoder().encodeToString(hexDigits);
+        // System.err.println(sha);
+        // 拼接
+        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", apiKey, "hmac-sha256", "host date request-line", sha);
+        // 拼接地址
+        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().//
+                addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).//
+                addQueryParameter("date", date).//
+                addQueryParameter("host", url.getHost()).//
+                build();
+
+        // System.err.println(httpUrl.toString());
+        return httpUrl.toString();
+    }
+
+
+
+    //返回的json结果拆解
+    class JsonParse {
+        Header header;
+        Payload payload;
+    }
+
+    class Header {
+        int code;
+        int status;
+        String sid;
+    }
+
+    class Payload {
+        Choices choices;
+    }
+
+    class Choices {
+        List<Text> text;
+    }
+
+    class Text {
+        String role;
+        String content;
+    }
+    class RoleContent{
+        String role;
+        String content;
+
+        String content_type;
+
+        public String getContent_type() {
+            return content_type;
+        }
+
+        public void setContent_type(String content_type) {
+            this.content_type = content_type;
+        }
+
+        public String getRole() {
+            return role;
+        }
+
+        public void setRole(String role) {
+            this.role = role;
+        }
+
+        public String getContent() {
+            return content;
+        }
+
+        public void setContent(String content) {
+            this.content = content;
+        }
+    }
+}

+ 5 - 0
src/main/resources/mapper/fusion/XfyunConfigMapper.xml

@@ -0,0 +1,5 @@
+<?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.fusion.mapper.IXfyunConfigMapper">
+
+</mapper>

+ 5 - 0
src/main/resources/mapper/fusion/XfyunImageMapper.xml

@@ -0,0 +1,5 @@
+<?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.fusion.mapper.IXfyunImageMapper">
+
+</mapper>

BIN
src/main/resources/template/~$quest_criminal-template.docx