| @ -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/ | |||||
| @ -0,0 +1,202 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> | |||||
| <modelVersion>4.0.0</modelVersion> | |||||
| <groupId>com.mortal</groupId> | |||||
| <artifactId>inspect-luminous</artifactId> | |||||
| <version>0.0.1-SNAPSHOT</version> | |||||
| <name>inspect-luminous</name> | |||||
| <description>inspect-luminous</description> | |||||
| <properties> | |||||
| <java.version>1.8</java.version> | |||||
| <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | |||||
| <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> | |||||
| <spring-boot.version>2.6.13</spring-boot.version> | |||||
| </properties> | |||||
| <dependencies> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-web</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-test</artifactId> | |||||
| <scope>test</scope> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.projectlombok</groupId> | |||||
| <artifactId>lombok</artifactId> | |||||
| <version>1.16.18</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>cn.hutool</groupId> | |||||
| <artifactId>hutool-all</artifactId> | |||||
| <version>5.8.9</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.squareup.okhttp3</groupId> | |||||
| <artifactId>okhttp</artifactId> | |||||
| <version>4.9.3</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-websocket</artifactId> | |||||
| </dependency> | |||||
| <!-- MySQL 驱动 --> | |||||
| <dependency> | |||||
| <groupId>mysql</groupId> | |||||
| <artifactId>mysql-connector-java</artifactId> | |||||
| <version>8.0.33</version> | |||||
| </dependency> | |||||
| <!-- Druid 数据源 --> | |||||
| <dependency> | |||||
| <groupId>com.alibaba</groupId> | |||||
| <artifactId>druid-spring-boot-starter</artifactId> | |||||
| <version>1.2.20</version> | |||||
| </dependency> | |||||
| <!-- Spring JDBC 支持 --> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-starter-jdbc</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.mybatis.spring.boot</groupId> | |||||
| <artifactId>mybatis-spring-boot-starter</artifactId> | |||||
| <version>2.2.2</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.apache.commons</groupId> | |||||
| <artifactId>commons-lang3</artifactId> | |||||
| <version>3.12.0</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.fasterxml.jackson.core</groupId> | |||||
| <artifactId>jackson-databind</artifactId> | |||||
| <version>2.13.0</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>org.projectlombok</groupId> | |||||
| <artifactId>lombok</artifactId> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.alibaba</groupId> | |||||
| <artifactId>fastjson</artifactId> | |||||
| <version>1.2.83</version> | |||||
| </dependency> | |||||
| <!-- Retrofit Gson 转换器 --> | |||||
| <dependency> | |||||
| <groupId>com.squareup.retrofit2</groupId> | |||||
| <artifactId>converter-gson</artifactId> | |||||
| <version>2.9.0</version> | |||||
| </dependency> | |||||
| <!-- Gson 库 --> | |||||
| <dependency> | |||||
| <groupId>com.google.code.gson</groupId> | |||||
| <artifactId>gson</artifactId> | |||||
| <version>2.8.9</version> | |||||
| </dependency> | |||||
| <!-- 日志拦截器 (可选) --> | |||||
| <dependency> | |||||
| <groupId>com.squareup.okhttp3</groupId> | |||||
| <artifactId>logging-interceptor</artifactId> | |||||
| <version>4.9.3</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.squareup.retrofit2</groupId> | |||||
| <artifactId>retrofit</artifactId> | |||||
| <version>2.9.0</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.squareup.retrofit2</groupId> | |||||
| <artifactId>converter-scalars</artifactId> | |||||
| <version>2.9.0</version> <!-- 版本应与retrofit核心库一致 --> | |||||
| </dependency> | |||||
| <!-- Retrofit Jackson 转换器 --> | |||||
| <dependency> | |||||
| <groupId>com.squareup.retrofit2</groupId> | |||||
| <artifactId>converter-jackson</artifactId> | |||||
| <version>2.9.0</version> <!-- 版本应与retrofit核心库一致 --> | |||||
| </dependency> | |||||
| <!-- Jackson 核心库 --> | |||||
| <dependency> | |||||
| <groupId>com.fasterxml.jackson.core</groupId> | |||||
| <artifactId>jackson-databind</artifactId> | |||||
| <version>2.13.0</version> | |||||
| </dependency> | |||||
| </dependencies> | |||||
| <dependencyManagement> | |||||
| <dependencies> | |||||
| <dependency> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-dependencies</artifactId> | |||||
| <version>${spring-boot.version}</version> | |||||
| <type>pom</type> | |||||
| <scope>import</scope> | |||||
| </dependency> | |||||
| </dependencies> | |||||
| </dependencyManagement> | |||||
| <build> | |||||
| <plugins> | |||||
| <plugin> | |||||
| <groupId>org.apache.maven.plugins</groupId> | |||||
| <artifactId>maven-compiler-plugin</artifactId> | |||||
| <version>3.8.1</version> | |||||
| <configuration> | |||||
| <source>1.8</source> | |||||
| <target>1.8</target> | |||||
| <encoding>UTF-8</encoding> | |||||
| </configuration> | |||||
| </plugin> | |||||
| <plugin> | |||||
| <groupId>org.springframework.boot</groupId> | |||||
| <artifactId>spring-boot-maven-plugin</artifactId> | |||||
| <version>${spring-boot.version}</version> | |||||
| <configuration> | |||||
| <mainClass>com.mortal.bigmodelr.BigModelrApplication</mainClass> | |||||
| </configuration> | |||||
| <executions> | |||||
| <execution> | |||||
| <id>repackage</id> | |||||
| <goals> | |||||
| <goal>repackage</goal> | |||||
| </goals> | |||||
| </execution> | |||||
| </executions> | |||||
| </plugin> | |||||
| </plugins> | |||||
| </build> | |||||
| </project> | |||||
| @ -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); | |||||
| } | |||||
| } | |||||
| @ -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<WebSocketSession> 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); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -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<WebSocketSession> 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(); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -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("*"); | |||||
| } | |||||
| } | |||||
| @ -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<String> bigModelPicAnalyse(@RequestBody final String analyseRequestStr) { | |||||
| return ResponseEntity.ok().body(algorithmService.bigModelPicAnalyse(analyseRequestStr)); | |||||
| } | |||||
| @PostMapping("/picAnalyseRetNotify") | |||||
| public ResponseEntity<String> bigModelPicAnalyseRetNotify(@RequestBody String picAnalyseResult) { | |||||
| return ResponseEntity | |||||
| .ok() | |||||
| .body(algorithmService.bigModelPicAnalyseRetNotify(picAnalyseResult)); | |||||
| } | |||||
| } | |||||
| @ -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<String> 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); | |||||
| } | |||||
| } | |||||
| @ -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; | |||||
| } | |||||
| } | |||||
| @ -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<Message> messages; | |||||
| private int maxTokens; | |||||
| } | |||||
| @ -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<Choice> choices; | |||||
| private String info; | |||||
| private Usage usage; | |||||
| @JsonProperty("model") | |||||
| private String model; | |||||
| //存数据库 | |||||
| private String content; | |||||
| private String picPath; | |||||
| } | |||||
| @ -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; | |||||
| } | |||||
| @ -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时使用 | |||||
| } | |||||
| @ -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时使用 | |||||
| } | |||||
| @ -0,0 +1,9 @@ | |||||
| package com.mortal.bigmodelr.domain; | |||||
| import lombok.Data; | |||||
| @Data | |||||
| public class ImageUrl { | |||||
| private String url; | |||||
| } | |||||
| @ -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> content; | |||||
| private Object content; // 可以是 String 或 List<Content> | |||||
| @JsonSetter("content") | |||||
| public void setContent(Object content) { | |||||
| if (content instanceof String) { | |||||
| this.content = (String) content; | |||||
| } else if (content instanceof List) { | |||||
| this.content = (List<ContentItem>) content; | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -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; | |||||
| } | |||||
| @ -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; | |||||
| } | |||||
| @ -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; | |||||
| } | |||||
| @ -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"; | |||||
| } | |||||
| @ -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) + | |||||
| '}'; | |||||
| } | |||||
| } | |||||
| @ -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<AnalyseReqItem> 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); | |||||
| } | |||||
| } | |||||
| @ -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<AnalyseResPoint> 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 + | |||||
| // '}'; | |||||
| // } | |||||
| } | |||||
| @ -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> 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<Pos> 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> 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); | |||||
| // } | |||||
| } | |||||
| @ -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<AnalyseResItem> resultList; | |||||
| private List<AnalyseResItem> resultsList; | |||||
| private String taskPatrolId; | |||||
| private String filter = "0"; | |||||
| private String result = "1"; | |||||
| // public void setResultsList(List<AnalyseResItem> resultsList) { | |||||
| // this.resultsList = resultsList; | |||||
| // if (resultsList != null) { | |||||
| // this.resultList = resultsList; | |||||
| // } | |||||
| // | |||||
| // } | |||||
| // | |||||
| // public void reloadReq(AnalyseRequest analyseRequest) { | |||||
| // AnalyseResItem analyseResItem = this.resultList.get(0); | |||||
| // List<AnalyseResItem> 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<AnalyseResPoint> 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<AnalyseResItem> 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 + '\'' + | |||||
| // '}'; | |||||
| // } | |||||
| } | |||||
| @ -0,0 +1,12 @@ | |||||
| package com.mortal.bigmodelr.domain.algorithm.out; | |||||
| import lombok.*; | |||||
| @Data | |||||
| @AllArgsConstructor | |||||
| @NoArgsConstructor | |||||
| public class Pos { | |||||
| private String[] areas; | |||||
| } | |||||
| @ -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<String> typeList; | |||||
| private List<String> imageUrlList; | |||||
| } | |||||
| @ -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<AnalysisObject> objectList; | |||||
| } | |||||
| @ -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<String> pos; | |||||
| private String resImageUrl; | |||||
| private Double conf; | |||||
| private String type; | |||||
| private String value; | |||||
| private String desc; | |||||
| } | |||||
| @ -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<AnalysisResultList> resultList; | |||||
| } | |||||
| @ -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<AnalysisResult> results; | |||||
| } | |||||
| @ -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); | |||||
| } | |||||
| @ -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<VisualModel> visualModels); | |||||
| List<String> selectImgUrl(); | |||||
| } | |||||
| @ -0,0 +1,7 @@ | |||||
| package com.mortal.bigmodelr.service; | |||||
| public interface AlgorithmService { | |||||
| String bigModelPicAnalyse(final String analyseRequestStr); | |||||
| String bigModelPicAnalyseRetNotify(final String picAnalyseResult); | |||||
| } | |||||
| @ -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<String> enquire(); | |||||
| //图片下载到本地 | |||||
| public void downImg(); | |||||
| } | |||||
| @ -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<AnalyseResPoint> analyseResPoints = new ArrayList<>(); | |||||
| analyseResPoints.add(analyseResPoint); | |||||
| AnalyseResItem analyseResItem = new AnalyseResItem(); | |||||
| analyseResItem.setObjectId(analyseRequest.getObjectList().get(0).getObjectId()); | |||||
| // analyseResItem.setAlgFactory("yd"); | |||||
| analyseResItem.setResults(analyseResPoints); | |||||
| List<AnalyseResItem> analyseResItems = new ArrayList<>(); | |||||
| analyseResItems.add(analyseResItem); | |||||
| analyseResult.setResultList(analyseResItems); | |||||
| if (infraredPath.equals("null")) { | |||||
| // 如果nacos中没有配置红外路径,则将结果返回调用方 | |||||
| try { | |||||
| // Call<Object> call = analysisRemoteService.picAnalyseRetNotify(analyseResult); | |||||
| // Response<Object> 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<Object> call = analysisRemoteService.picAnalyseRetNotify(analyseResult); | |||||
| Response<Object> response = call.execute(); | |||||
| Object result = response.body(); | |||||
| System.out.println("result: " + result); | |||||
| } catch (Exception e) { | |||||
| e.printStackTrace(); | |||||
| } | |||||
| return ""; | |||||
| } | |||||
| } | |||||
| @ -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<String> 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<VisualModel> 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<String, Object> requestBody = new HashMap<>(); | |||||
| Map<String, String> 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<Content> 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<String> enquire() { | |||||
| String currentDatePath = getCurrentDatePath(); | |||||
| // 获取日期目录下所有图片 | |||||
| List<String> 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<String> getAllImagesUnderDateDir(String baseDir, String datePath) { | |||||
| List<String> imagePaths = new ArrayList<>(); | |||||
| Path dateDirPath = Paths.get(baseDir, datePath); | |||||
| // 检查日期目录是否存在 | |||||
| if (!Files.exists(dateDirPath)) { | |||||
| System.out.println("日期目录不存在: " + dateDirPath); | |||||
| return imagePaths; | |||||
| } | |||||
| try (Stream<Path> 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<String> imageUrls = visualModelMapper.selectImgUrl(); | |||||
| batchDownloadImages(imageUrls, "C:\\Users\\王寻\\Desktop\\1111\\大模型\\模型图片集", DEFAULT_THREADS, DEFAULT_TIMEOUT); | |||||
| } | |||||
| } | |||||
| @ -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<Object> analysisResultNotify(@Body AnalysisResultEntity analysisResultEntity); | |||||
| @POST("picAnalyseRetNotify") | |||||
| Call<Object> picAnalyseRetNotify(@Body AnalyseResult analyseResult); | |||||
| } | |||||
| @ -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<Object> analysisResultNotify(AnalysisResultEntity analysisResultEntity) { | |||||
| return analysisRemoteService.analysisResultNotify(analysisResultEntity); | |||||
| } | |||||
| @Override | |||||
| public Call<Object> picAnalyseRetNotify(AnalyseResult analyseResult) { | |||||
| return analysisRemoteService.picAnalyseRetNotify(analyseResult); | |||||
| } | |||||
| } | |||||
| @ -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<String> 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); | |||||
| } | |||||
| } | |||||
| } | |||||
| @ -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<String> imageUrls, String saveDir, | |||||
| int threadCount, int timeout) { | |||||
| // 创建线程池 | |||||
| ExecutorService executor = Executors.newFixedThreadPool(threadCount); | |||||
| List<Future<DownloadResult>> futures = new ArrayList<>(); | |||||
| try { | |||||
| // 创建保存目录 | |||||
| Path dirPath = Paths.get(saveDir); | |||||
| if (!Files.exists(dirPath)) { | |||||
| Files.createDirectories(dirPath); | |||||
| } | |||||
| // 提交下载任务 | |||||
| for (String url : imageUrls) { | |||||
| Future<DownloadResult> 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<DownloadResult> 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<String> imageUrls = visualModelMapper.selectImgUrl(); | |||||
| // | |||||
| // batchDownloadImages(imageUrls, "C:\\Users\\王寻\\Desktop\\1111\\大模型\\模型图片集", DEFAULT_THREADS, DEFAULT_TIMEOUT); | |||||
| // } | |||||
| } | |||||
| @ -0,0 +1,159 @@ | |||||
| package com.mortal.bigmodelr.utils; | |||||
| import java.util.HashMap; | |||||
| /** | |||||
| * 操作消息提醒 | |||||
| */ | |||||
| public class AjaxResult extends HashMap<String, Object> | |||||
| { | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @ -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; | |||||
| } | |||||
| @ -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> 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); | |||||
| } | |||||
| /** | |||||
| * 格式化文本, {} 表示占位符<br> | |||||
| * 此方法只是简单将占位符 {} 按照顺序替换为参数<br> | |||||
| * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> | |||||
| * 例:<br> | |||||
| * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br> | |||||
| * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> | |||||
| * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> | |||||
| * | |||||
| * @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(); | |||||
| } | |||||
| } | |||||
| @ -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 | |||||
| @ -0,0 +1,3 @@ | |||||
| spring: | |||||
| profiles: | |||||
| active: local | |||||
| @ -0,0 +1,17 @@ | |||||
| <?xml version="1.0" encoding="UTF-8" ?> | |||||
| <!DOCTYPE mapper | |||||
| PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||||
| "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
| <mapper namespace="com.mortal.bigmodelr.mapper.multimodalMapper"> | |||||
| <resultMap type="com.mortal.bigmodelr.domain.ChatCompletionResponse" id="ChatCompletionResponseResult"> | |||||
| <result property="picPath" column="pic_path"/> | |||||
| <result property="info" column="info"/> | |||||
| <result property="content" column="content"/> | |||||
| <result property="id" column="data_id"/> | |||||
| </resultMap> | |||||
| <insert id="addMultimodalModelInfo" parameterType="com.mortal.bigmodelr.domain.ChatCompletionResponse"> | |||||
| insert into multimodal (info,content,pic_path,data_id) values (#{info},#{content},#{picPath},#{id}) | |||||
| </insert> | |||||
| </mapper> | |||||
| @ -0,0 +1,28 @@ | |||||
| <?xml version="1.0" encoding="UTF-8" ?> | |||||
| <!DOCTYPE mapper | |||||
| PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" | |||||
| "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
| <mapper namespace="com.mortal.bigmodelr.mapper.visualModelMapper"> | |||||
| <insert id="addVisualModelInfo"> | |||||
| insert into visual (info) | |||||
| <foreach collection="list" item="visualModels" separator="),(" open="values (" close=")"> | |||||
| #{visualModels.stringData} | |||||
| </foreach> | |||||
| </insert> | |||||
| <select id="selectImgUrl" resultType="java.lang.String"> | |||||
| SELECT | |||||
| CONCAT('http://192.168.4.129:18891/lingzhou/videoMonitor/app/htjc6/htjcImage/', res_img_url) AS full_img_url | |||||
| FROM | |||||
| `result_analysis` | |||||
| WHERE | |||||
| result_type = 1 | |||||
| GROUP BY | |||||
| res_img_url; | |||||
| </select> | |||||
| </mapper> | |||||
| @ -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() { | |||||
| } | |||||
| } | |||||