diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViProjectController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViProjectController.java index d3cf5d9..249db2a 100644 --- a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViProjectController.java +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViProjectController.java @@ -16,6 +16,7 @@ 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; @@ -40,7 +41,7 @@ public class ViProjectController extends BaseController { @ApiOperation("根据id获取项目信息") @PreAuthorize("@ss.hasPermi('vi:project:query')") @GetMapping(value = "/{projectId}") - public AjaxResult getInfo(@PathVariable("projectId") Long projectId) { + public AjaxResult getInfo(@PathVariable("projectId") String projectId) { return success(viProjectService.selectViProjectByProjectId(projectId)); } @@ -61,7 +62,13 @@ public class ViProjectController extends BaseController { @ApiOperation("删除项目") @PreAuthorize("@ss.hasPermi('vi:project:remove')") @DeleteMapping("/{projectIds}") - public AjaxResult remove(@PathVariable Long[] projectIds) { + public AjaxResult remove(@PathVariable String[] projectIds) { return toAjax(viProjectService.deleteViProjectByProjectIds(projectIds)); } + +// @ApiOperation("执行项目") + @PostMapping("/execute") + public AjaxResult execute(@RequestParam("projectId") String projectId) { + return AjaxResult.ok(viProjectService.execute(projectId)); + } } diff --git a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViSchemeController.java b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViSchemeController.java index f35d80e..d9ca7ef 100644 --- a/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViSchemeController.java +++ b/cmvr-iot-admin/src/main/java/com/cmvr/web/controller/vi/ViSchemeController.java @@ -39,7 +39,7 @@ public class ViSchemeController extends BaseController { @ApiOperation("根据ID查询方案详细信息") @PreAuthorize("@ss.hasPermi('vi:scheme:query')") @GetMapping(value = "/{schemeId}") - public AjaxResult getInfo(@PathVariable("schemeId") Long schemeId) { + public AjaxResult getInfo(@PathVariable("schemeId") String schemeId) { return success(viSchemeService.selectViSchemeBySchemeId(schemeId)); } @@ -60,7 +60,7 @@ public class ViSchemeController extends BaseController { @ApiOperation("删除方案") @PreAuthorize("@ss.hasPermi('vi:scheme:remove')") @DeleteMapping("/{schemeIds}") - public AjaxResult remove(@PathVariable Long[] schemeIds) { + public AjaxResult remove(@PathVariable String[] schemeIds) { return toAjax(viSchemeService.deleteViSchemeBySchemeIds(schemeIds)); } } diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/model/domain/TeDetectionItem.java b/cmvr-iot-test/src/main/java/com/cmvr/test/model/domain/TeDetectionItem.java index 37193cd..95b0139 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/model/domain/TeDetectionItem.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/model/domain/TeDetectionItem.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import com.cmvr.common.annotation.Excel; import com.cmvr.common.core.domain.BaseEntity; +import com.cmvr.test.enums.LoopNodeTypeEnum; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -49,4 +50,10 @@ public class TeDetectionItem extends BaseEntity { @ApiModelProperty("检测项参数配置(JSON)") private String config; + + /** + * #{@link LoopNodeTypeEnum} + */ + @ApiModelProperty("场景标识,默认 NORMAL") + private String sceneCode = LoopNodeTypeEnum.NORMAL.name(); } diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/service/ITeDetectionItemService.java b/cmvr-iot-test/src/main/java/com/cmvr/test/service/ITeDetectionItemService.java index fd03c85..0d7243a 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/service/ITeDetectionItemService.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/service/ITeDetectionItemService.java @@ -70,4 +70,12 @@ public interface ITeDetectionItemService extends IService { * @return 结果 */ public int deleteTeDetectionItemById(String id); + + /** + * 根据场景类型查询检测项 + * + * @param sceneType 场景类型 + * @return 结果 + */ + public TeDetectionItem selectTeDetectionItemBySceneType(String sceneType); } diff --git a/cmvr-iot-test/src/main/java/com/cmvr/test/service/impl/TeDetectionItemServiceImpl.java b/cmvr-iot-test/src/main/java/com/cmvr/test/service/impl/TeDetectionItemServiceImpl.java index 8ae3077..512e878 100644 --- a/cmvr-iot-test/src/main/java/com/cmvr/test/service/impl/TeDetectionItemServiceImpl.java +++ b/cmvr-iot-test/src/main/java/com/cmvr/test/service/impl/TeDetectionItemServiceImpl.java @@ -3,6 +3,8 @@ package com.cmvr.test.service.impl; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.cmvr.common.core.domain.entity.SysGroup; @@ -60,7 +62,8 @@ public class TeDetectionItemServiceImpl extends ServiceImpl queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(TeDetectionItem::getSceneCode, sceneType); + return this.getOne(queryWrapper); + } } diff --git a/cmvr-iot-vi/pom.xml b/cmvr-iot-vi/pom.xml index e5c2a34..b87c779 100644 --- a/cmvr-iot-vi/pom.xml +++ b/cmvr-iot-vi/pom.xml @@ -23,6 +23,12 @@ cmvr-iot-common + + + com.cmvr + cmvr-iot-test + + \ No newline at end of file diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViProject.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViProject.java index b3a5518..a82dd9f 100644 --- a/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViProject.java +++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViProject.java @@ -17,8 +17,8 @@ public class ViProject extends BaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty("项目ID") - @TableId(type = IdType.AUTO) - private Long projectId; + @TableId(type = IdType.ASSIGN_UUID) + private String projectId; @Excel(name = "项目名称") @ApiModelProperty("项目名称") diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViScheme.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViScheme.java index 67e2740..10afd0c 100644 --- a/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViScheme.java +++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/model/domain/ViScheme.java @@ -15,12 +15,12 @@ public class ViScheme extends BaseEntity { private static final long serialVersionUID = 1L; @ApiModelProperty("方案ID") - @TableId(type = IdType.AUTO) - private Long schemeId; + @TableId(type = IdType.ASSIGN_UUID) + private String schemeId; @Excel(name = "所属项目ID") @ApiModelProperty("所属项目ID") - private Long projectId; + private String projectId; @Excel(name = "方案名称") @ApiModelProperty("方案名称") @@ -32,6 +32,9 @@ public class ViScheme extends BaseEntity { @ApiModelProperty("唤醒语料parent_id") private String wakeId; + @ApiModelProperty("排序") + private Integer sort; + @Excel(name = "语料ID列表") @ApiModelProperty(value = "语料parent_id列表,逗号分隔",notes = "单次和唤醒的parent_id和id一致,连续语料的parent_id下有多条子语料") private String corpusIds; 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 b1697b2..4c371bd 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 @@ -17,7 +17,7 @@ public interface IViProjectService extends IService { * @param projectId 语音交互-项目主键 * @return 语音交互-项目 */ - public ViProject selectViProjectByProjectId(Long projectId); + public ViProject selectViProjectByProjectId(String projectId); /** * 查询语音交互-项目列表 @@ -49,5 +49,10 @@ public interface IViProjectService extends IService { * @param projectIds 需要删除的语音交互-项目主键集合 * @return 结果 */ - public int deleteViProjectByProjectIds(Long[] projectIds); + public int deleteViProjectByProjectIds(String[] projectIds); + + /** + * 执行项目 + */ + public String execute(String projectId); } diff --git a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViSchemeService.java b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViSchemeService.java index 1296b4d..e6fdfda 100644 --- a/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViSchemeService.java +++ b/cmvr-iot-vi/src/main/java/com/cmvr/vi/service/IViSchemeService.java @@ -17,7 +17,7 @@ public interface IViSchemeService extends IService { * @param schemeId 语音交互-方案主键 * @return 语音交互-方案 */ - public ViScheme selectViSchemeBySchemeId(Long schemeId); + public ViScheme selectViSchemeBySchemeId(String schemeId); /** * 查询语音交互-方案列表 @@ -49,5 +49,5 @@ public interface IViSchemeService extends IService { * @param schemeIds 需要删除的语音交互-方案主键集合 * @return 结果 */ - public int deleteViSchemeBySchemeIds(Long[] schemeIds); + public int deleteViSchemeBySchemeIds(String[] schemeIds); } 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 17925df..74658cb 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 @@ -21,7 +21,7 @@ import java.util.List; public class ViProjectServiceImpl extends ServiceImpl implements IViProjectService { @Override - public ViProject selectViProjectByProjectId(Long projectId) { + public ViProject selectViProjectByProjectId(String projectId) { return this.getById(projectId); } @@ -44,7 +44,13 @@ public class ViProjectServiceImpl extends ServiceImpl implements IViSchemeService { + + private final ITeTaskOrchestrationService teTaskOrchestrationService; + private final ITeDetectionItemService detectionItemService; + @Override - public ViScheme selectViSchemeBySchemeId(Long schemeId) { + public ViScheme selectViSchemeBySchemeId(String schemeId) { return this.getById(schemeId); } @Override public List selectViSchemeList(ViScheme viScheme) { LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(); - wrapper.eq(ObjUtil.isNotEmpty(viScheme.getSchemeName()), ViScheme::getSchemeName, viScheme.getSchemeName()) - .eq(ObjUtil.isNotEmpty(viScheme.getStatus()), ViScheme::getStatus, viScheme.getStatus()); + wrapper.eq(ViScheme::getProjectId, viScheme.getProjectId()) + .eq(ObjUtil.isNotEmpty(viScheme.getSchemeName()), ViScheme::getSchemeName, viScheme.getSchemeName()) + .eq(ObjUtil.isNotEmpty(viScheme.getStatus()), ViScheme::getStatus, viScheme.getStatus()) + .orderByAsc(ViScheme::getSort); return this.list(wrapper); } @Override public int insertViScheme(ViScheme viScheme) { - return this.baseMapper.insert(viScheme); + // 先插方案 + int insert = this.baseMapper.insert(viScheme); + + String taskId = viScheme.getProjectId(); + Integer sort = viScheme.getSort(); + + // 获取对应场景流程id + Integer sceneType = viScheme.getSceneType(); // 1:唤醒 2:单次对话 3:连续对话 + String key; + switch (sceneType) { + case 1: key = FlowSceneTypeEnum.VI_WAKEUP_CORPUS.name(); break; + case 2: key = FlowSceneTypeEnum.VI_SINGLE_CORPUS.name(); break; + case 3: key = FlowSceneTypeEnum.VI_CONTINUOUS_CORPUS.name(); break; + default: throw new GlobalException("场景类型参数错误!"); + } + TeDetectionItem item = detectionItemService.selectTeDetectionItemBySceneType(key); + String itemId = item.getId(); + + // 查询已有编排项 + List items = teTaskOrchestrationService.queryByTaskId(taskId); + + // 插入新编排项 + TeQueryTaskOrchestraItemVO itemVO = new TeQueryTaskOrchestraItemVO(); + itemVO.setItemId(itemId); + itemVO.setOrderNum(sort); + items.add(itemVO); + + // 落库并归一化 + normalizeTaskItems(taskId); + + return insert; } @Override public int updateViScheme(ViScheme viScheme) { - return this.baseMapper.updateById(viScheme); + int update = this.baseMapper.updateById(viScheme); + + String taskId = viScheme.getProjectId(); + + // 这里不管 sort 是否改动,都做一次归一化,避免乱序 + normalizeTaskItems(taskId); + + return update; } @Override - public int deleteViSchemeBySchemeIds(Long[] schemeIds) { - return this.baseMapper.deleteBatchIds(Arrays.asList(schemeIds)); + public int deleteViSchemeBySchemeIds(String[] schemeIds) { + List schemeIdList = Arrays.asList(schemeIds); + + // 查要删除的方案,获取对应 taskId 和流程 itemId + List schemes = this.baseMapper.selectBatchIds(schemeIdList); + int delete = this.baseMapper.deleteBatchIds(schemeIdList); + + // 每个 taskId 单独归一化一次 + Map> taskSchemeMap = schemes.stream() + .collect(Collectors.groupingBy(ViScheme::getProjectId)); + + for (String taskId : taskSchemeMap.keySet()) { + List items = teTaskOrchestrationService.queryByTaskId(taskId); + + if (items != null && !items.isEmpty()) { + // 找出要删的流程 itemId + List deleteItemIds = taskSchemeMap.get(taskId).stream() + .map(s -> { + String key; + switch (s.getSceneType()) { + case 1: key = FlowSceneTypeEnum.VI_WAKEUP_CORPUS.name(); break; + case 2: key = FlowSceneTypeEnum.VI_SINGLE_CORPUS.name(); break; + case 3: key = FlowSceneTypeEnum.VI_CONTINUOUS_CORPUS.name(); break; + default: throw new GlobalException("场景类型参数错误!"); + } + return detectionItemService.selectTeDetectionItemBySceneType(key).getId(); + }) + .collect(Collectors.toList()); + + // 移除这些 item + items.removeIf(i -> deleteItemIds.contains(i.getItemId())); + + // 覆盖保存并归一化 + normalizeTaskItems(taskId); + } + } + + return delete; } + + /** + * 根据 taskId 对编排表的检测项重新排序(1..N) + */ + private void normalizeTaskItems(String taskId) { + List items = teTaskOrchestrationService.queryByTaskId(taskId); + if (items == null || items.isEmpty()) { + return; + } + + // 按顺序排序 + items.sort(Comparator.comparing(TeQueryTaskOrchestraItemVO::getOrderNum)); + + // 重新归一化 1..N + for (int i = 0; i < items.size(); i++) { + items.get(i).setOrderNum(i + 1); + } + + // 落库 + List itemIds = items.stream() + .map(TeQueryTaskOrchestraItemVO::getItemId) + .collect(Collectors.toList()); + + TeTaskOrchestraVO orchestraVO = new TeTaskOrchestraVO(); + orchestraVO.setTaskId(taskId); + orchestraVO.setItemIds(itemIds); + + teTaskOrchestrationService.insertTeTaskOrchestration(orchestraVO); + } + }