diff --git a/cmvr-iot-admin/pom.xml b/cmvr-iot-admin/pom.xml
index 540366b..9b66bc1 100644
--- a/cmvr-iot-admin/pom.xml
+++ b/cmvr-iot-admin/pom.xml
@@ -71,6 +71,12 @@
com.cmvr
cmvr-iot-ti
+
+
+
+ com.cmvr
+ cmvr-iot-evaluation
+
dev
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
index 937313f..1383675 100644
--- 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
@@ -84,4 +84,17 @@ public class TiProjectController extends BaseController {
public AjaxResult queryExecuteInstId(@PathVariable("projectId") String projectId) {
return AjaxResult.ok(tiProjectService.queryExecuteInstId(projectId));
}
+
+ @ApiOperation("临时执行项目评估")
+ @PostMapping("/evaluation")
+ public AjaxResult evaluation(@RequestBody List funcIds) {
+ tiProjectService.executeTiEvaluation(funcIds);
+ return AjaxResult.ok();
+ }
+
+ @ApiOperation("评估查询")
+ @GetMapping("/evaluation/{projectId}")
+ public AjaxResult queryEvaluation(@PathVariable("projectId") String projectId) {
+ return AjaxResult.ok(tiProjectService.queryEvaluation(projectId));
+ }
}
diff --git a/cmvr-iot-admin/src/main/resources/application-dev.yml b/cmvr-iot-admin/src/main/resources/application-dev.yml
index 25ec2cd..7e3f327 100644
--- a/cmvr-iot-admin/src/main/resources/application-dev.yml
+++ b/cmvr-iot-admin/src/main/resources/application-dev.yml
@@ -123,7 +123,7 @@ api:
TOUCH_COORDINATES: # 意图识别
app-id: d5thge2cktmipk78h82g
app-key: d1ebtabnjkflk4gmhikg
- evaluation: http://192.168.0.18:8000/analyze
+ evaluation: http://192.168.0.8:8000/analyze
flowise:
tts: 192.168.0.222:8080/tts/
diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiProjectService.java b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/ExTiProjectService.java
similarity index 53%
rename from cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiProjectService.java
rename to cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/ExTiProjectService.java
index 7e78c08..a2703b8 100644
--- a/cmvr-iot-test/src/main/java/com/cmvr/test/service/ex/ExTiProjectService.java
+++ b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/ExTiProjectService.java
@@ -1,4 +1,4 @@
-package com.cmvr.test.service.ex;
+package com.cmvr.evaluation.service;
import com.alibaba.fastjson2.JSONObject;
@@ -6,4 +6,6 @@ public interface ExTiProjectService {
public JSONObject queryById(String id);
+ public boolean updateProjectStatus(String projectId, Integer status);
+
}
diff --git a/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/IAeEvaluationService.java b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/IAeEvaluationService.java
index 1736dcd..e6fe87d 100644
--- a/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/IAeEvaluationService.java
+++ b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/IAeEvaluationService.java
@@ -16,6 +16,8 @@ public interface IAeEvaluationService extends IService {
List queryEvaluation(String instId);
+ public List queryEvaluationByProjectId(String projectId);
+
/**
* 判断当前项目是否已完成全部评估
*/
diff --git a/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeCallbackServiceImpl.java b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeCallbackServiceImpl.java
index 2024bc0..ad6de14 100644
--- a/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeCallbackServiceImpl.java
+++ b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeCallbackServiceImpl.java
@@ -8,8 +8,10 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.evaluation.model.domain.AeEvaluation;
import com.cmvr.evaluation.service.AeCallbackService;
+import com.cmvr.evaluation.service.ExTiProjectService;
import com.cmvr.evaluation.service.ExViProjectService;
import com.cmvr.evaluation.service.IAeEvaluationService;
+import com.cmvr.test.enums.RunModeEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -25,6 +27,7 @@ public class AeCallbackServiceImpl implements AeCallbackService {
private final IAeEvaluationService aeEvaluationService;
private final ExViProjectService exViProjectService;
+ private final ExTiProjectService exTiProjectService;
@Override
public void callback(AeEvaluation aeEvaluation) {
@@ -59,7 +62,13 @@ public class AeCallbackServiceImpl implements AeCallbackService {
// 判断是否是最后一次评估 更改项目状态
boolean finished = aeEvaluationService.isAllEvaluationsFinished(byId.getInstId());
- if (finished) {
+ if (!finished) {
+ return;
+ }
+ String aeType = aeEvaluation.getAeType();
+ if (RunModeEnum.TI_PROJECT.name().equals(aeType)) {
+ exTiProjectService.updateProjectStatus(byId.getTaskId(), 2);
+ } else {
exViProjectService.updateStatus(byId.getTaskId());
}
}
diff --git a/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeEvaluationServiceImpl.java b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeEvaluationServiceImpl.java
index c378fd2..962c1d0 100644
--- a/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeEvaluationServiceImpl.java
+++ b/cmvr-iot-evaluation/src/main/java/com/cmvr/evaluation/service/impl/AeEvaluationServiceImpl.java
@@ -194,7 +194,8 @@ public class AeEvaluationServiceImpl extends ServiceImpl queryEvaluationByProjectId(String projectId) {
+ LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(AeEvaluation.class);
+ wrapper.eq(AeEvaluation::getTaskId, projectId);
+ return this.list(wrapper);
+ }
+
@Override
public boolean isAllEvaluationsFinished(String instId) {
long total = this.count(
diff --git a/cmvr-iot-framework/src/main/java/com/cmvr/framework/mybatisPlus/MyMetaObjectHandler.java b/cmvr-iot-framework/src/main/java/com/cmvr/framework/mybatisPlus/MyMetaObjectHandler.java
index cd77510..d53d4e0 100644
--- a/cmvr-iot-framework/src/main/java/com/cmvr/framework/mybatisPlus/MyMetaObjectHandler.java
+++ b/cmvr-iot-framework/src/main/java/com/cmvr/framework/mybatisPlus/MyMetaObjectHandler.java
@@ -30,7 +30,10 @@ public class MyMetaObjectHandler implements MetaObjectHandler {
this.setFieldValByName(UPDATE_BY, SecurityUtils.getUsername(), metaObject);
this.setFieldValByName(UPDATE_TIME, formatDate(metaObject.getSetterType(CREATE_TIME)), metaObject);
this.setFieldValByName(DELETED, "0", metaObject);
- this.setFieldValByName(STATUS, "1", metaObject);
+// this.setFieldValByName(STATUS, "1", metaObject);
+ if (getFieldValByName(STATUS, metaObject) == null) {
+ this.setFieldValByName(STATUS, "1", metaObject);
+ }
}
/**
diff --git a/cmvr-iot-ti/pom.xml b/cmvr-iot-ti/pom.xml
index df5344e..46b21fa 100644
--- a/cmvr-iot-ti/pom.xml
+++ b/cmvr-iot-ti/pom.xml
@@ -28,6 +28,11 @@
cmvr-iot-test
+
+
+ com.cmvr
+ cmvr-iot-evaluation
+
\ No newline at end of file
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
index b197964..a9661b2 100644
--- 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
@@ -74,7 +74,7 @@ public class TiProject extends BaseEntity {
@ApiModelProperty("送样日期")
private Date sampleDate;
- @ApiModelProperty(value = "状态", notes = "状态(0已执行 1未执行)")
+ @ApiModelProperty(value = "状态", notes = "状态(0未执行 1执行中 2执行完成(评估))")
private String status;
@ApiModelProperty(value = "评价id")
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
index b57a88c..fbb5f8c 100644
--- 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
@@ -1,8 +1,8 @@
package com.cmvr.ti.service;
import com.baomidou.mybatisplus.extension.service.IService;
+import com.cmvr.evaluation.model.vo.AeViEvaluationVO;
import com.cmvr.test.model.domain.TeTaskInst;
-import com.cmvr.test.model.vo.TeQueryProjectOrchestraItemVO;
import com.cmvr.test.model.vo.TeQueryTaskOrchestraItemVO;
import com.cmvr.test.model.vo.TeTaskExecuteProjectVO;
import com.cmvr.ti.model.domain.TiProject;
@@ -27,4 +27,10 @@ public interface ITiProjectService extends IService {
public TeTaskInst getTeTaskInst(String projectId);
public String queryExecuteInstId(String projectId);
+
+ public boolean updateProjectStatus(String projectId, Integer status);
+
+ public void executeTiEvaluation(List funcIds);
+
+ public AeViEvaluationVO queryEvaluation(String projectId);
}
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
index 0482e29..43a71c2 100644
--- 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
@@ -1,7 +1,7 @@
package com.cmvr.ti.service.ex;
import com.alibaba.fastjson2.JSONObject;
-import com.cmvr.test.service.ex.ExTiProjectService;
+import com.cmvr.evaluation.service.ExTiProjectService;
import com.cmvr.ti.service.ITiProjectService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
@@ -16,4 +16,9 @@ public class ExTiProjectServiceImpl implements ExTiProjectService {
public JSONObject queryById(String id) {
return JSONObject.from(tiProjectService.getById(id));
}
+
+ @Override
+ public boolean updateProjectStatus(String projectId, Integer status) {
+ return tiProjectService.updateProjectStatus(projectId, status);
+ }
}
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
index 62a5003..f1bbd88 100644
--- 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
@@ -1,13 +1,25 @@
package com.cmvr.ti.service.impl;
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSON;
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.core.domain.entity.SysDictData;
import com.cmvr.common.exception.GlobalException;
+import com.cmvr.evaluation.model.domain.AeEvaluation;
+import com.cmvr.evaluation.model.domain.AeIndicatorEntity;
+import com.cmvr.evaluation.model.dto.AeIResultDTO;
+import com.cmvr.evaluation.model.vo.AeViEvaluationVO;
+import com.cmvr.evaluation.service.AeIndicatorService;
+import com.cmvr.evaluation.service.IAeEvaluationService;
+import com.cmvr.system.service.ISysDictTypeService;
import com.cmvr.test.enums.FlowSceneTypeEnum;
import com.cmvr.test.enums.RunModeEnum;
import com.cmvr.test.flow.runtime.engine.FlowTaskRuntimeService;
@@ -26,12 +38,19 @@ 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.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
+import java.math.BigDecimal;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
@@ -42,6 +61,11 @@ public class TiProjectServiceImpl extends ServiceImpl wrapper = Wrappers.lambdaUpdate();
+ wrapper.eq(TiProject::getProjectId, projectId)
+ .set(TiProject::getStatus, status);
+ return this.update(null, wrapper);
+ }
+
+ // 功能ID -> 音频地址
+ private final Map AUDIO_PATH_MAP = new HashMap() {{
+ put("8", "http://192.168.0.100:9000/cmvr-iot/AUDIO/20260310/1773108837127.wav"); // 播放音乐
+ put("12", "http://192.168.0.100:9000/cmvr-iot/AUDIO/20260310/1773108916488.wav"); // 打开导航
+ put("9", "http://192.168.0.100:9000/cmvr-iot/AUDIO/20260310/1773108933968.wav"); // 能量回收
+ }};
+
+ // 功能ID -> 视频地址
+ private final Map VIDEO_PATH_MAP = new HashMap() {{
+ put("8", "http://192.168.0.100:9000/cmvr-iot/VIDEO/20260310/1773108955700.mp4"); // 播放音乐
+ put("12", "http://192.168.0.100:9000/cmvr-iot/VIDEO/20260310/1773108967164.mp4"); // 打开导航
+ put("9", "http://192.168.0.100:9000/cmvr-iot/VIDEO/20260310/1773108978124.mp4"); // 能量回收
+ }};
+
+ @Override
+ public void executeTiEvaluation(List funcIds) {
+ AeEvaluation aeEvaluation = new AeEvaluation();
+ aeEvaluation.setAeType(RunModeEnum.TI_PROJECT.name());
+ aeEvaluation.setInstId(IdUtil.fastSimpleUUID());
+ aeEvaluation.setTaskId("aadb21a32e7990456b866e844a7d4a54");
+ aeEvaluation.setItemId(IdUtil.fastSimpleUUID());
+
+ // todo 触控交互评估
+ String taskId = aeEvaluation.getTaskId();
+ updateProjectStatus(taskId, 1); // 执行中
+ // 模拟流程运行
+// try {
+// Thread.sleep(30000);
+// } catch (InterruptedException e) {
+// throw new RuntimeException(e);
+// }
+
+
+ // 查字典
+ List tiFunctionConfig = dictTypeService.selectDictDataByType("ti_function_config");
+ Map functionMap = tiFunctionConfig.stream()
+ .collect(Collectors.toMap(
+ SysDictData::getDictValue,
+ SysDictData::getDictLabel
+ ));
+
+ // 构建评估任务列表
+ List evaluations = new LinkedList<>();
+ for (Long funcId : funcIds) {
+ TiVehicleFunction byId = vehicleFunctionService.getById(funcId);
+ String funcName = functionMap.get(byId.getFuncKey());
+ AeEvaluation eval = new AeEvaluation();
+ BeanUtil.copyProperties(aeEvaluation, eval);
+ eval.setAeId(IdUtil.fastSimpleUUID());
+ eval.setStatus(0); // 待评估
+ eval.setAvContent(funcName);
+ eval.setAudioPath(AUDIO_PATH_MAP.get(byId.getFuncKey()));
+ eval.setVideoPath(VIDEO_PATH_MAP.get(byId.getFuncKey()));
+ evaluations.add(eval);
+ }
+
+ try {
+ // 入库
+ aeEvaluationService.saveBatch(evaluations);
+
+ // 提交评估
+ for (AeEvaluation e : evaluations) {
+ redisTemplate.opsForList()
+ .rightPush("ae:evaluation:queue", JSON.toJSONString(e));
+ }
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public AeViEvaluationVO queryEvaluation(String projectId) {
+ // 1. 查询项目
+ TiProject project = getById(projectId);
+
+ // 2. 查询评估数据(允许不完整)
+ List evaluations = aeEvaluationService.queryEvaluationByProjectId(projectId);
+ if (CollUtil.isEmpty(evaluations)) {
+ throw new GlobalException(StrUtil.format("暂无项目id为{}的数据", projectId));
+ }
+
+ // 3. 获取指标定义
+ List indicators =
+ aeIndicatorService.getChildrenByParentIdWithLevelLimit(
+ project.getIndicatorId(), 4, 1
+ );
+
+ List itemDetails = new ArrayList<>();
+
+ int failureCount = 0;
+ for (AeEvaluation evaluation : evaluations) {
+ AeViEvaluationVO.AeItemDetail itemDto = new AeViEvaluationVO.AeItemDetail();
+ itemDto.setAeId(evaluation.getAeId());
+ itemDto.setContent(evaluation.getAvContent());
+ AeIResultDTO dto = JSON.parseObject(evaluation.getResult(), AeIResultDTO.class);
+ itemDto.setItemResponseTime(dto.getResponseTime());
+ itemDto.setStatus(evaluation.getStatus());
+
+ boolean success = "成功".equals(dto.getOverallResult());
+
+ if (!success) {
+ itemDto.setFailureReason(dto.getFailureReason());
+ failureCount++;
+ }
+
+ itemDto.setVideoPath(dto.getVideoPath());
+ itemDto.setExecutionDetail(dto.getExecutionDetail());
+
+ itemDetails.add(itemDto);
+ }
+
+ // 计算成功率
+ Long successRate = (long) (((evaluations.size() - failureCount) * 100.0) / evaluations.size());
+
+ //成功率得分
+ Long score = calculateSuccessRateScore(successRate, indicators);
+
+
+ AeViEvaluationVO vo = new AeViEvaluationVO();
+ vo.setItemDetails(itemDetails);
+ vo.setSuccessRate(successRate);
+ vo.setSuccessRateScore(score);
+ return vo;
+ }
+
+ private Long calculateSuccessRateScore(Long successRate, List indicators) {
+ // 查找成功率指标
+ AeIndicatorEntity successRateIndicator = findIndicatorByName(indicators, "成功率");
+
+ if (successRateIndicator == null) {
+ return 0L; // 如果没有匹配的成功率指标,返回 0 分
+ }
+ List children = successRateIndicator.getChildren();
+
+ long score = 0L;
+ for (AeIndicatorEntity child : children) {
+ // 子指标的比较值(例如响应时间阈值)和符号(如 <, <=, >, >=)
+ BigDecimal compareValue1 = child.getCompareNum1();
+ BigDecimal compareValue2 = child.getCompareNum2();
+ String symbol = child.getSymbol();
+
+ // 4. 根据符号和阈值判断响应时间是否符合子指标的规则,计算得分
+ if (compareRange(successRate, compareValue1, compareValue2, symbol)) {
+ score = child.getScore().longValue(); // 得分等于子指标的得分
+ break; // 找到符合条件的子指标后直接返回得分
+ }
+ }
+ return score;
+ }
+
+ private AeIndicatorEntity findIndicatorByName(List indicators, String indicatorName) {
+ for (AeIndicatorEntity indicator : indicators) {
+ if (indicator.getName().equals(indicatorName)) {
+ return indicator;
+ }
+ }
+ return null; // 如果找不到,返回null
+ }
+
+ // 处理区间比较(例如:<=,>=)
+ private boolean compareRange(Long itemResponseTime, BigDecimal compareValue1, BigDecimal compareValue2, String symbol) {
+ // 如果 compareValue1 > compareValue2,交换两者
+ if (compareValue1.compareTo(compareValue2) > 0) {
+ BigDecimal temp = compareValue1;
+ compareValue1 = compareValue2;
+ compareValue2 = temp;
+ }
+
+ switch (symbol) {
+ case "≤":
+ return itemResponseTime <= compareValue2.longValue() && itemResponseTime >= compareValue1.longValue();
+ case "<":
+ return itemResponseTime < compareValue2.longValue() && itemResponseTime >= compareValue1.longValue();
+ case ">":
+ return itemResponseTime > compareValue1.longValue() && itemResponseTime <= compareValue2.longValue();
+ case "≥":
+ return itemResponseTime >= compareValue1.longValue() && itemResponseTime <= compareValue2.longValue();
+ default:
+ return false;
+ }
+ }
}