feat: 触控交互实现、触控交互节点

fix: 分支节点在循环体内部的问题解决
This commit is contained in:
stream 2025-08-22 17:02:26 +08:00
parent 04e0fc2684
commit ba20ac1416
41 changed files with 274 additions and 63 deletions

View File

@ -3,8 +3,8 @@ package com.cmvr.web.controller.test;
import com.cmvr.common.core.controller.BaseController; import com.cmvr.common.core.controller.BaseController;
import com.cmvr.common.core.domain.AjaxResult; import com.cmvr.common.core.domain.AjaxResult;
import com.cmvr.llm.model.CarIcon; import com.cmvr.system.domain.vo.CarIcon;
import com.cmvr.llm.service.CarPathFinderService; import com.cmvr.system.service.CarPathFinderService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -19,6 +19,11 @@
<artifactId>cmvr-iot-common</artifactId> <artifactId>cmvr-iot-common</artifactId>
</dependency> </dependency>
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-system</artifactId>
</dependency>
<dependency> <dependency>
<groupId>com.volcengine</groupId> <groupId>com.volcengine</groupId>
<artifactId>volc-sdk-java</artifactId> <artifactId>volc-sdk-java</artifactId>

View File

@ -1,5 +1,7 @@
package com.cmvr.llm.service; package com.cmvr.llm.service;
import com.alibaba.fastjson2.JSONObject;
import java.io.File; import java.io.File;
public interface LLMTouchService { public interface LLMTouchService {
@ -14,5 +16,5 @@ public interface LLMTouchService {
*/ */
public String getCoordinates(String iconImage, String iconDesc, String inputImage); public String getCoordinates(String iconImage, String iconDesc, String inputImage);
public String touchCoordinates(File image,String targetUi,String manufacturer, String vehType); public JSONObject touchCoordinates(File image, String targetUi, String manufacturer, String vehType);
} }

View File

@ -1,13 +1,15 @@
package com.cmvr.llm.service.impl; package com.cmvr.llm.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.exception.GlobalException; import com.cmvr.common.exception.GlobalException;
import com.cmvr.common.utils.http.CallAPIUtil; import com.cmvr.common.utils.http.CallAPIUtil;
import com.cmvr.llm.config.APIProperties; import com.cmvr.llm.config.APIProperties;
import com.cmvr.llm.model.CarIcon;
import com.cmvr.llm.service.CarPathFinderService;
import com.cmvr.llm.service.LLMTouchService; import com.cmvr.llm.service.LLMTouchService;
import com.cmvr.system.domain.vo.CarIcon;
import com.cmvr.system.service.CarPathFinderService;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -25,7 +27,9 @@ public class LLMTouchServiceImpl implements LLMTouchService {
@Override @Override
public String bgeVl(File image) { public String bgeVl(File image) {
return CallAPIUtil.doPostFile(apiProperties.getBgeVl(), null, "image", image, null); String response = CallAPIUtil.doPostFile(apiProperties.getBgeVl(), null, "image", image, null);
JSONObject result = JSON.parseObject(response);
return result.getString("uiName");
} }
@Override @Override
@ -56,24 +60,151 @@ public class LLMTouchServiceImpl implements LLMTouchService {
} }
@Override @Override
public String touchCoordinates(File image,String targetUi, String manufacturer, String vehType) { public JSONObject touchCoordinates(File image, String targetUi, String manufacturer, String vehType) {
JSONObject result = new JSONObject();
result.put("isFinish", false);
// 当前界面识别
String currentUi = bgeVl(image); String currentUi = bgeVl(image);
if (currentUi != null && currentUi.equals(targetUi)) { if (StrUtil.isEmpty(currentUi)) {
return null; throw new GlobalException("未获取到当前位置");
} }
if (currentUi.equals("设置驾驶偏好")) {
currentUi = "驾驶偏好";
}
// 已在目标界面直接返回完成
if (StrUtil.equals(currentUi, targetUi)) {
result.put("isFinish", true);
result.put("coordinates", "");
return result;
}
// 计算从当前到目标的路径
List<CarIcon> path = carPathFinderService.findPath(manufacturer, vehType, currentUi, targetUi); List<CarIcon> path = carPathFinderService.findPath(manufacturer, vehType, currentUi, targetUi);
String nextUi; if (CollUtil.isEmpty(path)) {
for (int i = 0; i < path.size(); i++) { throw new GlobalException(StrUtil.format("未找到从 [{}] 到 [{}] 的路径", currentUi, targetUi));
CarIcon carIcon = path.get(i);
if (carIcon.getIconName().equals(currentUi)) {
nextUi = path.get(i + 1).getIconName();
} }
// 下一步就是 path.get(0)
CarIcon nextStepIcon = path.get(0);
// 分别上传当前截图和图标图片获得可访问 URL
String imageUrl;
String iconImageUrl;
String iconName = nextStepIcon.getIconName();
try {
// 上传截图
// byte[] imageBytes = FileUtil.readBytes(image);
// imageUrl = LargeModelFileUploadUtil.uploadFile(imageBytes);
//
// // 拼接图标路径例如 icons/honda/sedan/空调控制.png
// String iconPath = StrUtil.format("icon/{}/{}/{}.png", manufacturer, vehType, iconName);
//
// // resources 加载图标文件
// InputStream iconStream = this.getClass().getClassLoader().getResourceAsStream(iconPath);
// if (iconStream == null) {
// throw new GlobalException("未找到图标资源文件:" + iconPath);
// }
//
// // 上传图标
// byte[] iconBytes = IoUtil.readBytes(iconStream);
// iconImageUrl = LargeModelFileUploadUtil.uploadFile(iconBytes);
imageUrl = "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload/full/5d/a3/07244360c69636d5c146e5470d8d5ddf12ceed2643ffd892b7b7a5c4aaeb&IsAnonymous=true";
iconImageUrl =
iconName.equals("驾驶偏好") ?
"https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload/full/a4/1b/6a7319709844c0f483a1d7adcfdbbff478ff5e34bed9ecff5d8fd407f3ac&IsAnonymous=true"
: "https://aiagentplatform.cmft.com/api/proxy/down?Action=Download&Version=2022-01-01&Path=upload%2Ffull%2Ff1%2Fb9%2F8fb5f96f0299ccef60511eb8f7cfdcec890e563bc8e00854e63484086953&IsAnonymous=true";
} catch (Exception e) {
throw new GlobalException("上传图标或截图失败:" + e.getMessage());
} }
// getCoordinates()
return ""; // 获取下一步点击坐标
String coordinates;
try {
coordinates = getCoordinates(iconImageUrl, nextStepIcon.getIconDesc(), imageUrl);
} catch (Exception e) {
throw new GlobalException("获取点击坐标失败:" + e.getMessage());
}
// 7) 返回
result.put("isFinish", false);
result.put("coordinates", coordinates);
return result;
} }
private String queryResultByRunId(String processId) { private String queryResultByRunId(String processId) {
return ""; Map<String, String> headers = new HashMap<>();
headers.put("Apikey", "d1ebtc5u6s5pkko77dkg");
Map<String, String> body = new HashMap<>();
body.put("AppKey", "d1ebtc5u6s5pkko77dkg");
body.put("AppID", "d1ebtabnjkflk4gmhikg");
body.put("RunID", processId);
body.put("UserID", "18888888888");
String responseBody;
JSONObject endNode;
int failCount = 0;
int maxFail = 40;
while (true) {
responseBody = CallAPIUtil.doPostJson(apiProperties.getQueryResultUrl(), headers, body);
JSONObject jsonObject = JSON.parseObject(responseBody);
String status = jsonObject.getString("status");
if ("success".equals(status)) {
JSONObject nodes = jsonObject.getJSONObject("nodes");
if (nodes == null) {
throw new GlobalException("响应中 nodes 为空:" + responseBody);
}
endNode = findEndNode(nodes);
if (endNode != null) {
break;
} else {
throw new GlobalException("未找到 nodeType=end 的节点:" + nodes);
}
} else if ("failed".equals(status)) {
// 如果失败
throw new GlobalException(responseBody);
} else {
// 处理其他状态码
failCount++;
if (failCount > maxFail) {
throw new GlobalException("达到最大重试次数API状态仍未成功" + status);
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new GlobalException("轮询被中断");
}
}
// 解析 output 内容并清洗
JSONObject output = endNode.getJSONObject("output");
String res = output.getString("content");
if (StrUtil.isEmpty(res)) {
throw new GlobalException("未找到坐标内容");
}
return res;
}
/**
* nodes 中提取 nodeType=end 的节点
*/
private JSONObject findEndNode(JSONObject nodes) {
for (Map.Entry<String, Object> entry : nodes.entrySet()) {
JSONObject node = (JSONObject) entry.getValue();
if ("end".equalsIgnoreCase(node.getString("nodeType"))) {
return node;
}
}
return null;
} }
} }

