2 İşlemeler 7186dd5f17 ... b14dede171

Yazar SHA1 Mesaj Tarih
  huiqi b14dede171 Merge remote-tracking branch 'origin/permission_20250617' into permission_20250617 3 hafta önce
  huiqi ebc513d897 视觉数据大模型总结接口 3 hafta önce
18 değiştirilmiş dosya ile 634 ekleme ve 1 silme
  1. 214 0
      takai-admin/src/main/java/com/takai/web/controller/droneai/DroneAiController.java
  2. 3 0
      takai-admin/src/main/resources/application.yml
  3. 21 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ClientInfo.java
  4. 60 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ProjectDetectionParam.java
  5. 30 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/QualityInfo.java
  6. 26 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/QualityWarning.java
  7. 24 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/RebarInfo.java
  8. 5 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ReferenceResult.java
  9. 16 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/SafeInfo.java
  10. 35 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/SafeWarning.java
  11. 21 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ThicknessData.java
  12. 21 0
      takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ThicknessInfo.java
  13. 2 0
      takai-ai/src/main/java/com/takai/ai/service/ITakaiAiService.java
  14. 67 0
      takai-ai/src/main/java/com/takai/ai/service/impl/TakaiAiServiceImpl.java
  15. 2 0
      takai-common/src/main/java/com/takai/common/config/DeepseekConfig.java
  16. 43 0
      takai-common/src/main/java/com/takai/common/enums/QualityTypeEnum.java
  17. 43 0
      takai-common/src/main/java/com/takai/common/enums/VisionTypeEnum.java
  18. 1 1
      takai-framework/src/main/java/com/takai/framework/config/SecurityConfig.java

+ 214 - 0
takai-admin/src/main/java/com/takai/web/controller/droneai/DroneAiController.java

