fix: 项目管理、方案管理

This commit is contained in:
stream 2025-09-12 16:34:14 +08:00
parent de4bb9b0b4
commit 0adeb20010
12 changed files with 196 additions and 23 deletions

View File

@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import java.util.List; import java.util.List;
@ -40,7 +41,7 @@ public class ViProjectController extends BaseController {
@ApiOperation("根据id获取项目信息") @ApiOperation("根据id获取项目信息")
@PreAuthorize("@ss.hasPermi('vi:project:query')") @PreAuthorize("@ss.hasPermi('vi:project:query')")
@GetMapping(value = "/{projectId}") @GetMapping(value = "/{projectId}")
public AjaxResult getInfo(@PathVariable("projectId") Long projectId) { public AjaxResult getInfo(@PathVariable("projectId") String projectId) {
return success(viProjectService.selectViProjectByProjectId(projectId)); return success(viProjectService.selectViProjectByProjectId(projectId));
} }
@ -61,7 +62,13 @@ public class ViProjectController extends BaseController {
@ApiOperation("删除项目") @ApiOperation("删除项目")
@PreAuthorize("@ss.hasPermi('vi:project:remove')") @PreAuthorize("@ss.hasPermi('vi:project:remove')")
@DeleteMapping("/{projectIds}") @DeleteMapping("/{projectIds}")
public AjaxResult remove(@PathVariable Long[] projectIds) { public AjaxResult remove(@PathVariable String[] projectIds) {
return toAjax(viProjectService.deleteViProjectByProjectIds(projectIds)); return toAjax(viProjectService.deleteViProjectByProjectIds(projectIds));
} }
// @ApiOperation("执行项目")
@PostMapping("/execute")
public AjaxResult execute(@RequestParam("projectId") String projectId) {
return AjaxResult.ok(viProjectService.execute(projectId));
}
} }

View File

@ -39,7 +39,7 @@ public class ViSchemeController extends BaseController {
@ApiOperation("根据ID查询方案详细信息") @ApiOperation("根据ID查询方案详细信息")
@PreAuthorize("@ss.hasPermi('vi:scheme:query')") @PreAuthorize("@ss.hasPermi('vi:scheme:query')")
@GetMapping(value = "/{schemeId}") @GetMapping(value = "/{schemeId}")
public AjaxResult getInfo(@PathVariable("schemeId") Long schemeId) { public AjaxResult getInfo(@PathVariable("schemeId") String schemeId) {
return success(viSchemeService.selectViSchemeBySchemeId(schemeId)); return success(viSchemeService.selectViSchemeBySchemeId(schemeId));
} }
@ -60,7 +60,7 @@ public class ViSchemeController extends BaseController {
@ApiOperation("删除方案") @ApiOperation("删除方案")
@PreAuthorize("@ss.hasPermi('vi:scheme:remove')") @PreAuthorize("@ss.hasPermi('vi:scheme:remove')")
@DeleteMapping("/{schemeIds}") @DeleteMapping("/{schemeIds}")
public AjaxResult remove(@PathVariable Long[] schemeIds) { public AjaxResult remove(@PathVariable String[] schemeIds) {
return toAjax(viSchemeService.deleteViSchemeBySchemeIds(schemeIds)); return toAjax(viSchemeService.deleteViSchemeBySchemeIds(schemeIds));
} }
} }

View File

@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.cmvr.common.annotation.Excel; import com.cmvr.common.annotation.Excel;
import com.cmvr.common.core.domain.BaseEntity; import com.cmvr.common.core.domain.BaseEntity;
import com.cmvr.test.enums.LoopNodeTypeEnum;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
@ -49,4 +50,10 @@ public class TeDetectionItem extends BaseEntity {
@ApiModelProperty("检测项参数配置(JSON)") @ApiModelProperty("检测项参数配置(JSON)")
private String config; private String config;
/**
* #{@link LoopNodeTypeEnum}
*/
@ApiModelProperty("场景标识,默认 NORMAL")
private String sceneCode = LoopNodeTypeEnum.NORMAL.name();
} }

View File