View File

@ -1,4 +1,4 @@
package com.cmvr.llm.model; package com.cmvr.system.domain.vo;
import lombok.Data; import lombok.Data;

View File

@ -1,4 +1,4 @@
package com.cmvr.llm.model; package com.cmvr.system.domain.vo;
import lombok.Data; import lombok.Data;

View File

@ -1,7 +1,7 @@
package com.cmvr.llm.service; package com.cmvr.system.service;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.cmvr.llm.model.CarIcon; import com.cmvr.system.domain.vo.CarIcon;
import java.util.List; import java.util.List;

View File

@ -1,14 +1,16 @@
package com.cmvr.llm.service.impl; package com.cmvr.system.service.impl;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.cmvr.common.exception.GlobalException;
import com.cmvr.common.core.redis.RedisCache; import com.cmvr.system.domain.SysVehOperConfig;
import com.cmvr.llm.model.CarIcon; import com.cmvr.system.domain.vo.CarIcon;
import com.cmvr.llm.model.CarUi; import com.cmvr.system.domain.vo.CarUi;
import com.cmvr.llm.service.CarPathFinderService; import com.cmvr.system.service.CarPathFinderService;
import com.cmvr.llm.util.CarPathFinderUtil; import com.cmvr.system.service.ISysVehOperConfigService;
import com.cmvr.system.util.CarPathFinderUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -23,20 +25,22 @@ import java.util.Map;
@RequiredArgsConstructor @RequiredArgsConstructor
public class CarPathFinderServiceImpl implements CarPathFinderService { public class CarPathFinderServiceImpl implements CarPathFinderService {
private final RedisCache redisCache; private final ISysVehOperConfigService vehOperConfigService;
/** /**
* Redis 获取 JSON 配置查找路径 * 获取 JSON 配置查找路径
*/ */
@Override @Override
public List<CarIcon> findPath(String manufacturer, String vehType, String startUi, String targetFeature) { public List<CarIcon> findPath(String manufacturer, String vehType, String startUi, String targetFeature) {
String redisKey = StrUtil.format("{}:{}:{}", "veh_oper_config", manufacturer, vehType); SysVehOperConfig sysVehOperConfig = vehOperConfigService.selectSysVehOperConfig(manufacturer, vehType);
String configStr = redisCache.getCacheObject(redisKey); if (ObjUtil.isEmpty(sysVehOperConfig)) {
throw new GlobalException("未找到对应的车机配置");
}
String configStr = sysVehOperConfig.getJsonData();
if (StrUtil.isEmpty(configStr)) { if (StrUtil.isEmpty(configStr)) {
return null; return null;
} }
JSONObject configObj = JSON.parseObject(configStr); JSONArray jsonData = JSON.parseArray(configStr);
JSONArray jsonData = configObj.getJSONArray("jsonData");
return findPath(jsonData, startUi, targetFeature); return findPath(jsonData, startUi, targetFeature);
} }

View File

@ -1,9 +1,9 @@
package com.cmvr.llm.util; package com.cmvr.system.util;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.alibaba.fastjson2.JSONObject;
import com.cmvr.llm.model.CarIcon; import com.cmvr.system.domain.vo.CarIcon;
import com.cmvr.llm.model.CarUi; import com.cmvr.system.domain.vo.CarUi;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;

View File

@ -19,9 +19,9 @@ public enum ActionEnum {
SUB_START("NONE", "SUB_START", "循环开始(子流程开始)"), SUB_START("NONE", "SUB_START", "循环开始(子流程开始)"),
END("NONE", "END", "结束"), END("NONE", "END", "结束"),
START_LOOP("NONE", "START_LOOP", "开始循环"), START_LOOP("NONE", "START_LOOP", "开始循环"),
STOP_LOOP("NONE", "START_LOOP", "结束循环"), STOP_LOOP("NONE", "STOP_LOOP", "结束循环"),
BRANCH("NONE", "BRANCH", "分支"), BRANCH("NONE", "BRANCH", "分支"),
SUB_END("NONE", "SUB_STOP", "子流程结束"), SUB_END("NONE", "SUB_END", "子流程结束"),
SLEEP("NONE", "SLEEP", "延迟节点"), SLEEP("NONE", "SLEEP", "延迟节点"),
// 系统行为 // 系统行为

View File

@ -15,9 +15,10 @@ public enum NodeTypeEnum {
FUNCTION("function"), FUNCTION("function"),
BRANCH("branch"), BRANCH("branch"),
LOOP("loop"), LOOP("loop"),
STOP_LOOP("stopLoop"),
END("end"), END("end"),
SLEEP("sleep"), SLEEP("sleep"),
// SUB_END("sub_end"), SUB_END("subEnd"),
; ;
private final String code; private final String code;

View File

@ -45,6 +45,8 @@ public class FlowGraph {
*/ */
private List<FlowParamDef> startInputParamsDefs = new ArrayList<>(); private List<FlowParamDef> startInputParamsDefs = new ArrayList<>();
// 是否跳出循环
private volatile boolean stopLoop = false;
/** /**
* 是否为子图 * 是否为子图
@ -92,6 +94,22 @@ public class FlowGraph {
} }
} }
/**
* 查找子图起始节点SUB_START 类型
*/
public FlowNodeWrapper findSubStartNodeId() {
lock.readLock().lock();
try {
return nodeMap.values().stream()
.filter(n -> n.getNodeType() == NodeTypeEnum.SUB_START)
// .map(FlowNodeWrapper::getNodeId)
.findFirst()
.orElseThrow(() -> new RuntimeException("未找到开始节点"));
} finally {
lock.readLock().unlock();
}
}
/** /**
* 获取子图中起始节点入度为0 * 获取子图中起始节点入度为0
*/ */
@ -268,4 +286,11 @@ public class FlowGraph {
lock.readLock().unlock(); lock.readLock().unlock();
} }
} }
/**
* 是否跳出循环用于 STOP_LOOP 控制节点
*/
public boolean isBreakLoop() {
return stopLoop;
}
} }