@@ -0,0 +1,214 @@
+package com.takai.web.controller.droneai;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.crypto.digest.DigestUtil;
+import com.alibaba.fastjson2.JSONObject;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.takai.ai.domain.dto.drone.ProjectDetectionParam;
+import com.takai.ai.domain.entity.*;
+import com.takai.ai.service.ITakaiAiService;
+import com.takai.common.core.controller.BaseController;
+import com.takai.common.core.domain.AjaxResult;
+import com.takai.common.enums.QualityTypeEnum;
+import com.takai.common.enums.VisionTypeEnum;
+import com.takai.system.domain.SysClient;
+import com.takai.system.service.ISysClientService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.util.StringUtils;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.*;
+
+@Slf4j
+@RestController
+@RequestMapping("/vision")
+public class DroneAiController extends BaseController {
+
+    @Autowired
+    private ISysClientService clientService;
+
+    @Autowired
+    private ITakaiAiService takaiAisService;
+
+    // 静态ObjectMapper实例(线程安全,可复用)
+    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
+
+    /**
+     * 视觉数据大模型总结
+     *
+     * @param requestBody 登录信息
+     * @return 结果
+     */
+    @PostMapping("/ai_check")
+    public AjaxResult aiCheck(@RequestBody ProjectDetectionParam requestBody) throws Exception
+    {
+        log.info("登录请求参数:{}", requestBody.toString());
+        AjaxResult ajax = AjaxResult.success();
+
+        if(
+                requestBody.getClient() == null
+            ||  requestBody.getClient().getClientId() == null
+            ||  requestBody.getClient().getTimestamp() == null
+            ||  requestBody.getClient().getSignature() == null
+            ||
+        !StringUtils.hasText(requestBody.getType())
+            ||  (VisionTypeEnum.SAFE.getCode().equals(requestBody.getType()) && requestBody.getSafe() == null)
+            ||  (VisionTypeEnum.QUALITY.getCode().equals(requestBody.getType()) && requestBody.getQuality() == null)
+            ||  (VisionTypeEnum.QUALITY.getCode().equals(requestBody.getType()) &&
+                        (!StringUtils.hasText(requestBody.getQuality().getSubType())
+                                || (QualityTypeEnum.WARNING.getCode().equalsIgnoreCase(requestBody.getQuality().getSubType()) && requestBody.getQuality().getWarning() == null)
+                                || (QualityTypeEnum.THICKNESS.getCode().equalsIgnoreCase(requestBody.getQuality().getSubType()) && requestBody.getQuality().getThickness() == null)
+                                || (QualityTypeEnum.REBAR_INFO.getCode().equalsIgnoreCase(requestBody.getQuality().getSubType()) && requestBody.getQuality().getRebarInfo() == null)
+                        )
+                )
+        ) {
+            return AjaxResult.error(org.springframework.http.HttpStatus.BAD_REQUEST.value(),"参数错误");
+        }
+        String clientId = requestBody.getClient().getClientId();
+        String timestamp = requestBody.getClient().getTimestamp();
+        String type = requestBody.getType();
+        String imageId = requestBody.getResImageId();
+        String sign = requestBody.getClient().getSignature();
+
+        //检查ClientId是否存在
+        SysClient client = clientService.selectSysClientById(clientId);
+        if(client == null) {
+            return AjaxResult.error(org.springframework.http.HttpStatus.BAD_REQUEST.value(),"无效的client_id");
+        }
+
+        long btwTime = System.currentTimeMillis() - Long.parseLong(timestamp);
+
+        // Step 3: Check if the difference is greater than 5 minutes
+        boolean isMoreThanFiveMinutes = btwTime > 5 * 1000 * 60;
+        if (isMoreThanFiveMinutes) {
+            return AjaxResult.error(org.springframework.http.HttpStatus.BAD_REQUEST.value(),"请求已过期,请重新发起请求");
+        }
+        if (sign != null) {
+            String dataInput  = clientId+timestamp+type+imageId;
+            String generatedHash = DigestUtil.sha256Hex(dataInput.toUpperCase()+client.getClientSecret());
+            if(!StrUtil.equals(generatedHash, sign)) {
+                return AjaxResult.error(org.springframework.http.HttpStatus.UNAUTHORIZED.value(),"签名验证失败");
+            }
+        } else {
+            return AjaxResult.error(HttpStatus.UNAUTHORIZED.value(),"无效的签名");
+        }
+        //处理请求报文
+        TakaiSseInfoParams requestParams = new TakaiSseInfoParams();
+        //如果是浇筑厚度,不处理,直接调研APP后端接口
+        if(QualityTypeEnum.THICKNESS.getCode().equalsIgnoreCase(requestBody.getQuality().getSubType())) {
+
+        } else {
+            List<String> extractFields = null;
+            String rootArrayPath = null;
+            if (VisionTypeEnum.SAFE.getCode().equals(type)) {
+                // 调用通用方法:提取safe.warning下的label和judgment字段
+                extractFields = Arrays.asList("label", "judgment");
+                rootArrayPath = "safe.warning";
+                requestParams.setAppId("3010574988024877056");
+
+            } else if (VisionTypeEnum.QUALITY.getCode().equals(type)) {
+                if (QualityTypeEnum.WARNING.getCode().equalsIgnoreCase(requestBody.getQuality().getSubType())) {
+                    extractFields = Arrays.asList("label", "judgment");
+                    rootArrayPath = "quality.warning";
+                } else if (QualityTypeEnum.REBAR_INFO.getCode().equalsIgnoreCase(requestBody.getQuality().getSubType())) {
+                    extractFields = Collections.singletonList("remark");
+                    rootArrayPath = "quality.rebarInfo";
+                }
+                requestParams.setAppId("3010568863451844608");
+            }
+            String requestJson = JSONObject.toJSONString(requestBody);
+            String simpleJson = extractFields(requestJson, rootArrayPath, extractFields);
+            //调用大模型接口
+
+            //messages示例:[{'role': 'user', 'content': '你是谁?'}, {'role': 'assistant', 'content': '我是小智'}, {'role': 'user', 'content': '你能做什么?'}]
+            List<TakaiPromptInfo> messages = new ArrayList<>();
+            TakaiPromptInfo message = new TakaiPromptInfo();
+            message.setRole("user");
+            message.setContent(simpleJson);
+            messages.add(message);
+            requestParams.setMessages(messages);
+            String result =  takaiAisService.syncInvoke(requestParams);
+            if(StringUtils.hasText(result)) {
+                //调用安卓后端接口
+            } else {
+                ajax = AjaxResult.error("调用知识库异常");
+            }
+        }
+//        ObjectMapper objectMapper = new ObjectMapper();
+//        Map<String, Object> map  = null;
+//        ajax.put("data", map);
+        return ajax;
+    }
+
+    /**
+     * 通用JSON字段提取方法
+     * @param originalJson 原始JSON字符串
+     * @param rootArrayPath 要提取的数组根路径(如safe.warning)
+     * @param fieldPaths 要提取的字段路径列表(如label、judgment,基于rootArrayPath的相对路径)
+     * @return 简化后的JSON字符串(格式化输出)
+     * @throws JsonProcessingException JSON解析/生成异常
+     */
+    public String extractFields(String originalJson, String rootArrayPath, List<String> fieldPaths)
+            throws JsonProcessingException {
+        // 1. 解析原始JSON为树形结构
+        JsonNode rootNode = OBJECT_MAPPER.readTree(originalJson);
+
+        // 2. 定位到目标数组节点(解析rootArrayPath,如safe.warning)
+        JsonNode targetArrayNode = getNodeByPath(rootNode, rootArrayPath);
+        if (targetArrayNode == null || !targetArrayNode.isArray()) {
+            throw new IllegalArgumentException("路径[" + rootArrayPath + "]不是有效的JSON数组");
+        }
+
+        // 3. 创建简化后的数组节点
+        ArrayNode simplifiedArray = OBJECT_MAPPER.createArrayNode();
+
+        // 4. 遍历数组,提取指定字段
+        Iterator<JsonNode> arrayIterator = targetArrayNode.iterator();
+        while (arrayIterator.hasNext()) {
+            JsonNode itemNode = arrayIterator.next();
+            ObjectNode simplifiedItem = OBJECT_MAPPER.createObjectNode();
+
+            // 遍历需要提取的字段,逐个赋值
+            for (String fieldPath : fieldPaths) {
+                JsonNode fieldNode = getNodeByPath(itemNode, fieldPath);
+                String fieldValue = (fieldNode == null) ? "" : fieldNode.asText("");
+                simplifiedItem.put(fieldPath, fieldValue);
+            }
+
+            simplifiedArray.add(simplifiedItem);
+        }
+
+        // 5. 转换为格式化的JSON字符串返回
+        return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(simplifiedArray);
+    }
+
+    /**
+     * 辅助方法:根据路径(如a.b.c)从JsonNode中获取对应节点
+     * @param startNode 起始节点
+     * @param path 字段路径(点分隔,如safe.warning)
+     * @return 目标节点(null表示路径不存在)
+     */
+    private static JsonNode getNodeByPath(JsonNode startNode, String path) {
+        if (startNode == null || path == null || path.isEmpty()) {
+            return startNode;
+        }
+
+        String[] pathSegments = path.split("\\.");
+        JsonNode currentNode = startNode;
+        for (String segment : pathSegments) {
+            currentNode = currentNode.path(segment);
+            // 如果路径中某一级不存在,直接返回null
+            if (currentNode.isMissingNode()) {
+                return null;
+            }
+        }
+        return currentNode;
+    }
+
+}