@ -70,4 +70,12 @@ public interface ITeDetectionItemService extends IService<TeDetectionItem> {
* @return 结果 * @return 结果
*/ */
public int deleteTeDetectionItemById(String id); public int deleteTeDetectionItemById(String id);
/**
* 根据场景类型查询检测项
*
* @param sceneType 场景类型
* @return 结果
*/
public TeDetectionItem selectTeDetectionItemBySceneType(String sceneType);
} }

View File

@ -3,6 +3,8 @@ package com.cmvr.test.service.impl;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject; import com.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.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.common.core.domain.entity.SysGroup; import com.cmvr.common.core.domain.entity.SysGroup;
@ -60,7 +62,8 @@ public class TeDetectionItemServiceImpl extends ServiceImpl<TeDetectionItemMappe
.like(StringUtils.isNotBlank(teDetectionItem.getDetectDesc()), TeDetectionItem::getDetectDesc, teDetectionItem.getDetectDesc()) .like(StringUtils.isNotBlank(teDetectionItem.getDetectDesc()), TeDetectionItem::getDetectDesc, teDetectionItem.getDetectDesc())
.eq(StringUtils.isNotBlank(teDetectionItem.getStatus()), TeDetectionItem::getStatus, teDetectionItem.getStatus()) .eq(StringUtils.isNotBlank(teDetectionItem.getStatus()), TeDetectionItem::getStatus, teDetectionItem.getStatus())
.eq(StringUtils.isNotBlank(teDetectionItem.getIsDeploy()), TeDetectionItem::getIsDeploy, teDetectionItem.getIsDeploy()) .eq(StringUtils.isNotBlank(teDetectionItem.getIsDeploy()), TeDetectionItem::getIsDeploy, teDetectionItem.getIsDeploy())
.eq(StringUtils.isNotBlank(teDetectionItem.getDetectVersion()), TeDetectionItem::getDetectVersion, teDetectionItem.getDetectVersion()); .eq(StringUtils.isNotBlank(teDetectionItem.getDetectVersion()), TeDetectionItem::getDetectVersion, teDetectionItem.getDetectVersion())
.orderByDesc(TeDetectionItem::getCreateTime);
// 执行查询并返回结果 // 执行查询并返回结果
return this.baseMapper.selectJoinList(TeDetectionItemVO.class, queryWrapper); return this.baseMapper.selectJoinList(TeDetectionItemVO.class, queryWrapper);
@ -180,4 +183,11 @@ public class TeDetectionItemServiceImpl extends ServiceImpl<TeDetectionItemMappe
public int deleteTeDetectionItemById(String id) { public int deleteTeDetectionItemById(String id) {
return this.baseMapper.deleteById(id); return this.baseMapper.deleteById(id);
} }
@Override
public TeDetectionItem selectTeDetectionItemBySceneType(String sceneType) {
LambdaQueryWrapper<TeDetectionItem> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(TeDetectionItem::getSceneCode, sceneType);
return this.getOne(queryWrapper);
}
} }

View File

@ -23,6 +23,12 @@
<artifactId>cmvr-iot-common</artifactId> <artifactId>cmvr-iot-common</artifactId>
</dependency> </dependency>
<!-- 测试流程-->
<dependency>
<groupId>com.cmvr</groupId>
<artifactId>cmvr-iot-test</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -17,8 +17,8 @@ public class ViProject extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("项目ID") @ApiModelProperty("项目ID")
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_UUID)
private Long projectId; private String projectId;
@Excel(name = "项目名称") @Excel(name = "项目名称")
@ApiModelProperty("项目名称") @ApiModelProperty("项目名称")

View File

