From 0a0eac52f6786342fa487330fb68653741daac7a Mon Sep 17 00:00:00 2001 From: wangxun Date: Tue, 1 Jul 2025 18:21:30 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B0=83=E7=94=A8=E8=AF=AD=E4=B9=89=E5=A4=A7?= =?UTF-8?q?=E6=A8=A1=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/InfraredController.java | 16 ++ .../simulator/domain/Infrared/Coordinate.java | 3 + .../domain/Infrared/InfraredBox.java | 4 + .../domain/bigmodelr/ApiResponse.java | 15 ++ .../bigmodelr/ChatCompletionRequest.java | 14 ++ .../bigmodelr/ChatCompletionResponse.java | 33 ++++ .../simulator/domain/bigmodelr/Choice.java | 13 ++ .../simulator/domain/bigmodelr/Content.java | 17 +++ .../domain/bigmodelr/ContentItem.java | 15 ++ .../simulator/domain/bigmodelr/ImageUrl.java | 9 ++ .../simulator/domain/bigmodelr/Message.java | 23 +++ .../domain/bigmodelr/Multimodal.java | 20 +++ .../simulator/domain/bigmodelr/Usage.java | 10 ++ .../domain/bigmodelr/VisualModel.java | 26 ++++ .../simulator/service/ModelService.java | 16 ++ .../service/impl/HikVisionServiceImpl.java | 5 +- .../service/impl/ModelServiceImpl.java | 142 ++++++++++++++++++ .../resources/mapper/InfraredBoxMapper.xml | 8 +- 18 files changed, 385 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/ApiResponse.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionRequest.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionResponse.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/Choice.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/Content.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/ContentItem.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/ImageUrl.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/Message.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/Multimodal.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/Usage.java create mode 100644 src/main/java/com/inspect/simulator/domain/bigmodelr/VisualModel.java create mode 100644 src/main/java/com/inspect/simulator/service/ModelService.java create mode 100644 src/main/java/com/inspect/simulator/service/impl/ModelServiceImpl.java diff --git a/src/main/java/com/inspect/simulator/controller/InfraredController.java b/src/main/java/com/inspect/simulator/controller/InfraredController.java index cd50feb..1ab356b 100644 --- a/src/main/java/com/inspect/simulator/controller/InfraredController.java +++ b/src/main/java/com/inspect/simulator/controller/InfraredController.java @@ -3,9 +3,13 @@ package com.inspect.simulator.controller; import com.alibaba.fastjson.JSONObject; import com.alibaba.nacos.shaded.org.checkerframework.checker.units.qual.A; import com.inspect.simulator.domain.Infrared.*; +import com.inspect.simulator.domain.bigmodelr.Multimodal; import com.inspect.simulator.hikVision.utils.StringUtils; + + import com.inspect.simulator.service.HikVisionService; import com.inspect.simulator.hikVision.utils.AjaxResult; +import com.inspect.simulator.service.ModelService; import com.inspect.simulator.service.ResultAnalysisService; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -33,6 +37,9 @@ public class InfraredController { @Resource private ResultAnalysisService resultAnnalysisService; + @Resource + private ModelService modelService; + /** * ----登录---- * nvrIp nvrIp @@ -161,4 +168,13 @@ public class InfraredController { return AjaxResult.success().put("data", string); } + + @PostMapping("/model/semanticsModel") + @ResponseBody + public AjaxResult semanticsModel(@RequestBody Multimodal multimodal) + { + String string = modelService.semanticsModel(multimodal); + return AjaxResult.success().put("data", string); + } + } diff --git a/src/main/java/com/inspect/simulator/domain/Infrared/Coordinate.java b/src/main/java/com/inspect/simulator/domain/Infrared/Coordinate.java index 278ede9..34bc039 100644 --- a/src/main/java/com/inspect/simulator/domain/Infrared/Coordinate.java +++ b/src/main/java/com/inspect/simulator/domain/Infrared/Coordinate.java @@ -26,6 +26,9 @@ public class Coordinate { private String height; + private String maxValueX; + private String maxValueY; + public Coordinate(int firstX, int firstY, int secondX, int secondY) { this.firstX=firstX; this.firstY=firstY; diff --git a/src/main/java/com/inspect/simulator/domain/Infrared/InfraredBox.java b/src/main/java/com/inspect/simulator/domain/Infrared/InfraredBox.java index 379f2f5..9ff85a9 100644 --- a/src/main/java/com/inspect/simulator/domain/Infrared/InfraredBox.java +++ b/src/main/java/com/inspect/simulator/domain/Infrared/InfraredBox.java @@ -32,5 +32,9 @@ public class InfraredBox { private String height; + private String maxValueX; + + private String maxValueY; + } diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/ApiResponse.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/ApiResponse.java new file mode 100644 index 0000000..fa352b8 --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/ApiResponse.java @@ -0,0 +1,15 @@ +package com.inspect.simulator.domain.bigmodelr; + +import lombok.Data; + +@Data +public class ApiResponse { + private String code; + private String message; + private Object data; + + public ApiResponse(String code, String message) { + this.code = code; + this.message = message; + } +} diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionRequest.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionRequest.java new file mode 100644 index 0000000..815501d --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionRequest.java @@ -0,0 +1,14 @@ +package com.inspect.simulator.domain.bigmodelr; + +import com.fasterxml.jackson.annotation.JsonInclude; +import lombok.Data; + +import java.util.List; + +@Data +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ChatCompletionRequest { + private String model; + private List messages; + private int maxTokens; +} \ No newline at end of file diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionResponse.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionResponse.java new file mode 100644 index 0000000..52db2a2 --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/ChatCompletionResponse.java @@ -0,0 +1,33 @@ +package com.inspect.simulator.domain.bigmodelr; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@JsonIgnoreProperties(ignoreUnknown = true) +public class ChatCompletionResponse { + private String id; + private String object; + private long created; + private List choices; + + private String info; + + private Usage usage; + + @JsonProperty("model") + private String model; + + //存数据库 + private String content; + + private String picPath; + +} diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/Choice.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/Choice.java new file mode 100644 index 0000000..d7925ca --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/Choice.java @@ -0,0 +1,13 @@ +package com.inspect.simulator.domain.bigmodelr; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import lombok.Data; + +@Data +@JsonIgnoreProperties(ignoreUnknown = true) // 忽略所有未定义的字段 +public class Choice { + private int index; + private Message message; + private String finish_reason; + +} \ No newline at end of file diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/Content.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/Content.java new file mode 100644 index 0000000..40f5993 --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/Content.java @@ -0,0 +1,17 @@ +package com.inspect.simulator.domain.bigmodelr; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class Content { + private String type; // text/image_url + + @JsonInclude(JsonInclude.Include.NON_NULL) + private String text; // type=text时使用 + + @JsonInclude(JsonInclude.Include.NON_NULL) + @JsonProperty("image_url") + private ImageUrl imageUrl; // type=image_url时使用 +} \ No newline at end of file diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/ContentItem.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/ContentItem.java new file mode 100644 index 0000000..ba8c0d9 --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/ContentItem.java @@ -0,0 +1,15 @@ +package com.inspect.simulator.domain.bigmodelr; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class ContentItem { + private String type; // text/image_url/image_base64 + private String text; // type=text时使用 + + @JsonProperty("image_url") + private ImageUrl imageUrl; // type=image_url时使用 + + private String image; // type=image_base64时使用 +} diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/ImageUrl.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/ImageUrl.java new file mode 100644 index 0000000..3a87b52 --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/ImageUrl.java @@ -0,0 +1,9 @@ +package com.inspect.simulator.domain.bigmodelr; + +import lombok.Data; + +@Data +public class ImageUrl { + + private String url; +} diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/Message.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/Message.java new file mode 100644 index 0000000..28c1d0e --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/Message.java @@ -0,0 +1,23 @@ +package com.inspect.simulator.domain.bigmodelr; + +import com.fasterxml.jackson.annotation.JsonSetter; +import lombok.Data; + +import java.util.List; + +@Data +public class Message { + private String role; +// private List content; + + private Object content; // 可以是 String 或 List + + @JsonSetter("content") + public void setContent(Object content) { + if (content instanceof String) { + this.content = (String) content; + } else if (content instanceof List) { + this.content = (List) content; + } + } +} diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/Multimodal.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/Multimodal.java new file mode 100644 index 0000000..d65c64b --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/Multimodal.java @@ -0,0 +1,20 @@ +package com.inspect.simulator.domain.bigmodelr; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Multimodal { + + private String role; + private String imageType; + private String imageData; + private String model; + private String text; + private String imageName; + private int maxTokens; + +} diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/Usage.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/Usage.java new file mode 100644 index 0000000..000c998 --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/Usage.java @@ -0,0 +1,10 @@ +package com.inspect.simulator.domain.bigmodelr; + +import lombok.Data; + +@Data +public class Usage { + private int prompt_tokens; + private int completion_tokens; + private int total_tokens; +} diff --git a/src/main/java/com/inspect/simulator/domain/bigmodelr/VisualModel.java b/src/main/java/com/inspect/simulator/domain/bigmodelr/VisualModel.java new file mode 100644 index 0000000..0129720 --- /dev/null +++ b/src/main/java/com/inspect/simulator/domain/bigmodelr/VisualModel.java @@ -0,0 +1,26 @@ +package com.inspect.simulator.domain.bigmodelr; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class VisualModel { + + //照片类型(url ,base64) + private String image_type; + + //照片名称 + private String image_name; + + //照片地址(http,https无鉴权) + private String image_url; + + //照片base64 + private String image_base64; + + private String stringData; + +} diff --git a/src/main/java/com/inspect/simulator/service/ModelService.java b/src/main/java/com/inspect/simulator/service/ModelService.java new file mode 100644 index 0000000..9b805db --- /dev/null +++ b/src/main/java/com/inspect/simulator/service/ModelService.java @@ -0,0 +1,16 @@ +package com.inspect.simulator.service; + + +import com.inspect.simulator.domain.bigmodelr.Multimodal; +import com.inspect.simulator.domain.bigmodelr.VisualModel; + +import java.util.List; + +public interface ModelService { + + //语义大模型 + public String semanticsModel(Multimodal multimodal); + + + +} diff --git a/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java b/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java index 6d77c6d..67f89a5 100644 --- a/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java +++ b/src/main/java/com/inspect/simulator/service/impl/HikVisionServiceImpl.java @@ -83,6 +83,7 @@ public class HikVisionServiceImpl implements HikVisionService { // @Value("${file.ftpUrlAddress:test}") private String ftpUrlAddress = "192.168.4.129"; +// private String ftpUrlAddress = "192.168.1.116"; // @Value("${file.ftpUrlAccount:test}") private String ftpUrlAccount = "ftpuser"; @@ -92,7 +93,7 @@ public class HikVisionServiceImpl implements HikVisionService { // @Value("${file.ftpUrlPort:10000}") private Integer ftpUrlPort = 10012; - +// private Integer ftpUrlPort = 10990; // @Value("${file.produceEnvironment:true}") private Boolean produceEnvironment = true; @@ -1695,6 +1696,8 @@ public class HikVisionServiceImpl implements HikVisionService { box.setBoxName(infraPictureInfo.getCoordinates().get(i).getBoxName()); box.setWidth(infraPictureInfo.getCoordinates().get(i).getWidth()); box.setHeight(infraPictureInfo.getCoordinates().get(i).getHeight()); + box.setMaxValueX(infraPictureInfo.getCoordinates().get(i).getMaxValueX()); + box.setMaxValueY(infraPictureInfo.getCoordinates().get(i).getMaxValueY()); infraredBoxes.add(box); } } diff --git a/src/main/java/com/inspect/simulator/service/impl/ModelServiceImpl.java b/src/main/java/com/inspect/simulator/service/impl/ModelServiceImpl.java new file mode 100644 index 0000000..1436b1a --- /dev/null +++ b/src/main/java/com/inspect/simulator/service/impl/ModelServiceImpl.java @@ -0,0 +1,142 @@ +package com.inspect.simulator.service.impl; + + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; + +import com.inspect.simulator.domain.bigmodelr.*; +import com.inspect.simulator.service.ModelService; +import okhttp3.*; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.io.IOException; +import java.net.SocketTimeoutException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import java.util.stream.Stream; + + + +@Service +public class ModelServiceImpl implements ModelService { + + + + + + + // 设置支持的图片文件扩展名 + private static final List IMAGE_EXTENSIONS = Arrays.asList(".jpg", ".jpeg", ".png"); + + private final ObjectMapper objectMapper = new ObjectMapper(); + private final OkHttpClient httpClient = new OkHttpClient.Builder() + .connectTimeout(40, TimeUnit.SECONDS) // 连接超时 + .readTimeout(60, TimeUnit.SECONDS) // 读取超时 + .writeTimeout(30, TimeUnit.SECONDS) // 写入超时 + .build(); + public ModelServiceImpl() { + // 设置JSON序列化时忽略null值 + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + + + //调用语义大模型接口 + public String semanticsModel(Multimodal multimodal){ + // 重试次数 + int maxRetries = 3; + int attempt = 0; + + while (attempt < maxRetries) { + try { + // 构建请求JSON + ChatCompletionRequest request = buildRequestBody(multimodal); + System.out.println("创建json" + request.getClass()); + // 发送请求并获取响应 + ChatCompletionResponse response = semanticsModelResponse(request); + String content = String.valueOf(response.getChoices().get(0).getMessage().getContent()); + System.out.println("语义大模型返回结果:"+content); + return content; + } catch (IOException e) { + if (attempt == maxRetries) { + return "请求超时,请稍后重试"; + } + System.out.println("第" + attempt + "次尝试超时,准备重试..."); + try { + Thread.sleep(1000 * attempt); // 指数退避 + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } + } + return "请求处理失败"; + } + private ChatCompletionRequest buildRequestBody(Multimodal multimodal) { + + ChatCompletionRequest request = new ChatCompletionRequest(); + // 设置模型名称,默认"SGGM-VL-74B-V1.2" + request.setModel(multimodal.getModel() != null ? multimodal.getModel() : "SGGM-VL-74B-V1.2"); + + // 构建消息 + Message message = new Message(); + message.setRole(StringUtils.isNotBlank(multimodal.getRole()) ? multimodal.getRole() : "user"); + message.setContent(multimodal.getText()); + request.setMessages(Collections.singletonList(message)); + + return request; + } + + private ChatCompletionResponse semanticsModelResponse(ChatCompletionRequest request) throws IOException { + String requestBody; + try { + requestBody = objectMapper.writeValueAsString(request); + } catch (JsonProcessingException e) { + throw new IOException("请求体序列化失败", e); + } + + Request httpRequest = new Request.Builder() + .url("http://25.80.45.92:18063/lmp-cloud-ias-server/api/llm/chat/completions") + .post(RequestBody.create(MediaType.parse("application/json"), requestBody)) + .addHeader("Authorization", "Bearer 54c1ae2c5fd54afe85e74d6fe9161f7f") + .addHeader("Content-Type", "application/json") + .build(); + + try (Response response = httpClient.newCall(httpRequest).execute()) { + if (!response.isSuccessful()) { + String errorBody = response.body() != null ? response.body().string() : "无响应体"; + throw new IOException(String.format("请求失败,状态码: %d,错误信息: %s", response.code(), errorBody)); + } + String responseBody = response.body().string(); + System.out.println("语义大模型API响应内容: " + responseBody); + return objectMapper.readValue(responseBody, ChatCompletionResponse.class); + + } catch (SocketTimeoutException e) { + throw new IOException("请求超时,请检查网络连接或增加超时时间", e); + } + } + + + + + + + + + + + + + + + + +} diff --git a/src/main/resources/mapper/InfraredBoxMapper.xml b/src/main/resources/mapper/InfraredBoxMapper.xml index 7c3d0c2..bd280b5 100644 --- a/src/main/resources/mapper/InfraredBoxMapper.xml +++ b/src/main/resources/mapper/InfraredBoxMapper.xml @@ -16,14 +16,16 @@ + + - insert into basedata_infrared_box (img_name,img_width,img_height,points_xy,max_value,min_value,avg_value,box_name,width,height) + insert into basedata_infrared_box (img_name,img_width,img_height,points_xy,max_value,min_value,avg_value,box_name,width,height,max_value_x,max_value_y) #{infraredBox.imgName},#{infraredBox.imgWidth},#{infraredBox.imgHeight},#{infraredBox.pointsXy}, #{infraredBox.maxValue},#{infraredBox.minValue},#{infraredBox.avgValue},#{infraredBox.boxName}, - #{infraredBox.width},#{infraredBox.height} + #{infraredBox.width},#{infraredBox.height},#{infraredBox.maxValueX},#{infraredBox.maxValueY} @@ -32,7 +34,7 @@