View File

@ -286,10 +286,14 @@ public class FlowModelBuilder {
return NodeTypeEnum.SUB_START; return NodeTypeEnum.SUB_START;
case "end": case "end":
return NodeTypeEnum.END; return NodeTypeEnum.END;
case "subend":
return NodeTypeEnum.SUB_END;
case "branch": case "branch":
return NodeTypeEnum.BRANCH; return NodeTypeEnum.BRANCH;
case "loop": case "loop":
return NodeTypeEnum.LOOP; return NodeTypeEnum.LOOP;
case "stoploop":
return NodeTypeEnum.STOP_LOOP;
case "sleep": case "sleep":
return NodeTypeEnum.SLEEP; return NodeTypeEnum.SLEEP;
default: default:

View File

@ -22,6 +22,7 @@ public class FlowLoopNodeHandler implements FlowNodeTypeHandler {
@Override @Override
public TaskNodeExecuteResult handle(TaskNodeExecuteMessage message) { public TaskNodeExecuteResult handle(TaskNodeExecuteMessage message) {
String instId = message.getInstId();
FlowGraph graph = message.getGraph(); FlowGraph graph = message.getGraph();
// 当前从第几次循环开始 // 当前从第几次循环开始
int loopNum = message.getLoopNum() < 0 ? 1 : message.getLoopNum(); int loopNum = message.getLoopNum() < 0 ? 1 : message.getLoopNum();
@ -40,8 +41,13 @@ public class FlowLoopNodeHandler implements FlowNodeTypeHandler {
// 循环执行子图 // 循环执行子图
for (int i = loopNum; i <= loopCount; i++) { for (int i = loopNum; i <= loopCount; i++) {
// 如果子图设置了跳出标志则结束循环
if (subGraph.isBreakLoop()) {
log.info("检测到子图设置跳出标志提前结束循环instId={}, nodeId={}", instId, nodeId);
break;
}
CountDownLatch latch = new CountDownLatch(1); CountDownLatch latch = new CountDownLatch(1);
String instId = message.getInstId();
taskThreadRegistry.registerLatch(instId, nodeId, latch); taskThreadRegistry.registerLatch(instId, nodeId, latch);
FlowItemExecutor flowItemExecutor = SpringUtils.getBean(FlowItemExecutor.class); FlowItemExecutor flowItemExecutor = SpringUtils.getBean(FlowItemExecutor.class);
flowItemExecutor.executeSubGraph(subGraph, message, latch::countDown, i); flowItemExecutor.executeSubGraph(subGraph, message, latch::countDown, i);

View File

@ -0,0 +1,21 @@
package com.cmvr.test.flow.runtime.dispatcher;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component("STOP_LOOP")
@RequiredArgsConstructor
public class FlowStopLoopNodeHandler implements FlowNodeTypeHandler {
@Override
public TaskNodeExecuteResult handle(TaskNodeExecuteMessage message) {
message.getGraph().setStopLoop(true);
log.info("STOP_LOOP 节点执行设置跳出标志instId={}, nodeId={}", message.getInstId(), message.getNodeId());
return TaskNodeExecuteResult.success();
}
}

View File

@ -0,0 +1,18 @@
package com.cmvr.test.flow.runtime.dispatcher;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component("SUB_END")
@RequiredArgsConstructor
public class FlowSubEndNodeHandler implements FlowNodeTypeHandler {
@Override
public TaskNodeExecuteResult handle(TaskNodeExecuteMessage message) {
return TaskNodeExecuteResult.success(message.getInputParams());
}
}

View File

@ -76,7 +76,7 @@ public class FlowItemExecutor {
List<FlowParamDef> startInputDefs = subGraph.getStartInputParamsDefs(); List<FlowParamDef> startInputDefs = subGraph.getStartInputParamsDefs();
// 子图的 start 节点 // 子图的 start 节点
FlowNodeWrapper subStartNode = subGraph.getInDegreeZeroNode(); FlowNodeWrapper subStartNode = subGraph.findSubStartNodeId();
String subStartNodeId = subStartNode.getNodeId(); String subStartNodeId = subStartNode.getNodeId();
NodeExecutor executor = node -> executeNode( NodeExecutor executor = node -> executeNode(
@ -131,7 +131,7 @@ public class FlowItemExecutor {
} }
// END 节点 or 子图结束 // END 节点 or 子图结束
if (node.getNodeType() == NodeTypeEnum.END || graph.isSubGraphEndNode(nodeId)) { if (node.getNodeType() == NodeTypeEnum.END || node.getNodeType() == NodeTypeEnum.SUB_END) {
try { try {
onFinished.run(); onFinished.run();
} catch (Exception e) { } catch (Exception e) {

View File

@ -58,7 +58,7 @@ public class FlowTaskScheduler {
int loopIteration) { int loopIteration) {
String instId = context.getInstId(); String instId = context.getInstId();
FlowNodeWrapper startNode = graph.getInDegreeZeroNode(); FlowNodeWrapper startNode = graph.findSubStartNodeId();
List<String> nextNodes = graph.getNextNodes(startNode.getNodeId()); List<String> nextNodes = graph.getNextNodes(startNode.getNodeId());
if (nextNodes.isEmpty()) { if (nextNodes.isEmpty()) {

View File

@ -55,8 +55,15 @@ public class EdgeCameraOperateService implements EdgeOperateService {
} }
case CAMERA_GETRGBIMAGE: { case CAMERA_GETRGBIMAGE: {
String imageUrl;
// String imageUrl = StrUtil.format("id为 [{}] 的相机拍照了", deviceId); // String imageUrl = StrUtil.format("id为 [{}] 的相机拍照了", deviceId);
String imageUrl = "http://10.148.20.35:9000/cmvr-iot/FILE/20250820/1755670270208.jpg"; if (message.getLoopNum() <= 1) {
// 车辆控制调节
imageUrl = "http://192.168.1.100:9000/cmvr-iot/FILE/20250821/1755761816340.jpg";
} else {
// 驾驶偏好
imageUrl = "http://192.168.1.100:9000/cmvr-iot/FILE/20250822/1755849654731.jpg";
}
// String imageUrl = edgeCameraService.getRGBImage(terminalId, deviceId); // String imageUrl = edgeCameraService.getRGBImage(terminalId, deviceId);
JSONArray imageUrls = new JSONArray(); JSONArray imageUrls = new JSONArray();

View File

@ -6,8 +6,6 @@ import com.alibaba.fastjson2.JSONObject;
import com.cmvr.common.config.properties.MinioProperties; import com.cmvr.common.config.properties.MinioProperties;
import com.cmvr.common.core.minio.MinioService; import com.cmvr.common.core.minio.MinioService;
import com.cmvr.common.exception.GlobalException; import com.cmvr.common.exception.GlobalException;
import com.cmvr.llm.model.CarIcon;
import com.cmvr.llm.service.CarPathFinderService;
import com.cmvr.llm.service.LLMTouchService; import com.cmvr.llm.service.LLMTouchService;
import com.cmvr.test.enums.ActionEnum; import com.cmvr.test.enums.ActionEnum;
import com.cmvr.test.flow.builder.FlowNodeWrapper; import com.cmvr.test.flow.builder.FlowNodeWrapper;
@ -19,7 +17,6 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.io.File; import java.io.File;
import java.util.List;
@Slf4j @Slf4j
@Service @Service
@ -29,7 +26,6 @@ public class LLMTouchOperateService implements LLMOperateService {
private final TaskInstHolder taskInstHolder; private final TaskInstHolder taskInstHolder;
private final MinioService minioService; private final MinioService minioService;
private final MinioProperties minioProps; private final MinioProperties minioProps;
private final CarPathFinderService carPathFinderService;
private final LLMTouchService llmTouchService; private final LLMTouchService llmTouchService;
@Override @Override
@ -46,9 +42,9 @@ public class LLMTouchOperateService implements LLMOperateService {
JSONObject output = new JSONObject(); JSONObject output = new JSONObject();
switch (action) { switch (action) {
case TOUCH_COORDINATES: { case TOUCH_COORDINATES: {
// 必须获取前面的图片 和当前节点的指令
String words = inputParams.getString("words");
String targetFeature = inputParams.getString("targetFeature"); String targetFeature = inputParams.getString("targetFeature");
String manufacturer = inputParams.getString("manufacturer");
String vehType = inputParams.getString("vehType");
// 图片节点的id // 图片节点的id
FlowNodeWrapper imageNode = message.getGraph() FlowNodeWrapper imageNode = message.getGraph()
.getNodeMap() .getNodeMap()
@ -65,8 +61,7 @@ public class LLMTouchOperateService implements LLMOperateService {
String objectName = StrUtil.removePrefix(url, StrUtil.subBefore(url, prefix, true) + prefix); String objectName = StrUtil.removePrefix(url, StrUtil.subBefore(url, prefix, true) + prefix);
try { try {
File image = minioService.getFile(bucketName, objectName); File image = minioService.getFile(bucketName, objectName);
// llmTouchService.touchCoordinates(); output = llmTouchService.touchCoordinates(image, targetFeature, manufacturer, vehType);
output.put("coordinates", "");
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
@ -79,11 +74,3 @@ public class LLMTouchOperateService implements LLMOperateService {
return TaskNodeExecuteResult.success(output); return TaskNodeExecuteResult.success(output);
} }
} }
/**
* String uiName = llmTouchService.bgeVl(image);
* List<CarIcon> path = carPathFinderService.findPath("厂商", "车型", uiName, targetFeature);
*
* String coordinates = llmTouchService.getCoordinates("", "", "");
*
*/