@ -15,12 +15,12 @@ public class ViScheme extends BaseEntity {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ApiModelProperty("方案ID") @ApiModelProperty("方案ID")
@TableId(type = IdType.AUTO) @TableId(type = IdType.ASSIGN_UUID)
private Long schemeId; private String schemeId;
@Excel(name = "所属项目ID") @Excel(name = "所属项目ID")
@ApiModelProperty("所属项目ID") @ApiModelProperty("所属项目ID")
private Long projectId; private String projectId;
@Excel(name = "方案名称") @Excel(name = "方案名称")
@ApiModelProperty("方案名称") @ApiModelProperty("方案名称")
@ -32,6 +32,9 @@ public class ViScheme extends BaseEntity {
@ApiModelProperty("唤醒语料parent_id") @ApiModelProperty("唤醒语料parent_id")
private String wakeId; private String wakeId;
@ApiModelProperty("排序")
private Integer sort;
@Excel(name = "语料ID列表") @Excel(name = "语料ID列表")
@ApiModelProperty(value = "语料parent_id列表逗号分隔",notes = "单次和唤醒的parent_id和id一致连续语料的parent_id下有多条子语料") @ApiModelProperty(value = "语料parent_id列表逗号分隔",notes = "单次和唤醒的parent_id和id一致连续语料的parent_id下有多条子语料")
private String corpusIds; private String corpusIds;

View File

@ -17,7 +17,7 @@ public interface IViProjectService extends IService<ViProject> {
* @param projectId 语音交互-项目主键 * @param projectId 语音交互-项目主键
* @return 语音交互-项目 * @return 语音交互-项目
*/ */
public ViProject selectViProjectByProjectId(Long projectId); public ViProject selectViProjectByProjectId(String projectId);
/** /**
* 查询语音交互-项目列表 * 查询语音交互-项目列表
@ -49,5 +49,10 @@ public interface IViProjectService extends IService<ViProject> {
* @param projectIds 需要删除的语音交互-项目主键集合 * @param projectIds 需要删除的语音交互-项目主键集合
* @return 结果 * @return 结果
*/ */
public int deleteViProjectByProjectIds(Long[] projectIds); public int deleteViProjectByProjectIds(String[] projectIds);
/**
* 执行项目
*/
public String execute(String projectId);
} }

View File

@ -17,7 +17,7 @@ public interface IViSchemeService extends IService<ViScheme> {
* @param schemeId 语音交互-方案主键 * @param schemeId 语音交互-方案主键
* @return 语音交互-方案 * @return 语音交互-方案
*/ */
public ViScheme selectViSchemeBySchemeId(Long schemeId); public ViScheme selectViSchemeBySchemeId(String schemeId);
/** /**
* 查询语音交互-方案列表 * 查询语音交互-方案列表
@ -49,5 +49,5 @@ public interface IViSchemeService extends IService<ViScheme> {
* @param schemeIds 需要删除的语音交互-方案主键集合 * @param schemeIds 需要删除的语音交互-方案主键集合
* @return 结果 * @return 结果
*/ */
public int deleteViSchemeBySchemeIds(Long[] schemeIds); public int deleteViSchemeBySchemeIds(String[] schemeIds);
} }

View File

@ -21,7 +21,7 @@ import java.util.List;
public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject> implements IViProjectService { public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject> implements IViProjectService {
@Override @Override
public ViProject selectViProjectByProjectId(Long projectId) { public ViProject selectViProjectByProjectId(String projectId) {
return this.getById(projectId); return this.getById(projectId);
} }
@ -44,7 +44,13 @@ public class ViProjectServiceImpl extends ServiceImpl<ViProjectMapper, ViProject
} }
@Override @Override
public int deleteViProjectByProjectIds(Long[] projectIds) { public int deleteViProjectByProjectIds(String[] projectIds) {
return this.baseMapper.deleteBatchIds(Arrays.asList(projectIds)); return this.baseMapper.deleteBatchIds(Arrays.asList(projectIds));
} }
@Override
public String execute(String projectId) {
return "";
}
} }

View File

