feat: 触控交互(部分)
This commit is contained in:
parent
e3e5626e20
commit
e58ac937ec
@ -4,11 +4,9 @@ import com.cmvr.common.core.controller.BaseController;
|
||||
import com.cmvr.common.core.domain.AjaxResult;
|
||||
import com.cmvr.evaluation.model.domain.AeEvaluation;
|
||||
import com.cmvr.evaluation.service.IAeEvaluationService;
|
||||
import com.cmvr.test.model.domain.TeAiEvaluation;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
@ -23,20 +21,12 @@ public class AeEvaluationController extends BaseController {
|
||||
|
||||
private final IAeEvaluationService aeEvaluationService;
|
||||
|
||||
// @ApiOperation("回调AI评估")
|
||||
// @GetMapping("/test")
|
||||
// public AjaxResult execute() {
|
||||
// AeEvaluation aeEvaluation = new AeEvaluation();
|
||||
// aeEvaluation.setInstId("1336caf1e80b2d23b706ad1cd05d78bd");
|
||||
// aeEvaluation.setItemId("18483d62ccec13c0a336d1d605e9b06c");
|
||||
// aeEvaluationService.executeEvaluation(aeEvaluation);
|
||||
// return AjaxResult.ok();
|
||||
// }
|
||||
|
||||
@ApiOperation("回调AI评估")
|
||||
@PostMapping("/callback")
|
||||
public AjaxResult list(@RequestBody AeEvaluation aeEvaluation) {
|
||||
aeEvaluationService.callback(aeEvaluation);
|
||||
return AjaxResult.ok();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,87 @@
|
||||
package com.cmvr.web.controller.ti;
|
||||
|
||||
import com.cmvr.common.core.controller.BaseController;
|
||||
import com.cmvr.common.core.domain.AjaxResult;
|
||||
import com.cmvr.common.core.page.TableDataInfo;
|
||||
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
|
||||
import com.cmvr.ti.model.domain.TiProject;
|
||||
import com.cmvr.ti.service.ITiProjectService;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Api(tags = "触控交互--项目管理")
|
||||
@RestController
|
||||
@RequestMapping("/ti/project")
|
||||
@RequiredArgsConstructor
|
||||
public class TiProjectController extends BaseController {
|
||||
|
||||
private final ITiProjectService tiProjectService;
|
||||
|
||||
@ApiOperation("获取项目列表")
|
||||
@PreAuthorize("@ss.hasPermi('ti:project:list')")
|
||||
@GetMapping("/list")
|
||||
public TableDataInfo list(TiProject tiProject) {
|
||||
startPage();
|
||||
List<TiProject> list = tiProjectService.selectTiProjectList(tiProject);
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
@ApiOperation("根据id获取项目信息")
|
||||
@PreAuthorize("@ss.hasPermi('ti:project:query')")
|
||||
@GetMapping(value = "/{projectId}")
|
||||
public AjaxResult getInfo(@PathVariable("projectId") String projectId) {
|
||||
return success(tiProjectService.selectTiProjectByProjectId(projectId));
|
||||
}
|
||||
|
||||
@ApiOperation("添加项目")
|
||||
@PreAuthorize("@ss.hasPermi('ti:project:add')")
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody TiProject tiProject) {
|
||||
return toAjax(tiProjectService.insertTiProject(tiProject));
|
||||
}
|
||||
|
||||
@ApiOperation("编辑项目")
|
||||
@PreAuthorize("@ss.hasPermi('ti:project:edit')")
|
||||
@PutMapping
|
||||
public AjaxResult edit(@RequestBody TiProject tiProject) {
|
||||
return toAjax(tiProjectService.updateTiProject(tiProject));
|
||||
}
|
||||
|
||||
@ApiOperation("删除项目")
|
||||
@PreAuthorize("@ss.hasPermi('ti:project:remove')")
|
||||
@DeleteMapping("/{projectIds}")
|
||||
public AjaxResult remove(@PathVariable String[] projectIds) {
|
||||
return toAjax(tiProjectService.deleteTiProjectByProjectIds(projectIds));
|
||||
}
|
||||
|
||||
@ApiOperation("查询项目执行时运行参数")
|
||||
@GetMapping("/queryExecuteRunParams")
|
||||
public AjaxResult queryExecuteRunParams(@RequestParam("projectId") String projectId) {
|
||||
return AjaxResult.ok(tiProjectService.queryExecuteRunParams(projectId));
|
||||
}
|
||||
|
||||
@ApiOperation("执行项目")
|
||||
@PostMapping("/execute")
|
||||
public AjaxResult execute(@RequestBody TeTaskExecuteProjectVO taskExecuteProjectVO) {
|
||||
return AjaxResult.ok(tiProjectService.executeProject(taskExecuteProjectVO));
|
||||
}
|
||||
|
||||
@ApiOperation("查询最近一次项目执行实例id")
|
||||
@GetMapping("/queryExecuteInstId/{projectId}")
|
||||
public AjaxResult queryExecuteInstId(@PathVariable("projectId") String projectId) {
|
||||
return AjaxResult.ok(tiProjectService.queryExecuteInstId(projectId));
|
||||
}
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
port: 13081
|
||||
port: 13080
|
||||
# 数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
@ -120,9 +120,11 @@ api:
|
||||
INTENT_RECOGNITION: # 意图识别
|
||||
app-id: d3c98sp0gdon0fcf6l00
|
||||
app-key: d3c98vp0gdon0fcf6n20
|
||||
TOUCH_COORDINATES: # 意图识别
|
||||
app-id: d5thge2cktmipk78h82g
|
||||
app-key: d1ebtabnjkflk4gmhikg
|
||||
evaluation: http://192.168.0.18:8000/analyze
|
||||
|
||||
|
||||
flowise:
|
||||
tts: 192.168.0.222:8080/tts/
|
||||
start: http://192.168.0.108:3000/api/v1/prediction/f99329e9-b33d-437d-90ed-69eaa8a05418
|
||||
|
||||
@ -23,6 +23,7 @@ public enum ActionEnum {
|
||||
BRANCH("NONE", "BRANCH", "分支"),
|
||||
SUB_END("NONE", "SUB_END", "子流程结束"),
|
||||
SLEEP("NONE", "SLEEP", "延迟节点"),
|
||||
HTTP("NONE", "HTTP", "HTTP调用"),
|
||||
// AI评估
|
||||
AI_EVALUATION_PRE("AE", "AI_EVALUATION_PRE", "AI评估预处理"),
|
||||
// AI评估
|
||||
@ -66,6 +67,9 @@ public enum ActionEnum {
|
||||
INTENT_RECOGNITION("LLM", "INTENT_RECOGNITION", "意图识别"),
|
||||
GENERATE_ADVANCED_AUDIO("LLM", "GENERATE_ADVANCED_AUDIO", "tts语音合成"),
|
||||
|
||||
// 触控交互
|
||||
TI_PATH_SEARCH("EDGE", "TI_PATH_SEARCH", "路径搜索"),
|
||||
TI_TOUCH_COORDINATES("EDGE", "TI_TOUCH_COORDINATES", "获取触控二维坐标")
|
||||
;
|
||||
|
||||
|
||||
|
||||
@ -0,0 +1,96 @@
|
||||
package com.cmvr.test.flow.runtime.dispatcher;
|
||||
|
||||
import cn.hutool.http.HttpRequest;
|
||||
import cn.hutool.http.HttpResponse;
|
||||
import cn.hutool.http.Method;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
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("HTTP")
|
||||
@RequiredArgsConstructor
|
||||
public class FlowHttpNodeHandler implements FlowNodeTypeHandler {
|
||||
|
||||
@Override
|
||||
public TaskNodeExecuteResult handle(TaskNodeExecuteMessage message) {
|
||||
try {
|
||||
JSONObject inputParams = message.getInputParams();
|
||||
|
||||
// 1. 必填参数校验
|
||||
String url = inputParams.getString("url");
|
||||
if (url == null || url.isEmpty()) {
|
||||
return TaskNodeExecuteResult.failure("HTTP url is required");
|
||||
}
|
||||
|
||||
String method = inputParams.getString("method");
|
||||
if (method == null) {
|
||||
method = "POST";
|
||||
}
|
||||
|
||||
int timeout = inputParams.getIntValue("timeout", 100000);
|
||||
|
||||
JSONObject headers = inputParams.getJSONObject("headers");
|
||||
Object bodyCfg = inputParams.get("body");
|
||||
|
||||
// 2. 构造 HTTP 请求
|
||||
HttpRequest request = HttpRequest.of(url)
|
||||
.method(Method.valueOf(method.toUpperCase()))
|
||||
.timeout(timeout);
|
||||
|
||||
// 3. headers(可选)
|
||||
if (headers != null) {
|
||||
for (String key : headers.keySet()) {
|
||||
String value = headers.getString(key);
|
||||
if (value != null) {
|
||||
request.header(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. body(可选,JSON)
|
||||
if (bodyCfg != null) {
|
||||
request.header("Content-Type", "application/json");
|
||||
request.body(bodyCfg.toString());
|
||||
}
|
||||
|
||||
log.info("[FLOW][HTTP] {} {}", method, url);
|
||||
|
||||
// 5. 执行请求
|
||||
HttpResponse response = request.execute();
|
||||
|
||||
if (!response.isOk()) {
|
||||
log.error("[FLOW][HTTP] 调用失败,status={}", response.getStatus());
|
||||
return TaskNodeExecuteResult.failure("HTTP status=" + response.getStatus());
|
||||
}
|
||||
|
||||
// 6. 原样解析返回(JSON / String)
|
||||
Object resp;
|
||||
String respBody = response.body();
|
||||
try {
|
||||
resp = JSON.parse(respBody);
|
||||
} catch (Exception e) {
|
||||
resp = respBody;
|
||||
}
|
||||
|
||||
JSONObject output = new JSONObject();
|
||||
output.put("result", resp);
|
||||
|
||||
log.info(
|
||||
"[FLOW][HTTP] success, nodeId={}, responseType={}",
|
||||
message.getNodeId(),
|
||||
resp.getClass().getSimpleName()
|
||||
);
|
||||
|
||||
return TaskNodeExecuteResult.success(output);
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("[FLOW][HTTP] 执行异常", e);
|
||||
return TaskNodeExecuteResult.failure(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,8 +15,6 @@ import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class EdgeCameraOperateService implements EdgeOperateService {
|
||||
|
||||
@ -0,0 +1,257 @@
|
||||
package com.cmvr.test.flow.runtime.operator.edge.ti;
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.text.StrPool;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cmvr.common.config.properties.MinioProperties;
|
||||
import com.cmvr.common.core.minio.MinioService;
|
||||
import com.cmvr.common.exception.GlobalException;
|
||||
import com.cmvr.common.utils.http.CallAPIUtil;
|
||||
import com.cmvr.llm.config.APIProperties;
|
||||
import com.cmvr.llm.config.AgentConfig;
|
||||
import com.cmvr.llm.util.LargeModelFileUploadUtil;
|
||||
import com.cmvr.test.enums.ActionEnum;
|
||||
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteMessage;
|
||||
import com.cmvr.test.flow.runtime.message.TaskNodeExecuteResult;
|
||||
import com.cmvr.test.flow.runtime.operator.edge.EdgeOperateService;
|
||||
import com.cmvr.test.service.ex.ExTiVehicleFunctionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TiTouchOperateService implements EdgeOperateService {
|
||||
|
||||
private final ExTiVehicleFunctionService exTiVehicleFunctionService;
|
||||
private final MinioService minioService;
|
||||
private final MinioProperties minioProps;
|
||||
private final APIProperties apiProperties;
|
||||
|
||||
// 设置运动模式
|
||||
public static final List<String> DRIVE_MODE_PATH = Arrays.asList("主页", "设置", "驾驶模式", "运动模式");
|
||||
|
||||
// 打开空调
|
||||
public static final List<String> OPEN_AC_PATH = Arrays.asList("主页", "空调", "打开");
|
||||
|
||||
// 所有路径集合
|
||||
public static final List<List<String>> ALL_PATHS =
|
||||
Arrays.asList(
|
||||
OPEN_AC_PATH,
|
||||
DRIVE_MODE_PATH
|
||||
);
|
||||
|
||||
@Override
|
||||
public boolean supports(ActionEnum action) {
|
||||
return action.name().startsWith("TI_");
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskNodeExecuteResult execute(TaskNodeExecuteMessage message) {
|
||||
ActionEnum action = message.getAction();
|
||||
JSONObject inputParams = message.getInputParams();
|
||||
|
||||
JSONObject output = new JSONObject();
|
||||
|
||||
|
||||
switch (action) {
|
||||
case TI_PATH_SEARCH: {
|
||||
// 当前界面
|
||||
String currentLocation = inputParams.getString("currentLocation");
|
||||
|
||||
// 查询功能
|
||||
long funcId = inputParams.getLongValue("funcId");
|
||||
JSONObject funcObj = exTiVehicleFunctionService.queryById(funcId);
|
||||
|
||||
String funcKey = funcObj.getString("funcKey");
|
||||
String iconUrl = funcObj.getString("iconUrl");
|
||||
|
||||
|
||||
// ========== 根据当前界面匹配路径 ==========
|
||||
List<String> matchedPath = null;
|
||||
|
||||
for (List<String> path : ALL_PATHS) {
|
||||
if (path.contains(funcKey)) {
|
||||
matchedPath = path;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (matchedPath == null) {
|
||||
throw new GlobalException("未匹配到可用路径");
|
||||
}
|
||||
|
||||
// ========== 计算下一步 ==========
|
||||
int index = matchedPath.indexOf(currentLocation);
|
||||
|
||||
String nextLocation;
|
||||
boolean isEnd;
|
||||
|
||||
if (index == -1 || index == matchedPath.size() - 1) {
|
||||
nextLocation = currentLocation;
|
||||
isEnd = true;
|
||||
} else {
|
||||
nextLocation = matchedPath.get(index + 1);
|
||||
isEnd = (index + 1 == matchedPath.size() - 1);
|
||||
}
|
||||
|
||||
// 输出
|
||||
output.put("nextLocation", nextLocation);
|
||||
output.put("isEnd", isEnd);
|
||||
output.put("iconUrl", iconUrl);
|
||||
|
||||
break;
|
||||
}
|
||||
case TI_TOUCH_COORDINATES: {
|
||||
// 页面图片(相机)
|
||||
String imageUrl = inputParams.getString("imageUrl");
|
||||
String pageImageUrl = uploadImageFromMinio(imageUrl);
|
||||
|
||||
// icon图片
|
||||
String iconUrl = inputParams.getString("iconUrl");
|
||||
String iconImageUrl = uploadImageFromMinio(iconUrl);
|
||||
|
||||
// 获取触控坐标
|
||||
String touchCoordinates = getTouchCoordinates(pageImageUrl, iconImageUrl);
|
||||
|
||||
output.put("touchCoordinates", touchCoordinates);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new GlobalException("不支持的触控操作类型: " + action);
|
||||
}
|
||||
|
||||
return TaskNodeExecuteResult.success(output);
|
||||
}
|
||||
|
||||
private String getTouchCoordinates(String pageImageUrl, String iconImageUrl) {
|
||||
AgentConfig agentConfig = apiProperties.getAgentConfig(ActionEnum.TI_TOUCH_COORDINATES.getAction());
|
||||
Map<String, String> params = new HashMap<>();
|
||||
params.put("input_image", pageImageUrl);
|
||||
params.put("icon_image", iconImageUrl);
|
||||
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Apikey", agentConfig.getAppKey());
|
||||
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("AppKey", agentConfig.getAppKey());
|
||||
body.put("AppID", agentConfig.getAppId());
|
||||
body.put("InputData", JSON.toJSONString(params));
|
||||
body.put("UserID", "18888888888");
|
||||
String response = CallAPIUtil.doPostJson(apiProperties.getWorkFlowUrl(), headers, body);
|
||||
JSONObject resObject1 = JSON.parseObject(response);
|
||||
if (resObject1.containsKey("runId")) {
|
||||
String processId = resObject1.getString("runId");
|
||||
return queryResultByRunId(processId, agentConfig);
|
||||
} else {
|
||||
throw new GlobalException("未获取到 runId,响应内容:" + response);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 MinIO 文件访问地址上传到商道,返回商道文件地址
|
||||
*/
|
||||
private String uploadImageFromMinio(String url) {
|
||||
try {
|
||||
String bucketName = minioProps.getBucketName();
|
||||
String prefix = StrPool.SLASH + bucketName + StrPool.SLASH;
|
||||
|
||||
String objectName = StrUtil.removePrefix(
|
||||
url,
|
||||
StrUtil.subBefore(url, prefix, true) + prefix
|
||||
);
|
||||
|
||||
File imageFile = minioService.getFile(bucketName, objectName);
|
||||
byte[] imageBytes = FileUtil.readBytes(imageFile);
|
||||
|
||||
return LargeModelFileUploadUtil.uploadFile(imageBytes);
|
||||
} catch (Exception e) {
|
||||
log.error("上传 MinIO 文件到商道失败,url={}", url, e);
|
||||
throw new GlobalException("图片上传失败");
|
||||
}
|
||||
}
|
||||
|
||||
private String queryResultByRunId(String processId, AgentConfig agentConfig) {
|
||||
Map<String, String> headers = new HashMap<>();
|
||||
headers.put("Apikey", agentConfig.getAppKey());
|
||||
|
||||
Map<String, String> body = new HashMap<>();
|
||||
body.put("AppKey", agentConfig.getAppKey());
|
||||
body.put("AppID", agentConfig.getAppId());
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package com.cmvr.test.service.ex;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
public interface ExTiProjectService {
|
||||
|
||||
public JSONObject queryById(String id);
|
||||
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.cmvr.test.service.ex;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
|
||||
public interface ExTiVehicleFunctionService {
|
||||
|
||||
public JSONArray queryByIds(String ids);
|
||||
|
||||
public JSONObject queryById(Long id);
|
||||
|
||||
}
|
||||
@ -0,0 +1,7 @@
|
||||
package com.cmvr.ti.mapper;
|
||||
|
||||
import com.cmvr.ti.model.domain.TiProject;
|
||||
import com.github.yulichang.base.MPJBaseMapper;
|
||||
|
||||
public interface TiProjectMapper extends MPJBaseMapper<TiProject> {
|
||||
}
|
||||
@ -0,0 +1,85 @@
|
||||
package com.cmvr.ti.model.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.cmvr.common.annotation.Excel;
|
||||
import com.cmvr.common.core.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@ApiModel("触控交互--项目表")
|
||||
public class TiProject extends BaseEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@ApiModelProperty("项目ID")
|
||||
@TableId(type = IdType.ASSIGN_UUID)
|
||||
private String projectId;
|
||||
|
||||
@Excel(name = "项目名称")
|
||||
@ApiModelProperty("项目名称")
|
||||
private String projectName;
|
||||
|
||||
@Excel(name = "测试人员")
|
||||
@ApiModelProperty("测试人员")
|
||||
private String tester;
|
||||
|
||||
@Excel(name = "计划测试开始时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty("计划测试开始时间")
|
||||
private Date planStart;
|
||||
|
||||
@Excel(name = "计划测试结束时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
|
||||
@ApiModelProperty("计划测试结束时间")
|
||||
private Date planEnd;
|
||||
|
||||
@Excel(name = "项目描述")
|
||||
@ApiModelProperty("项目描述")
|
||||
private String description;
|
||||
|
||||
@Excel(name = "样品名称")
|
||||
@ApiModelProperty("样品名称")
|
||||
private String sampleName;
|
||||
|
||||
@Excel(name = "商标")
|
||||
@ApiModelProperty("商标")
|
||||
private String trademark;
|
||||
|
||||
@Excel(name = "型号规格")
|
||||
@ApiModelProperty("型号规格")
|
||||
private String modelSpec;
|
||||
|
||||
@Excel(name = "数量")
|
||||
@ApiModelProperty("数量")
|
||||
private Integer quantity;
|
||||
|
||||
@Excel(name = "委托单位")
|
||||
@ApiModelProperty("委托单位")
|
||||
private String entrustUnit;
|
||||
|
||||
@Excel(name = "生产单位")
|
||||
@ApiModelProperty("生产单位")
|
||||
private String productionUnit;
|
||||
|
||||
@Excel(name = "生产日期", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
@ApiModelProperty("生产日期")
|
||||
private Date productionDate;
|
||||
|
||||
@Excel(name = "送样日期", width = 30, dateFormat = "yyyy-MM-dd")
|
||||
@ApiModelProperty("送样日期")
|
||||
private Date sampleDate;
|
||||
|
||||
@ApiModelProperty(value = "状态", notes = "状态(0已执行 1未执行)")
|
||||
private String status;
|
||||
|
||||
@ApiModelProperty(value = "评价id")
|
||||
private Long indicatorId;
|
||||
|
||||
@ApiModelProperty(value = "测试功能id列表")
|
||||
private String testfuncs;
|
||||
}
|
||||
@ -1,65 +0,0 @@
|
||||
CREATE TABLE `te_vehicle_config`
|
||||
(
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
|
||||
`oem` VARCHAR(50) NOT NULL COMMENT '车企名称',
|
||||
`model` VARCHAR(50) NOT NULL COMMENT '车型名称',
|
||||
`version` VARCHAR(50) NOT NULL COMMENT '车机版本',
|
||||
|
||||
`remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||||
|
||||
|
||||
`create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='触控交互-车辆配置表';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `ti_vehicle_ui`;
|
||||
CREATE TABLE `ti_vehicle_ui`
|
||||
(
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
|
||||
`vehicle_config_id` BIGINT(20) NOT NULL COMMENT '所属车辆配置ID(te_vehicle_config.id)',
|
||||
|
||||
`ui_key` VARCHAR(50) NOT NULL COMMENT '界面字典键值(来自 sys_dict_data.value)',
|
||||
|
||||
`ui_url` VARCHAR(255) DEFAULT NULL COMMENT '界面截图URL',
|
||||
|
||||
`remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||||
|
||||
`create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='触控交互-车机界面表';
|
||||
|
||||
|
||||
DROP TABLE IF EXISTS `ti_vehicle_function`;
|
||||
CREATE TABLE `ti_vehicle_function`
|
||||
(
|
||||
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
|
||||
|
||||
`vehicle_config_id` BIGINT(20) NOT NULL COMMENT '关联车辆配置ID(te_vehicle_config.id)',
|
||||
`ui_id` BIGINT(20) NOT NULL COMMENT '所属界面ID(ti_vehicle_ui.id)',
|
||||
|
||||
`func_key` VARCHAR(50) NOT NULL COMMENT '功能字典键值(来自 sys_dict_data.value)',
|
||||
|
||||
`icon_url` VARCHAR(255) DEFAULT NULL COMMENT '图标URL(可选)',
|
||||
|
||||
`remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
|
||||
|
||||
`create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
|
||||
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
|
||||
`update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
|
||||
`update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='触控交互-车机功能表';
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
package com.cmvr.ti.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.cmvr.test.model.domain.TeTaskInst;
|
||||
import com.cmvr.test.model.vo.TeQueryProjectOrchestraItemVO;
|
||||
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
|
||||
import com.cmvr.ti.model.domain.TiProject;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ITiProjectService extends IService<TiProject> {
|
||||
public TiProject selectTiProjectByProjectId(String projectId);
|
||||
|
||||
public List<TiProject> selectTiProjectList(TiProject tiProject);
|
||||
|
||||
public int insertTiProject(TiProject tiProject);
|
||||
|
||||
public int updateTiProject(TiProject tiProject);
|
||||
|
||||
public int deleteTiProjectByProjectIds(String[] projectIds);
|
||||
|
||||
public List<TeQueryProjectOrchestraItemVO> queryExecuteRunParams(String projectId);
|
||||
|
||||
public String executeProject(TeTaskExecuteProjectVO taskExecuteProjectVO);
|
||||
|
||||
public TeTaskInst getTeTaskInst(String projectId);
|
||||
|
||||
public String queryExecuteInstId(String projectId);
|
||||
}
|
||||
@ -18,6 +18,8 @@ public interface ITiVehicleFunctionService extends IService<TiVehicleFunction> {
|
||||
*/
|
||||
public TiVehicleFunction selectTiVehicleFunctionById(Long id);
|
||||
|
||||
public List<TiVehicleFunction> queryByIds(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 查询车辆功能列表
|
||||
*
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package com.cmvr.ti.service.ex;
|
||||
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cmvr.test.service.ex.ExTiProjectService;
|
||||
import com.cmvr.ti.service.ITiProjectService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ExTiProjectServiceImpl implements ExTiProjectService {
|
||||
|
||||
private final ITiProjectService tiProjectService;
|
||||
|
||||
@Override
|
||||
public JSONObject queryById(String id) {
|
||||
return JSONObject.from(tiProjectService.getById(id));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,33 @@
|
||||
package com.cmvr.ti.service.ex;
|
||||
|
||||
import cn.hutool.core.text.StrPool;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import com.alibaba.fastjson2.JSONObject;
|
||||
import com.cmvr.test.service.ex.ExTiVehicleFunctionService;
|
||||
import com.cmvr.ti.model.domain.TiVehicleFunction;
|
||||
import com.cmvr.ti.service.ITiVehicleFunctionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ExTiVehicleFunctionServiceImpl implements ExTiVehicleFunctionService {
|
||||
|
||||
private final ITiVehicleFunctionService tiVehicleFunctionService;
|
||||
|
||||
@Override
|
||||
public JSONArray queryByIds(String ids) {
|
||||
List<TiVehicleFunction> tiVehicleFunctions = tiVehicleFunctionService.listByIds(StrUtil.split(StrPool.COMMA, ids));
|
||||
return JSONArray.from(tiVehicleFunctions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSONObject queryById(Long id) {
|
||||
return JSONObject.from(tiVehicleFunctionService.getById(id));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,124 @@
|
||||
package com.cmvr.ti.service.impl;
|
||||
|
||||
|
||||
import cn.hutool.core.text.CharPool;
|
||||
import cn.hutool.core.util.ObjUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.cmvr.common.exception.GlobalException;
|
||||
import com.cmvr.test.enums.RunModeEnum;
|
||||
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
|
||||
import com.cmvr.test.model.domain.TeTaskConfigInfo;
|
||||
import com.cmvr.test.model.domain.TeTaskInst;
|
||||
import com.cmvr.test.model.vo.TeQueryProjectOrchestraItemVO;
|
||||
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
|
||||
import com.cmvr.test.service.ITeTaskConfigInfoService;
|
||||
import com.cmvr.ti.mapper.TiProjectMapper;
|
||||
import com.cmvr.ti.model.domain.TiProject;
|
||||
import com.cmvr.ti.model.domain.TiVehicleFunction;
|
||||
import com.cmvr.ti.service.ITiProjectService;
|
||||
import com.cmvr.ti.service.ITiVehicleFunctionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TiProjectServiceImpl extends ServiceImpl<TiProjectMapper, TiProject> implements ITiProjectService {
|
||||
|
||||
private final ITeTaskConfigInfoService taskConfigInfoService;
|
||||
private final FlowTaskRuntimeService flowTaskRuntimeService;
|
||||
private final ITiVehicleFunctionService tiVehicleFunctionService;
|
||||
|
||||
@Override
|
||||
public TiProject selectTiProjectByProjectId(String projectId) {
|
||||
return this.getById(projectId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TiProject> selectTiProjectList(TiProject tiProject) {
|
||||
LambdaQueryWrapper<TiProject> wrapper = Wrappers.lambdaQuery();
|
||||
wrapper.eq(ObjUtil.isNotEmpty(tiProject.getProjectName()), TiProject::getProjectName, tiProject.getProjectName())
|
||||
.eq(ObjUtil.isNotEmpty(tiProject.getStatus()), TiProject::getStatus, tiProject.getStatus());
|
||||
return this.list(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int insertTiProject(TiProject tiProject) {
|
||||
// 校验功能ID是否属于同一车型配置
|
||||
List<Long> ids = StrUtil.split(tiProject.getTestfuncs(), CharPool.COMMA)
|
||||
.stream()
|
||||
.map(Long::valueOf)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
List<TiVehicleFunction> functions = tiVehicleFunctionService.queryByIds(ids);
|
||||
|
||||
if (functions.size() != ids.size()) {
|
||||
throw new GlobalException("存在无效的功能ID");
|
||||
}
|
||||
|
||||
if (functions.stream()
|
||||
.map(TiVehicleFunction::getVehicleConfigId)
|
||||
.distinct()
|
||||
.count() != 1) {
|
||||
throw new GlobalException("功能ID不属于同一车型配置");
|
||||
}
|
||||
|
||||
int insert = this.baseMapper.insert(tiProject);
|
||||
TeTaskConfigInfo taskConfigInfo = new TeTaskConfigInfo();
|
||||
taskConfigInfo.setRunMode(RunModeEnum.TI_PROJECT.name());
|
||||
taskConfigInfo.setId(tiProject.getProjectId());
|
||||
taskConfigInfo.setStatus("0");
|
||||
taskConfigInfo.setTaskName(StrUtil.format("{}_{}", RunModeEnum.TI_PROJECT, tiProject.getProjectName()));
|
||||
taskConfigInfoService.save(taskConfigInfo);
|
||||
return insert;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int updateTiProject(TiProject tiProject) {
|
||||
return this.baseMapper.updateById(tiProject);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int deleteTiProjectByProjectIds(String[] projectIds) {
|
||||
taskConfigInfoService.deleteTeTaskConfigInfoByIds(projectIds);
|
||||
return this.baseMapper.deleteBatchIds(Arrays.asList(projectIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TeQueryProjectOrchestraItemVO> queryExecuteRunParams(String projectId) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String executeProject(TeTaskExecuteProjectVO taskExecuteProjectVO) {
|
||||
TeTaskExecuteProjectVO normalVO = new TeTaskExecuteProjectVO();
|
||||
normalVO.setProjectId(taskExecuteProjectVO.getProjectId());
|
||||
normalVO.setRunParams(taskExecuteProjectVO.getRunParams());
|
||||
normalVO.setTerminalId(taskExecuteProjectVO.getTerminalId());
|
||||
String instId = flowTaskRuntimeService.executeProjectTask(normalVO);
|
||||
this.update(
|
||||
new LambdaUpdateWrapper<TiProject>()
|
||||
.eq(TiProject::getProjectId, taskExecuteProjectVO.getProjectId())
|
||||
.set(TiProject::getStatus, "0")
|
||||
);
|
||||
return instId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeTaskInst getTeTaskInst(String projectId) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String queryExecuteInstId(String projectId) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@ -14,6 +14,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -21,13 +22,19 @@ import java.util.List;
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class TiVehicleFunctionServiceImpl extends ServiceImpl<TiVehicleFunctionMapper, TiVehicleFunction> implements ITiVehicleFunctionService {
|
||||
public class TiVehicleFunctionServiceImpl extends ServiceImpl<TiVehicleFunctionMapper, TiVehicleFunction>
|
||||
implements ITiVehicleFunctionService {
|
||||
|
||||
@Override
|
||||
public TiVehicleFunction selectTiVehicleFunctionById(Long id) {
|
||||
return this.getById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TiVehicleFunction> queryByIds(List<Long> ids) {
|
||||
return this.listByIds(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<TiVehicleFunction> selectTiVehicleFunctionList(TiVehicleFunctionVO tiVehicleFunctionVO) {
|
||||
LambdaQueryWrapper<TiVehicleFunction> wrapper = Wrappers.lambdaQuery();
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
package com.cmvr.vi.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.cmvr.test.model.domain.TeTaskInst;
|
||||
import com.cmvr.test.model.vo.TeQueryProjectOrchestraItemVO;
|
||||
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
|
||||
import com.cmvr.vi.model.domain.ViProject;
|
||||
@ -63,9 +64,12 @@ public interface IViProjectService extends IService<ViProject> {
|
||||
*/
|
||||
public String executeProject(TeTaskExecuteProjectVO taskExecuteProjectVO);
|
||||
|
||||
public TeTaskInst getTeTaskInst(String projectId);
|
||||
|
||||
/**
|
||||
* 查询最近一次项目执行记录
|
||||
*/
|
||||
public String queryExecuteInstId(String projectId);
|
||||
|
||||
Object queryEvaluation(String projectId);
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.cmvr.common.exception.GlobalException;
|
||||
import com.cmvr.evaluation.service.IAeEvaluationService;
|
||||
import com.cmvr.test.enums.FlowSceneTypeEnum;
|
||||
import com.cmvr.test.enums.RunModeEnum;
|
||||
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
|
||||
@ -44,6 +45,7 @@ public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject
|
||||
private final ITeDetectionItemService detectionItemService;
|
||||
private final ITeTaskConfigInfoService taskConfigInfoService;
|
||||
private final ITeTaskInstService taskInstService;
|
||||
private final IAeEvaluationService aeEvaluationService;
|
||||
|
||||
@Override
|
||||
public ViProject selectViProjectByProjectId(String projectId) {
|
||||
@ -132,6 +134,12 @@ public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject
|
||||
|
||||
@Override
|
||||
public String queryExecuteInstId(String projectId) {
|
||||
TeTaskInst latestTaskInst = getTeTaskInst(projectId);
|
||||
return latestTaskInst.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TeTaskInst getTeTaskInst(String projectId) {
|
||||
LambdaQueryWrapper<ViProject> wrapperProject = Wrappers.lambdaQuery(ViProject.class);
|
||||
wrapperProject.eq(ViProject::getProjectId, projectId)
|
||||
.eq(ViProject::getStatus, "0");
|
||||
@ -144,6 +152,23 @@ public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject
|
||||
.orderByDesc(TeTaskInst::getCreateTime)
|
||||
.last("LIMIT 1");
|
||||
TeTaskInst latestTaskInst = taskInstService.getOne(wrapper);
|
||||
return latestTaskInst.getId();
|
||||
return latestTaskInst;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object queryEvaluation(String projectId) {
|
||||
// 查询项目信息
|
||||
ViProject project = getById(projectId);
|
||||
// 查询对应的实例id
|
||||
String instId = queryExecuteInstId(projectId);
|
||||
// 查询对应检测项信息
|
||||
List<TeQueryProjectOrchestraItemVO> items = queryExecuteRunParams(projectId);
|
||||
|
||||
|
||||
// 查询对应评估信息
|
||||
// aeEvaluationService
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user