mirror of
https://gitcode.com/ageerle/ruoyi-ai.git
synced 2026-04-16 13:23:42 +00:00
解决冲突
This commit is contained in:
File diff suppressed because it is too large
Load Diff
7
pom.xml
7
pom.xml
@@ -389,13 +389,6 @@
|
|||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 数字人模块 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-aihuman</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- AI流程编排模块 -->
|
<!-- AI流程编排模块 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ruoyi</groupId>
|
<groupId>org.ruoyi</groupId>
|
||||||
|
|||||||
@@ -104,12 +104,6 @@
|
|||||||
<artifactId>ruoyi-wechat</artifactId>
|
<artifactId>ruoyi-wechat</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- 数字人模块 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-aihuman</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- AI流程编排模块 -->
|
<!-- AI流程编排模块 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ruoyi</groupId>
|
<groupId>org.ruoyi</groupId>
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
<module>ruoyi-aihuman</module>
|
|
||||||
<module>ruoyi-aiflow</module>
|
<module>ruoyi-aiflow</module>
|
||||||
<module>ruoyi-chat</module>
|
<module>ruoyi-chat</module>
|
||||||
<module>ruoyi-demo</module>
|
<module>ruoyi-demo</module>
|
||||||
|
|||||||
@@ -1,101 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-modules</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
<relativePath>../pom.xml</relativePath>
|
|
||||||
</parent>
|
|
||||||
|
|
||||||
<artifactId>ruoyi-aihuman</artifactId>
|
|
||||||
|
|
||||||
<description>
|
|
||||||
aihuman模块
|
|
||||||
</description>
|
|
||||||
|
|
||||||
<properties>
|
|
||||||
<easyexcel.version>3.2.1</easyexcel.version>
|
|
||||||
<jna.version>5.13.0</jna.version>
|
|
||||||
<java-websocket.version>1.5.5</java-websocket.version>
|
|
||||||
</properties>
|
|
||||||
|
|
||||||
<!-- 按照用户要求,不添加任何依赖 -->
|
|
||||||
<dependencies>
|
|
||||||
<!-- 通用工具-->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-common-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-common-doc</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-common-mybatis</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-common-web</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-common-log</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-common-idempotent</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!--velocity代码生成使用模板 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.velocity</groupId>
|
|
||||||
<artifactId>velocity-engine-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- <dependency>-->
|
|
||||||
<!-- <groupId>com.alibaba</groupId>-->
|
|
||||||
<!-- <artifactId>easyexcel</artifactId>-->
|
|
||||||
<!-- <version>${easyexcel.version}</version>-->
|
|
||||||
<!-- <exclusions>-->
|
|
||||||
<!-- <exclusion>-->
|
|
||||||
<!-- <groupId>org.apache.poi</groupId>-->
|
|
||||||
<!-- <artifactId>poi-ooxml-schemas</artifactId>-->
|
|
||||||
<!-- </exclusion>-->
|
|
||||||
<!-- </exclusions>-->
|
|
||||||
<!-- </dependency>-->
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.ruoyi</groupId>
|
|
||||||
<artifactId>ruoyi-common-excel</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.java.dev.jna</groupId>
|
|
||||||
<artifactId>jna</artifactId>
|
|
||||||
<version>${jna.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.java.dev.jna</groupId>
|
|
||||||
<artifactId>jna-platform</artifactId>
|
|
||||||
<version>${jna.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.java-websocket</groupId>
|
|
||||||
<artifactId>Java-WebSocket</artifactId>
|
|
||||||
<version>${java-websocket.version}</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
|
|
||||||
</dependencies>
|
|
||||||
</project>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.config;
|
|
||||||
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
|
||||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
|
||||||
|
|
||||||
@Configuration
|
|
||||||
public class WebConfig implements WebMvcConfigurer {
|
|
||||||
@Override
|
|
||||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
|
||||||
// 映射/voice/**路径到classpath:/voice/目录
|
|
||||||
registry.addResourceHandler("/voice/**")
|
|
||||||
.addResourceLocations("classpath:/voice/")
|
|
||||||
.setCachePeriod(3600);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.controller;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.ruoyi.aihuman.domain.bo.AihumanConfigBo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
|
|
||||||
import org.ruoyi.aihuman.service.AihumanConfigService;
|
|
||||||
import org.ruoyi.common.core.domain.R;
|
|
||||||
import org.ruoyi.common.core.validate.AddGroup;
|
|
||||||
import org.ruoyi.common.core.validate.EditGroup;
|
|
||||||
import org.ruoyi.common.excel.utils.ExcelUtil;
|
|
||||||
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
|
|
||||||
import org.ruoyi.common.log.annotation.Log;
|
|
||||||
import org.ruoyi.common.log.enums.BusinessType;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
import org.ruoyi.common.web.core.BaseController;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互数字人配置
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 22:27:00 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
|
|
||||||
//临时免登录
|
|
||||||
@SaIgnore
|
|
||||||
|
|
||||||
@Validated
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/aihuman/aihumanConfig")
|
|
||||||
public class AihumanConfigController extends BaseController {
|
|
||||||
|
|
||||||
private final AihumanConfigService aihumanConfigService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询交互数字人配置列表
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanConfig:list")
|
|
||||||
@GetMapping("/list")
|
|
||||||
public TableDataInfo<AihumanConfigVo> list(AihumanConfigBo bo, PageQuery pageQuery) {
|
|
||||||
return aihumanConfigService.queryPageList(bo, pageQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出交互数字人配置列表
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanConfig:export")
|
|
||||||
@Log(title = "交互数字人配置", businessType = BusinessType.EXPORT)
|
|
||||||
@PostMapping("/export")
|
|
||||||
public void export(AihumanConfigBo bo, HttpServletResponse response) {
|
|
||||||
List<AihumanConfigVo> list = aihumanConfigService.queryList(bo);
|
|
||||||
ExcelUtil.exportExcel(list, "交互数字人配置", AihumanConfigVo.class, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取交互数字人配置详细信息
|
|
||||||
*
|
|
||||||
* @param id 主键
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanConfig:query")
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public R<AihumanConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
|
||||||
@PathVariable Integer id) {
|
|
||||||
return R.ok(aihumanConfigService.queryById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增交互数字人配置
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanConfig:add")
|
|
||||||
@Log(title = "交互数字人配置", businessType = BusinessType.INSERT)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PostMapping()
|
|
||||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody AihumanConfigBo bo) {
|
|
||||||
return toAjax(aihumanConfigService.insertByBo(bo));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改交互数字人配置
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanConfig:edit")
|
|
||||||
@Log(title = "交互数字人配置", businessType = BusinessType.UPDATE)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PutMapping()
|
|
||||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody AihumanConfigBo bo) {
|
|
||||||
return toAjax(aihumanConfigService.updateByBo(bo));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除交互数字人配置
|
|
||||||
*
|
|
||||||
* @param ids 主键串
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanConfig:remove")
|
|
||||||
@Log(title = "交互数字人配置", businessType = BusinessType.DELETE)
|
|
||||||
@DeleteMapping("/{ids}")
|
|
||||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
|
||||||
@PathVariable Integer[] ids) {
|
|
||||||
return toAjax(aihumanConfigService.deleteWithValidByIds(List.of(ids), true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询已发布的交互数字人配置列表
|
|
||||||
* 只返回 publish = 1 的数据
|
|
||||||
*/
|
|
||||||
@GetMapping("/publishedList")
|
|
||||||
public TableDataInfo<AihumanConfigVo> publishedList(PageQuery pageQuery) {
|
|
||||||
// 创建查询条件对象并设置publish=1
|
|
||||||
AihumanConfigBo bo = new AihumanConfigBo();
|
|
||||||
bo.setPublish(1);
|
|
||||||
// 调用现有的查询方法,传入预设了publish=1条件的bo对象
|
|
||||||
return aihumanConfigService.queryPageList(bo, pageQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.controller;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanInfo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanInfoVo;
|
|
||||||
import org.ruoyi.aihuman.service.IAihumanInfoService;
|
|
||||||
import org.ruoyi.common.core.domain.R;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI人类交互信息Controller
|
|
||||||
* 免登录接口,方便验证
|
|
||||||
*
|
|
||||||
* @author QingYunAI
|
|
||||||
*/
|
|
||||||
@SaIgnore
|
|
||||||
@Validated
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/aihuman/info")
|
|
||||||
public class AihumanInfoController {
|
|
||||||
|
|
||||||
private final IAihumanInfoService aihumanInfoService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取AI人类交互信息详情
|
|
||||||
*/
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public R<AihumanInfoVo> getInfo(@PathVariable Long id) {
|
|
||||||
return R.ok(aihumanInfoService.queryById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询AI人类交互信息列表
|
|
||||||
*/
|
|
||||||
@GetMapping("/list")
|
|
||||||
public R<TableDataInfo<AihumanInfoVo>> list(AihumanInfo aihumanInfo, PageQuery pageQuery) {
|
|
||||||
TableDataInfo<AihumanInfoVo> tableDataInfo = aihumanInfoService.queryPageList(aihumanInfo, pageQuery);
|
|
||||||
return R.ok(tableDataInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增AI人类交互信息
|
|
||||||
*/
|
|
||||||
@PostMapping
|
|
||||||
public R<Integer> add(@Validated @RequestBody AihumanInfo aihumanInfo) {
|
|
||||||
return R.ok(aihumanInfoService.insert(aihumanInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改AI人类交互信息
|
|
||||||
*/
|
|
||||||
@PutMapping
|
|
||||||
public R<Integer> edit(@Validated @RequestBody AihumanInfo aihumanInfo) {
|
|
||||||
return R.ok(aihumanInfoService.update(aihumanInfo));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除AI人类交互信息
|
|
||||||
*/
|
|
||||||
@DeleteMapping("/{ids}")
|
|
||||||
public R<Integer> remove(@PathVariable Long[] ids) {
|
|
||||||
return R.ok(aihumanInfoService.deleteWithValidByIds(Arrays.asList(ids), true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 测试接口
|
|
||||||
* 提供一个简单的GET接口用于快速验证控制器是否正常工作
|
|
||||||
*/
|
|
||||||
@GetMapping("/test")
|
|
||||||
public R<String> test() {
|
|
||||||
return R.ok("AI Human Controller is working!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.controller;
|
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
|
||||||
import cn.dev33.satoken.annotation.SaIgnore;
|
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import jakarta.validation.constraints.NotEmpty;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo;
|
|
||||||
import org.ruoyi.aihuman.service.AihumanRealConfigService;
|
|
||||||
import org.ruoyi.common.core.domain.R;
|
|
||||||
import org.ruoyi.common.core.validate.AddGroup;
|
|
||||||
import org.ruoyi.common.core.validate.EditGroup;
|
|
||||||
import org.ruoyi.common.excel.utils.ExcelUtil;
|
|
||||||
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
|
|
||||||
import org.ruoyi.common.log.annotation.Log;
|
|
||||||
import org.ruoyi.common.log.enums.BusinessType;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
import org.ruoyi.common.web.core.BaseController;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真人交互数字人配置
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Tue Oct 21 11:46:52 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
//临时免登录
|
|
||||||
@SaIgnore
|
|
||||||
|
|
||||||
@Validated
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/aihuman/aihumanRealConfig")
|
|
||||||
public class AihumanRealConfigController extends BaseController {
|
|
||||||
|
|
||||||
private final AihumanRealConfigService aihumanRealConfigService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询真人交互数字人配置列表
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:list")
|
|
||||||
@GetMapping("/list")
|
|
||||||
public TableDataInfo<AihumanRealConfigVo> list(AihumanRealConfigBo bo, PageQuery pageQuery) {
|
|
||||||
return aihumanRealConfigService.queryPageList(bo, pageQuery);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出真人交互数字人配置列表
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:export")
|
|
||||||
@Log(title = "真人交互数字人配置", businessType = BusinessType.EXPORT)
|
|
||||||
@PostMapping("/export")
|
|
||||||
public void export(AihumanRealConfigBo bo, HttpServletResponse response) {
|
|
||||||
List<AihumanRealConfigVo> list = aihumanRealConfigService.queryList(bo);
|
|
||||||
ExcelUtil.exportExcel(list, "真人交互数字人配置", AihumanRealConfigVo.class, response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取真人交互数字人配置详细信息
|
|
||||||
*
|
|
||||||
* @param id 主键
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:query")
|
|
||||||
@GetMapping("/{id}")
|
|
||||||
public R<AihumanRealConfigVo> getInfo(@NotNull(message = "主键不能为空")
|
|
||||||
@PathVariable Integer id) {
|
|
||||||
return R.ok(aihumanRealConfigService.queryById(id));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增真人交互数字人配置
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:add")
|
|
||||||
@Log(title = "真人交互数字人配置", businessType = BusinessType.INSERT)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PostMapping()
|
|
||||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody AihumanRealConfigBo bo) {
|
|
||||||
return toAjax(aihumanRealConfigService.insertByBo(bo));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改真人交互数字人配置
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:edit")
|
|
||||||
@Log(title = "真人交互数字人配置", businessType = BusinessType.UPDATE)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PutMapping()
|
|
||||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody AihumanRealConfigBo bo) {
|
|
||||||
return toAjax(aihumanRealConfigService.updateByBo(bo));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除真人交互数字人配置
|
|
||||||
*
|
|
||||||
* @param ids 主键串
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:remove")
|
|
||||||
@Log(title = "真人交互数字人配置", businessType = BusinessType.DELETE)
|
|
||||||
@DeleteMapping("/{ids}")
|
|
||||||
public R<Void> remove(@NotEmpty(message = "主键不能为空")
|
|
||||||
@PathVariable Integer[] ids) {
|
|
||||||
return toAjax(aihumanRealConfigService.deleteWithValidByIds(List.of(ids), true));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1.执行以下命令:
|
|
||||||
* cd F:\Projects\AI-Human\LiveTalking
|
|
||||||
* conda activate D:\zg117\C\Users\zg117\.conda\envs\livetalking_new
|
|
||||||
* python app.py --transport webrtc --model wav2lip --avatar_id wav2lip256_avatar1
|
|
||||||
* <p>
|
|
||||||
* 2.监听 python app.py --transport webrtc --model wav2lip --avatar_id wav2lip256_avatar1 执行情况
|
|
||||||
* <p>
|
|
||||||
* 3.返回执行结果并打开页面
|
|
||||||
* http://127.0.0.1:8010/webrtcapi-diy.html
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:run")
|
|
||||||
//@Log(title = "真人交互数字人配置", businessType = BusinessType.UPDATE, operatorType = OperatorType.OTHER)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PutMapping("/run")
|
|
||||||
public R<String> run(@Validated(EditGroup.class) @RequestBody AihumanRealConfigBo bo) {
|
|
||||||
boolean result = aihumanRealConfigService.runByBo(bo);
|
|
||||||
if (result) {
|
|
||||||
// 返回前端页面URL,前端可以根据这个URL跳转或打开新页面
|
|
||||||
// http://127.0.0.1:8010/webrtcapi-diy.html 其中的 http://127.0.0.1 获取当前java服务的IP地址
|
|
||||||
// return R.ok("http://127.0.0.1:8010/webrtcapi-diy.html");
|
|
||||||
// 运行状态
|
|
||||||
bo.setRunStatus("1");
|
|
||||||
return R.ok("http://127.0.0.1:8010/webrtcapi-diy.html");
|
|
||||||
} else {
|
|
||||||
return R.fail("启动真人交互数字人失败");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 停止真人交互数字人配置任务
|
|
||||||
*/
|
|
||||||
@SaCheckPermission("aihuman:aihumanRealConfig:stop")
|
|
||||||
//@Log(title = "真人交互数字人配置", businessType = BusinessType.UPDATE, operatorType = OperatorType.OTHER)
|
|
||||||
@RepeatSubmit()
|
|
||||||
@PutMapping("/stop")
|
|
||||||
public R<String> stop(@Validated(EditGroup.class) @RequestBody AihumanRealConfigBo bo) {
|
|
||||||
boolean result = aihumanRealConfigService.stopByBo(bo);
|
|
||||||
if (result) {
|
|
||||||
// 运行状态
|
|
||||||
bo.setRunStatus("0");
|
|
||||||
return R.ok("真人交互数字人任务已停止");
|
|
||||||
} else {
|
|
||||||
return R.fail("停止真人交互数字人任务失败或没有正在运行的任务");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,74 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互数字人配置对象 aihuman_config
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 22:27:00 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("aihuman_config")
|
|
||||||
public class AihumanConfig implements Serializable {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* id
|
|
||||||
*/
|
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* name
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* modelName
|
|
||||||
*/
|
|
||||||
private String modelName;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* modelPath
|
|
||||||
*/
|
|
||||||
private String modelPath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* modelParams
|
|
||||||
*/
|
|
||||||
private String modelParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* agentParams
|
|
||||||
*/
|
|
||||||
private String agentParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* createTime
|
|
||||||
*/
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* updateTime
|
|
||||||
*/
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* status
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* publish
|
|
||||||
*/
|
|
||||||
private Integer publish;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.*;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI人类交互信息实体类
|
|
||||||
*
|
|
||||||
* @author QingYunAI
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("aihuman_info")
|
|
||||||
public class AihumanInfo implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键ID
|
|
||||||
*/
|
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互内容
|
|
||||||
*/
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@TableField(fill = FieldFill.INSERT)
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
|
||||||
private Date updateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除标志(0代表存在 2代表删除)
|
|
||||||
*/
|
|
||||||
@TableLogic
|
|
||||||
private String delFlag;
|
|
||||||
}
|
|
||||||
@@ -1,104 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真人交互数字人配置对象 aihuman_real_config
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Tue Oct 21 11:46:52 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@TableName("aihuman_real_config")
|
|
||||||
public class AihumanRealConfig implements Serializable {
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键id
|
|
||||||
*/
|
|
||||||
@TableId(value = "id", type = IdType.AUTO)
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 场景名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真人形象名称
|
|
||||||
*/
|
|
||||||
private String avatars;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模型名称
|
|
||||||
*/
|
|
||||||
private String models;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 形象参数(预留)
|
|
||||||
*/
|
|
||||||
private String avatarsParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模型参数(预留)
|
|
||||||
*/
|
|
||||||
private String modelsParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 智能体参数(扣子)
|
|
||||||
*/
|
|
||||||
private String agentParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发布状态
|
|
||||||
*/
|
|
||||||
private Integer publish;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行参数
|
|
||||||
*/
|
|
||||||
private String runParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行状态
|
|
||||||
*/
|
|
||||||
private String runStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建部门
|
|
||||||
*/
|
|
||||||
private String createDept;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建用户
|
|
||||||
*/
|
|
||||||
private String createBy;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新用户
|
|
||||||
*/
|
|
||||||
private String updateBy;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 语音请求参数实体类
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class VoiceRequest {
|
|
||||||
|
|
||||||
@JsonProperty("ENDPOINT")
|
|
||||||
private String endpoint;
|
|
||||||
private String appId;
|
|
||||||
private String accessToken;
|
|
||||||
private String resourceId;
|
|
||||||
private String voice;
|
|
||||||
private String text;
|
|
||||||
private String encoding;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain.bo;
|
|
||||||
|
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanConfig;
|
|
||||||
import org.ruoyi.common.core.validate.AddGroup;
|
|
||||||
import org.ruoyi.common.core.validate.EditGroup;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互数字人配置业务对象 aihuman_config
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 22:27:00 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
|
|
||||||
@AutoMapper(target = AihumanConfig.class, reverseConvertGenerate = false)
|
|
||||||
public class AihumanConfigBo implements Serializable {
|
|
||||||
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* name
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* modelName
|
|
||||||
*/
|
|
||||||
private String modelName;
|
|
||||||
/**
|
|
||||||
* modelPath
|
|
||||||
*/
|
|
||||||
private String modelPath;
|
|
||||||
/**
|
|
||||||
* modelParams
|
|
||||||
*/
|
|
||||||
private String modelParams;
|
|
||||||
/**
|
|
||||||
* agentParams
|
|
||||||
*/
|
|
||||||
private String agentParams;
|
|
||||||
/**
|
|
||||||
* createTime
|
|
||||||
*/
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
/**
|
|
||||||
* updateTime
|
|
||||||
*/
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
/**
|
|
||||||
* status
|
|
||||||
*/
|
|
||||||
@NotNull(message = "status不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* publish
|
|
||||||
*/
|
|
||||||
@NotNull(message = "publish不能为空", groups = {AddGroup.class, EditGroup.class})
|
|
||||||
private Integer publish;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain.bo;
|
|
||||||
|
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanInfo;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数字人信息管理业务对象 aihuman_info
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 20:03:06 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
|
|
||||||
@AutoMapper(target = AihumanInfo.class, reverseConvertGenerate = false)
|
|
||||||
public class AihumanInfoBo implements Serializable {
|
|
||||||
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 交互内容
|
|
||||||
*/
|
|
||||||
private String content;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
/**
|
|
||||||
* 删除标志(0代表存在 2代表删除)
|
|
||||||
*/
|
|
||||||
private String delFlag;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain.bo;
|
|
||||||
|
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanRealConfig;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真人交互数字人配置业务对象 aihuman_real_config
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Tue Oct 21 11:46:52 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
|
|
||||||
@AutoMapper(target = AihumanRealConfig.class, reverseConvertGenerate = false)
|
|
||||||
public class AihumanRealConfigBo implements Serializable {
|
|
||||||
|
|
||||||
private Integer id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 场景名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 真人形象名称
|
|
||||||
*/
|
|
||||||
private String avatars;
|
|
||||||
/**
|
|
||||||
* 模型名称
|
|
||||||
*/
|
|
||||||
private String models;
|
|
||||||
/**
|
|
||||||
* 形象参数(预留)
|
|
||||||
*/
|
|
||||||
private String avatarsParams;
|
|
||||||
/**
|
|
||||||
* 模型参数(预留)
|
|
||||||
*/
|
|
||||||
private String modelsParams;
|
|
||||||
/**
|
|
||||||
* 智能体参数(扣子)
|
|
||||||
*/
|
|
||||||
private String agentParams;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*/
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* 发布状态
|
|
||||||
*/
|
|
||||||
private Integer publish;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行参数
|
|
||||||
*/
|
|
||||||
private String runParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行状态
|
|
||||||
*/
|
|
||||||
private String runStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建部门
|
|
||||||
*/
|
|
||||||
private String createDept;
|
|
||||||
/**
|
|
||||||
* 创建用户
|
|
||||||
*/
|
|
||||||
private String createBy;
|
|
||||||
/**
|
|
||||||
* 更新用户
|
|
||||||
*/
|
|
||||||
private String updateBy;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain.vo;
|
|
||||||
|
|
||||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
|
||||||
import cn.idev.excel.annotation.ExcelProperty;
|
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanConfig;
|
|
||||||
import org.ruoyi.common.excel.annotation.ExcelDictFormat;
|
|
||||||
import org.ruoyi.common.excel.convert.ExcelDictConvert;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互数字人配置视图对象 aihuman_config
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 22:27:00 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@ExcelIgnoreUnannotated
|
|
||||||
@AutoMapper(target = AihumanConfig.class)
|
|
||||||
public class AihumanConfigVo implements Serializable {
|
|
||||||
|
|
||||||
private Integer id;
|
|
||||||
/**
|
|
||||||
* name
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "name")
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* modelName
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "modelName")
|
|
||||||
private String modelName;
|
|
||||||
/**
|
|
||||||
* modelPath
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "modelPath")
|
|
||||||
private String modelPath;
|
|
||||||
/**
|
|
||||||
* modelParams
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "modelParams")
|
|
||||||
private String modelParams;
|
|
||||||
/**
|
|
||||||
* agentParams
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "agentParams")
|
|
||||||
private String agentParams;
|
|
||||||
/**
|
|
||||||
* createTime
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "createTime")
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
/**
|
|
||||||
* updateTime
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "updateTime")
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
/**
|
|
||||||
* status
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "status", converter = ExcelDictConvert.class)
|
|
||||||
@ExcelDictFormat(dictType = "sys_common_status")
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* publish
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "publish", converter = ExcelDictConvert.class)
|
|
||||||
@ExcelDictFormat(dictType = "sys_common_status")
|
|
||||||
private Integer publish;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain.vo;
|
|
||||||
|
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanInfo;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI人类交互信息视图对象
|
|
||||||
*
|
|
||||||
* @author QingYunAI
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@AutoMapper(target = AihumanInfo.class)
|
|
||||||
public class AihumanInfoVo implements Serializable {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主键ID
|
|
||||||
*/
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互名称
|
|
||||||
*/
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互内容
|
|
||||||
*/
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
private Date updateTime;
|
|
||||||
}
|
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.domain.vo;
|
|
||||||
|
|
||||||
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
|
||||||
import cn.idev.excel.annotation.ExcelProperty;
|
|
||||||
import io.github.linpeilie.annotations.AutoMapper;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanRealConfig;
|
|
||||||
import org.ruoyi.common.excel.annotation.ExcelDictFormat;
|
|
||||||
import org.ruoyi.common.excel.convert.ExcelDictConvert;
|
|
||||||
|
|
||||||
import java.io.Serializable;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真人交互数字人配置视图对象 aihuman_real_config
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Tue Oct 21 11:46:52 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@ExcelIgnoreUnannotated
|
|
||||||
@AutoMapper(target = AihumanRealConfig.class)
|
|
||||||
public class AihumanRealConfigVo implements Serializable {
|
|
||||||
|
|
||||||
private Integer id;
|
|
||||||
/**
|
|
||||||
* 场景名称
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "场景名称")
|
|
||||||
private String name;
|
|
||||||
/**
|
|
||||||
* 真人形象名称
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "真人形象名称")
|
|
||||||
private String avatars;
|
|
||||||
/**
|
|
||||||
* 模型名称
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "模型名称")
|
|
||||||
private String models;
|
|
||||||
/**
|
|
||||||
* 形象参数(预留)
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "形象参数", converter = ExcelDictConvert.class)
|
|
||||||
@ExcelDictFormat(readConverterExp = "$column.readConverterExp()")
|
|
||||||
private String avatarsParams;
|
|
||||||
/**
|
|
||||||
* 模型参数(预留)
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "模型参数", converter = ExcelDictConvert.class)
|
|
||||||
@ExcelDictFormat(readConverterExp = "$column.readConverterExp()")
|
|
||||||
private String modelsParams;
|
|
||||||
/**
|
|
||||||
* 智能体参数(扣子)
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "智能体参数", converter = ExcelDictConvert.class)
|
|
||||||
@ExcelDictFormat(readConverterExp = "$column.readConverterExp()")
|
|
||||||
private String agentParams;
|
|
||||||
/**
|
|
||||||
* 创建时间
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "创建时间")
|
|
||||||
private LocalDateTime createTime;
|
|
||||||
/**
|
|
||||||
* 更新时间
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "更新时间")
|
|
||||||
private LocalDateTime updateTime;
|
|
||||||
/**
|
|
||||||
* 状态
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "状态")
|
|
||||||
private Integer status;
|
|
||||||
/**
|
|
||||||
* 发布状态
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "发布状态")
|
|
||||||
private Integer publish;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行参数
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "运行参数")
|
|
||||||
private String runParams;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 运行状态
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "运行状态")
|
|
||||||
private String runStatus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 创建部门
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "创建部门")
|
|
||||||
private String createDept;
|
|
||||||
/**
|
|
||||||
* 创建用户
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "创建用户")
|
|
||||||
private String createBy;
|
|
||||||
/**
|
|
||||||
* 更新用户
|
|
||||||
*/
|
|
||||||
@ExcelProperty(value = "更新用户")
|
|
||||||
private String updateBy;
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.mapper;
|
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanConfig;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
|
|
||||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互数字人配置Mapper接口
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 22:27:00 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface AihumanConfigMapper extends BaseMapperPlus<AihumanConfig, AihumanConfigVo> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.mapper;
|
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanInfo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanInfoVo;
|
|
||||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI人类交互信息Mapper接口
|
|
||||||
*
|
|
||||||
* @author QingYunAI
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface AihumanInfoMapper extends BaseMapperPlus<AihumanInfo, AihumanInfoVo> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.mapper;
|
|
||||||
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanRealConfig;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo;
|
|
||||||
import org.ruoyi.common.mybatis.core.mapper.BaseMapperPlus;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真人交互数字人配置Mapper接口
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Tue Oct 21 11:46:52 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface AihumanRealConfigMapper extends BaseMapperPlus<AihumanRealConfig, AihumanRealConfigVo> {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum CompressionBits {
|
|
||||||
None_((byte) 0),
|
|
||||||
Gzip((byte) 0b1),
|
|
||||||
Custom((byte) 0b11),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final byte value;
|
|
||||||
|
|
||||||
CompressionBits(byte b) {
|
|
||||||
this.value = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CompressionBits fromValue(int value) {
|
|
||||||
for (CompressionBits type : CompressionBits.values()) {
|
|
||||||
if (type.value == value) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown CompressionBits value: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,90 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum EventType {
|
|
||||||
// Default event
|
|
||||||
NONE(0),
|
|
||||||
|
|
||||||
// Upstream Connection events (1-49)
|
|
||||||
START_CONNECTION(1),
|
|
||||||
START_TASK(1),
|
|
||||||
FINISH_CONNECTION(2),
|
|
||||||
FINISH_TASK(2),
|
|
||||||
|
|
||||||
// Downstream Connection events (50-99)
|
|
||||||
CONNECTION_STARTED(50),
|
|
||||||
TASK_STARTED(50),
|
|
||||||
CONNECTION_FAILED(51),
|
|
||||||
TASK_FAILED(51),
|
|
||||||
CONNECTION_FINISHED(52),
|
|
||||||
TASK_FINISHED(52),
|
|
||||||
|
|
||||||
// Upstream Session events (100-149)
|
|
||||||
START_SESSION(100),
|
|
||||||
CANCEL_SESSION(101),
|
|
||||||
FINISH_SESSION(102),
|
|
||||||
|
|
||||||
// Downstream Session events (150-199)
|
|
||||||
SESSION_STARTED(150),
|
|
||||||
SESSION_CANCELED(151),
|
|
||||||
SESSION_FINISHED(152),
|
|
||||||
SESSION_FAILED(153),
|
|
||||||
USAGE_RESPONSE(154),
|
|
||||||
CHARGE_DATA(154),
|
|
||||||
|
|
||||||
// Upstream General events (200-249)
|
|
||||||
TASK_REQUEST(200),
|
|
||||||
UPDATE_CONFIG(201),
|
|
||||||
|
|
||||||
// Downstream General events (250-299)
|
|
||||||
AUDIO_MUTED(250),
|
|
||||||
|
|
||||||
// Upstream TTS events (300-349)
|
|
||||||
SAY_HELLO(300),
|
|
||||||
|
|
||||||
// Downstream TTS events (350-399)
|
|
||||||
TTS_SENTENCE_START(350),
|
|
||||||
TTS_SENTENCE_END(351),
|
|
||||||
TTS_RESPONSE(352),
|
|
||||||
TTS_ENDED(359),
|
|
||||||
PODCAST_ROUND_START(360),
|
|
||||||
PODCAST_ROUND_RESPONSE(361),
|
|
||||||
PODCAST_ROUND_END(362),
|
|
||||||
|
|
||||||
// Downstream ASR events (450-499)
|
|
||||||
ASR_INFO(450),
|
|
||||||
ASR_RESPONSE(451),
|
|
||||||
ASR_ENDED(459),
|
|
||||||
|
|
||||||
// Upstream Chat events (500-549)
|
|
||||||
CHAT_TTS_TEXT(500),
|
|
||||||
|
|
||||||
// Downstream Chat events (550-599)
|
|
||||||
CHAT_RESPONSE(550),
|
|
||||||
CHAT_ENDED(559),
|
|
||||||
|
|
||||||
// Subtitle events (650-699)
|
|
||||||
SOURCE_SUBTITLE_START(650),
|
|
||||||
SOURCE_SUBTITLE_RESPONSE(651),
|
|
||||||
SOURCE_SUBTITLE_END(652),
|
|
||||||
TRANSLATION_SUBTITLE_START(653),
|
|
||||||
TRANSLATION_SUBTITLE_RESPONSE(654),
|
|
||||||
TRANSLATION_SUBTITLE_END(655);
|
|
||||||
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
EventType(int value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EventType fromValue(int value) {
|
|
||||||
for (EventType type : EventType.values()) {
|
|
||||||
if (type.value == value) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown EventType value: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum HeaderSizeBits {
|
|
||||||
HeaderSize4((byte) 1),
|
|
||||||
HeaderSize8((byte) 2),
|
|
||||||
HeaderSize12((byte) 3),
|
|
||||||
HeaderSize16((byte) 4),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final byte value;
|
|
||||||
|
|
||||||
HeaderSizeBits(byte b) {
|
|
||||||
this.value = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static HeaderSizeBits fromValue(int value) {
|
|
||||||
for (HeaderSizeBits type : HeaderSizeBits.values()) {
|
|
||||||
if (type.value == value) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown HeaderSizeBits value: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Data;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Data
|
|
||||||
public class Message {
|
|
||||||
private byte version = VersionBits.Version1.getValue();
|
|
||||||
private byte headerSize = HeaderSizeBits.HeaderSize4.getValue();
|
|
||||||
private MsgType type;
|
|
||||||
private MsgTypeFlagBits flag;
|
|
||||||
private byte serialization = SerializationBits.JSON.getValue();
|
|
||||||
private byte compression = 0;
|
|
||||||
|
|
||||||
private EventType event;
|
|
||||||
private String sessionId;
|
|
||||||
private String connectId;
|
|
||||||
private int sequence;
|
|
||||||
private int errorCode;
|
|
||||||
|
|
||||||
private byte[] payload;
|
|
||||||
|
|
||||||
public Message(MsgType type, MsgTypeFlagBits flag) {
|
|
||||||
this.type = type;
|
|
||||||
this.flag = flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Message unmarshal(byte[] data) throws Exception {
|
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(data);
|
|
||||||
|
|
||||||
byte type_and_flag = data[1];
|
|
||||||
MsgType type = MsgType.fromValue((type_and_flag >> 4) & 0x0F);
|
|
||||||
MsgTypeFlagBits flag = MsgTypeFlagBits.fromValue(type_and_flag & 0x0F);
|
|
||||||
|
|
||||||
// Read version and header size
|
|
||||||
int versionAndHeaderSize = buffer.get();
|
|
||||||
VersionBits version = VersionBits.fromValue((versionAndHeaderSize >> 4) & 0x0F);
|
|
||||||
HeaderSizeBits headerSize = HeaderSizeBits.fromValue(versionAndHeaderSize & 0x0F);
|
|
||||||
|
|
||||||
// Skip second byte
|
|
||||||
buffer.get();
|
|
||||||
|
|
||||||
// Read serialization and compression method
|
|
||||||
int serializationCompression = buffer.get();
|
|
||||||
SerializationBits serialization = SerializationBits.fromValue((serializationCompression >> 4) & 0x0F);
|
|
||||||
CompressionBits compression = CompressionBits.fromValue(serializationCompression & 0x0F);
|
|
||||||
|
|
||||||
// Skip padding bytes
|
|
||||||
int headerSizeInt = 4 * (int) headerSize.getValue();
|
|
||||||
int paddingSize = headerSizeInt - 3;
|
|
||||||
while (paddingSize > 0) {
|
|
||||||
buffer.get();
|
|
||||||
paddingSize -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Message message = new Message(type, flag);
|
|
||||||
message.setVersion(version.getValue());
|
|
||||||
message.setHeaderSize(headerSize.getValue());
|
|
||||||
message.setSerialization(serialization.getValue());
|
|
||||||
message.setCompression(compression.getValue());
|
|
||||||
|
|
||||||
// Read sequence if present
|
|
||||||
if (flag == MsgTypeFlagBits.POSITIVE_SEQ || flag == MsgTypeFlagBits.NEGATIVE_SEQ) {
|
|
||||||
// Read 4 bytes from ByteBuffer and parse as int (big-endian)
|
|
||||||
byte[] sequeueBytes = new byte[4];
|
|
||||||
if (buffer.remaining() >= 4) {
|
|
||||||
buffer.get(sequeueBytes); // Read 4 bytes into array
|
|
||||||
ByteBuffer wrapper = ByteBuffer.wrap(sequeueBytes);
|
|
||||||
wrapper.order(ByteOrder.BIG_ENDIAN); // Set big-endian order
|
|
||||||
message.setSequence(wrapper.getInt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read event if present
|
|
||||||
if (flag == MsgTypeFlagBits.WITH_EVENT) {
|
|
||||||
// Read 4 bytes from ByteBuffer and parse as int (big-endian)
|
|
||||||
byte[] eventBytes = new byte[4];
|
|
||||||
if (buffer.remaining() >= 4) {
|
|
||||||
buffer.get(eventBytes); // Read 4 bytes into array
|
|
||||||
ByteBuffer wrapper = ByteBuffer.wrap(eventBytes);
|
|
||||||
wrapper.order(ByteOrder.BIG_ENDIAN); // Set big-endian order
|
|
||||||
message.setEvent(EventType.fromValue(wrapper.getInt()));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type != MsgType.ERROR && !(message.event == EventType.START_CONNECTION
|
|
||||||
|| message.event == EventType.FINISH_CONNECTION ||
|
|
||||||
message.event == EventType.CONNECTION_STARTED
|
|
||||||
|| message.event == EventType.CONNECTION_FAILED ||
|
|
||||||
message.event == EventType.CONNECTION_FINISHED)) {
|
|
||||||
// Read sessionId if present
|
|
||||||
int sessionIdLength = buffer.getInt();
|
|
||||||
if (sessionIdLength > 0) {
|
|
||||||
byte[] sessionIdBytes = new byte[sessionIdLength];
|
|
||||||
buffer.get(sessionIdBytes);
|
|
||||||
message.setSessionId(new String(sessionIdBytes, StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.event == EventType.CONNECTION_STARTED || message.event == EventType.CONNECTION_FAILED
|
|
||||||
|| message.event == EventType.CONNECTION_FINISHED) {
|
|
||||||
// Read connectId if present
|
|
||||||
int connectIdLength = buffer.getInt();
|
|
||||||
if (connectIdLength > 0) {
|
|
||||||
byte[] connectIdBytes = new byte[connectIdLength];
|
|
||||||
buffer.get(connectIdBytes);
|
|
||||||
message.setConnectId(new String(connectIdBytes, StandardCharsets.UTF_8));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read errorCode if present
|
|
||||||
if (type == MsgType.ERROR) {
|
|
||||||
// Read 4 bytes from ByteBuffer and parse as int (big-endian)
|
|
||||||
byte[] errorCodeBytes = new byte[4];
|
|
||||||
if (buffer.remaining() >= 4) {
|
|
||||||
buffer.get(errorCodeBytes); // Read 4 bytes into array
|
|
||||||
ByteBuffer wrapper = ByteBuffer.wrap(errorCodeBytes);
|
|
||||||
wrapper.order(ByteOrder.BIG_ENDIAN); // Set big-endian order
|
|
||||||
message.setErrorCode(wrapper.getInt());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read remaining bytes as payload
|
|
||||||
if (buffer.remaining() > 0) {
|
|
||||||
// 4 bytes length
|
|
||||||
int payloadLength = buffer.getInt();
|
|
||||||
if (payloadLength > 0) {
|
|
||||||
byte[] payloadBytes = new byte[payloadLength];
|
|
||||||
buffer.get(payloadBytes);
|
|
||||||
message.setPayload(payloadBytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] marshal() throws Exception {
|
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
// Write header
|
|
||||||
buffer.write((version & 0x0F) << 4 | (headerSize & 0x0F));
|
|
||||||
buffer.write((type.getValue() & 0x0F) << 4 | (flag.getValue() & 0x0F));
|
|
||||||
buffer.write((serialization & 0x0F) << 4 | (compression & 0x0F));
|
|
||||||
|
|
||||||
int headerSizeInt = 4 * (int) headerSize;
|
|
||||||
int padding = headerSizeInt - buffer.size();
|
|
||||||
while (padding > 0) {
|
|
||||||
buffer.write(0);
|
|
||||||
padding -= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write event if present
|
|
||||||
if (event != null) {
|
|
||||||
byte[] eventBytes = ByteBuffer.allocate(4).putInt(event.getValue()).array();
|
|
||||||
buffer.write(eventBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write sessionId if present
|
|
||||||
if (sessionId != null) {
|
|
||||||
byte[] sessionIdBytes = sessionId.getBytes(StandardCharsets.UTF_8);
|
|
||||||
buffer.write(ByteBuffer.allocate(4).putInt(sessionIdBytes.length).array());
|
|
||||||
buffer.write(sessionIdBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write connectId if present
|
|
||||||
if (connectId != null) {
|
|
||||||
byte[] connectIdBytes = connectId.getBytes(StandardCharsets.UTF_8);
|
|
||||||
buffer.write(ByteBuffer.allocate(4).putInt(connectIdBytes.length).array());
|
|
||||||
buffer.write(connectIdBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write sequence if present
|
|
||||||
if (sequence != 0) {
|
|
||||||
buffer.write(ByteBuffer.allocate(4).putInt(sequence).array());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write errorCode if present
|
|
||||||
if (errorCode != 0) {
|
|
||||||
buffer.write(ByteBuffer.allocate(4).putInt(errorCode).array());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write payload if present
|
|
||||||
if (payload != null && payload.length > 0) {
|
|
||||||
buffer.write(ByteBuffer.allocate(4).putInt(payload.length).array());
|
|
||||||
buffer.write(payload);
|
|
||||||
}
|
|
||||||
return buffer.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
switch (this.type) {
|
|
||||||
case AUDIO_ONLY_SERVER:
|
|
||||||
case AUDIO_ONLY_CLIENT:
|
|
||||||
if (this.flag == MsgTypeFlagBits.POSITIVE_SEQ || this.flag == MsgTypeFlagBits.NEGATIVE_SEQ) {
|
|
||||||
return String.format("MsgType: %s, EventType: %s, Sequence: %d, PayloadSize: %d", this.type, this.event, this.sequence,
|
|
||||||
this.payload != null ? this.payload.length : 0);
|
|
||||||
}
|
|
||||||
return String.format("MsgType: %s, EventType: %s, PayloadSize: %d", this.type, this.event,
|
|
||||||
this.payload != null ? this.payload.length : 0);
|
|
||||||
case ERROR:
|
|
||||||
return String.format("MsgType: %s, EventType: %s, ErrorCode: %d, Payload: %s", this.type, this.event, this.errorCode,
|
|
||||||
this.payload != null ? new String(this.payload) : "null");
|
|
||||||
default:
|
|
||||||
if (this.flag == MsgTypeFlagBits.POSITIVE_SEQ || this.flag == MsgTypeFlagBits.NEGATIVE_SEQ) {
|
|
||||||
return String.format("MsgType: %s, EventType: %s, Sequence: %d, Payload: %s",
|
|
||||||
this.type, this.event, this.sequence,
|
|
||||||
this.payload != null ? new String(this.payload) : "null");
|
|
||||||
}
|
|
||||||
return String.format("MsgType: %s, EventType: %s, Payload: %s", this.type, this.event,
|
|
||||||
this.payload != null ? new String(this.payload) : "null");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum MsgType {
|
|
||||||
INVALID((byte) 0),
|
|
||||||
FULL_CLIENT_REQUEST((byte) 0b1),
|
|
||||||
AUDIO_ONLY_CLIENT((byte) 0b10),
|
|
||||||
FULL_SERVER_RESPONSE((byte) 0b1001),
|
|
||||||
AUDIO_ONLY_SERVER((byte) 0b1011),
|
|
||||||
FRONT_END_RESULT_SERVER((byte) 0b1100),
|
|
||||||
ERROR((byte) 0b1111);
|
|
||||||
|
|
||||||
private final byte value;
|
|
||||||
|
|
||||||
MsgType(byte value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MsgType fromValue(int value) {
|
|
||||||
for (MsgType type : MsgType.values()) {
|
|
||||||
if (type.value == value) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown MsgType value: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum MsgTypeFlagBits {
|
|
||||||
NO_SEQ((byte) 0), // Non-terminating packet without sequence number
|
|
||||||
POSITIVE_SEQ((byte) 0b1), // Non-terminating packet with positive sequence number
|
|
||||||
LAST_NO_SEQ((byte) 0b10), // Terminating packet without sequence number
|
|
||||||
NEGATIVE_SEQ((byte) 0b11), // Terminating packet with negative sequence number
|
|
||||||
WITH_EVENT((byte) 0b100); // Packet containing event number
|
|
||||||
|
|
||||||
private final byte value;
|
|
||||||
|
|
||||||
MsgTypeFlagBits(byte value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MsgTypeFlagBits fromValue(int value) {
|
|
||||||
for (MsgTypeFlagBits flag : MsgTypeFlagBits.values()) {
|
|
||||||
if (flag.value == value) {
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown MsgTypeFlagBits value: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum SerializationBits {
|
|
||||||
Raw((byte) 0),
|
|
||||||
JSON((byte) 0b1),
|
|
||||||
Thrift((byte) 0b11),
|
|
||||||
Custom((byte) 0b1111),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final byte value;
|
|
||||||
|
|
||||||
SerializationBits(byte b) {
|
|
||||||
this.value = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static SerializationBits fromValue(int value) {
|
|
||||||
for (SerializationBits type : SerializationBits.values()) {
|
|
||||||
if (type.value == value) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown SerializationBits value: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.java_websocket.client.WebSocketClient;
|
|
||||||
import org.java_websocket.handshake.ServerHandshake;
|
|
||||||
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class SpeechWebSocketClient extends WebSocketClient {
|
|
||||||
private final BlockingQueue<Message> messageQueue = new LinkedBlockingQueue<>();
|
|
||||||
|
|
||||||
public SpeechWebSocketClient(URI serverUri, Map<String, String> headers) {
|
|
||||||
super(serverUri, headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onOpen(ServerHandshake handshakedata) {
|
|
||||||
log.info("WebSocket connection established, Logid: {}", handshakedata.getFieldValue("x-tt-logid"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(String message) {
|
|
||||||
log.warn("Received unexpected text message: {}", message);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onMessage(ByteBuffer bytes) {
|
|
||||||
try {
|
|
||||||
Message message = Message.unmarshal(bytes.array());
|
|
||||||
messageQueue.put(message);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Failed to parse message", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClose(int code, String reason, boolean remote) {
|
|
||||||
log.info("WebSocket connection closed: code={}, reason={}, remote={}", code, reason, remote);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(Exception ex) {
|
|
||||||
log.error("WebSocket error", ex);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendStartConnection() throws Exception {
|
|
||||||
Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT);
|
|
||||||
message.setEvent(EventType.START_CONNECTION);
|
|
||||||
message.setPayload("{}".getBytes());
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendFinishConnection() throws Exception {
|
|
||||||
Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT);
|
|
||||||
message.setEvent(EventType.FINISH_CONNECTION);
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendStartSession(byte[] payload, String sessionId) throws Exception {
|
|
||||||
Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT);
|
|
||||||
message.setEvent(EventType.START_SESSION);
|
|
||||||
message.setSessionId(sessionId);
|
|
||||||
message.setPayload(payload);
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendFinishSession(String sessionId) throws Exception {
|
|
||||||
Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT);
|
|
||||||
message.setEvent(EventType.FINISH_SESSION);
|
|
||||||
message.setSessionId(sessionId);
|
|
||||||
message.setPayload("{}".getBytes());
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendTaskRequest(byte[] payload, String sessionId) throws Exception {
|
|
||||||
Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.WITH_EVENT);
|
|
||||||
message.setEvent(EventType.TASK_REQUEST);
|
|
||||||
message.setSessionId(sessionId);
|
|
||||||
message.setPayload(payload);
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendFullClientMessage(byte[] payload) throws Exception {
|
|
||||||
Message message = new Message(MsgType.FULL_CLIENT_REQUEST, MsgTypeFlagBits.NO_SEQ);
|
|
||||||
message.setPayload(payload);
|
|
||||||
sendMessage(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sendMessage(Message message) throws Exception {
|
|
||||||
log.info("Send: {}", message);
|
|
||||||
send(message.marshal());
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message receiveMessage() throws InterruptedException {
|
|
||||||
Message message = messageQueue.take();
|
|
||||||
log.info("Receive: {}", message);
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Message waitForMessage(MsgType type, EventType event) throws InterruptedException {
|
|
||||||
while (true) {
|
|
||||||
Message message = receiveMessage();
|
|
||||||
if (message.getType() == type && message.getEvent() == event) {
|
|
||||||
return message;
|
|
||||||
} else {
|
|
||||||
throw new RuntimeException("Unexpected message: " + message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.protocol;
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum VersionBits {
|
|
||||||
Version1((byte) 1),
|
|
||||||
Version2((byte) 2),
|
|
||||||
Version3((byte) 3),
|
|
||||||
Version4((byte) 4),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final byte value;
|
|
||||||
|
|
||||||
VersionBits(byte b) {
|
|
||||||
this.value = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static VersionBits fromValue(int value) {
|
|
||||||
for (VersionBits type : VersionBits.values()) {
|
|
||||||
if (type.value == value) {
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw new IllegalArgumentException("Unknown VersionBits value: " + value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.service;
|
|
||||||
|
|
||||||
import org.ruoyi.aihuman.domain.bo.AihumanConfigBo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互数字人配置Service接口
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 22:27:00 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
public interface AihumanConfigService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询交互数字人配置
|
|
||||||
*/
|
|
||||||
AihumanConfigVo queryById(Integer id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询交互数字人配置列表
|
|
||||||
*/
|
|
||||||
TableDataInfo<AihumanConfigVo> queryPageList(AihumanConfigBo bo, PageQuery pageQuery);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询交互数字人配置列表
|
|
||||||
*/
|
|
||||||
List<AihumanConfigVo> queryList(AihumanConfigBo bo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增交互数字人配置
|
|
||||||
*/
|
|
||||||
Boolean insertByBo(AihumanConfigBo bo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改交互数字人配置
|
|
||||||
*/
|
|
||||||
Boolean updateByBo(AihumanConfigBo bo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验并批量删除交互数字人配置信息
|
|
||||||
*/
|
|
||||||
Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid);
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.service;
|
|
||||||
|
|
||||||
import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 真人交互数字人配置Service接口
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Tue Oct 21 11:46:52 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
public interface AihumanRealConfigService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询真人交互数字人配置
|
|
||||||
*/
|
|
||||||
AihumanRealConfigVo queryById(Integer id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询真人交互数字人配置列表
|
|
||||||
*/
|
|
||||||
TableDataInfo<AihumanRealConfigVo> queryPageList(AihumanRealConfigBo bo, PageQuery pageQuery);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询真人交互数字人配置列表
|
|
||||||
*/
|
|
||||||
List<AihumanRealConfigVo> queryList(AihumanRealConfigBo bo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增真人交互数字人配置
|
|
||||||
*/
|
|
||||||
Boolean insertByBo(AihumanRealConfigBo bo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改真人交互数字人配置
|
|
||||||
*/
|
|
||||||
Boolean updateByBo(AihumanRealConfigBo bo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行真人交互数字人配置
|
|
||||||
*/
|
|
||||||
Boolean runByBo(AihumanRealConfigBo bo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 校验并批量删除真人交互数字人配置信息
|
|
||||||
*/
|
|
||||||
Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid);
|
|
||||||
|
|
||||||
// 在AihumanRealConfigService接口中添加
|
|
||||||
Boolean stopByBo(AihumanRealConfigBo bo);
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.service;
|
|
||||||
|
|
||||||
public interface AihumanVolcengineService {
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.service;
|
|
||||||
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanInfo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanInfoVo;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI人类交互信息Service接口
|
|
||||||
*
|
|
||||||
* @author QingYunAI
|
|
||||||
*/
|
|
||||||
public interface IAihumanInfoService {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询AI人类交互信息
|
|
||||||
*/
|
|
||||||
AihumanInfoVo queryById(Long id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询AI人类交互信息列表
|
|
||||||
*/
|
|
||||||
TableDataInfo<AihumanInfoVo> queryPageList(AihumanInfo record, PageQuery pageQuery);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询AI人类交互信息列表
|
|
||||||
*/
|
|
||||||
List<AihumanInfoVo> queryList(AihumanInfo record);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增AI人类交互信息
|
|
||||||
*/
|
|
||||||
int insert(AihumanInfo record);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改AI人类交互信息
|
|
||||||
*/
|
|
||||||
int update(AihumanInfo record);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除AI人类交互信息
|
|
||||||
*/
|
|
||||||
int deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
|
||||||
}
|
|
||||||
@@ -1,115 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.service.impl;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanConfig;
|
|
||||||
import org.ruoyi.aihuman.domain.bo.AihumanConfigBo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
|
|
||||||
import org.ruoyi.aihuman.mapper.AihumanConfigMapper;
|
|
||||||
import org.ruoyi.aihuman.service.AihumanConfigService;
|
|
||||||
import org.ruoyi.common.core.utils.MapstructUtils;
|
|
||||||
import org.ruoyi.common.core.utils.StringUtils;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 交互数字人配置Service业务层处理
|
|
||||||
*
|
|
||||||
* @author ageerle
|
|
||||||
* @date Fri Sep 26 22:27:00 GMT+08:00 2025
|
|
||||||
*/
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Service
|
|
||||||
public class AihumanConfigServiceImpl implements AihumanConfigService {
|
|
||||||
|
|
||||||
private final AihumanConfigMapper baseMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询交互数字人配置
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AihumanConfigVo queryById(Integer id) {
|
|
||||||
return baseMapper.selectVoById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询交互数字人配置列表
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public TableDataInfo<AihumanConfigVo> queryPageList(AihumanConfigBo bo, PageQuery pageQuery) {
|
|
||||||
LambdaQueryWrapper<AihumanConfig> lqw = buildQueryWrapper(bo);
|
|
||||||
Page<AihumanConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
||||||
return TableDataInfo.build(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询交互数字人配置列表
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<AihumanConfigVo> queryList(AihumanConfigBo bo) {
|
|
||||||
LambdaQueryWrapper<AihumanConfig> lqw = buildQueryWrapper(bo);
|
|
||||||
return baseMapper.selectVoList(lqw);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LambdaQueryWrapper<AihumanConfig> buildQueryWrapper(AihumanConfigBo bo) {
|
|
||||||
LambdaQueryWrapper<AihumanConfig> lqw = Wrappers.lambdaQuery();
|
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getName()), AihumanConfig::getName, bo.getName());
|
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getModelName()), AihumanConfig::getModelName, bo.getModelName());
|
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getModelPath()), AihumanConfig::getModelPath, bo.getModelPath());
|
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getModelParams()), AihumanConfig::getModelParams, bo.getModelParams());
|
|
||||||
lqw.eq(StringUtils.isNotBlank(bo.getAgentParams()), AihumanConfig::getAgentParams, bo.getAgentParams());
|
|
||||||
lqw.eq(bo.getCreateTime() != null, AihumanConfig::getCreateTime, bo.getCreateTime());
|
|
||||||
lqw.eq(bo.getUpdateTime() != null, AihumanConfig::getUpdateTime, bo.getUpdateTime());
|
|
||||||
lqw.eq(bo.getStatus() != null, AihumanConfig::getStatus, bo.getStatus());
|
|
||||||
lqw.eq(bo.getPublish() != null, AihumanConfig::getPublish, bo.getPublish());
|
|
||||||
return lqw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增交互数字人配置
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Boolean insertByBo(AihumanConfigBo bo) {
|
|
||||||
AihumanConfig add = MapstructUtils.convert(bo, AihumanConfig.class);
|
|
||||||
validEntityBeforeSave(add);
|
|
||||||
boolean flag = baseMapper.insert(add) > 0;
|
|
||||||
if (flag) {
|
|
||||||
bo.setId(add.getId());
|
|
||||||
}
|
|
||||||
return flag;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改交互数字人配置
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Boolean updateByBo(AihumanConfigBo bo) {
|
|
||||||
AihumanConfig update = MapstructUtils.convert(bo, AihumanConfig.class);
|
|
||||||
validEntityBeforeSave(update);
|
|
||||||
return baseMapper.updateById(update) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 保存前的数据校验
|
|
||||||
*/
|
|
||||||
private void validEntityBeforeSave(AihumanConfig entity) {
|
|
||||||
//TODO 做一些数据校验,如唯一约束
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除交互数字人配置
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Boolean deleteWithValidByIds(Collection<Integer> ids, Boolean isValid) {
|
|
||||||
if (isValid) {
|
|
||||||
//TODO 做一些业务上的校验,判断是否需要校验
|
|
||||||
}
|
|
||||||
return baseMapper.deleteBatchIds(ids) > 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.service.impl;
|
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import org.ruoyi.aihuman.domain.AihumanInfo;
|
|
||||||
import org.ruoyi.aihuman.domain.vo.AihumanInfoVo;
|
|
||||||
import org.ruoyi.aihuman.mapper.AihumanInfoMapper;
|
|
||||||
import org.ruoyi.aihuman.service.IAihumanInfoService;
|
|
||||||
import org.ruoyi.common.core.utils.StringUtils;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.PageQuery;
|
|
||||||
import org.ruoyi.common.mybatis.core.page.TableDataInfo;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* AI人类交互信息Service业务层处理
|
|
||||||
*
|
|
||||||
* @author QingYunAI
|
|
||||||
*/
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
@Service
|
|
||||||
public class AihumanInfoServiceImpl implements IAihumanInfoService {
|
|
||||||
|
|
||||||
private final AihumanInfoMapper baseMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询AI人类交互信息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AihumanInfoVo queryById(Long id) {
|
|
||||||
return baseMapper.selectVoById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询AI人类交互信息列表
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public TableDataInfo<AihumanInfoVo> queryPageList(AihumanInfo record, PageQuery pageQuery) {
|
|
||||||
LambdaQueryWrapper<AihumanInfo> lqw = buildQueryWrapper(record);
|
|
||||||
Page<AihumanInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
|
|
||||||
return TableDataInfo.build(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询AI人类交互信息列表
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<AihumanInfoVo> queryList(AihumanInfo record) {
|
|
||||||
LambdaQueryWrapper<AihumanInfo> lqw = buildQueryWrapper(record);
|
|
||||||
return baseMapper.selectVoList(lqw);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建查询条件
|
|
||||||
*/
|
|
||||||
private LambdaQueryWrapper<AihumanInfo> buildQueryWrapper(AihumanInfo record) {
|
|
||||||
LambdaQueryWrapper<AihumanInfo> lqw = Wrappers.lambdaQuery();
|
|
||||||
lqw.eq(record.getId() != null, AihumanInfo::getId, record.getId());
|
|
||||||
lqw.like(StringUtils.isNotBlank(record.getName()), AihumanInfo::getName, record.getName());
|
|
||||||
lqw.like(StringUtils.isNotBlank(record.getContent()), AihumanInfo::getContent, record.getContent());
|
|
||||||
lqw.orderByDesc(AihumanInfo::getCreateTime);
|
|
||||||
return lqw;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 新增AI人类交互信息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int insert(AihumanInfo record) {
|
|
||||||
return baseMapper.insert(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改AI人类交互信息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int update(AihumanInfo record) {
|
|
||||||
return baseMapper.updateById(record);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量删除AI人类交互信息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public int deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
||||||
if (isValid) {
|
|
||||||
// 如果需要逻辑删除,MyBatis-Plus会自动处理
|
|
||||||
// 这里的@TableLogic注解已经在实体类中配置
|
|
||||||
}
|
|
||||||
return baseMapper.deleteBatchIds(ids);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.service.impl;
|
|
||||||
|
|
||||||
public class AihumanVolcengineServiceImpl {
|
|
||||||
}
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
package org.ruoyi.aihuman.volcengine;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.ruoyi.aihuman.protocol.EventType;
|
|
||||||
import org.ruoyi.aihuman.protocol.Message;
|
|
||||||
import org.ruoyi.aihuman.protocol.MsgType;
|
|
||||||
import org.ruoyi.aihuman.protocol.SpeechWebSocketClient;
|
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.net.URI;
|
|
||||||
import java.nio.file.Files;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
public class Bidirection {
|
|
||||||
private static final String ENDPOINT = "wss://openspeech.bytedance.com/api/v3/tts/bidirection";
|
|
||||||
private static final ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get resource ID based on voice type
|
|
||||||
*
|
|
||||||
* @param voice Voice type string
|
|
||||||
* @return Corresponding resource ID
|
|
||||||
*/
|
|
||||||
public static String voiceToResourceId(String voice) {
|
|
||||||
// Map different voice types to resource IDs based on actual needs
|
|
||||||
if (voice.startsWith("S_")) {
|
|
||||||
return "volc.megatts.default";
|
|
||||||
}
|
|
||||||
return "volc.service_type.10029";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
|
||||||
// Configure parameters
|
|
||||||
String appId = System.getProperty("appId", "1055299334");
|
|
||||||
String accessToken = System.getProperty("accessToken", "fOHuq4R4dirMYiOruCU3Ek9q75zV0KVW");
|
|
||||||
String resourceId = System.getProperty("resourceId", "seed-tts-2.0");
|
|
||||||
String voice = System.getProperty("voice", "zh_female_vv_uranus_bigtts");
|
|
||||||
String text = System.getProperty("text", "你好呀!我是AI合成的语音,很高兴认识你。");
|
|
||||||
String encoding = System.getProperty("encoding", "mp3");
|
|
||||||
|
|
||||||
if (appId.isEmpty() || accessToken.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("Please set appId and accessToken system properties");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set request headers
|
|
||||||
Map<String, String> headers = Map.of(
|
|
||||||
"X-Api-App-Key", appId,
|
|
||||||
"X-Api-Access-Key", accessToken,
|
|
||||||
"X-Api-Resource-Id", resourceId.isEmpty() ? voiceToResourceId(voice) : resourceId,
|
|
||||||
"X-Api-Connect-Id", UUID.randomUUID().toString());
|
|
||||||
|
|
||||||
// Create WebSocket client
|
|
||||||
SpeechWebSocketClient client = new SpeechWebSocketClient(new URI(ENDPOINT), headers);
|
|
||||||
try {
|
|
||||||
client.connectBlocking();
|
|
||||||
Map<String, Object> request = Map.of(
|
|
||||||
"user", Map.of("uid", UUID.randomUUID().toString()),
|
|
||||||
"namespace", "BidirectionalTTS",
|
|
||||||
"req_params", Map.of(
|
|
||||||
"speaker", voice,
|
|
||||||
"audio_params", Map.of(
|
|
||||||
"format", encoding,
|
|
||||||
"sample_rate", 24000,
|
|
||||||
"enable_timestamp", true),
|
|
||||||
// additions requires a JSON string
|
|
||||||
"additions", objectMapper.writeValueAsString(Map.of(
|
|
||||||
"disable_markdown_filter", false))));
|
|
||||||
|
|
||||||
// Start connection
|
|
||||||
client.sendStartConnection();
|
|
||||||
// Wait for connection started
|
|
||||||
client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.CONNECTION_STARTED);
|
|
||||||
|
|
||||||
// Process each sentence
|
|
||||||
String[] sentences = text.split("。");
|
|
||||||
boolean audioReceived = false;
|
|
||||||
for (int i = 0; i < sentences.length; i++) {
|
|
||||||
if (sentences[i].trim().isEmpty()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
String sessionId = UUID.randomUUID().toString();
|
|
||||||
ByteArrayOutputStream audioStream = new ByteArrayOutputStream();
|
|
||||||
|
|
||||||
// Start session
|
|
||||||
Map<String, Object> startReq = Map.of(
|
|
||||||
"user", request.get("user"),
|
|
||||||
"namespace", request.get("namespace"),
|
|
||||||
"req_params", request.get("req_params"),
|
|
||||||
"event", EventType.START_SESSION.getValue());
|
|
||||||
client.sendStartSession(objectMapper.writeValueAsBytes(startReq), sessionId);
|
|
||||||
// Wait for session started
|
|
||||||
client.waitForMessage(MsgType.FULL_SERVER_RESPONSE, EventType.SESSION_STARTED);
|
|
||||||
|
|
||||||
// Send text
|
|
||||||
for (char c : sentences[i].toCharArray()) {
|
|
||||||
// Create new req_params with text
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
Map<String, Object> currentReqParams = new HashMap<>(
|
|
||||||
(Map<String, Object>) request.get("req_params"));
|
|
||||||
currentReqParams.put("text", String.valueOf(c));
|
|
||||||
|
|
||||||
// Create current request
|
|
||||||
Map<String, Object> currentRequest = Map.of(
|
|
||||||
"user", request.get("user"),
|
|
||||||
"namespace", request.get("namespace"),
|
|
||||||
"req_params", currentReqParams,
|
|
||||||
"event", EventType.TASK_REQUEST.getValue());
|
|
||||||
|
|
||||||
client.sendTaskRequest(objectMapper.writeValueAsBytes(currentRequest), sessionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
// End session
|
|
||||||
client.sendFinishSession(sessionId);
|
|
||||||
|
|
||||||
// Receive response
|
|
||||||
while (true) {
|
|
||||||
Message msg = client.receiveMessage();
|
|
||||||
switch (msg.getType()) {
|
|
||||||
case FULL_SERVER_RESPONSE:
|
|
||||||
break;
|
|
||||||
case AUDIO_ONLY_SERVER:
|
|
||||||
if (!audioReceived && audioStream.size() > 0) {
|
|
||||||
audioReceived = true;
|
|
||||||
}
|
|
||||||
if (msg.getPayload() != null) {
|
|
||||||
audioStream.write(msg.getPayload());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new RuntimeException("Unexpected message: " + msg);
|
|
||||||
}
|
|
||||||
if (msg.getEvent() == EventType.SESSION_FINISHED) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (audioStream.size() > 0) {
|
|
||||||
String fileName = String.format("%s_session_%d.%s", voice, i, encoding);
|
|
||||||
Files.write(new File(fileName).toPath(), audioStream.toByteArray());
|
|
||||||
log.info("Audio saved to file: {}", fileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!audioReceived) {
|
|
||||||
throw new RuntimeException("No audio data received");
|
|
||||||
}
|
|
||||||
|
|
||||||
// End connection
|
|
||||||
client.sendFinishConnection();
|
|
||||||
} finally {
|
|
||||||
client.closeBlocking();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE mapper
|
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="org.ruoyi.aihuman.mapper.AihumanInfoMapper">
|
|
||||||
|
|
||||||
<!-- 可在此添加自定义SQL语句 -->
|
|
||||||
|
|
||||||
</mapper>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE mapper
|
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="org.ruoyi.aihuman.mapper.AihumanConfigMapper">
|
|
||||||
|
|
||||||
</mapper>
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
|
||||||
<!DOCTYPE mapper
|
|
||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
|
||||||
<mapper namespace="org.ruoyi.aihuman.mapper.AihumanRealConfigMapper">
|
|
||||||
|
|
||||||
</mapper>
|
|
||||||
Reference in New Issue
Block a user