+ 3 - 0
takai-admin/src/main/resources/application.yml

@@ -202,6 +202,9 @@ deepseek:
   prompt: 你是总结和提问大师。你只根据用户的对话记录,根据对话记录生成可能会问的问题,不要杜撰问题。问题的答案必须来自上面的对话记录。 你必须遵守以下要求:1. 不要输出用户问过的问题;2. 你需要输出3个问题供用户选择。3. 你只需要输出问题,不需要解释,不需要提问。4. 你的问题可以是空的,但你不能杜撰问题。5. 问题需要站在使用这个应用的人的视角提出,因此你要注意提问的语气和人称代词。不要用您这个字。6.生成的问题,必须能从提供的对话记录中找到答案。你一定要按照以下格式输出:{'问题':['xxx','xxx','xxx']}
   #消息是否Base64编码
   contentBase64Encode: true
+  #图片检测接口url
+  #pictureCheckUrl: http://xia0miduo.gicp.net:6001/rag/chat/sync
+  pictureCheckUrl: http://10.1.27.4:18071/rag/chat/sync
 jk:
   #Appid
   iamAppid: e971e84b574c40b2

+ 21 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ClientInfo.java

@@ -0,0 +1,21 @@
+package com.takai.ai.domain.dto.drone;
+
+import lombok.Data;
+
+/**
+ * 客户端信息
+ * 验证客户端
+ */
+@Data
+public class ClientInfo {
+
+    private String clientId;
+    /**
+     * 请求时间
+     */
+    private String timestamp;
+    /**
+     * 签名
+     */
+    private String signature;
+}

+ 60 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ProjectDetectionParam.java