@ -4,13 +4,24 @@ import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.common.exception.GlobalException;
import com.cmvr.test.enums.FlowSceneTypeEnum;
import com.cmvr.test.model.domain.TeDetectionItem;
import com.cmvr.test.model.vo.TeQueryTaskOrchestraItemVO;
import com.cmvr.test.model.vo.TeTaskOrchestraVO;
import com.cmvr.test.service.ITeDetectionItemService;
import com.cmvr.test.service.ITeTaskOrchestrationService;
import com.cmvr.vi.mapper.ViSchemeMapper; import com.cmvr.vi.mapper.ViSchemeMapper;
import com.cmvr.vi.model.domain.ViScheme; import com.cmvr.vi.model.domain.ViScheme;
import com.cmvr.vi.service.IViSchemeService; import com.cmvr.vi.service.IViSchemeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.Arrays; import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 语音交互-方案Service业务层处理 * 语音交互-方案Service业务层处理
@ -18,32 +29,142 @@ import java.util.List;
* @author cmvr-iot * @author cmvr-iot
*/ */
@Service @Service
@RequiredArgsConstructor
public class ViSchemeServiceImpl extends ServiceImpl<ViSchemeMapper, ViScheme> implements IViSchemeService { public class ViSchemeServiceImpl extends ServiceImpl<ViSchemeMapper, ViScheme> implements IViSchemeService {
private final ITeTaskOrchestrationService teTaskOrchestrationService;
private final ITeDetectionItemService detectionItemService;
@Override @Override
public ViScheme selectViSchemeBySchemeId(Long schemeId) { public ViScheme selectViSchemeBySchemeId(String schemeId) {
return this.getById(schemeId); return this.getById(schemeId);
} }
@Override @Override
public List<ViScheme> selectViSchemeList(ViScheme viScheme) { public List<ViScheme> selectViSchemeList(ViScheme viScheme) {
LambdaQueryWrapper<ViScheme> wrapper = Wrappers.lambdaQuery(); LambdaQueryWrapper<ViScheme> wrapper = Wrappers.lambdaQuery();
wrapper.eq(ObjUtil.isNotEmpty(viScheme.getSchemeName()), ViScheme::getSchemeName, viScheme.getSchemeName()) wrapper.eq(ViScheme::getProjectId, viScheme.getProjectId())
.eq(ObjUtil.isNotEmpty(viScheme.getStatus()), ViScheme::getStatus, viScheme.getStatus()); .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); return this.list(wrapper);
} }
@Override @Override
public int insertViScheme(ViScheme viScheme) { 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<TeQueryTaskOrchestraItemVO> items = teTaskOrchestrationService.queryByTaskId(taskId);
// 插入新编排项
TeQueryTaskOrchestraItemVO itemVO = new TeQueryTaskOrchestraItemVO();
itemVO.setItemId(itemId);
itemVO.setOrderNum(sort);
items.add(itemVO);
// 落库并归一化
normalizeTaskItems(taskId);
return insert;
} }
@Override @Override
public int updateViScheme(ViScheme viScheme) { 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 @Override
public int deleteViSchemeBySchemeIds(Long[] schemeIds) { public int deleteViSchemeBySchemeIds(String[] schemeIds) {
return this.baseMapper.deleteBatchIds(Arrays.asList(schemeIds)); List<String> schemeIdList = Arrays.asList(schemeIds);
// 查要删除的方案获取对应 taskId 和流程 itemId
List<ViScheme> schemes = this.baseMapper.selectBatchIds(schemeIdList);
int delete = this.baseMapper.deleteBatchIds(schemeIdList);
// 每个 taskId 单独归一化一次
Map<String, List<ViScheme>> taskSchemeMap = schemes.stream()
.collect(Collectors.groupingBy(ViScheme::getProjectId));
for (String taskId : taskSchemeMap.keySet()) {
List<TeQueryTaskOrchestraItemVO> items = teTaskOrchestrationService.queryByTaskId(taskId);
if (items != null && !items.isEmpty()) {
// 找出要删的流程 itemId
List<String> 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<TeQueryTaskOrchestraItemVO> 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<String> itemIds = items.stream()
.map(TeQueryTaskOrchestraItemVO::getItemId)
.collect(Collectors.toList());
TeTaskOrchestraVO orchestraVO = new TeTaskOrchestraVO();
orchestraVO.setTaskId(taskId);
orchestraVO.setItemIds(itemIds);
teTaskOrchestrationService.insertTeTaskOrchestration(orchestraVO);
}
} }