diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/evaluation/AeEvaluationController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/evaluation/AeEvaluationController.java index d7daae3..11ee75d 100644 --- a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/evaluation/AeEvaluationController.java +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/evaluation/AeEvaluationController.java @@ -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(); } + + } diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/ti/TiProjectController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/ti/TiProjectController.java new file mode 100644 index 0000000..937313f --- /dev/null +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/ti/TiProjectController.java @@ -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 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)); + } +} diff --git a/cmvr-iot-admin/src/main/resources/application-dev.yml b/cmvr-iot-admin/src/main/resources/application-dev.yml index 77c645d..25ec2cd 100644 --- a/cmvr-iot-admin/src/main/resources/application-dev.yml +++ b/cmvr-iot-admin/src/main/resources/application-dev.yml @@ -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 diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/enums/ActionEnum.java b/cmvr-iot-test/src/main/java/com/cmvr/test/enums/ActionEnum.java index 401ae44..0049a41 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/enums/ActionEnum.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/enums/ActionEnum.java @@ -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", "获取触控二维坐标") ; diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/dispatcher/FlowHttpNodeHandler.java b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/dispatcher/FlowHttpNodeHandler.java new file mode 100644 index 0000000..e913398 --- /dev/null +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/dispatcher/FlowHttpNodeHandler.java @@ -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()); + } + } +} diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java index 5350972..b1b348b 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/EdgeCameraOperateService.java @@ -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 { diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/ti/TiTouchOperateService.java b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/ti/TiTouchOperateService.java new file mode 100644 index 0000000..3f2bdf8 --- /dev/null +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/flow/runtime/operator/edge/ti/TiTouchOperateService.java @@ -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 DRIVE_MODE_PATH = Arrays.asList("主页", "设置", "驾驶模式", "运动模式"); + + // 打开空调 + public static final List OPEN_AC_PATH = Arrays.asList("主页", "空调", "打开"); + + // 所有路径集合 + public static final List> 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 matchedPath = null; + + for (List 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 params = new HashMap<>(); + params.put("input_image", pageImageUrl); + params.put("icon_image", iconImageUrl); + + Map headers = new HashMap<>(); + headers.put("Apikey", agentConfig.getAppKey()); + + Map 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 headers = new HashMap<>(); + headers.put("Apikey", agentConfig.getAppKey()); + + Map 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 entry : nodes.entrySet()) { + JSONObject node = (JSONObject) entry.getValue(); + if ("end".equalsIgnoreCase(node.getString("nodeType"))) { + return node; + } + } + return null; + } +} diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiProjectService.java b/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiProjectService.java new file mode 100644 index 0000000..7e78c08 --- /dev/null +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiProjectService.java @@ -0,0 +1,9 @@ +package com.cmvr.test.service.ex; + +import com.alibaba.fastjson2.JSONObject; + +public interface ExTiProjectService { + + public JSONObject queryById(String id); + +} diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiVehicleFunctionService.java b/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiVehicleFunctionService.java new file mode 100644 index 0000000..b2451af --- /dev/null +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiVehicleFunctionService.java @@ -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); + +} diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/mapper/TiProjectMapper.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/mapper/TiProjectMapper.java new file mode 100644 index 0000000..0466d52 --- /dev/null +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/mapper/TiProjectMapper.java @@ -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 { +} diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/model/domain/TiProject.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/model/domain/TiProject.java new file mode 100644 index 0000000..009805b --- /dev/null +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/model/domain/TiProject.java @@ -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; +} diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/model/te.sql b/cmvr-iot-ti/src/main/java/com/cmvr/ti/model/te.sql deleted file mode 100644 index b27f9ad..0000000 --- a/cmvr-iot-ti/src/main/java/com/cmvr/ti/model/te.sql +++ /dev/null @@ -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='触控交互-车机功能表'; - diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ITiProjectService.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ITiProjectService.java new file mode 100644 index 0000000..8cd61b2 --- /dev/null +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ITiProjectService.java @@ -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 { + public TiProject selectTiProjectByProjectId(String projectId); + + public List selectTiProjectList(TiProject tiProject); + + public int insertTiProject(TiProject tiProject); + + public int updateTiProject(TiProject tiProject); + + public int deleteTiProjectByProjectIds(String[] projectIds); + + public List queryExecuteRunParams(String projectId); + + public String executeProject(TeTaskExecuteProjectVO taskExecuteProjectVO); + + public TeTaskInst getTeTaskInst(String projectId); + + public String queryExecuteInstId(String projectId); +} diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ITiVehicleFunctionService.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ITiVehicleFunctionService.java index 03686ee..31ab093 100644 --- a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ITiVehicleFunctionService.java +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ITiVehicleFunctionService.java @@ -18,6 +18,8 @@ public interface ITiVehicleFunctionService extends IService { */ public TiVehicleFunction selectTiVehicleFunctionById(Long id); + public List queryByIds(List ids); + /** * 查询车辆功能列表 * diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ex/ExTiProjectServiceImpl.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ex/ExTiProjectServiceImpl.java new file mode 100644 index 0000000..0482e29 --- /dev/null +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ex/ExTiProjectServiceImpl.java @@ -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)); + } +} diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ex/ExTiVehicleFunctionServiceImpl.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ex/ExTiVehicleFunctionServiceImpl.java new file mode 100644 index 0000000..3e276e5 --- /dev/null +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/ex/ExTiVehicleFunctionServiceImpl.java @@ -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 tiVehicleFunctions = tiVehicleFunctionService.listByIds(StrUtil.split(StrPool.COMMA, ids)); + return JSONArray.from(tiVehicleFunctions); + } + + @Override + public JSONObject queryById(Long id) { + return JSONObject.from(tiVehicleFunctionService.getById(id)); + } + + +} diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/impl/TiProjectServiceImpl.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/impl/TiProjectServiceImpl.java new file mode 100644 index 0000000..3902d1d --- /dev/null +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/impl/TiProjectServiceImpl.java @@ -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 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 selectTiProjectList(TiProject tiProject) { + LambdaQueryWrapper 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 ids = StrUtil.split(tiProject.getTestfuncs(), CharPool.COMMA) + .stream() + .map(Long::valueOf) + .collect(Collectors.toList()); + + List 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 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() + .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 ""; + } +} diff --git a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/impl/TiVehicleFunctionServiceImpl.java b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/impl/TiVehicleFunctionServiceImpl.java index 302dfb6..9e4c634 100644 --- a/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/impl/TiVehicleFunctionServiceImpl.java +++ b/cmvr-iot-ti/src/main/java/com/cmvr/ti/service/impl/TiVehicleFunctionServiceImpl.java @@ -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 implements ITiVehicleFunctionService { +public class TiVehicleFunctionServiceImpl extends ServiceImpl + implements ITiVehicleFunctionService { @Override public TiVehicleFunction selectTiVehicleFunctionById(Long id) { return this.getById(id); } + @Override + public List queryByIds(List ids) { + return this.listByIds(ids); + } + @Override public List selectTiVehicleFunctionList(TiVehicleFunctionVO tiVehicleFunctionVO) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViProjectService.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViProjectService.java index ffb1830..f4a14d9 100644 --- a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViProjectService.java +++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViProjectService.java @@ -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 { */ public String executeProject(TeTaskExecuteProjectVO taskExecuteProjectVO); + public TeTaskInst getTeTaskInst(String projectId); + /** * 查询最近一次项目执行记录 */ public String queryExecuteInstId(String projectId); + Object queryEvaluation(String projectId); } diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/impl/ViProjectServiceImpl.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/impl/ViProjectServiceImpl.java index 20b0590..07c8d11 100644 --- a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/impl/ViProjectServiceImpl.java +++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/impl/ViProjectServiceImpl.java @@ -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 wrapperProject = Wrappers.lambdaQuery(ViProject.class); wrapperProject.eq(ViProject::getProjectId, projectId) .eq(ViProject::getStatus, "0"); @@ -144,6 +152,23 @@ public class ViProjectServiceImpl extends ServiceImpl items = queryExecuteRunParams(projectId); + + + // 查询对应评估信息 +// aeEvaluationService + + return null; + } }