@@ -0,0 +1,60 @@
+package com.takai.ai.domain.dto.drone;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import java.util.List;
+import java.time.LocalDateTime;
+
+/**
+ * 工程检测数据主入参类
+ * 对应JSON根节点的所有字段
+ */
+@Data
+public class ProjectDetectionParam {
+
+    private ClientInfo client;
+    /**
+     * 设备ID
+     */
+    private String deviceId;
+
+    /**
+     * 项目ID
+     */
+    private String projectId;
+
+    /**
+     * 阶段ID
+     */
+    private String phaseId;
+
+    /**
+     * 类型 safe:安全检测 quality:质量检测
+     */
+    private String type;
+
+    /**
+     * 检测结果图片(Base64编码)
+     */
+    private String resImage;
+
+    /**
+     * 图片ID
+     */
+    private String resImageId;
+
+    /**
+     * 安全检测相关信息
+     */
+    private SafeInfo safe;
+
+    /**
+     * 质量检测相关信息
+     */
+    private QualityInfo quality;
+
+    /**
+     * 检测时间
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private LocalDateTime time;
+}

+ 30 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/QualityInfo.java

@@ -0,0 +1,30 @@
+package com.takai.ai.domain.dto.drone;
+import lombok.Data;
+import java.util.List;
+
+/**
+ * 质量检测信息类
+ * 对应JSON中的quality节点
+ */
+@Data
+public class QualityInfo {
+
+    /**
+     * 风险类型,(w:warning,t:thickness,r:rebarInfo)
+     */
+    private String subType;
+    /**
+     * 质量预警列表
+     */
+    private List<QualityWarning> warning;
+
+    /**
+     * 厚度检测数据
+     */
+    private ThicknessInfo thickness;
+
+    /**
+     * 钢筋信息列表
+     */
+    private List<RebarInfo> rebarInfo;
+}

+ 26 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/QualityWarning.java

@@ -0,0 +1,26 @@
+package com.takai.ai.domain.dto.drone;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * 质量预警详情类
+ * 对应JSON中quality.warning的单个元素
+ */
+@Data
+public class QualityWarning {
+    /**
+     * 预警标签(如:破损)
+     */
+    private String label;
+
+    /**
+     * 检测目标的边界框坐标 [x1, y1, x2, y2]
+     */
+    private List<Integer> bbox;
+
+    /**
+     * 判定说明
+     */
+    private String judgment;
+}

+ 24 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/RebarInfo.java

@@ -0,0 +1,24 @@
+package com.takai.ai.domain.dto.drone;
+import lombok.Data;
+
+/**
+ * 钢筋信息类
+ * 对应JSON中quality.rebarInfo的单个元素
+ */
+@Data
+public class RebarInfo {
+    /**
+     * 索引
+     */
+    private Integer index;
+
+    /**
+     * 图片ID
+     */
+    private String imageId;
+
+    /**
+     * 钢筋参数备注
+     */
+    private String remark;
+}

+ 5 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ReferenceResult.java

@@ -0,0 +1,5 @@
+package com.takai.ai.domain.dto.drone;
+
+public class ReferenceResult {
+
+}

+ 16 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/SafeInfo.java

@@ -0,0 +1,16 @@
+package com.takai.ai.domain.dto.drone;
+import lombok.Data;
+import java.util.List;
+
+/**
+ * 安全检测信息类
+ * 对应JSON中的safe节点
+ */
+@Data
+public class SafeInfo {
+
+    /**
+     * 安全预警列表
+     */
+    private List<SafeWarning> warning;
+}

+ 35 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/SafeWarning.java

@@ -0,0 +1,35 @@
+package com.takai.ai.domain.dto.drone;
+import lombok.Data;
+import java.util.List;
+
+/**
+ * 安全预警详情类
+ * 对应JSON中safe.warning的单个元素
+ */
+@Data
+public class SafeWarning {
+    /**
+     * 预警标签(如:未佩戴安全帽、未穿戴反光衣)
+     */
+    private String label;
+
+    /**
+     * 检测目标的边界框坐标 [x1, y1, x2, y2]
+     */
+    private List<Integer> bbox;
+
+    /**
+     * 判定说明
+     */
+    private String judgment;
+
+    /**
+     * 整改建议(可选字段)
+     */
+    private String suggestion;
+
+    /**
+     * 严重程度(可选字段)
+     */
+    private String severity;
+}

+ 21 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ThicknessData.java

@@ -0,0 +1,21 @@
+package com.takai.ai.domain.dto.drone;
+
+import lombok.Data;
+import java.time.LocalDateTime;
+
+/**
+ * 单条厚度数据类
+ * 对应JSON中quality.thickness.map的单个元素
+ */
+@Data
+public class ThicknessData {
+    /**
+     * 检测时间
+     */
+    private LocalDateTime time;
+
+    /**
+     * 厚度值
+     */
+    private Double value;
+}

+ 21 - 0
takai-ai/src/main/java/com/takai/ai/domain/dto/drone/ThicknessInfo.java

@@ -0,0 +1,21 @@
+package com.takai.ai.domain.dto.drone;
+
+import lombok.Data;
+import java.util.List;
+
+/**
+ * 厚度检测数据类
+ * 对应JSON中quality.thickness节点
+ */
+@Data
+public class ThicknessInfo {
+    /**
+     * 厚度数据时序列表
+     */
+    private List<ThicknessData> map;
+
+    /**
+     * 厚度趋势折线图(Base64编码)
+     */
+    private String lineChartImage;
+}

+ 2 - 0
takai-ai/src/main/java/com/takai/ai/service/ITakaiAiService.java

@@ -23,6 +23,8 @@ public interface ITakaiAiService
 
     SseEmitter sseInvoke(TakaiSseInfoParams sseParams);
 
+    String syncInvoke(TakaiSseInfoParams sseParams);
+
     List<String> asyncCompletions(TakaiCompletionsParams params);
 
     List<TakaiDialogRespDTO> getDialogDetail(String dialogId);

+ 67 - 0
takai-ai/src/main/java/com/takai/ai/service/impl/TakaiAiServiceImpl.java

@@ -386,6 +386,73 @@ public class TakaiAiServiceImpl implements ITakaiAiService {
         return null;
     }
 
+
+    @Override
+    public String syncInvoke(TakaiSseInfoParams sseParams) {
+        TakaiApplication appInfo = takaiApplicationMapper.selectTargetApplication(TakaiApplication.builder().appId(sseParams.getAppId()).build());
+        if (appInfo != null) {
+            List<String> idList = Arrays.stream(appInfo.getKnowledgeIds().split(",")) // 按「逗号+空格」拆分字符串为数组
+                    .filter(str -> str != null && !str.trim().isEmpty()) // 过滤 null 和空字符串(防异常)
+                    .collect(Collectors.toList());
+            TakaiKnowledge knowledgeParam = TakaiKnowledge.builder().knowledgeIds(idList).build();
+            List<TakaiKnowledge> knowledgeList = takaiKnowledgeMapper.selectAllKnowledgeList(knowledgeParam);
+            if (knowledgeList != null && !knowledgeList.isEmpty()) {
+                SseEmitter sseEmitter = new SseEmitter(0L);
+                String url = deepseekConfig.getPictureCheckUrl();
+                TakaiAppInfo info = takaiAppInfoMapper.selectAppInfoByAppId(sseParams.getAppId());
+                JSONObject json = JSONObject.parseObject(info.getAppInfo());
+                //重新设置knowledgeIds为数组
+                json.put("knowledgeIds",idList);
+                String query = null;
+//                decodeMessage(sseParams.getMessages());
+//                decodeMessage(sseParams.getPrompt());
+                if(sseParams.getMessages() != null && !sseParams.getMessages().isEmpty() ) {
+                    query = sseParams.getMessages().get(sseParams.getMessages().size() - 1).getContent();
+                } else {
+                    return null;
+                }
+                log.info("图片检测结果聊天请求参数:" + query);
+                json.put("query", query);
+                json.put("embeddingId", knowledgeList.get(0).getEmbeddingId());
+                if(UserConstants.YES.equals(json.getString("isDeepThink"))) {
+                    json.put("enable_think", true);
+                } else {
+                    json.put("enable_think", false);
+                }
+
+                RequestBody requestBody = FormBody.create(MediaType.parse("application/json; charset=utf-8"), json.toJSONString());
+                Request request = buildPostRequest(url, requestBody);
+                OkHttpClient client = buildOkHttpClient();
+                Response response = null;
+                try {
+                    response = client.newCall(request).execute();
+                    //{"code":200,"data":
+                    // {"answer":"你好!欢迎来到企业级知识库问答系统。我可以根据您提供的知识片段为您进行归纳总结并生成对话式回答。请您提出具体问题,以便我为您提供准确的信息。","
+                    // chat_id":"chatcmpl-c5fedbec954a4966a92c5c01857987a7"}
+                    // }
+                    if (response.isSuccessful()) {
+                        String body = response.body().string();
+                        JSONObject obj = JSON.parseObject(body);
+                        Integer code = obj.getInteger("code");
+                        if (code == 200) {
+                            logger.info("图片检测结果调用python接口成功,返回内容:{}", body);
+                        } else {
+                            logger.info("图片检测结果调用python接口失败,返回内容:{}", body);
+                        }
+                        return obj.getJSONObject("data").getString("answer");
+                    } else {
+                        logger.error("图片检测结果调用python接口失败返回code:{}", response.code());
+                        return null;
+                    }
+                } catch (IOException e) {
+                    logger.error("上传文档调用python接口失败", e.getMessage());
+                    return null;
+                }
+            }
+        }
+        return null;
+    }
+
     private void decodeMessage(List<TakaiPromptInfo> messages) {
         if(messages == null || messages.isEmpty()) {
             return;

+ 2 - 0
takai-common/src/main/java/com/takai/common/config/DeepseekConfig.java

@@ -46,4 +46,6 @@ public class DeepseekConfig {
 
     private String cancelTask;
 
+    private String pictureCheckUrl;
+
 }

+ 43 - 0
takai-common/src/main/java/com/takai/common/enums/QualityTypeEnum.java

@@ -0,0 +1,43 @@
+package com.takai.common.enums;
+
+/**
+ * 视频解析数据类型w:模板破损 t:浇筑厚度  r:钢筋间距
+ *
+ * @author takai
+ */
+public enum QualityTypeEnum
+{
+    WARNING("w", "模板破损"), THICKNESS("t", "浇筑厚度"), REBAR_INFO("r", "钢筋间距");
+
+    private final String code;
+    private final String info;
+
+    QualityTypeEnum(String code, String info)
+    {
+        this.code = code;
+        this.info = info;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getInfo()
+    {
+        return info;
+    }
+
+    // 新增:通过code获取info的方法
+    public static String getInfoByCode(String code) {
+        // 遍历所有枚举值
+        for (QualityTypeEnum userType : values()) {
+            // 找到匹配的code
+            if (userType.code.equals(code)) {
+                return userType.info;
+            }
+        }
+        // 没有找到对应code时返回null或默认值
+        return null;
+    }
+}

+ 43 - 0
takai-common/src/main/java/com/takai/common/enums/VisionTypeEnum.java

@@ -0,0 +1,43 @@
+package com.takai.common.enums;
+
+/**
+ * 视频解析数据类型safe:安全检测 quality:质量检测
+ *
+ * @author takai
+ */
+public enum VisionTypeEnum
+{
+    SAFE("safe", "安全检测"), QUALITY("quality", "质量检测");
+
+    private final String code;
+    private final String info;
+
+    VisionTypeEnum(String code, String info)
+    {
+        this.code = code;
+        this.info = info;
+    }
+
+    public String getCode()
+    {
+        return code;
+    }
+
+    public String getInfo()
+    {
+        return info;
+    }
+
+    // 新增:通过code获取info的方法
+    public static String getInfoByCode(String code) {
+        // 遍历所有枚举值
+        for (VisionTypeEnum userType : values()) {
+            // 找到匹配的code
+            if (userType.code.equals(code)) {
+                return userType.info;
+            }
+        }
+        // 没有找到对应code时返回null或默认值
+        return null;
+    }
+}

+ 1 - 1
takai-framework/src/main/java/com/takai/framework/config/SecurityConfig.java

@@ -111,7 +111,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 过滤请求
                 .authorizeRequests()
                 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
-                .antMatchers("/login", "/jk_code_login","/frame_login","/register", "/captchaImage","/getToken","/**/sse-invoke","/**/application/list","/bigmodel/api/dialog/**",
+                .antMatchers("/login", "/jk_code_login","/frame_login","/vision/ai_check","/register", "/captchaImage","/getToken","/**/sse-invoke","/**/application/list","/bigmodel/api/dialog/**",
                         "/**/completions", "/**/slice_info/**", "/**/async_result/**", "/**/assistant/**", "/getInfo",
                         "/checkToken/**", "/**/presets/**", "/**/index/**", "/**/createApplaction/**", "/**/createKnowledge/**",
                         "/**/updateKnowledge/**", "/**/detailKnowledge/**", "/**/delKnowledge/**", "/**/knowledgeList/**",