commit 856dfa6048afdb94858f71360458d8f2ac61fdff Author: htjcAdmin Date: Tue Jul 1 14:37:09 2025 +0800 /*光明大模型工程*/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..549e00a --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +HELP.md +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### STS ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### IntelliJ IDEA ### +.idea +*.iws +*.iml +*.ipr + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..c27c29c --- /dev/null +++ b/pom.xml @@ -0,0 +1,202 @@ + + + 4.0.0 + com.mortal + inspect-luminous + 0.0.1-SNAPSHOT + inspect-luminous + inspect-luminous + + 1.8 + UTF-8 + UTF-8 + 2.6.13 + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + org.projectlombok + lombok + 1.16.18 + + + + cn.hutool + hutool-all + 5.8.9 + + + com.squareup.okhttp3 + okhttp + 4.9.3 + + + + org.springframework.boot + spring-boot-starter-websocket + + + + + mysql + mysql-connector-java + 8.0.33 + + + + + com.alibaba + druid-spring-boot-starter + 1.2.20 + + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + org.mybatis.spring.boot + mybatis-spring-boot-starter + 2.2.2 + + + + + org.apache.commons + commons-lang3 + 3.12.0 + + + + com.fasterxml.jackson.core + jackson-databind + 2.13.0 + + + org.projectlombok + lombok + + + + com.alibaba + fastjson + 1.2.83 + + + + + + + com.squareup.retrofit2 + converter-gson + 2.9.0 + + + + + com.google.code.gson + gson + 2.8.9 + + + + + com.squareup.okhttp3 + logging-interceptor + 4.9.3 + + + + + com.squareup.retrofit2 + retrofit + 2.9.0 + + + + + com.squareup.retrofit2 + converter-scalars + 2.9.0 + + + + + com.squareup.retrofit2 + converter-jackson + 2.9.0 + + + + + com.fasterxml.jackson.core + jackson-databind + 2.13.0 + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.8 + 1.8 + UTF-8 + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + com.mortal.bigmodelr.BigModelrApplication + + + + + repackage + + repackage + + + + + + + + diff --git a/src/main/java/com/mortal/bigmodelr/BigModelrApplication.java b/src/main/java/com/mortal/bigmodelr/BigModelrApplication.java new file mode 100644 index 0000000..f7992ab --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/BigModelrApplication.java @@ -0,0 +1,50 @@ +package com.mortal.bigmodelr; + +import okhttp3.Interceptor; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import org.mybatis.spring.annotation.MapperScan; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.scheduling.annotation.EnableScheduling; +import retrofit2.Retrofit; +import retrofit2.converter.jackson.JacksonConverterFactory; +import retrofit2.converter.scalars.ScalarsConverterFactory; + +@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class}) +@EnableScheduling +@MapperScan("com.mortal.bigmodelr.mapper") +public class BigModelrApplication { + + @Value("${analysis.api.url}") + private String apiUrlOfAnalysis; + @Value("${analysis.api.token}") + private String apiTokenOfAnalysis; + + OkHttpClient.Builder clientBuilderOfAnalysis = new OkHttpClient.Builder(); + Interceptor interceptorOfAnalysis = chain -> { + Request request = chain.request() + .newBuilder() + .build(); + return chain.proceed(request); + }; + + @Bean(name = "RetrofitOfAnalysis") + public Retrofit retrofitOfAnalysis() { + clientBuilderOfAnalysis.interceptors().add(interceptorOfAnalysis); + return new Retrofit.Builder() + .baseUrl(apiUrlOfAnalysis) + .client(clientBuilderOfAnalysis.build()) + .addConverterFactory(ScalarsConverterFactory.create()) + .addConverterFactory(JacksonConverterFactory.create()) + .build(); + } + + + public static void main(String[] args) { + SpringApplication.run(BigModelrApplication.class, args); + } +} diff --git a/src/main/java/com/mortal/bigmodelr/config/MultimodalWebSocketHandler.java b/src/main/java/com/mortal/bigmodelr/config/MultimodalWebSocketHandler.java new file mode 100644 index 0000000..18de761 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/config/MultimodalWebSocketHandler.java @@ -0,0 +1,29 @@ +package com.mortal.bigmodelr.config; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class MultimodalWebSocketHandler extends TextWebSocketHandler { + private static final List sessions = new CopyOnWriteArrayList<>(); + + @Override + public void afterConnectionEstablished(WebSocketSession session) { + sessions.add(session); + } + + public static void broadcast(String message) { + for (WebSocketSession session : sessions) { + try { + if (session.isOpen()) { + session.sendMessage(new TextMessage(message)); + } + } catch (IOException e) { + e.printStackTrace(); + sessions.remove(session); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/mortal/bigmodelr/config/MyWebSocketHandler.java b/src/main/java/com/mortal/bigmodelr/config/MyWebSocketHandler.java new file mode 100644 index 0000000..451b742 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/config/MyWebSocketHandler.java @@ -0,0 +1,30 @@ +package com.mortal.bigmodelr.config; + +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; +import java.io.IOException; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +public class MyWebSocketHandler extends TextWebSocketHandler { + private static final List sessions = new CopyOnWriteArrayList<>(); + + @Override + public void afterConnectionEstablished(WebSocketSession session) { + sessions.add(session); + } + + // 向所有客户端推送数据 + public static void broadcast(String message) { + for (WebSocketSession session : sessions) { + try { + if (session.isOpen()) { + session.sendMessage(new TextMessage(message)); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } +} diff --git a/src/main/java/com/mortal/bigmodelr/config/WebSocketConfig.java b/src/main/java/com/mortal/bigmodelr/config/WebSocketConfig.java new file mode 100644 index 0000000..04b72f7 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/config/WebSocketConfig.java @@ -0,0 +1,20 @@ +package com.mortal.bigmodelr.config; + + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +@Configuration +@EnableWebSocket +public class WebSocketConfig implements WebSocketConfigurer { + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(new MyWebSocketHandler(), "/visualModel/ws/data") + .setAllowedOrigins("*"); // 允许跨域 + + registry.addHandler(new MultimodalWebSocketHandler(), "/multimodal/ws/data") + .setAllowedOrigins("*"); + } +} \ No newline at end of file diff --git a/src/main/java/com/mortal/bigmodelr/controller/AnalysisController.java b/src/main/java/com/mortal/bigmodelr/controller/AnalysisController.java new file mode 100644 index 0000000..8cab3c3 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/controller/AnalysisController.java @@ -0,0 +1,47 @@ +package com.mortal.bigmodelr.controller; + +import com.mortal.bigmodelr.service.AlgorithmService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; + +@RestController +@CrossOrigin +public class AnalysisController { + + @Resource + private AlgorithmService algorithmService; + +// { +// "requestId": "72ae37f4b229445fb44701f724efaf55", +// "resultList": [ +// { +// "algFactory": "yd", +// "results": [ +// { +// "code": "2000", +// "pos": "[]", +// "resImageUrl": "1/2024/05/28/1216/CCD/1216_20240528100000_2024193_02160558340721910121.jpg", +// "conf": 0.99, +// "type": "", +// "value": "0", +// "desc": "" +// } +// ], +// "objectId": "2024193" +// } +// ] +// } + @PostMapping("/picAnalyse") + public ResponseEntity bigModelPicAnalyse(@RequestBody final String analyseRequestStr) { + return ResponseEntity.ok().body(algorithmService.bigModelPicAnalyse(analyseRequestStr)); + } + + @PostMapping("/picAnalyseRetNotify") + public ResponseEntity bigModelPicAnalyseRetNotify(@RequestBody String picAnalyseResult) { + return ResponseEntity + .ok() + .body(algorithmService.bigModelPicAnalyseRetNotify(picAnalyseResult)); + } +} diff --git a/src/main/java/com/mortal/bigmodelr/controller/ModelController.java b/src/main/java/com/mortal/bigmodelr/controller/ModelController.java new file mode 100644 index 0000000..d846c67 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/controller/ModelController.java @@ -0,0 +1,80 @@ +package com.mortal.bigmodelr.controller; + +import com.mortal.bigmodelr.domain.Multimodal; +import com.mortal.bigmodelr.domain.VisualModel; +import com.mortal.bigmodelr.service.ModelService; +import com.mortal.bigmodelr.utils.AjaxResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +@RestController +@CrossOrigin +public class ModelController { + + + @Resource + private ModelService modelService; + + @PostMapping("/model/analysis") + @ResponseBody + public String Visualization(@RequestBody VisualModel visualModel) + { + return modelService.Visualization(visualModel); + } + + @PostMapping("/model/multimodal") + @ResponseBody + public String Multimodal(@RequestBody Multimodal multimodal) + { + return modelService.Multimodal(multimodal); + } + + + @PostMapping("/model/xunWen") + @ResponseBody + public void runJob() { +// { +// "role": "user", +// "imageType": "image_url", +// "imageData": "/home/atia/bigModel/124.jpg", +// "model": "rsv-0zygizvz", +// "text": "这张图片存在什么问题缺陷吗?", +// "imageName": "121.jpg", +// "maxTokens": 300 +// } + //获取基本目录下当前日期的所有图片 + List enquire = modelService.enquire(); + for (int i = 0; i < enquire.size(); i++) { + Multimodal multimodal=new Multimodal(); + multimodal.setRole("user"); + multimodal.setImageType("image_url"); + multimodal.setText("这张图片存在什么问题缺陷吗"); + multimodal.setImageData(enquire.get(i)); + //询问多模态大模型 + modelService.Multimodal(multimodal); + } + + } + + //数据库照片下载 + @PostMapping("/model/downImg") + public void runJob2() { + modelService.downImg(); + } + + + + //测试(可正常) + @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/mortal/bigmodelr/domain/ApiResponse.java b/src/main/java/com/mortal/bigmodelr/domain/ApiResponse.java new file mode 100644 index 0000000..38da7a9 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/ApiResponse.java @@ -0,0 +1,15 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/ChatCompletionRequest.java b/src/main/java/com/mortal/bigmodelr/domain/ChatCompletionRequest.java new file mode 100644 index 0000000..beb23eb --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/ChatCompletionRequest.java @@ -0,0 +1,14 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/ChatCompletionResponse.java b/src/main/java/com/mortal/bigmodelr/domain/ChatCompletionResponse.java new file mode 100644 index 0000000..a7091ac --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/ChatCompletionResponse.java @@ -0,0 +1,33 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/Choice.java b/src/main/java/com/mortal/bigmodelr/domain/Choice.java new file mode 100644 index 0000000..4e9869b --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/Choice.java @@ -0,0 +1,13 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/Content.java b/src/main/java/com/mortal/bigmodelr/domain/Content.java new file mode 100644 index 0000000..dd62773 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/Content.java @@ -0,0 +1,17 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/ContentItem.java b/src/main/java/com/mortal/bigmodelr/domain/ContentItem.java new file mode 100644 index 0000000..38cee52 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/ContentItem.java @@ -0,0 +1,15 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/ImageUrl.java b/src/main/java/com/mortal/bigmodelr/domain/ImageUrl.java new file mode 100644 index 0000000..2959789 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/ImageUrl.java @@ -0,0 +1,9 @@ +package com.mortal.bigmodelr.domain; + +import lombok.Data; + +@Data +public class ImageUrl { + + private String url; +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/Message.java b/src/main/java/com/mortal/bigmodelr/domain/Message.java new file mode 100644 index 0000000..63ee674 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/Message.java @@ -0,0 +1,29 @@ +package com.mortal.bigmodelr.domain; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonSetter; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.Data; + + + +import java.util.Collections; +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/mortal/bigmodelr/domain/Multimodal.java b/src/main/java/com/mortal/bigmodelr/domain/Multimodal.java new file mode 100644 index 0000000..8b1908d --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/Multimodal.java @@ -0,0 +1,20 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/Usage.java b/src/main/java/com/mortal/bigmodelr/domain/Usage.java new file mode 100644 index 0000000..0d3e039 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/Usage.java @@ -0,0 +1,10 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/VisualModel.java b/src/main/java/com/mortal/bigmodelr/domain/VisualModel.java new file mode 100644 index 0000000..b6a9671 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/VisualModel.java @@ -0,0 +1,26 @@ +package com.mortal.bigmodelr.domain; + +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/mortal/bigmodelr/domain/algorithm/in/AnalyseConstants.java b/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseConstants.java new file mode 100644 index 0000000..e495678 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseConstants.java @@ -0,0 +1,35 @@ +package com.inspect.simulator.domain.algorithm.in; + +public class AnalyseConstants { + public static final String ANALYSE_FILTER_REQUEST = "ANALYSE_FILTER_REQUEST:"; + public static final String ANALYSE_REQUEST_ALG = "ANALYSE_REQUEST_ALG:"; + public static final String ANALYSE_TASK_REQUEST = "ANALYSE_TASK_REQUEST:"; + public static final String ANALYSE_REQUEST_ID = "ANALYSE_REQUEST_ID:"; + public static final String ANALYSE_OK = "2000"; + public static final String ANALYSE_FAIL_NO_FILE = "2001"; + public static final String ANALYSE_FAIL_ALG_EXCEPT = "2002"; + public static final String ANALYSE_FAIL_FILE_EXCEPT = "2003"; + public static final String ANALYSE_FAIL_FILE_INCOMPATIBLE = "2004"; + public static final String ANALYSE_CODE = "code"; + public static final String ANALYSE_UPPER_VALUE = "upperValue"; + public static final String ANALYSE_LOWER_VALUE = "lowerValue"; + public static final String ANALYSE_ALARM_THRESHOLD = "alarm_threshold"; + public static final String ANALYSE_VALUE_ERROR = "1"; + public static final String ANALYSE_SPLIT = "$analyse$"; + public static final String POINT_STATUS_FAIL = "0"; + public static final String POINT_STATUS_OK = "1"; + public static final String POINT_STATUS_PERSON = "2"; + public static final String RES_STATUS_UN = "0"; + public static final String RES_STATUS_ED = "1"; + public static final String RES_STATUS_NO = "2"; + public static final String RESULT_TYPE_ALARM = "0"; + public static final String RESULT_TYPE_RESULT = "1"; + public static final String RESULT_TYPE_ERROR = "2"; + public static final String TASK_PROGRESS_WAITING = "99.99"; + public static final String TASK_PROGRESS_OK = "100"; + public static final String ANALYSE_IS_FILTER = "ANALYSE_IS_FILTER"; + public static final String ANALYSE_IS_METER_FILTER = "ANALYSE_IS_METER_FILTER"; + public static final String ANALYSE_FILTER_URL = "ANALYSE_FILTER_URL"; + public static final String ANALYSIS_BIG_URL = "ANALYSIS_BIG_URL"; + public static final String MAX_NUM = "MAX_NUM"; +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseReqItem.java b/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseReqItem.java new file mode 100644 index 0000000..26d476a --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseReqItem.java @@ -0,0 +1,51 @@ +package com.mortal.bigmodelr.domain.algorithm.in; + + + +import com.alibaba.fastjson.JSONObject; +import lombok.*; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Objects; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AnalyseReqItem implements Serializable { + private String objectId; + private String imageNormalUrlPath; + private String[] typeList; + private String[] imageUrlList; + + public AnalyseReqItem clone() { + return JSONObject.parseObject(JSONObject.toJSONString(this), AnalyseReqItem.class); + } + + public String toResultValue(String type) { + return this.objectId + com.inspect.simulator.domain.algorithm.in.AnalyseConstants.ANALYSE_SPLIT + type; + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null || getClass() != object.getClass()) return false; + AnalyseReqItem that = (AnalyseReqItem) object; + return Objects.equals(objectId, that.objectId) && Objects.equals(imageNormalUrlPath, that.imageNormalUrlPath) && Objects.deepEquals(typeList, that.typeList) && Objects.deepEquals(imageUrlList, that.imageUrlList); + } + + @Override + public int hashCode() { + return Objects.hash(objectId, imageNormalUrlPath, Arrays.hashCode(typeList), Arrays.hashCode(imageUrlList)); + } + + @Override + public String toString() { + return "AnalyseReqItem{" + + "objectId='" + objectId + '\'' + + ", imageNormalUrlPath='" + imageNormalUrlPath + '\'' + + ", typeList=" + Arrays.toString(typeList) + + ", imageUrlList=" + Arrays.toString(imageUrlList) + + '}'; + } +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseRequest.java b/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseRequest.java new file mode 100644 index 0000000..90013ee --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/algorithm/in/AnalyseRequest.java @@ -0,0 +1,50 @@ +package com.mortal.bigmodelr.domain.algorithm.in; + +import com.alibaba.fastjson.JSONObject; + +import lombok.Getter; +import lombok.Setter; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Setter +@Getter +public class AnalyseRequest implements Serializable { + private List objectList; + private String requestHostIp; + private String requestHostPort; + private String requestId; + private String algorithmPath; + private String taskPatrolId; + private String sftpHostIp; + private String sftpHostPort; + private String sftpUsername; + private String sftpPassword; + + public AnalyseRequest clone() { + return JSONObject.parseObject(JSONObject.toJSONString(this), AnalyseRequest.class); + } + + + + public String toString() { + return JSONObject.toJSONString(this); + } + + @Override + public boolean equals(Object object) { + if (this == object) return true; + if (object == null || getClass() != object.getClass()) return false; + AnalyseRequest that = (AnalyseRequest) object; + return Objects.equals(objectList, that.objectList) && Objects.equals(requestHostIp, that.requestHostIp) && Objects.equals(requestHostPort, that.requestHostPort) && Objects.equals(requestId, that.requestId) && Objects.equals(algorithmPath, that.algorithmPath) && Objects.equals(taskPatrolId, that.taskPatrolId); + } + + @Override + public int hashCode() { + return Objects.hash(objectList, requestHostIp, requestHostPort, requestId, algorithmPath, taskPatrolId); + } + +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResItem.java b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResItem.java new file mode 100644 index 0000000..eb3fc95 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResItem.java @@ -0,0 +1,43 @@ +package com.mortal.bigmodelr.domain.algorithm.out; + + +import com.alibaba.fastjson.JSONObject; +import lombok.*; + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AnalyseResItem implements Serializable { + private String objectId; + private String algFactory; + private List results; + +// public AnalyseResItem clone() { +// return JSONObject.parseObject(JSONObject.toJSONString(this), AnalyseResItem.class); +// } +// +// @Override +// public boolean equals(Object object) { +// if (this == object) return true; +// if (object == null || getClass() != object.getClass()) return false; +// AnalyseResItem that = (AnalyseResItem) object; +// return Objects.equals(objectId, that.objectId) && Objects.equals(results, that.results); +// } +// +// @Override +// public int hashCode() { +// return Objects.hash(objectId, results); +// } +// +// @Override +// public String toString() { +// return "AnalyseResItem{" + +// "objectId='" + objectId + '\'' + +// ", results=" + results + +// '}'; +// } +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResPoint.java b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResPoint.java new file mode 100644 index 0000000..47b6270 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResPoint.java @@ -0,0 +1,127 @@ +package com.mortal.bigmodelr.domain.algorithm.out; + + +import com.alibaba.fastjson.JSONObject; +import com.inspect.simulator.domain.algorithm.in.AnalyseConstants; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.apache.commons.lang3.StringUtils; + + +import java.io.Serializable; +import java.util.List; +import java.util.Objects; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AnalyseResPoint implements Serializable { + private String type; +// private String Value; + private String value; + private String code; +// private String resImageUrl; + private String resImagePath; + private String imageNormalUrlPath; + private String conf; + private String desc; + private List pos; + +// public boolean checkSuccess() { +// return "2000".equals(this.code) && "1".equals(this.value); +// } +// +// public String toString() { +// return JSONObject.toJSONString(this); +// } +// +// public void setValue(String value) { +// this.value = value; +// if (!StringUtils.isEmpty(value)) { +// this.Value = value; +// } +// +// } +// +// public String toResultValue(String objectId) { +// return objectId + AnalyseConstants.ANALYSE_SPLIT + this.type; +// } +// +// public AnalyseResPoint clone() { +// return JSONObject.parseObject(JSONObject.toJSONString(this), AnalyseResPoint.class); +// } +// +// public String getType() { +// return this.type; +// } +// +// public String getValue() { +// return this.Value; +// } +// +// public String getCode() { +// return this.code; +// } +// +// public String getResImageUrl() { +// return this.resImageUrl; +// } +// +// public String getImageNormalUrlPath() { +// return this.imageNormalUrlPath; +// } +// +// public String getConf() { +// return this.conf; +// } +// +// public String getDesc() { +// return this.desc; +// } +// +// public List getPos() { +// return this.pos; +// } +// +// public void setType(String type) { +// this.type = type; +// } +// +// public void setCode(String code) { +// this.code = code; +// } +// +// public void setResImageUrl(String resImageUrl) { +// this.resImageUrl = resImageUrl; +// } +// +// public void setImageNormalUrlPath(String imageNormalUrlPath) { +// this.imageNormalUrlPath = imageNormalUrlPath; +// } +// +// public void setConf(String conf) { +// this.conf = conf; +// } +// +// public void setDesc(String desc) { +// this.desc = desc; +// } +// +// public void setPos(List pos) { +// this.pos = pos; +// } +// +// @Override +// public boolean equals(Object object) { +// if (this == object) return true; +// if (object == null || getClass() != object.getClass()) return false; +// AnalyseResPoint that = (AnalyseResPoint) object; +// return Objects.equals(type, that.type) && Objects.equals(Value, that.Value) && Objects.equals(value, that.value) && Objects.equals(code, that.code) && Objects.equals(resImageUrl, that.resImageUrl) && Objects.equals(imageNormalUrlPath, that.imageNormalUrlPath) && Objects.equals(conf, that.conf) && Objects.equals(desc, that.desc) && Objects.equals(pos, that.pos); +// } +// +// @Override +// public int hashCode() { +// return Objects.hash(type, Value, value, code, resImageUrl, imageNormalUrlPath, conf, desc, pos); +// } +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResult.java b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResult.java new file mode 100644 index 0000000..93485a4 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/AnalyseResult.java @@ -0,0 +1,100 @@ +package com.mortal.bigmodelr.domain.algorithm.out; + + +import com.mortal.bigmodelr.domain.algorithm.in.AnalyseReqItem; +import com.mortal.bigmodelr.domain.algorithm.in.AnalyseRequest; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +@Data +@AllArgsConstructor +@NoArgsConstructor +public class AnalyseResult implements Serializable { + private String requestId; + private List resultList; + private List resultsList; + private String taskPatrolId; + private String filter = "0"; + private String result = "1"; + +// public void setResultsList(List resultsList) { +// this.resultsList = resultsList; +// if (resultsList != null) { +// this.resultList = resultsList; +// } +// +// } +// +// public void reloadReq(AnalyseRequest analyseRequest) { +// AnalyseResItem analyseResItem = this.resultList.get(0); +// List resultList = new ArrayList<>(); +// this.setResultsList(resultList); +// +// for (int i = 0; i < analyseRequest.getObjectList().size(); ++i) { +// AnalyseResItem resItem = analyseResItem.clone(); +// resultList.add(resItem); +// AnalyseReqItem analyseReqItem = analyseRequest.getObjectList().get(i); +// AnalyseResPoint resPoint = analyseResItem.getResults().get(0); +// List results = new ArrayList<>(); +// resItem.setResults(results); +// for (String type : analyseReqItem.getTypeList()) { +// AnalyseResPoint clone = resPoint.clone(); +// clone.setType(type); +// results.add(clone); +// } +// } +// +// } +// +// public void setRequestId(String requestId) { +// this.requestId = requestId; +// } +// +// public void setResultList(List resultList) { +// this.resultList = resultList; +// } +// +// public void setTaskPatrolId(String taskPatrolId) { +// this.taskPatrolId = taskPatrolId; +// } +// +// public void setFilter(String filter) { +// this.filter = filter; +// } +// +// public void setResult(String result) { +// this.result = result; +// } +// +// @Override +// public boolean equals(Object object) { +// if (this == object) return true; +// if (object == null || getClass() != object.getClass()) return false; +// AnalyseResult that = (AnalyseResult) object; +// return Objects.equals(requestId, that.requestId) && Objects.equals(resultList, that.resultList) && Objects.equals(resultsList, that.resultsList) && Objects.equals(taskPatrolId, that.taskPatrolId) && Objects.equals(filter, that.filter) && Objects.equals(result, that.result); +// } +// +// @Override +// public int hashCode() { +// return Objects.hash(requestId, resultList, resultsList, taskPatrolId, filter, result); +// } +// +// @Override +// public String toString() { +// return "AnalyseResult{" + +// "requestId='" + requestId + '\'' + +// ", resultList=" + resultList + +// ", resultsList=" + resultsList + +// ", taskPatrolId='" + taskPatrolId + '\'' + +// ", filter='" + filter + '\'' + +// ", result='" + result + '\'' + +// '}'; +// } +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/Pos.java b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/Pos.java new file mode 100644 index 0000000..d42d6a3 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/algorithm/out/Pos.java @@ -0,0 +1,12 @@ +package com.mortal.bigmodelr.domain.algorithm.out; + +import lombok.*; + +@Data +@AllArgsConstructor +@NoArgsConstructor + +public class Pos { + private String[] areas; + +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/analysis/vi/AnalysisObject.java b/src/main/java/com/mortal/bigmodelr/domain/analysis/vi/AnalysisObject.java new file mode 100644 index 0000000..1891a51 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/analysis/vi/AnalysisObject.java @@ -0,0 +1,19 @@ +package com.mortal.bigmodelr.domain.analysis.vi; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class AnalysisObject { + private String objectId; + private String imageNormalUrlPath; + private List typeList; + private List imageUrlList; +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/analysis/vi/AnalysisRequest.java b/src/main/java/com/mortal/bigmodelr/domain/analysis/vi/AnalysisRequest.java new file mode 100644 index 0000000..33cea3b --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/analysis/vi/AnalysisRequest.java @@ -0,0 +1,20 @@ +package com.mortal.bigmodelr.domain.analysis.vi; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.util.List; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class AnalysisRequest { + private String requestId; + private String taskPatrolId; + private String requestHostIp; + private String requestHostPort; + private List objectList; +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResult.java b/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResult.java new file mode 100644 index 0000000..513b30d --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResult.java @@ -0,0 +1,23 @@ +package com.mortal.bigmodelr.domain.analysis.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class AnalysisResult implements Serializable { + private String code; + private List pos; + private String resImageUrl; + private Double conf; + private String type; + private String value; + private String desc; +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResultEntity.java b/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResultEntity.java new file mode 100644 index 0000000..ace440f --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResultEntity.java @@ -0,0 +1,18 @@ +package com.mortal.bigmodelr.domain.analysis.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class AnalysisResultEntity implements Serializable { + private String requestId; + private List resultList; +} diff --git a/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResultList.java b/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResultList.java new file mode 100644 index 0000000..64593a2 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/domain/analysis/vo/AnalysisResultList.java @@ -0,0 +1,19 @@ +package com.mortal.bigmodelr.domain.analysis.vo; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import lombok.experimental.SuperBuilder; + +import java.io.Serializable; +import java.util.List; + +@Data +@SuperBuilder +@NoArgsConstructor +@AllArgsConstructor +public class AnalysisResultList implements Serializable { + private String algFactory; + private String objectId; + private List results; +} diff --git a/src/main/java/com/mortal/bigmodelr/mapper/multimodalMapper.java b/src/main/java/com/mortal/bigmodelr/mapper/multimodalMapper.java new file mode 100644 index 0000000..9d46a6d --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/mapper/multimodalMapper.java @@ -0,0 +1,17 @@ +package com.mortal.bigmodelr.mapper; + + +import com.mortal.bigmodelr.domain.ChatCompletionResponse; +import com.mortal.bigmodelr.domain.VisualModel; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface multimodalMapper { + + int addMultimodalModelInfo(ChatCompletionResponse completionResponse); + + + +} diff --git a/src/main/java/com/mortal/bigmodelr/mapper/visualModelMapper.java b/src/main/java/com/mortal/bigmodelr/mapper/visualModelMapper.java new file mode 100644 index 0000000..280fc8a --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/mapper/visualModelMapper.java @@ -0,0 +1,16 @@ +package com.mortal.bigmodelr.mapper; + + +import com.mortal.bigmodelr.domain.VisualModel; +import org.apache.ibatis.annotations.Mapper; + +import java.util.List; + +@Mapper +public interface visualModelMapper { + + int addVisualModelInfo(List visualModels); + + + List selectImgUrl(); +} diff --git a/src/main/java/com/mortal/bigmodelr/service/AlgorithmService.java b/src/main/java/com/mortal/bigmodelr/service/AlgorithmService.java new file mode 100644 index 0000000..3e58455 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/service/AlgorithmService.java @@ -0,0 +1,7 @@ +package com.mortal.bigmodelr.service; + +public interface AlgorithmService { + String bigModelPicAnalyse(final String analyseRequestStr); + + String bigModelPicAnalyseRetNotify(final String picAnalyseResult); +} diff --git a/src/main/java/com/mortal/bigmodelr/service/ModelService.java b/src/main/java/com/mortal/bigmodelr/service/ModelService.java new file mode 100644 index 0000000..4ac3814 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/service/ModelService.java @@ -0,0 +1,26 @@ +package com.mortal.bigmodelr.service; + +import com.mortal.bigmodelr.domain.Multimodal; +import com.mortal.bigmodelr.domain.VisualModel; +import org.springframework.http.ResponseEntity; + +import java.util.List; + +public interface ModelService { + + //视觉大模型服务接口 + String Visualization(VisualModel visualModel); + + //多模态大模型 + public String Multimodal(Multimodal multimodal); + + //语义大模型 + public String semanticsModel(Multimodal multimodal); + + //所有缺陷图片路径 + public List enquire(); + + //图片下载到本地 + public void downImg(); + +} diff --git a/src/main/java/com/mortal/bigmodelr/service/impl/AlgorithmServiceImpl.java b/src/main/java/com/mortal/bigmodelr/service/impl/AlgorithmServiceImpl.java new file mode 100644 index 0000000..4cbb4cd --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/service/impl/AlgorithmServiceImpl.java @@ -0,0 +1,107 @@ +package com.mortal.bigmodelr.service.impl; + +import com.google.gson.Gson; +import com.mortal.bigmodelr.domain.Multimodal; +import com.mortal.bigmodelr.domain.algorithm.in.AnalyseRequest; +import com.mortal.bigmodelr.domain.algorithm.out.AnalyseResItem; +import com.mortal.bigmodelr.domain.algorithm.out.AnalyseResPoint; +import com.mortal.bigmodelr.domain.algorithm.out.AnalyseResult; +import com.mortal.bigmodelr.service.AlgorithmService; +import com.mortal.bigmodelr.service.ModelService; +import com.mortal.bigmodelr.service.remote.AnalysisRemoteService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import retrofit2.Call; +import retrofit2.Response; + +import javax.annotation.Resource; +import java.awt.*; +import java.util.ArrayList; +import java.util.List; + +@Service +public class AlgorithmServiceImpl implements AlgorithmService { + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + @Value("${file.infraredPath:null}") + private String infraredPath; + + @Resource + private AnalysisRemoteService analysisRemoteService; + @Resource + private ModelService modelService; + @Override + public String bigModelPicAnalyse(String analyseRequestStr) { + log.info(Color.MAGENTA + "[BIG MODEL] bigModelPicAnalyse: analyseRequestStr={}", analyseRequestStr); + AnalyseRequest analyseRequest = new Gson().fromJson(analyseRequestStr, AnalyseRequest.class); + + Multimodal multimodal=new Multimodal(); + multimodal.setModel("rsv-0zygizvz"); + multimodal.setText("详细描述一下这张图片中的内容"); + multimodal.setImageType("image_url"); + multimodal.setImageData(analyseRequest.getObjectList().get(0).getImageUrlList()[0]); + //调用多模态大模型,语义大模型; + String multimodalResult = modelService.Multimodal(multimodal); + + + //返回结构体 + String[] typeList = analyseRequest.getObjectList().get(0).getTypeList(); + String typeListStr = String.join(",", typeList); + AnalyseResult analyseResult = new AnalyseResult(); + analyseResult.setRequestId(analyseRequest.getRequestId()); + AnalyseResPoint analyseResPoint = new AnalyseResPoint(); + analyseResPoint.setValue("1"); + analyseResPoint.setConf("0.95"); + analyseResPoint.setCode("2000"); + analyseResPoint.setType(typeListStr); + analyseResPoint.setResImagePath(analyseRequest.getObjectList().get(0).getImageUrlList()[0]); + + List analyseResPoints = new ArrayList<>(); + analyseResPoints.add(analyseResPoint); + + AnalyseResItem analyseResItem = new AnalyseResItem(); + analyseResItem.setObjectId(analyseRequest.getObjectList().get(0).getObjectId()); +// analyseResItem.setAlgFactory("yd"); + analyseResItem.setResults(analyseResPoints); + + List analyseResItems = new ArrayList<>(); + analyseResItems.add(analyseResItem); + analyseResult.setResultList(analyseResItems); + + if (infraredPath.equals("null")) { + // 如果nacos中没有配置红外路径,则将结果返回调用方 + try { +// Call call = analysisRemoteService.picAnalyseRetNotify(analyseResult); +// Response response = call.execute(); +// System.out.println("result: " + result); + + System.out.println(new Gson().toJson(analyseResult)); + + + } catch (Exception e) { + e.printStackTrace(); + } + } + return "{\"code\":\"200\"}"; + + } + + + @Override + public String bigModelPicAnalyseRetNotify(final String picAnalyseResult) { + AnalyseResult analyseResult = new Gson().fromJson(picAnalyseResult, AnalyseResult.class); + log.info(Color.MAGENTA + "[BIG MODEL] bigModelPicAnalyseRetNotify: picAnalyseResultStr={}, picAnalyseResult: {}", picAnalyseResult, analyseResult); + try { + Call call = analysisRemoteService.picAnalyseRetNotify(analyseResult); + Response response = call.execute(); + Object result = response.body(); + System.out.println("result: " + result); + } catch (Exception e) { + e.printStackTrace(); + } + return ""; + } + +} diff --git a/src/main/java/com/mortal/bigmodelr/service/impl/ModelServiceImpl.java b/src/main/java/com/mortal/bigmodelr/service/impl/ModelServiceImpl.java new file mode 100644 index 0000000..90c849a --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/service/impl/ModelServiceImpl.java @@ -0,0 +1,550 @@ +package com.mortal.bigmodelr.service.impl; + + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.*; +import com.mortal.bigmodelr.config.MultimodalWebSocketHandler; +import com.mortal.bigmodelr.config.MyWebSocketHandler; +import com.mortal.bigmodelr.domain.*; +import com.mortal.bigmodelr.mapper.multimodalMapper; +import com.mortal.bigmodelr.mapper.visualModelMapper; +import com.mortal.bigmodelr.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.*; +import java.net.HttpURLConnection; +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; + +import static com.mortal.bigmodelr.test.BatchImageDownloader.batchDownloadImages; + +@Service +public class ModelServiceImpl implements ModelService { + + @Value("${file.baseUrl}") + private String baseUrl; + + @Value("${file.apiPath}") + private String apiPath; + + @Value("${file.multimodalPath}") + private String multimodalPath; + + @Value("${file.semanticsModalPath}") + private String semanticsModalPath; + +// @Value("${file.semanticsModalAsk}") +// private String semanticsModalAsk; + + @Value("${file.authKey}") + private String authKey; + + @Value("${file.model}") + private String model; + + @Value("${file.picPath}") + private String picPath; + + + //智能巡视图片存放的基础目录 + @Value("${file.baseDirectory}") + private String baseDirectory; + +// private String baseDirectory = "C:\\Users\\王寻\\Desktop\\1111\\1"; + + // 设置支持的图片文件扩展名 + 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(); + + @Resource + private visualModelMapper visualModelMapper; + @Resource + private multimodalMapper multimodalMapper; + + public ModelServiceImpl() { + // 设置JSON序列化时忽略null值 + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + } + //视觉大模型 + @Override + public String Visualization(VisualModel visualModel) { + System.out.println("请求路径:"+baseUrl+apiPath+"使用密钥:"+authKey+"使用模型id"+model); + + System.out.println("访问的图片地址"+picPath); + String base64String = convertToBase64(picPath); + + List visualModels=new ArrayList<>(); +// 测试连接------------------- + // 1. 创建WebSocket处理器 + MyWebSocketHandler webSocketHandler = new MyWebSocketHandler(); + +// // 2. 生成100条数据并逐条推送 +// JsonArray mockDataArray = new JsonArray(); +// Random random = new Random(); +// +// for (int i = 1; i <= 100; i++) { +// // 生成单条数据 + +// JsonObject item = new JsonObject(); +// item.addProperty("id", i); +// item.addProperty("name", "Item-" + i); +// item.addProperty("value", random.nextInt(1000)); // 随机值0-999 +// +// // 将单条数据转为JSON字符串并推送 +// String itemJson = item.toString(); +// webSocketHandler.broadcast(itemJson); // 推送当前条目 +// +// VisualModel visual=new VisualModel(); +// visual.setStringData(itemJson); +// visualModels.add(visual); +// +// // 可选:添加延迟(模拟实时推送效果) +// try { +// Thread.sleep(100); // 延迟100毫秒 +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// +// // 如果需要,仍可保留添加到数组的逻辑(非必须) +// mockDataArray.add(item); +// } + + + +// -------------------- + OkHttpClient client = new OkHttpClient(); + // 使用 Map 和 List 动态构建 JSON 结构 + Map requestBody = new HashMap<>(); + Map imageData = new HashMap<>(); + imageData.put("image_name", "111.jpg"); + imageData.put("image_type", "base64"); + imageData.put("image_data", base64String); + requestBody.put("data", Collections.singletonList(imageData)); + requestBody.put("model", model); + + Gson gson = new Gson(); + String jsonBody = gson.toJson(requestBody); + + RequestBody body = RequestBody.create(jsonBody, MediaType.parse("application/json")); + + Request request = new Request.Builder() + .url(baseUrl + apiPath) + .post(body) + .addHeader("Content-Type", "application/json") + .addHeader("Authorization", authKey) + .build(); + try (Response response = client.newCall(request).execute()) { + System.out.println("打印response"+response); + if (!response.isSuccessful()) { + throw new IOException("请求失败: " + response.code()); + } + + if (response.body() != null) { + String responseBody = response.body().string(); + System.out.println("返回数据String"+responseBody); + +// webSocketHandler.broadcast(responseBody); // 推送当前条目 +// VisualModel visual=new VisualModel(); +// visual.setStringData(responseBody); +// visualModels.add(visual); + +// JsonObject jsonResponse = JsonParser.parseString(responseBody).getAsJsonObject(); +//// 解析返回数据 +// // 提取基础字段 +// String traceld = jsonResponse.get("traceld").getAsString(); +// boolean success = jsonResponse.get("success").getAsBoolean(); +// System.out.println("traceld: " + traceld); +// System.out.println("success: " + success); +// +// // 解析 data 对象 +// JsonObject data = jsonResponse.getAsJsonObject("data"); +// String imageName = data.get("image_name").getAsString(); +// int imageHeight = data.get("image_height").getAsInt(); +// int imageWidth = data.get("image_width").getAsInt(); +// System.out.println("\n图片信息:"); +// System.out.println(" name: " + imageName); +// System.out.println(" height: " + imageHeight); +// System.out.println(" width: " + imageWidth); +// +// // 解析 infer_results 数组 +// JsonArray inferResults = data.getAsJsonArray("infer_results"); +// System.out.println("\n推理结果:"); +// for (JsonElement element : inferResults) { +// JsonObject result = element.getAsJsonObject(); +// JsonArray bbox = result.getAsJsonArray("bbox"); +// String category = result.get("category").getAsString(); +// float score = result.get("score").getAsFloat(); +// +// System.out.println(" category: " + category); +// System.out.println(" score: " + score); +// System.out.println(" bbox: [" + +// bbox.get(0).getAsInt() + ", " + +// bbox.get(1).getAsInt() + ", " + +// bbox.get(2).getAsInt() + ", " + +// bbox.get(3).getAsInt() + "]"); +// } + }else { + System.out.println("无返回内容!!!"); + System.out.println("请求返回数据"+response.body()); + } + } catch (IOException e) { + e.printStackTrace(); + } + //添加到数据库 + if (visualModels.size()>0){ + visualModelMapper.addVisualModelInfo(visualModels); + } + return ""; + } + + + //图片路径转base64 + public String convertToBase64(String imagePath) { + try { + byte[] imageBytes = Files.readAllBytes(Paths.get(imagePath)); + return Base64.getEncoder().encodeToString(imageBytes); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + + //多模态大模型 + public String Multimodal(Multimodal multimodal) { + System.out.println("请求路径:" + baseUrl + multimodalPath); + MultimodalWebSocketHandler webSocketHandler = new MultimodalWebSocketHandler(); + // 重试次数 + int maxRetries = 3; + int attempt = 0; + + while (attempt < maxRetries) { + try { + attempt++; + ChatCompletionRequest request = buildCorrectRequest(multimodal); + ChatCompletionResponse response = sendRequest(request); + System.out.println("响应ID: " + response.getId()); + + String content = String.valueOf(response.getChoices().get(0).getMessage().getContent()); +// ChatCompletionResponse completionResponse=new ChatCompletionResponse(); +// completionResponse.setContent(content); +// completionResponse.setPicPath(multimodal.getImageData()); +// completionResponse.setId(response.getId()); +// completionResponse.setInfo(response.toString()); + // 存入数据库 +// if (completionResponse!=null) { +// multimodalMapper.addMultimodalModelInfo(completionResponse); +// } + + //调用语义大模型 + Multimodal askSemanticsModel =new Multimodal(); + askSemanticsModel.setText(content); + this.semanticsModel(askSemanticsModel); + + return processResponse(response); + } catch (SocketTimeoutException e) { + if (attempt == maxRetries) { + webSocketHandler.broadcast("请求超时,已达最大重试次数"); + return "请求超时,请稍后重试"; + } + System.out.println("第" + attempt + "次尝试超时,准备重试..."); + try { + Thread.sleep(1000 * attempt); // 指数退避 + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + } + } catch (Exception e) { + e.printStackTrace(); + webSocketHandler.broadcast("请求失败: " + e.getMessage()); + return "请求处理失败: " + e.getMessage(); + } + } + return "请求处理失败"; + } + + /** + * 构建符合规范的请求体 + */ + private ChatCompletionRequest buildCorrectRequest(Multimodal multimodal) { + ChatCompletionRequest request = new ChatCompletionRequest(); + // 设置模型名称,默认"rsv-0zygizvz" + request.setModel(multimodal.getModel() != null ? multimodal.getModel() : "rsv-0zygizvz"); + + // 构建消息内容列表 + List contents = new ArrayList<>(); + + // 添加文本内容 + if (StringUtils.isNotBlank(multimodal.getText())) { + Content textContent = new Content(); + textContent.setType("text"); + textContent.setText(multimodal.getText()); + contents.add(textContent); + } else { + // 默认文本 + Content textContent = new Content(); + textContent.setType("text"); + textContent.setText("图片设备是否存在缺陷情况?"); + contents.add(textContent); + } + + // 添加图片内容 + if (StringUtils.isNotBlank(multimodal.getImageData())) { + Content imageContent = new Content(); + imageContent.setType("image_url"); + + ImageUrl imageUrl = new ImageUrl(); + // 获取文件扩展名,默认为jpg + String fileExtension = "jpg"; + if (StringUtils.isNotBlank(multimodal.getImageName())) { + int lastDot = multimodal.getImageName().lastIndexOf('.'); + if (lastDot > 0) { + fileExtension = multimodal.getImageName().substring(lastDot + 1).toLowerCase(); + } + } + + // 转换图片为base64 + String base64String = convertToBase64(multimodal.getImageData()); + imageUrl.setUrl("data:image/" + fileExtension + ";base64," + base64String); + + imageContent.setImageUrl(imageUrl); + contents.add(imageContent); + } + // 构建消息 + Message message = new Message(); + message.setRole(StringUtils.isNotBlank(multimodal.getRole()) ? multimodal.getRole() : "user"); + message.setContent(contents); + + // 设置max_tokens,默认300 + request.setMaxTokens(multimodal.getMaxTokens() > 0 ? multimodal.getMaxTokens() : 300); + request.setMessages(Collections.singletonList(message)); + + return request; + } + + private ChatCompletionResponse sendRequest(ChatCompletionRequest request) throws IOException { + + MultimodalWebSocketHandler webSocketHandler = new MultimodalWebSocketHandler(); + String requestBody; + try { + requestBody = objectMapper.writeValueAsString(request); + } catch (JsonProcessingException e) { + throw new IOException("请求体序列化失败", e); + } + + Request httpRequest = new Request.Builder() + .url(baseUrl + multimodalPath) + .post(RequestBody.create(requestBody, MediaType.parse("application/json"))) + .addHeader("Authorization", authKey) + .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); + + // 发送WebSocket通知 + webSocketHandler.broadcast(responseBody); + + return objectMapper.readValue(responseBody, ChatCompletionResponse.class); + + } catch (SocketTimeoutException e) { + throw new IOException("请求超时,请检查网络连接或增加超时时间", e); + } + } + + private String processResponse(ChatCompletionResponse response) { + if (response == null || response.getChoices() == null || response.getChoices().isEmpty()) { + return "未收到有效响应"; + } + return java.lang.String.valueOf(response.getChoices().get(0).getMessage().getContent()); + } + + + + + + + + //调用语义大模型接口 + 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(baseUrl + semanticsModalPath) + .post(RequestBody.create(requestBody, MediaType.parse("application/json"))) + .addHeader("Authorization", "Bearer "+authKey) + .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); + } + } + + + + + + + + /** + *获取根目录下当前日期的所有图片 + */ + public List enquire() { + String currentDatePath = getCurrentDatePath(); + // 获取日期目录下所有图片 + List allImages = getAllImagesUnderDateDir(baseDirectory, currentDatePath); + return allImages; + + } + + /** + * 获取当前日期的文件夹路径格式(年/月/日) + * @return 格式化的日期路径字符串 + */ + private static String getCurrentDatePath() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd"); + return sdf.format(new Date()); + } + + /** + * 获取指定日期目录下所有子目录中的图片文件路径 + * @param baseDir 基础目录路径 + * @param datePath 日期路径(格式:yyyy/MM/dd) + * @return 包含基础目录的完整图片路径列表 + */ + public static List getAllImagesUnderDateDir(String baseDir, String datePath) { + List imagePaths = new ArrayList<>(); + Path dateDirPath = Paths.get(baseDir, datePath); + + // 检查日期目录是否存在 + if (!Files.exists(dateDirPath)) { + System.out.println("日期目录不存在: " + dateDirPath); + return imagePaths; + } + + try (Stream walk = Files.walk(dateDirPath)) { + imagePaths = walk + .filter(Files::isRegularFile) + .filter(path -> isImageFile(path.getFileName().toString())) + .map(path -> path.toString().replace("\\", "/")) + .collect(Collectors.toList()); + } catch (IOException e) { + System.err.println("遍历目录时出错: " + e.getMessage()); + } + return imagePaths; + } + + /** + * 检查文件是否是图片文件 + * @param fileName 文件名 + * @return 是否是图片文件 + */ + private static boolean isImageFile(String fileName) { + String lowerFileName = fileName.toLowerCase(); + return IMAGE_EXTENSIONS.stream() + .anyMatch(lowerFileName::endsWith); + } + + + + + private static final int DEFAULT_THREADS = 5; + private static final int DEFAULT_TIMEOUT = 10000; // 10秒超时 + public void downImg() { + List imageUrls = visualModelMapper.selectImgUrl(); + + batchDownloadImages(imageUrls, "C:\\Users\\王寻\\Desktop\\1111\\大模型\\模型图片集", DEFAULT_THREADS, DEFAULT_TIMEOUT); + } + + + + + + + + + +} diff --git a/src/main/java/com/mortal/bigmodelr/service/remote/AnalysisRemoteService.java b/src/main/java/com/mortal/bigmodelr/service/remote/AnalysisRemoteService.java new file mode 100644 index 0000000..5274145 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/service/remote/AnalysisRemoteService.java @@ -0,0 +1,17 @@ +package com.mortal.bigmodelr.service.remote; + + +import com.mortal.bigmodelr.domain.algorithm.out.AnalyseResult; +import com.mortal.bigmodelr.domain.analysis.vo.AnalysisResultEntity; +import retrofit2.Call; +import retrofit2.http.Body; +import retrofit2.http.POST; + +public interface AnalysisRemoteService { + @POST("picAnalyseRetNotify") + Call analysisResultNotify(@Body AnalysisResultEntity analysisResultEntity); + + @POST("picAnalyseRetNotify") + Call picAnalyseRetNotify(@Body AnalyseResult analyseResult); +} + diff --git a/src/main/java/com/mortal/bigmodelr/service/remote/impl/AnalysisRemoteServiceImpl.java b/src/main/java/com/mortal/bigmodelr/service/remote/impl/AnalysisRemoteServiceImpl.java new file mode 100644 index 0000000..fa6c361 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/service/remote/impl/AnalysisRemoteServiceImpl.java @@ -0,0 +1,42 @@ +package com.mortal.bigmodelr.service.remote.impl; + + + +import com.mortal.bigmodelr.domain.algorithm.out.AnalyseResult; +import com.mortal.bigmodelr.domain.analysis.vo.AnalysisResultEntity; +import com.mortal.bigmodelr.service.remote.AnalysisRemoteService; +import lombok.EqualsAndHashCode; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.stereotype.Service; +import retrofit2.Call; +import retrofit2.Retrofit; + +import javax.annotation.PostConstruct; + +@EqualsAndHashCode +@Service +public class AnalysisRemoteServiceImpl implements AnalysisRemoteService { + + private final Retrofit retrofit; + + private AnalysisRemoteService analysisRemoteService; + + public AnalysisRemoteServiceImpl(@Qualifier("RetrofitOfAnalysis") Retrofit retrofit) { + this.retrofit = retrofit; + } + + @PostConstruct + public void setup() { + analysisRemoteService = retrofit.create(AnalysisRemoteService.class); + } + + @Override + public Call analysisResultNotify(AnalysisResultEntity analysisResultEntity) { + return analysisRemoteService.analysisResultNotify(analysisResultEntity); + } + + @Override + public Call picAnalyseRetNotify(AnalyseResult analyseResult) { + return analysisRemoteService.picAnalyseRetNotify(analyseResult); + } +} diff --git a/src/main/java/com/mortal/bigmodelr/task/ModelTask.java b/src/main/java/com/mortal/bigmodelr/task/ModelTask.java new file mode 100644 index 0000000..efee845 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/task/ModelTask.java @@ -0,0 +1,45 @@ +package com.mortal.bigmodelr.task; + + +import com.mortal.bigmodelr.domain.Multimodal; +import com.mortal.bigmodelr.service.ModelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +@Component +public class ModelTask { + + @Resource + private ModelService modelService; + + //每天18点执行对当天的图片询问多模态大模型 +// @Scheduled(cron = "0 0 18 * * ?") + public void runJob() { +// { +// "role": "user", +// "imageType": "image_url", +// "imageData": "/home/atia/bigModel/124.jpg", +// "model": "rsv-0zygizvz", +// "text": "这张图片存在什么问题缺陷吗?", +// "imageName": "121.jpg", +// "maxTokens": 300 +// } + //获取基本目录下当前日期的所有图片 + List enquire = modelService.enquire(); + for (int i = 0; i < enquire.size(); i++) { + Multimodal multimodal=new Multimodal(); + multimodal.setRole("user"); + multimodal.setImageType("image_url"); + multimodal.setText("这张图片存在什么问题缺陷吗"); + multimodal.setImageData(enquire.get(i)); + //询问多模态大模型 + modelService.Multimodal(multimodal); + } + + } + +} diff --git a/src/main/java/com/mortal/bigmodelr/test/BatchImageDownloader.java b/src/main/java/com/mortal/bigmodelr/test/BatchImageDownloader.java new file mode 100644 index 0000000..e51de3a --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/test/BatchImageDownloader.java @@ -0,0 +1,146 @@ +package com.mortal.bigmodelr.test; + +import com.mortal.bigmodelr.mapper.visualModelMapper; + +import javax.annotation.Resource; +import java.io.*; +import java.net.*; +import java.nio.file.*; +import java.util.*; +import java.util.concurrent.*; + +//批量缺陷图片下载 +public class BatchImageDownloader { + + + + /** + * 批量下载图片 + * @param imageUrls 图片URL列表 + * @param saveDir 本地保存目录 + * @param threadCount 线程数 + * @param timeout 超时时间(毫秒) + */ + public static void batchDownloadImages(List imageUrls, String saveDir, + int threadCount, int timeout) { + // 创建线程池 + ExecutorService executor = Executors.newFixedThreadPool(threadCount); + List> futures = new ArrayList<>(); + + try { + // 创建保存目录 + Path dirPath = Paths.get(saveDir); + if (!Files.exists(dirPath)) { + Files.createDirectories(dirPath); + } + + // 提交下载任务 + for (String url : imageUrls) { + Future future = executor.submit(() -> { + try { + String fileName = extractFileName(url); + Path savePath = dirPath.resolve(fileName); + return downloadSingleImage(url, savePath.toString(), timeout); + } catch (Exception e) { + return new DownloadResult(url, false, e.getMessage()); + } + }); + futures.add(future); + } + + // 统计结果 + int successCount = 0; + for (Future future : futures) { + DownloadResult result = future.get(); + if (result.success) { + successCount++; + System.out.printf("下载成功: %s -> %s%n", result.url, result.message); + } else { + System.err.printf("下载失败: %s, 原因: %s%n", result.url, result.message); + } + } + + System.out.printf("批量下载完成! 成功: %d, 失败: %d%n", + successCount, imageUrls.size() - successCount); + } catch (Exception e) { + System.err.println("批量下载出错: " + e.getMessage()); + } finally { + executor.shutdown(); + } + } + + /** + * 下载单个图片 + */ + private static DownloadResult downloadSingleImage(String imageUrl, String savePath, int timeout) + throws IOException { + HttpURLConnection conn = null; + try { + URL url = new URL(imageUrl); + conn = (HttpURLConnection) url.openConnection(); + conn.setRequestMethod("GET"); + conn.setConnectTimeout(timeout); + conn.setReadTimeout(timeout); + + // 检查响应码 + int responseCode = conn.getResponseCode(); + if (responseCode != HttpURLConnection.HTTP_OK) { + return new DownloadResult(imageUrl, false, + "HTTP错误码: " + responseCode); + } + + // 获取文件类型 + String contentType = conn.getContentType(); + if (!contentType.startsWith("image/")) { + return new DownloadResult(imageUrl, false, + "不是图片类型: " + contentType); + } + + // 下载文件 + try (InputStream in = conn.getInputStream()) { + Files.copy(in, Paths.get(savePath), StandardCopyOption.REPLACE_EXISTING); + return new DownloadResult(imageUrl, true, savePath); + } + } finally { + if (conn != null) conn.disconnect(); + } + } + + /** + * 从URL提取文件名 + */ + private static String extractFileName(String url) { + String fileName = url.substring(url.lastIndexOf('/') + 1); + if (fileName.isEmpty()) { + fileName = "image_" + System.currentTimeMillis() + ".jpg"; + } + + // 移除URL参数 + if (fileName.contains("?")) { + fileName = fileName.substring(0, fileName.indexOf('?')); + } + + return fileName; + } + + /** + * 下载结果封装类 + */ + private static class DownloadResult { + String url; + boolean success; + String message; + + DownloadResult(String url, boolean success, String message) { + this.url = url; + this.success = success; + this.message = message; + } + } + +// public static void main(String[] args) { +// List imageUrls = visualModelMapper.selectImgUrl(); +// +// batchDownloadImages(imageUrls, "C:\\Users\\王寻\\Desktop\\1111\\大模型\\模型图片集", DEFAULT_THREADS, DEFAULT_TIMEOUT); +// } +} \ No newline at end of file diff --git a/src/main/java/com/mortal/bigmodelr/utils/AjaxResult.java b/src/main/java/com/mortal/bigmodelr/utils/AjaxResult.java new file mode 100644 index 0000000..8ad4e8e --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/utils/AjaxResult.java @@ -0,0 +1,159 @@ +package com.mortal.bigmodelr.utils; + + +import java.util.HashMap; + +/** + * 操作消息提醒 + */ +public class AjaxResult extends HashMap +{ + private static final long serialVersionUID = 1L; + + /** 状态码 */ + public static final String CODE_TAG = "code"; + + /** 返回内容 */ + public static final String MSG_TAG = "msg"; + + /** 数据对象 */ + public static final String DATA_TAG = "data"; + + /** + * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 + */ + public AjaxResult() + { + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + */ + public AjaxResult(int code, String msg) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + } + + /** + * 初始化一个新创建的 AjaxResult 对象 + * + * @param code 状态码 + * @param msg 返回内容 + * @param data 数据对象 + */ + public AjaxResult(int code, String msg, Object data) + { + super.put(CODE_TAG, code); + super.put(MSG_TAG, msg); + if (StringUtils.isNotNull(data)) + { + super.put(DATA_TAG, data); + } + } + + /** + * 返回成功消息 + * + * @return 成功消息 + */ + public static AjaxResult success() + { + return AjaxResult.success("操作成功"); + } + + /** + * 返回成功数据 + * + * @return 成功消息 + */ + public static AjaxResult success(Object data) + { + return AjaxResult.success("操作成功", data); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @return 成功消息 + */ + public static AjaxResult success(String msg) + { + return AjaxResult.success(msg, null); + } + + /** + * 返回成功消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 成功消息 + */ + public static AjaxResult success(String msg, Object data) + { + return new AjaxResult(HttpStatus.SUCCESS, msg, data); + } + + /** + * 返回错误消息 + * + * @return + */ + public static AjaxResult error() + { + return AjaxResult.error("操作失败"); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult error(String msg) + { + return AjaxResult.error(msg, null); + } + + /** + * 返回错误消息 + * + * @param msg 返回内容 + * @param data 数据对象 + * @return 警告消息 + */ + public static AjaxResult error(String msg, Object data) + { + return new AjaxResult(HttpStatus.ERROR, msg, data); + } + + /** + * 返回错误消息 + * + * @param code 状态码 + * @param msg 返回内容 + * @return 警告消息 + */ + public static AjaxResult error(int code, String msg) + { + return new AjaxResult(code, msg, null); + } + + /** + * 方便链式调用 + * + * @param key 键 + * @param value 值 + * @return 数据对象 + */ + @Override + public AjaxResult put(String key, Object value) + { + super.put(key, value); + return this; + } +} diff --git a/src/main/java/com/mortal/bigmodelr/utils/HttpStatus.java b/src/main/java/com/mortal/bigmodelr/utils/HttpStatus.java new file mode 100644 index 0000000..8f805e5 --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/utils/HttpStatus.java @@ -0,0 +1,90 @@ +package com.mortal.bigmodelr.utils; + + +/** + * 返回状态码 + * + * @author ruoyi + */ +public class HttpStatus +{ + /** + * 操作成功 + */ + public static final int SUCCESS = 200; + + /** + * 对象创建成功 + */ + public static final int CREATED = 201; + + /** + * 请求已经被接受 + */ + public static final int ACCEPTED = 202; + + /** + * 操作已经执行成功,但是没有返回数据 + */ + public static final int NO_CONTENT = 204; + + /** + * 资源已被移除 + */ + public static final int MOVED_PERM = 301; + + /** + * 重定向 + */ + public static final int SEE_OTHER = 303; + + /** + * 资源没有被修改 + */ + public static final int NOT_MODIFIED = 304; + + /** + * 参数列表错误(缺少,格式不匹配) + */ + public static final int BAD_REQUEST = 400; + + /** + * 未授权 + */ + public static final int UNAUTHORIZED = 401; + + /** + * 访问受限,授权过期 + */ + public static final int FORBIDDEN = 403; + + /** + * 资源,服务未找到 + */ + public static final int NOT_FOUND = 404; + + /** + * 不允许的http方法 + */ + public static final int BAD_METHOD = 405; + + /** + * 资源冲突,或者资源被锁 + */ + public static final int CONFLICT = 409; + + /** + * 不支持的数据,媒体类型 + */ + public static final int UNSUPPORTED_TYPE = 415; + + /** + * 系统内部错误 + */ + public static final int ERROR = 500; + + /** + * 接口未实现 + */ + public static final int NOT_IMPLEMENTED = 501; +} diff --git a/src/main/java/com/mortal/bigmodelr/utils/StringUtils.java b/src/main/java/com/mortal/bigmodelr/utils/StringUtils.java new file mode 100644 index 0000000..545bb6a --- /dev/null +++ b/src/main/java/com/mortal/bigmodelr/utils/StringUtils.java @@ -0,0 +1,353 @@ +package com.mortal.bigmodelr.utils; + + +import cn.hutool.core.text.StrFormatter; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.text.StrBuilder; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.Charset; +import java.util.Collection; +import java.util.Map; + +/** + * 字符串工具类 + */ +public class StringUtils extends org.apache.commons.lang3.StringUtils { + /** + * 空字符串 + */ + private static final String NULLSTR = ""; + + /** + * 下划线 + */ + private static final char SEPARATOR = '_'; + + /** + * 获取参数不为空值 + * + * @param value defaultValue 要判断的value + * @return value 返回值 + */ + public static T nvl(T value, T defaultValue) { + return value != null ? value : defaultValue; + } + + /** + * * 判断一个Collection是否为空, 包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Collection coll) { + return isNull(coll) || coll.isEmpty(); + } + + /** + * * 判断一个Collection是否非空,包含List,Set,Queue + * + * @param coll 要判断的Collection + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Collection coll) { + return !isEmpty(coll); + } + + /** + * * 判断一个对象数组是否为空 + * + * @param objects 要判断的对象数组 + * * @return true:为空 false:非空 + */ + public static boolean isEmpty(Object[] objects) { + return isNull(objects) || (objects.length == 0); + } + + /** + * * 判断一个对象数组是否非空 + * + * @param objects 要判断的对象数组 + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Object[] objects) { + return !isEmpty(objects); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:为空 false:非空 + */ + public static boolean isEmpty(Map map) { + return isNull(map) || map.isEmpty(); + } + + /** + * * 判断一个Map是否为空 + * + * @param map 要判断的Map + * @return true:非空 false:空 + */ + public static boolean isNotEmpty(Map map) { + return !isEmpty(map); + } + + /** + * * 判断一个字符串是否为空串 + * + * @param str String + * @return true:为空 false:非空 + */ + public static boolean isEmpty(String str) { + return isNull(str) || NULLSTR.equals(str.trim()); + } + + /** + * * 判断一个字符串是否为非空串 + * + * @param str String + * @return true:非空串 false:空串 + */ + public static boolean isNotEmpty(String str) { + return !isEmpty(str); + } + + /** + * * 判断一个对象是否为空 + * + * @param object Object + * @return true:为空 false:非空 + */ + public static boolean isNull(Object object) { + return object == null; + } + + /** + * * 判断一个对象是否非空 + * + * @param object Object + * @return true:非空 false:空 + */ + public static boolean isNotNull(Object object) { + return !isNull(object); + } + + /** + * * 判断一个对象是否是数组类型(Java基本型别的数组) + * + * @param object 对象 + * @return true:是数组 false:不是数组 + */ + public static boolean isArray(Object object) { + return isNotNull(object) && object.getClass().isArray(); + } + + /** + * 去空格 + */ + public static String trim(String str) { + return (str == null ? "" : str.trim()); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @return 结果 + */ + public static String substring(final String str, int start) { + if (str == null) { + return NULLSTR; + } + + if (start < 0) { + start = str.length() + start; + } + + if (start < 0) { + start = 0; + } + if (start > str.length()) { + return NULLSTR; + } + + return str.substring(start); + } + + /** + * 截取字符串 + * + * @param str 字符串 + * @param start 开始 + * @param end 结束 + * @return 结果 + */ + public static String substring(final String str, int start, int end) { + if (str == null) { + return NULLSTR; + } + + if (end < 0) { + end = str.length() + end; + } + if (start < 0) { + start = str.length() + start; + } + + if (end > str.length()) { + end = str.length(); + } + + if (start > end) { + return NULLSTR; + } + + if (start < 0) { + start = 0; + } + if (end < 0) { + end = 0; + } + + return str.substring(start, end); + } + + /** + * 格式化文本, {} 表示占位符
+ * 此方法只是简单将占位符 {} 按照顺序替换为参数
+ * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可
+ * 例:
+ * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b
+ * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a
+ * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b
+ * + * @param template 文本模板,被替换的部分用 {} 表示 + * @param params 参数值 + * @return 格式化后的文本 + */ + public static String format(String template, Object... params) { + if (isEmpty(params) || isEmpty(template)) { + return template; + } + return StrFormatter.format(template, params); + } + + /** + * 驼峰首字符小写 + */ + public static String uncapitalize(String str) { + int strLen; + if (str == null || (strLen = str.length()) == 0) { + return str; + } + return new StrBuilder(strLen).append(Character.toLowerCase(str.charAt(0))).append(str.substring(1)).toString(); + } + + /** + * 下划线转驼峰命名 + */ + public static String toUnderScoreCase(String s) { + if (s == null) { + return null; + } + StringBuilder sb = new StringBuilder(); + boolean upperCase = false; + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + + boolean nextUpperCase = true; + + if (i < (s.length() - 1)) { + nextUpperCase = Character.isUpperCase(s.charAt(i + 1)); + } + + if ((i > 0) && Character.isUpperCase(c)) { + if (!upperCase || !nextUpperCase) { + sb.append(SEPARATOR); + } + upperCase = true; + } else { + upperCase = false; + } + + sb.append(Character.toLowerCase(c)); + } + + return sb.toString(); + } + + /** + * 是否包含字符串 + * + * @param str 验证字符串 + * @param strs 字符串组 + * @return 包含返回true + */ + public static boolean inStringIgnoreCase(String str, String... strs) { + if (str != null && strs != null) { + for (String s : strs) { + if (str.equalsIgnoreCase(trim(s))) { + return true; + } + } + } + return false; + } + + /** + * 将下划线大写方式命名的字符串转换为驼峰式。如果转换前的下划线大写方式命名的字符串为空,则返回空字符串。 例如:HELLO_WORLD->HelloWorld + * + * @param name 转换前的下划线大写方式命名的字符串 + * @return 转换后的驼峰式命名的字符串 + */ + public static String convertToCamelCase(String name) { + StringBuilder result = new StringBuilder(); + // 快速检查 + if (name == null || name.isEmpty()) { + // 没必要转换 + return ""; + } else if (!name.contains("_")) { + // 不含下划线,仅将首字母大写 + return name.substring(0, 1).toUpperCase() + name.substring(1); + } + // 用下划线将原始字符串分割 + String[] camels = name.split("_"); + for (String camel : camels) { + // 跳过原始字符串中开头、结尾的下换线或双重下划线 + if (camel.isEmpty()) { + continue; + } + // 首字母大写 + result.append(camel.substring(0, 1).toUpperCase()); + result.append(camel.substring(1).toLowerCase()); + } + return result.toString(); + } + + public static String getRandomString(Integer length) { + return RandomStringUtils.randomAlphanumeric(length); + } + + /**校验是否存在字符串,不存在返回空字符*/ + public static String getString(Object obj){ + if(obj == null || obj.equals("null") || obj.equals("")){ + return ""; + } + return obj.toString(); + } + + public static String bytetoString(byte[] bs,String charsetName){ + //确定编码格式 + Charset charset = Charset.forName(charsetName); + + ByteBuffer buf = ByteBuffer.wrap(bs); + + CharBuffer cBuf = charset.decode(buf); + + return cBuf.toString(); + } +} \ No newline at end of file diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml new file mode 100644 index 0000000..ae7c77e --- /dev/null +++ b/src/main/resources/application-local.yml @@ -0,0 +1,113 @@ + +# 项目相关配置 +lightiot: + # 名称 + name: lightiots + # 版本 + version: 3.0.0 + # 版权年份 + copyrightYear: 2018 + # 文件上传路径 + profile: D:/profile/ + # 获取ip地址开关 + addressEnabled: true + +# 开发环境配置 +server: + # 服务端口 + port: 8080 + servlet: + # 项目contextPath + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # tomcat最大线程数,默认为200 + max-threads: 800 + # Tomcat启动初始化的线程数,默认值25 + min-spare-threads: 30 + +# 日志配置 +logging: + level: + com.lightiot: debug + org.springframework: WARN + org.spring.springboot.dao: debug + +# 用户配置 +user: + password: + # 密码错误{maxRetryCount}次锁定10分钟 + maxRetryCount: 5 + +# Spring配置 +spring: + resources: + cache: + period: 0 + static-locations: classpath:/static/ + # 模板引擎 + thymeleaf: + mode: HTML + encoding: utf-8 + # 禁用缓存 + cache: false + prefix: classpath:/templates/ + # 资源信息 + messages: + # 国际化资源文件路径 + basename: i18n/messages + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + serialization: + WRITE_DATES_AS_TIMESTAMPS: false + FAIL_ON_EMPTY_BEANS: false + # 文件上传 + servlet: + multipart: + max-file-size: 30MB + max-request-size: 30MB + # 临时存放上传文件 + location: d:/pic + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: true + additional-paths: resources/** + + datasource: + druid: + driver-class-name: com.mysql.cj.jdbc.Driver + url: jdbc:mysql://192.168.4.129:4406/inspect?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai + username: root + password: atia2018 + + +mybatis: + mapper-locations: classpath:mapper/*.xml + type-aliases-package: com.mortal.bigmodelr.domain + +analysis: + api: + url: http://199.199.199.104:9901 + token: 01234567890 + + +file: + # 接口地址 + baseUrl: http://25.80.45.92:18063 + #接口路径 + apiPath: /lmp-cloud-ias-server/api/lvm/completions/ + multimodalPath: /lmp-cloud-ias-server/api/vlm/chat/completions/ + semanticsModalPath: /lmp-cloud-ias-server/api/llm/chat/completions/ + + #密钥 + authKey: 54c1ae2c5fd54afe85e74d6fe9161f7f + model: 591304447029141504 + picPath: /home/atia/docker-deploy-encrypt/data/vsftpd/ftpuser/1/2025/06/23/1602/CCD/1602_20250623092918940_2080369_02160558348953680142.jpg + #下载缺陷图片到本地的基础路径 + baseDirectory: C:/1111/1 + + diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml new file mode 100644 index 0000000..d74c444 --- /dev/null +++ b/src/main/resources/application.yml @@ -0,0 +1,3 @@ +spring: + profiles: + active: local diff --git a/src/main/resources/mapper/multimodalMapper.xml b/src/main/resources/mapper/multimodalMapper.xml new file mode 100644 index 0000000..42a15bd --- /dev/null +++ b/src/main/resources/mapper/multimodalMapper.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + insert into multimodal (info,content,pic_path,data_id) values (#{info},#{content},#{picPath},#{id}) + + diff --git a/src/main/resources/mapper/visualModelMapper.xml b/src/main/resources/mapper/visualModelMapper.xml new file mode 100644 index 0000000..7144fa1 --- /dev/null +++ b/src/main/resources/mapper/visualModelMapper.xml @@ -0,0 +1,28 @@ + + + + + + insert into visual (info) + + #{visualModels.stringData} + + + + + + + + + diff --git a/src/test/java/com/mortal/bigmodelr/BigModelrApplicationTests.java b/src/test/java/com/mortal/bigmodelr/BigModelrApplicationTests.java new file mode 100644 index 0000000..67a9f3b --- /dev/null +++ b/src/test/java/com/mortal/bigmodelr/BigModelrApplicationTests.java @@ -0,0 +1,13 @@ +package com.mortal.bigmodelr; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +class BigModelrApplicationTests { + + @Test + void contextLoads() { + } + +}