Merge branch 'main' into main

This commit is contained in:
ageerle
2025-12-12 11:46:19 +08:00
committed by GitHub
535 changed files with 21172 additions and 14160 deletions

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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>
@@ -56,17 +56,17 @@
<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>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>

View File

@@ -1,27 +1,28 @@
package org.ruoyi.aihuman.controller;
import java.util.List;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.core.page.PageQuery;
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.log.enums.BusinessType;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
import org.ruoyi.aihuman.domain.bo.AihumanConfigBo;
import org.ruoyi.aihuman.service.AihumanConfigService;
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.web.core.BaseController;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 交互数字人配置
@@ -41,11 +42,11 @@ public class AihumanConfigController extends BaseController {
private final AihumanConfigService aihumanConfigService;
/**
* 查询交互数字人配置列表
*/
@SaCheckPermission("aihuman:aihumanConfig:list")
@GetMapping("/list")
/**
* 查询交互数字人配置列表
*/
@SaCheckPermission("aihuman:aihumanConfig:list")
@GetMapping("/list")
public TableDataInfo<AihumanConfigVo> list(AihumanConfigBo bo, PageQuery pageQuery) {
return aihumanConfigService.queryPageList(bo, pageQuery);
}
@@ -69,7 +70,7 @@ public class AihumanConfigController extends BaseController {
@SaCheckPermission("aihuman:aihumanConfig:query")
@GetMapping("/{id}")
public R<AihumanConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Integer id) {
@PathVariable Integer id) {
return R.ok(aihumanConfigService.queryById(id));
}

View File

@@ -2,14 +2,14 @@ package org.ruoyi.aihuman.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
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.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;

View File

@@ -1,28 +1,28 @@
package org.ruoyi.aihuman.controller;
import java.util.List;
import cn.dev33.satoken.annotation.SaIgnore;
import lombok.RequiredArgsConstructor;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.*;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.ruoyi.common.log.enums.OperatorType;
import org.springframework.web.bind.annotation.*;
import org.springframework.validation.annotation.Validated;
import org.ruoyi.common.idempotent.annotation.RepeatSubmit;
import org.ruoyi.common.log.annotation.Log;
import org.ruoyi.common.web.core.BaseController;
import org.ruoyi.core.page.PageQuery;
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.log.enums.BusinessType;
import org.ruoyi.common.excel.utils.ExcelUtil;
import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo;
import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo;
import org.ruoyi.aihuman.service.AihumanRealConfigService;
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.web.core.BaseController;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 真人交互数字人配置
@@ -41,11 +41,11 @@ public class AihumanRealConfigController extends BaseController {
private final AihumanRealConfigService aihumanRealConfigService;
/**
* 查询真人交互数字人配置列表
*/
@SaCheckPermission("aihuman:aihumanRealConfig:list")
@GetMapping("/list")
/**
* 查询真人交互数字人配置列表
*/
@SaCheckPermission("aihuman:aihumanRealConfig:list")
@GetMapping("/list")
public TableDataInfo<AihumanRealConfigVo> list(AihumanRealConfigBo bo, PageQuery pageQuery) {
return aihumanRealConfigService.queryPageList(bo, pageQuery);
}
@@ -69,7 +69,7 @@ public class AihumanRealConfigController extends BaseController {
@SaCheckPermission("aihuman:aihumanRealConfig:query")
@GetMapping("/{id}")
public R<AihumanRealConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Integer id) {
@PathVariable Integer id) {
return R.ok(aihumanRealConfigService.queryById(id));
}
@@ -113,45 +113,45 @@ public class AihumanRealConfigController extends BaseController {
* 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: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("停止真人交互数字人任务失败或没有正在运行的任务");
}
}
/**
* 停止真人交互数字人配置任务
*/
@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("停止真人交互数字人任务失败或没有正在运行的任务");
}
}
}

View File

@@ -1,43 +1,39 @@
package org.ruoyi.aihuman.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.core.io.ResourceLoader;
import org.springframework.beans.factory.annotation.Autowired;
import lombok.extern.slf4j.Slf4j;
import org.ruoyi.aihuman.domain.VoiceRequest;
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 com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import java.util.HashMap;
import java.util.UUID;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.concurrent.TimeUnit;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 火山引擎相关接口
@@ -54,12 +50,10 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@RequestMapping("/aihuman/volcengine")
public class AihumanVolcengineController {
@Autowired
private ResourceLoader resourceLoader;
private static final ObjectMapper objectMapper = new ObjectMapper();
private static final Logger logger = LoggerFactory.getLogger(AihumanVolcengineController.class);
@Autowired
private ResourceLoader resourceLoader;
@PostMapping("/generate-voice-direct")
public ResponseEntity<byte[]> generateVoiceDirect(@RequestBody VoiceRequest request) {
@@ -304,7 +298,7 @@ public class AihumanVolcengineController {
* 调用火山引擎TTS API生成音频文件
*/
private String callVolcengineTtsApi(String endpoint, String appId, String accessToken,
String resourceId, String voice, String text, String encoding) {
String resourceId, String voice, String text, String encoding) {
try {
// 确保resourceId不为空如果为空则根据voice类型获取默认值
if (resourceId == null || resourceId.isEmpty()) {

View File

@@ -1,9 +1,12 @@
package org.ruoyi.aihuman.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 交互数字人配置对象 aihuman_config
@@ -19,7 +22,7 @@ public class AihumanConfig implements Serializable {
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**

View File

@@ -2,6 +2,7 @@ package org.ruoyi.aihuman.domain;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@@ -15,25 +16,37 @@ import java.util.Date;
public class AihumanInfo implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键ID */
/**
* 主键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代表删除 */
/**
* 删除标志0代表存在 2代表删除
*/
@TableLogic
private String delFlag;
}

View File

@@ -1,9 +1,12 @@
package org.ruoyi.aihuman.domain;
import com.baomidou.mybatisplus.annotation.*;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 真人交互数字人配置对象 aihuman_real_config

View File

@@ -1,4 +1,5 @@
package org.ruoyi.aihuman.domain;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

View File

@@ -1,19 +1,14 @@
package org.ruoyi.aihuman.domain.bo;
import org.ruoyi.aihuman.domain.AihumanConfig;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
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;
import java.io.Serializable;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import java.io.Serializable;
import java.io.Serializable;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
/**
* 交互数字人配置业务对象 aihuman_config
@@ -59,12 +54,12 @@ public class AihumanConfigBo implements Serializable {
/**
* status
*/
@NotNull(message = "status不能为空", groups = { AddGroup.class, EditGroup.class })
@NotNull(message = "status不能为空", groups = {AddGroup.class, EditGroup.class})
private Integer status;
/**
* publish
*/
@NotNull(message = "publish不能为空", groups = { AddGroup.class, EditGroup.class })
@NotNull(message = "publish不能为空", groups = {AddGroup.class, EditGroup.class})
private Integer publish;
}

View File

@@ -1,19 +1,11 @@
package org.ruoyi.aihuman.domain.bo;
import org.ruoyi.aihuman.domain.AihumanInfo;
import org.ruoyi.core.domain.BaseEntity;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.*;
import org.ruoyi.aihuman.domain.AihumanInfo;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.io.Serializable;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
import java.io.Serializable;
import java.io.Serializable;
import org.ruoyi.common.core.validate.AddGroup;
import org.ruoyi.common.core.validate.EditGroup;
/**
* 数字人信息管理业务对象 aihuman_info

View File

@@ -1,11 +1,11 @@
package org.ruoyi.aihuman.domain.bo;
import org.ruoyi.aihuman.domain.AihumanRealConfig;
import io.github.linpeilie.annotations.AutoMapper;
import lombok.Data;
import org.ruoyi.aihuman.domain.AihumanRealConfig;
import java.time.LocalDateTime;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 真人交互数字人配置业务对象 aihuman_real_config
@@ -66,9 +66,9 @@ public class AihumanRealConfigBo implements Serializable {
*/
private String runParams;
/**
* 运行状态
*/
/**
* 运行状态
*/
private String runStatus;
/**

View File

@@ -1,16 +1,15 @@
package org.ruoyi.aihuman.domain.vo;
import java.time.LocalDateTime;
import java.io.Serializable;
import org.ruoyi.aihuman.domain.AihumanConfig;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.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.util.Date;
import java.io.Serializable;
import java.time.LocalDateTime;
/**

View File

@@ -3,6 +3,7 @@ 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;
@@ -16,18 +17,28 @@ import java.util.Date;
public class AihumanInfoVo implements Serializable {
private static final long serialVersionUID = 1L;
/** 主键ID */
/**
* 主键ID
*/
private Long id;
/** 交互名称 */
/**
* 交互名称
*/
private String name;
/** 交互内容 */
/**
* 交互内容
*/
private String content;
/** 创建时间 */
/**
* 创建时间
*/
private Date createTime;
/** 更新时间 */
/**
* 更新时间
*/
private Date updateTime;
}

View File

@@ -1,15 +1,16 @@
package org.ruoyi.aihuman.domain.vo;
import java.time.LocalDateTime;
import java.io.Serializable;
import org.ruoyi.aihuman.domain.AihumanRealConfig;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.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

View File

@@ -1,9 +1,9 @@
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.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Mapper;
/**
* 交互数字人配置Mapper接口

View File

@@ -1,9 +1,9 @@
package org.ruoyi.aihuman.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.ruoyi.core.mapper.BaseMapperPlus;
import org.ruoyi.aihuman.domain.AihumanInfo;
import org.ruoyi.aihuman.domain.vo.AihumanInfoVo;
import org.ruoyi.core.mapper.BaseMapperPlus;
/**
* AI人类交互信息Mapper接口

View File

@@ -1,9 +1,9 @@
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.core.mapper.BaseMapperPlus;
import org.apache.ibatis.annotations.Mapper;
/**
* 真人交互数字人配置Mapper接口

View File

@@ -1,9 +1,9 @@
package org.ruoyi.aihuman.service;
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
import org.ruoyi.aihuman.domain.bo.AihumanConfigBo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
@@ -19,12 +19,12 @@ public interface AihumanConfigService {
/**
* 查询交互数字人配置
*/
AihumanConfigVo queryById(Integer id);
AihumanConfigVo queryById(Integer id);
/**
* 查询交互数字人配置列表
*/
TableDataInfo<AihumanConfigVo> queryPageList(AihumanConfigBo bo, PageQuery pageQuery);
/**
* 查询交互数字人配置列表
*/
TableDataInfo<AihumanConfigVo> queryPageList(AihumanConfigBo bo, PageQuery pageQuery);
/**
* 查询交互数字人配置列表

View File

@@ -1,9 +1,9 @@
package org.ruoyi.aihuman.service;
import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo;
import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;
@@ -19,12 +19,12 @@ public interface AihumanRealConfigService {
/**
* 查询真人交互数字人配置
*/
AihumanRealConfigVo queryById(Integer id);
AihumanRealConfigVo queryById(Integer id);
/**
* 查询真人交互数字人配置列表
*/
TableDataInfo<AihumanRealConfigVo> queryPageList(AihumanRealConfigBo bo, PageQuery pageQuery);
/**
* 查询真人交互数字人配置列表
*/
TableDataInfo<AihumanRealConfigVo> queryPageList(AihumanRealConfigBo bo, PageQuery pageQuery);
/**
* 查询真人交互数字人配置列表

View File

@@ -2,8 +2,8 @@ package org.ruoyi.aihuman.service;
import org.ruoyi.aihuman.domain.AihumanInfo;
import org.ruoyi.aihuman.domain.vo.AihumanInfoVo;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import java.util.Collection;
import java.util.List;

View File

@@ -1,23 +1,22 @@
package org.ruoyi.aihuman.service.impl;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.springframework.stereotype.Service;
import org.ruoyi.aihuman.domain.AihumanConfig;
import org.ruoyi.aihuman.domain.bo.AihumanConfigBo;
import org.ruoyi.aihuman.domain.vo.AihumanConfigVo;
import org.ruoyi.aihuman.domain.AihumanConfig;
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.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.List;
/**
* 交互数字人配置Service业务层处理
@@ -39,15 +38,15 @@ public class AihumanConfigServiceImpl implements AihumanConfigService {
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 TableDataInfo<AihumanConfigVo> queryPageList(AihumanConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<AihumanConfig> lqw = buildQueryWrapper(bo);
Page<AihumanConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询交互数字人配置列表
@@ -60,15 +59,15 @@ public class AihumanConfigServiceImpl implements AihumanConfigService {
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());
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;
}
@@ -77,7 +76,7 @@ public class AihumanConfigServiceImpl implements AihumanConfigService {
*/
@Override
public Boolean insertByBo(AihumanConfigBo bo) {
AihumanConfig add = MapstructUtils.convert(bo, AihumanConfig. class);
AihumanConfig add = MapstructUtils.convert(bo, AihumanConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
@@ -91,7 +90,7 @@ public class AihumanConfigServiceImpl implements AihumanConfigService {
*/
@Override
public Boolean updateByBo(AihumanConfigBo bo) {
AihumanConfig update = MapstructUtils.convert(bo, AihumanConfig. class);
AihumanConfig update = MapstructUtils.convert(bo, AihumanConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}

View File

@@ -4,14 +4,14 @@ 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.springframework.stereotype.Service;
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.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;

View File

@@ -1,37 +1,36 @@
package org.ruoyi.aihuman.service.impl;
import com.sun.jna.Library;
import com.sun.jna.Native;
import jakarta.annotation.PreDestroy;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.core.page.TableDataInfo;
import org.ruoyi.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.WinNT;
import jakarta.annotation.PreDestroy;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.ruoyi.aihuman.domain.AihumanRealConfig;
import org.ruoyi.aihuman.domain.bo.AihumanRealConfigBo;
import org.ruoyi.aihuman.domain.vo.AihumanRealConfigVo;
import org.ruoyi.aihuman.domain.AihumanRealConfig;
import org.ruoyi.aihuman.mapper.AihumanRealConfigMapper;
import org.ruoyi.aihuman.service.AihumanRealConfigService;
import org.ruoyi.common.core.utils.MapstructUtils;
import org.ruoyi.common.core.utils.StringUtils;
import org.ruoyi.common.redis.utils.RedisUtils;
import org.ruoyi.core.page.PageQuery;
import org.ruoyi.core.page.TableDataInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Collection;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.sun.jna.platform.win32.WinNT;
import com.sun.jna.Pointer;
import java.util.concurrent.TimeUnit;
/**
@@ -44,6 +43,7 @@ import java.util.concurrent.TimeUnit;
@Service
public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
private static final Logger log = LoggerFactory.getLogger(AihumanRealConfigServiceImpl.class);
private final AihumanRealConfigMapper baseMapper;
// 存储当前运行的进程,用于停止操作
private volatile Process runningProcess = null;
@@ -56,15 +56,15 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
return baseMapper.selectVoById(id);
}
/**
* 查询真人交互数字人配置列表
*/
@Override
public TableDataInfo<AihumanRealConfigVo> queryPageList(AihumanRealConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<AihumanRealConfig> lqw = buildQueryWrapper(bo);
Page<AihumanRealConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询真人交互数字人配置列表
*/
@Override
public TableDataInfo<AihumanRealConfigVo> queryPageList(AihumanRealConfigBo bo, PageQuery pageQuery) {
LambdaQueryWrapper<AihumanRealConfig> lqw = buildQueryWrapper(bo);
Page<AihumanRealConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
return TableDataInfo.build(result);
}
/**
* 查询真人交互数字人配置列表
@@ -77,22 +77,22 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
private LambdaQueryWrapper<AihumanRealConfig> buildQueryWrapper(AihumanRealConfigBo bo) {
LambdaQueryWrapper<AihumanRealConfig> lqw = Wrappers.lambdaQuery();
lqw.like(StringUtils.isNotBlank(bo.getName()), AihumanRealConfig::getName, bo.getName());
lqw.like(StringUtils.isNotBlank(bo.getAvatars()), AihumanRealConfig::getAvatars, bo.getAvatars());
lqw.like(StringUtils.isNotBlank(bo.getModels()), AihumanRealConfig::getModels, bo.getModels());
lqw.eq(StringUtils.isNotBlank(bo.getAvatarsParams()), AihumanRealConfig::getAvatarsParams, bo.getAvatarsParams());
lqw.eq(StringUtils.isNotBlank(bo.getModelsParams()), AihumanRealConfig::getModelsParams, bo.getModelsParams());
lqw.eq(StringUtils.isNotBlank(bo.getAgentParams()), AihumanRealConfig::getAgentParams, bo.getAgentParams());
lqw.eq(bo.getCreateTime() != null, AihumanRealConfig::getCreateTime, bo.getCreateTime());
lqw.eq(bo.getUpdateTime() != null, AihumanRealConfig::getUpdateTime, bo.getUpdateTime());
lqw.eq(bo.getStatus() != null, AihumanRealConfig::getStatus, bo.getStatus());
lqw.eq(bo.getPublish() != null, AihumanRealConfig::getPublish, bo.getPublish());
lqw.eq(StringUtils.isNotBlank(bo.getRunParams()), AihumanRealConfig::getRunParams, bo.getRunParams());
// 添加runStatus字段的查询条件
lqw.eq(StringUtils.isNotBlank(bo.getRunStatus()), AihumanRealConfig::getRunStatus, bo.getRunStatus());
lqw.eq(StringUtils.isNotBlank(bo.getCreateDept()), AihumanRealConfig::getCreateDept, bo.getCreateDept());
lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), AihumanRealConfig::getCreateBy, bo.getCreateBy());
lqw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), AihumanRealConfig::getUpdateBy, bo.getUpdateBy());
lqw.like(StringUtils.isNotBlank(bo.getName()), AihumanRealConfig::getName, bo.getName());
lqw.like(StringUtils.isNotBlank(bo.getAvatars()), AihumanRealConfig::getAvatars, bo.getAvatars());
lqw.like(StringUtils.isNotBlank(bo.getModels()), AihumanRealConfig::getModels, bo.getModels());
lqw.eq(StringUtils.isNotBlank(bo.getAvatarsParams()), AihumanRealConfig::getAvatarsParams, bo.getAvatarsParams());
lqw.eq(StringUtils.isNotBlank(bo.getModelsParams()), AihumanRealConfig::getModelsParams, bo.getModelsParams());
lqw.eq(StringUtils.isNotBlank(bo.getAgentParams()), AihumanRealConfig::getAgentParams, bo.getAgentParams());
lqw.eq(bo.getCreateTime() != null, AihumanRealConfig::getCreateTime, bo.getCreateTime());
lqw.eq(bo.getUpdateTime() != null, AihumanRealConfig::getUpdateTime, bo.getUpdateTime());
lqw.eq(bo.getStatus() != null, AihumanRealConfig::getStatus, bo.getStatus());
lqw.eq(bo.getPublish() != null, AihumanRealConfig::getPublish, bo.getPublish());
lqw.eq(StringUtils.isNotBlank(bo.getRunParams()), AihumanRealConfig::getRunParams, bo.getRunParams());
// 添加runStatus字段的查询条件
lqw.eq(StringUtils.isNotBlank(bo.getRunStatus()), AihumanRealConfig::getRunStatus, bo.getRunStatus());
lqw.eq(StringUtils.isNotBlank(bo.getCreateDept()), AihumanRealConfig::getCreateDept, bo.getCreateDept());
lqw.eq(StringUtils.isNotBlank(bo.getCreateBy()), AihumanRealConfig::getCreateBy, bo.getCreateBy());
lqw.eq(StringUtils.isNotBlank(bo.getUpdateBy()), AihumanRealConfig::getUpdateBy, bo.getUpdateBy());
return lqw;
}
@@ -101,7 +101,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
*/
@Override
public Boolean insertByBo(AihumanRealConfigBo bo) {
AihumanRealConfig add = MapstructUtils.convert(bo, AihumanRealConfig. class);
AihumanRealConfig add = MapstructUtils.convert(bo, AihumanRealConfig.class);
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
@@ -115,7 +115,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
*/
@Override
public Boolean updateByBo(AihumanRealConfigBo bo) {
AihumanRealConfig update = MapstructUtils.convert(bo, AihumanRealConfig. class);
AihumanRealConfig update = MapstructUtils.convert(bo, AihumanRealConfig.class);
validEntityBeforeSave(update);
return baseMapper.updateById(update) > 0;
}
@@ -138,8 +138,6 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
return baseMapper.deleteBatchIds(ids) > 0;
}
private static final Logger log = LoggerFactory.getLogger(AihumanRealConfigServiceImpl.class);
/**
* 执行真人交互数字人配置
* 通过主键获取数据库记录然后从run_params字段读取命令并执行
@@ -153,7 +151,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
log.error("执行命令失败主键ID为空");
throw new RuntimeException("执行命令失败主键ID为空");
}
// 检查是否已经有对应的进程在运行
String redisKey = "aihuman:process:" + id;
String existingPid = RedisUtils.getCacheObject(redisKey);
@@ -166,21 +164,21 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
baseMapper.updateById(updateStatus);
return true;
}
// 查询数据库记录
AihumanRealConfig config = baseMapper.selectById(id);
if (config == null) {
log.error("执行命令失败未找到ID为{}的配置记录", id);
throw new RuntimeException("执行命令失败:未找到对应的配置记录");
}
// 2. 从记录中获取run_params字段
String runParams = config.getRunParams();
if (StringUtils.isBlank(runParams)) {
log.error("执行命令失败ID为{}的记录中run_params字段为空", id);
throw new RuntimeException("执行命令失败run_params字段为空");
}
// 3. 解析并执行命令
// 将多行命令合并为一个命令字符串
String[] commands = runParams.split("\\r?\\n");
@@ -188,7 +186,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
log.error("执行命令失败runParams中没有有效的命令");
throw new RuntimeException("执行命令失败runParams中没有有效的命令");
}
// 将所有命令合并到一个命令字符串中,使用&&连接,确保在同一个进程中执行
StringBuilder mergedCmd = new StringBuilder();
for (int i = 0; i < commands.length; i++) {
@@ -196,23 +194,23 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
if (command.isEmpty()) {
continue;
}
if (mergedCmd.length() > 0) {
mergedCmd.append(" && ");
}
mergedCmd.append(command);
}
String cmd = "cmd.exe /c " + mergedCmd.toString();
log.info("准备执行合并命令:{}", cmd);
// 更新数据库中的运行状态为运行中
AihumanRealConfig updateStatus = new AihumanRealConfig();
updateStatus.setId(id);
updateStatus.setRunStatus("1"); // 1表示运行中
baseMapper.updateById(updateStatus);
// 使用线程池执行命令并监听输出
ExecutorService executor = Executors.newSingleThreadExecutor();
executor.submit(() -> {
@@ -220,14 +218,14 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
Process process = Runtime.getRuntime().exec(cmd);
// 保存进程引用,用于后续停止操作
runningProcess = process;
// 获取进程ID并保存到Redis
String pid = getProcessId(process);
if (!"unknown".equals(pid)) {
RedisUtils.setCacheObject(redisKey, pid);
log.info("保存进程ID到Rediskey={}, pid={}", redisKey, pid);
}
// 读取标准输出
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
@@ -239,7 +237,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
log.error("读取命令输出失败", e);
}
}).start();
// 读取debug输出
new Thread(() -> {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
@@ -251,21 +249,21 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
log.error("读取命令debug输出失败", e);
}
}).start();
// 等待进程结束
int exitCode = process.waitFor();
log.info("LiveTalking进程结束退出码: {}", exitCode);
// 进程结束后更新数据库状态为已停止
AihumanRealConfig endStatus = new AihumanRealConfig();
endStatus.setId(id);
endStatus.setRunStatus("0"); // 0表示已停止
baseMapper.updateById(endStatus);
// 进程结束后从Redis中删除进程ID
RedisUtils.deleteObject(redisKey);
log.info("从Redis中删除进程IDkey={}", redisKey);
// 进程结束后清空引用
runningProcess = null;
} catch (Exception e) {
@@ -285,7 +283,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
runningProcess = null;
}
});
executor.shutdown();
return true;
} catch (Exception e) {
@@ -293,9 +291,10 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
return false;
}
}
/**
* 检查进程是否正在运行
*
* @param pid 进程ID
* @return 是否正在运行
*/
@@ -303,20 +302,20 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
if (StringUtils.isEmpty(pid) || "unknown".equals(pid)) {
return false;
}
try {
boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");
ProcessBuilder processBuilder;
if (isWindows) {
processBuilder = new ProcessBuilder("tasklist", "/FI", "PID eq " + pid);
} else {
processBuilder = new ProcessBuilder("ps", "-p", pid);
}
Process process = processBuilder.start();
int exitCode = process.waitFor();
// 在Windows上tasklist命令如果找不到进程退出码也是0但输出中不会包含PID
if (isWindows) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
@@ -346,7 +345,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
try {
Integer id = bo.getId();
String redisKey = "aihuman:process:" + id;
// 首先检查Redis中是否有对应的进程ID
String pid = RedisUtils.getCacheObject(redisKey);
if (StringUtils.isNotEmpty(pid)) {
@@ -367,19 +366,19 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
log.error("通过Redis中的PID停止进程失败", e);
}
}
// 然后检查本地runningProcess引用
if (runningProcess != null && runningProcess.isAlive()) {
log.info("正在停止LiveTalking进程...");
// 强制销毁进程树,确保完全停止
destroyProcessTree(runningProcess);
// 更新数据库中的运行状态为已停止
AihumanRealConfig updateStatus = new AihumanRealConfig();
updateStatus.setId(id);
updateStatus.setRunStatus("0"); // 0表示已停止
baseMapper.updateById(updateStatus);
runningProcess = null;
log.info("LiveTalking进程已停止");
} else {
@@ -390,11 +389,11 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
updateStatus.setRunStatus("0"); // 0表示已停止
baseMapper.updateById(updateStatus);
}
// 无论如何都从Redis中删除进程ID
RedisUtils.deleteObject(redisKey);
log.info("从Redis中删除进程IDkey={}", redisKey);
return true;
} catch (Exception e) {
log.error("停止进程时发生异常", e);
@@ -410,6 +409,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
/**
* 销毁进程及其子进程(进程树)
*
* @param process 要销毁的进程
*/
private void destroyProcessTree(Process process) {
@@ -418,7 +418,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
// 获取进程ID
String pid = getProcessId(process);
log.info("获取到进程ID: {}", pid);
// 根据操作系统类型,使用不同的命令终止进程树
if (System.getProperty("os.name").toLowerCase().contains("win")) {
// Windows系统使用taskkill命令终止进程树
@@ -449,14 +449,15 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
/**
* 获取进程ID
*
* @param process 进程对象
* @return 进程ID
*/
private String getProcessId(Process process) {
try {
// 不同JVM实现可能有所不同这里尝试通过反射获取
if (process.getClass().getName().equals("java.lang.Win32Process") ||
process.getClass().getName().equals("java.lang.ProcessImpl")) {
if (process.getClass().getName().equals("java.lang.Win32Process") ||
process.getClass().getName().equals("java.lang.ProcessImpl")) {
Field f = process.getClass().getDeclaredField("handle");
f.setAccessible(true);
long handl = f.getLong(process);
@@ -472,7 +473,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
} catch (Exception e) {
log.error("获取进程ID失败", e);
}
// 如果反射获取失败尝试通过wmic命令获取
try {
// 对于Windows系统可以尝试使用wmic命令获取进程ID
@@ -483,14 +484,8 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
} catch (Exception e) {
log.error("通过ProcessHandle获取进程ID失败", e);
}
return "unknown";
}
// JNA接口定义用于Windows系统获取进程ID
interface Kernel32 extends Library {
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
int GetProcessId(WinNT.HANDLE hProcess);
return "unknown";
}
@PreDestroy
@@ -499,7 +494,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
try {
log.info("应用关闭,正在停止数字人进程");
destroyProcessTree(runningProcess);
// 查找所有运行状态为运行中的配置,并更新为已停止
LambdaQueryWrapper<AihumanRealConfig> lqw = Wrappers.lambdaQuery();
lqw.eq(AihumanRealConfig::getRunStatus, "1");
@@ -507,7 +502,7 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
for (AihumanRealConfig config : runningConfigs) {
config.setRunStatus("0");
baseMapper.updateById(config);
// 从Redis中删除对应的进程ID记录
String redisKey = "aihuman:process:" + config.getId();
RedisUtils.deleteObject(redisKey);
@@ -529,4 +524,11 @@ public class AihumanRealConfigServiceImpl implements AihumanRealConfigService {
}
}
}
// JNA接口定义用于Windows系统获取进程ID
interface Kernel32 extends Library {
Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
int GetProcessId(WinNT.HANDLE hProcess);
}
}

View File

@@ -1,19 +1,31 @@
-- 菜单 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971582278942666752, '交互数字人配置', '2000', '1', 'aihumanConfig', 'aihuman/aihumanConfig/index', 1, 0, 'C', '0', '0', 'aihuman:aihumanConfig:list', '#', 103, 1, sysdate(), null, null, '交互数字人配置菜单');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971582278942666752, '交互数字人配置', '2000', '1', 'aihumanConfig', 'aihuman/aihumanConfig/index', 1, 0, 'C',
'0', '0', 'aihuman:aihumanConfig:list', '#', 103, 1, sysdate(), null, null, '交互数字人配置菜单');
-- 按钮 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971582278942666753, '交互数字人配置查询', 1971582278942666752, '1', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanConfig:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971582278942666753, '交互数字人配置查询', 1971582278942666752, '1', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanConfig:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971582278942666754, '交互数字人配置新增', 1971582278942666752, '2', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanConfig:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971582278942666754, '交互数字人配置新增', 1971582278942666752, '2', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanConfig:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971582278942666755, '交互数字人配置修改', 1971582278942666752, '3', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanConfig:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971582278942666755, '交互数字人配置修改', 1971582278942666752, '3', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanConfig:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971582278942666756, '交互数字人配置删除', 1971582278942666752, '4', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanConfig:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971582278942666756, '交互数字人配置删除', 1971582278942666752, '4', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanConfig:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971582278942666757, '交互数字人配置导出', 1971582278942666752, '5', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanConfig:export', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971582278942666757, '交互数字人配置导出', 1971582278942666752, '5', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanConfig:export', '#', 103, 1, sysdate(), null, null, '');

View File

@@ -1,19 +1,31 @@
-- 菜单 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971546066781597696, '数字人信息管理', '2000', '1', 'aihumanInfo', 'aihuman/aihumanInfo/index', 1, 0, 'C', '0', '0', 'aihuman:aihumanInfo:list', '#', 103, 1, sysdate(), null, null, '数字人信息管理菜单');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971546066781597696, '数字人信息管理', '2000', '1', 'aihumanInfo', 'aihuman/aihumanInfo/index', 1, 0, 'C', '0',
'0', 'aihuman:aihumanInfo:list', '#', 103, 1, sysdate(), null, null, '数字人信息管理菜单');
-- 按钮 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971546066781597697, '数字人信息管理查询', 1971546066781597696, '1', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971546066781597697, '数字人信息管理查询', 1971546066781597696, '1', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanInfo:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971546066781597698, '数字人信息管理新增', 1971546066781597696, '2', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971546066781597698, '数字人信息管理新增', 1971546066781597696, '2', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanInfo:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971546066781597699, '数字人信息管理修改', 1971546066781597696, '3', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971546066781597699, '数字人信息管理修改', 1971546066781597696, '3', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanInfo:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971546066781597700, '数字人信息管理删除', 1971546066781597696, '4', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971546066781597700, '数字人信息管理删除', 1971546066781597696, '4', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanInfo:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1971546066781597701, '数字人信息管理导出', 1971546066781597696, '5', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanInfo:export', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1971546066781597701, '数字人信息管理导出', 1971546066781597696, '5', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanInfo:export', '#', 103, 1, sysdate(), null, null, '');

View File

@@ -1,19 +1,32 @@
-- 菜单 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1980480880138051584, '真人交互数字人配置', '2000', '1', 'aihumanRealConfig', 'aihuman/aihumanRealConfig/index', 1, 0, 'C', '0', '0', 'aihuman:aihumanRealConfig:list', '#', 103, 1, sysdate(), null, null, '真人交互数字人配置菜单');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1980480880138051584, '真人交互数字人配置', '2000', '1', 'aihumanRealConfig', 'aihuman/aihumanRealConfig/index',
1, 0, 'C', '0', '0', 'aihuman:aihumanRealConfig:list', '#', 103, 1, sysdate(), null, null,
'真人交互数字人配置菜单');
-- 按钮 SQL
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1980480880138051585, '真人交互数字人配置查询', 1980480880138051584, '1', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanRealConfig:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1980480880138051585, '真人交互数字人配置查询', 1980480880138051584, '1', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanRealConfig:query', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1980480880138051586, '真人交互数字人配置新增', 1980480880138051584, '2', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanRealConfig:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1980480880138051586, '真人交互数字人配置新增', 1980480880138051584, '2', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanRealConfig:add', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1980480880138051587, '真人交互数字人配置修改', 1980480880138051584, '3', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanRealConfig:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1980480880138051587, '真人交互数字人配置修改', 1980480880138051584, '3', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanRealConfig:edit', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1980480880138051588, '真人交互数字人配置删除', 1980480880138051584, '4', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanRealConfig:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1980480880138051588, '真人交互数字人配置删除', 1980480880138051584, '4', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanRealConfig:remove', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values(1980480880138051589, '真人交互数字人配置导出', 1980480880138051584, '5', '#', '', 1, 0, 'F', '0', '0', 'aihuman:aihumanRealConfig:export', '#', 103, 1, sysdate(), null, null, '');
insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible,
status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark)
values (1980480880138051589, '真人交互数字人配置导出', 1980480880138051584, '5', '#', '', 1, 0, 'F', '0', '0',
'aihuman:aihumanRealConfig:export', '#', 103, 1, sysdate(), null, null, '');

View File

@@ -1,11 +1,11 @@
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 lombok.extern.slf4j.Slf4j;
import java.io.ByteArrayOutputStream;
import java.io.File;

View File

@@ -1,4 +1,4 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<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/maven-v4_0_0.xsd">
<parent>
<groupId>org.ruoyi</groupId>
@@ -11,7 +11,7 @@
<artifactId>ruoyi-chat</artifactId>
<description>
三方API接入
三方API接入
</description>
<properties>

View File

@@ -23,33 +23,32 @@ import java.util.concurrent.TimeUnit;
@RequiredArgsConstructor
public class ChatConfig {
private final ConfigService configService;
@Getter
private OpenAiStreamClient openAiStreamClient;
private final ConfigService configService;
@Bean
public OpenAiStreamClient openAiStreamClient() {
String apiHost = configService.getConfigValue("chat", "apiHost");
String apiKey = configService.getConfigValue("chat", "apiKey");
openAiStreamClient = createOpenAiStreamClient(apiHost,apiKey);
return openAiStreamClient;
}
public static OpenAiStreamClient createOpenAiStreamClient(String apiHost, String apiKey) {
HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor(new OpenAILogger());
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.HEADERS);
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(600, TimeUnit.SECONDS)
.readTimeout(600, TimeUnit.SECONDS)
.build();
.addInterceptor(httpLoggingInterceptor)
.connectTimeout(30, TimeUnit.SECONDS)
.writeTimeout(600, TimeUnit.SECONDS)
.readTimeout(600, TimeUnit.SECONDS)
.build();
return OpenAiStreamClient.builder()
.apiHost(apiHost)
.apiKey(Collections.singletonList(apiKey))
.keyStrategy(new KeyRandomStrategy())
.okHttpClient(okHttpClient)
.build();
.apiHost(apiHost)
.apiKey(Collections.singletonList(apiKey))
.keyStrategy(new KeyRandomStrategy())
.okHttpClient(okHttpClient)
.build();
}
@Bean
public OpenAiStreamClient openAiStreamClient() {
String apiHost = configService.getConfigValue("chat", "apiHost");
String apiKey = configService.getConfigValue("chat", "apiKey");
openAiStreamClient = createOpenAiStreamClient(apiHost, apiKey);
return openAiStreamClient;
}
}

View File

@@ -28,7 +28,7 @@ public class OkHttpConfig {
private void initializeOkHttpUtil(String modelName) {
ChatModelVo chatModelVo = chatModelService.selectModelByName(modelName);
if(chatModelVo==null){
if (chatModelVo == null) {
return;
}
OkHttpUtil okHttpUtil = new OkHttpUtil();

View File

@@ -68,7 +68,7 @@ public class ChatConfigController extends BaseController {
@SaCheckPermission("system:config:query")
@GetMapping("/{id}")
public R<ChatConfigVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
@PathVariable Long id) {
return R.ok(chatConfigService.queryById(id));
}
@@ -81,9 +81,9 @@ public class ChatConfigController extends BaseController {
@PostMapping("/saveOrUpdate")
public R<Void> saveOrUpdate(@RequestBody List<ChatConfigBo> boList) {
for (ChatConfigBo chatConfigBo : boList) {
if(chatConfigBo.getId() == null){
if (chatConfigBo.getId() == null) {
chatConfigService.insertByBo(chatConfigBo);
}else {
} else {
chatConfigService.updateByBo(chatConfigBo);
}
}
@@ -121,12 +121,11 @@ public class ChatConfigController extends BaseController {
*/
@GetMapping(value = "/configKey/{configKey}")
public R<String> getConfigKey(@PathVariable String configKey) {
return R.ok(configService.getConfigValue("sys",configKey));
return R.ok(configService.getConfigValue("sys", configKey));
}
/**
* 查询系统参数
*
*/
@GetMapping(value = "/sysConfigKey")
public R<List<ChatConfigVo>> getSysConfigKey() {

View File

@@ -19,7 +19,7 @@ import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
/**
* 聊天管理
* 聊天管理
*
* @author ageerle@163.com
* @date 2023-03-01
@@ -38,7 +38,7 @@ public class ChatController {
@PostMapping("/send")
@ResponseBody
public SseEmitter sseChat(@RequestBody @Valid ChatRequest chatRequest, HttpServletRequest request) {
return sseService.sseChat(chatRequest,request);
return sseService.sseChat(chatRequest, request);
}
/**

View File

@@ -74,12 +74,11 @@ public class ChatMessageController extends BaseController {
*/
@GetMapping("/{id}")
public R<ChatMessageVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
@PathVariable Long id) {
return R.ok(chatMessageService.queryById(id));
}
/**
* 查询聊天消息列表 uniapp
*/

View File

@@ -82,7 +82,7 @@ public class ChatModelController extends BaseController {
*/
@GetMapping("/{id}")
public R<ChatModelVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
@PathVariable Long id) {
return R.ok(chatModelService.queryById(id));
}

View File

@@ -1,6 +1,5 @@
package org.ruoyi.chat.controller.chat;
import cn.dev33.satoken.annotation.SaCheckPermission;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@@ -43,9 +42,9 @@ public class ChatSessionController extends BaseController {
*/
@GetMapping("/list")
public TableDataInfo<ChatSessionVo> list(ChatSessionBo bo, PageQuery pageQuery) {
if(!LoginHelper.isLogin()){
// 如果用户没有登录,返回空会话列表
return TableDataInfo.build();
if (!LoginHelper.isLogin()) {
// 如果用户没有登录,返回空会话列表
return TableDataInfo.build();
}
// 默认查询当前用户会话
bo.setUserId(LoginHelper.getUserId());
@@ -69,7 +68,7 @@ public class ChatSessionController extends BaseController {
*/
@GetMapping("/{id}")
public R<ChatSessionVo> getInfo(@NotNull(message = "主键不能为空")
@PathVariable Long id) {
@PathVariable Long id) {
return R.ok(chatSessionService.queryById(id));
}

View File

@@ -19,14 +19,7 @@ import org.ruoyi.domain.bo.PromptTemplateBo;
import org.ruoyi.domain.vo.PromptTemplateVo;
import org.ruoyi.service.IPromptTemplateService;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;
import java.util.List;

View File

@@ -1,7 +1,6 @@
package org.ruoyi.chat.controller.knowledge;
import cn.dev33.satoken.stp.StpUtil;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
@@ -30,7 +29,6 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Objects;

View File

@@ -36,7 +36,7 @@ public class FaceController {
@PostMapping("/insight-face/swap")
public String insightFace(@RequestBody InsightFace insightFace) {
// 扣除接口费用并且保存消息记录
chatCostService.taskDeduct("mj","Face Changing", 0.0);
chatCostService.taskDeduct("mj", "Face Changing", 0.0);
// 创建请求体这里使用JSON作为媒体类型
String insightFaceJson = JSONUtil.toJsonStr(insightFace);
String url = "mj/insight-face/swap";

View File

@@ -47,20 +47,20 @@ public class SubmitController {
public String action(@RequestBody SubmitActionDTO changeDTO) {
ActionType actionType = ActionType.fromCustomId(getAction(changeDTO.getCustomId()));
Optional.ofNullable(actionType).ifPresentOrElse(
type -> {
switch (type) {
case UP_SAMPLE:
chatCostService.taskDeduct("mj","enlarge", 0.0);
break;
case IN_PAINT:
// 局部重绘已经扣费,不执行任何操作
break;
default:
chatCostService.taskDeduct("mj","change", 0.0);
break;
}
},
() -> chatCostService.taskDeduct("mj","change", 0.0)
type -> {
switch (type) {
case UP_SAMPLE:
chatCostService.taskDeduct("mj", "enlarge", 0.0);
break;
case IN_PAINT:
// 局部重绘已经扣费,不执行任何操作
break;
default:
chatCostService.taskDeduct("mj", "change", 0.0);
break;
}
},
() -> chatCostService.taskDeduct("mj", "change", 0.0)
);
String jsonStr = JSONUtil.toJsonStr(changeDTO);
@@ -81,7 +81,7 @@ public class SubmitController {
@Operation(summary = "提交图生图、混图任务")
@PostMapping("/blend")
public String blend(@RequestBody SubmitBlendDTO blendDTO) {
chatCostService.taskDeduct("mj","blend", 0.0);
chatCostService.taskDeduct("mj", "blend", 0.0);
String jsonStr = JSONUtil.toJsonStr(blendDTO);
String url = "mj/submit/blend";
Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
@@ -91,7 +91,7 @@ public class SubmitController {
@Operation(summary = "提交图生文任务")
@PostMapping("/describe")
public String describe(@RequestBody SubmitDescribeDTO describeDTO) {
chatCostService.taskDeduct("mj","describe",0.0);
chatCostService.taskDeduct("mj", "describe", 0.0);
String jsonStr = JSONUtil.toJsonStr(describeDTO);
String url = "mj/submit/describe";
Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
@@ -101,7 +101,7 @@ public class SubmitController {
@Operation(summary = "提交文生图任务")
@PostMapping("/imagine")
public String imagine(@RequestBody SubmitImagineDTO imagineDTO) {
chatCostService.taskDeduct("mj",imagineDTO.getPrompt(), 0.0);
chatCostService.taskDeduct("mj", imagineDTO.getPrompt(), 0.0);
String jsonStr = JSONUtil.toJsonStr(imagineDTO);
String url = "mj/submit/imagine";
Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
@@ -111,7 +111,7 @@ public class SubmitController {
@Operation(summary = "提交局部重绘任务")
@PostMapping("/modal")
public String modal(@RequestBody SubmitModalDTO submitModalDTO) {
chatCostService.taskDeduct("mj","repaint ", 0.0);
chatCostService.taskDeduct("mj", "repaint ", 0.0);
String jsonStr = JSONUtil.toJsonStr(submitModalDTO);
String url = "mj/submit/modal";
Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);
@@ -121,7 +121,7 @@ public class SubmitController {
@Operation(summary = "提交提示词分析任务")
@PostMapping("/shorten")
public String shorten(@RequestBody SubmitShortenDTO submitShortenDTO) {
chatCostService.taskDeduct("mj","shorten", 0.0);
chatCostService.taskDeduct("mj", "shorten", 0.0);
String jsonStr = JSONUtil.toJsonStr(submitShortenDTO);
String url = "mj/submit/shorten";
Request request = mjOkHttpUtil.createPostRequest(url, jsonStr);

View File

@@ -34,7 +34,7 @@ public class SunoController {
public String generate(@RequestBody GenerateSuno generateSuno) {
OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("suno");
// 扣除接口费用并且保存消息记录
chatCostService.taskDeduct("suno","文生歌曲", NumberUtils.toDouble(okHttpConfig.getGenerate(), 0.3));
chatCostService.taskDeduct("suno", "文生歌曲", NumberUtils.toDouble(okHttpConfig.getGenerate(), 0.3));
// 创建请求体这里使用JSON作为媒体类型
String generateJson = JSONUtil.toJsonStr(generateSuno);
String url = "suno/generate";
@@ -57,7 +57,7 @@ public class SunoController {
@GetMapping("/lyrics/{taskId}")
public String lyrics(@PathVariable String taskId) {
OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("suno");
String url = "task/suno/v1/fetch/"+taskId;
String url = "task/suno/v1/fetch/" + taskId;
Request request = okHttpUtil.createGetRequest(url);
return okHttpUtil.executeRequest(request);
}
@@ -67,7 +67,7 @@ public class SunoController {
@GetMapping("/feed/{taskId}")
public String feed(@PathVariable String taskId) {
OkHttpUtil okHttpUtil = okHttpConfig.getOkHttpUtil("suno");
String url = "suno/feed/"+taskId;
String url = "suno/feed/" + taskId;
Request request = okHttpUtil.createGetRequest(url);
return okHttpUtil.executeRequest(request);
}

View File

@@ -27,22 +27,22 @@ public class TaskController {
private final MjOkHttpUtil mjOkHttpUtil;
@Operation(summary = "指定ID获取任务")
@GetMapping("/{id}/fetch")
@Operation(summary = "指定ID获取任务")
@GetMapping("/{id}/fetch")
public String fetch(@Parameter(description = "任务ID") @PathVariable String id) {
String url = "mj/task/" + id + "/fetch";
Request request = mjOkHttpUtil.createGetRequest(url);
return mjOkHttpUtil.executeRequest(request);
}
@Operation(summary = "根据ID列表查询任务")
@PostMapping("/list-by-condition")
public String listByIds(@RequestBody TaskConditionDTO conditionDTO) {
@Operation(summary = "根据ID列表查询任务")
@PostMapping("/list-by-condition")
public String listByIds(@RequestBody TaskConditionDTO conditionDTO) {
String url = "mj/task/list-by-condition";
String conditionJson = JSONUtil.toJsonStr(conditionDTO);
Request request = mjOkHttpUtil.createPostRequest(url,conditionJson);
Request request = mjOkHttpUtil.createPostRequest(url, conditionJson);
return mjOkHttpUtil.executeRequest(request);
}
}
@Operation(summary = "获取任务图片的seed")
@GetMapping("/{id}/image-seed")

View File

@@ -12,61 +12,59 @@ import java.util.Map;
public class DomainObject implements Serializable {
@Getter
@Setter
@Schema(description = "ID")
protected String id;
@JsonIgnore
private final transient Object lock = new Object();
@Getter
@Setter
@Schema(description = "ID")
protected String id;
@Setter
protected Map<String, Object> properties; // 扩展属性,仅支持基本类型
@Setter
protected Map<String, Object> properties; // 扩展属性,仅支持基本类型
public void sleep() throws InterruptedException {
synchronized (this.lock) {
this.lock.wait();
}
}
@JsonIgnore
private final transient Object lock = new Object();
public void awake() {
synchronized (this.lock) {
this.lock.notifyAll();
}
}
public void sleep() throws InterruptedException {
synchronized (this.lock) {
this.lock.wait();
}
}
public DomainObject setProperty(String name, Object value) {
getProperties().put(name, value);
return this;
}
public void awake() {
synchronized (this.lock) {
this.lock.notifyAll();
}
}
public DomainObject removeProperty(String name) {
getProperties().remove(name);
return this;
}
public DomainObject setProperty(String name, Object value) {
getProperties().put(name, value);
return this;
}
public Object getProperty(String name) {
return getProperties().get(name);
}
public DomainObject removeProperty(String name) {
getProperties().remove(name);
return this;
}
@SuppressWarnings("unchecked")
public <T> T getPropertyGeneric(String name) {
return (T) getProperty(name);
}
public Object getProperty(String name) {
return getProperties().get(name);
}
public <T> T getProperty(String name, Class<T> clz) {
return getProperty(name, clz, null);
}
@SuppressWarnings("unchecked")
public <T> T getPropertyGeneric(String name) {
return (T) getProperty(name);
}
public <T> T getProperty(String name, Class<T> clz, T defaultValue) {
Object value = getProperty(name);
return value == null ? defaultValue : clz.cast(value);
}
public <T> T getProperty(String name, Class<T> clz) {
return getProperty(name, clz, null);
}
public <T> T getProperty(String name, Class<T> clz, T defaultValue) {
Object value = getProperty(name);
return value == null ? defaultValue : clz.cast(value);
}
public Map<String, Object> getProperties() {
if (this.properties == null) {
this.properties = new HashMap<>();
}
return this.properties;
}
public Map<String, Object> getProperties() {
if (this.properties == null) {
this.properties = new HashMap<>();
}
return this.properties;
}
}

View File

@@ -11,11 +11,15 @@ import java.io.Serializable;
@Data
@Schema(name = "Discord账号")
public class InsightFace implements Serializable {
/**本人头像json*/
/**
* 本人头像json
*/
@Schema(description = "本人头像json")
private String sourceBase64;
/**明星头像json*/
/**
* 明星头像json
*/
@Schema(description = "明星头像json")
private String targetBase64;
}

View File

@@ -3,7 +3,7 @@ package org.ruoyi.chat.domain.bo;
import lombok.Data;
/**
* 文生视频请求对象
* 文生视频请求对象
*
* @author ageerle@163.com
* date 2024/6/27

View File

@@ -3,7 +3,7 @@ package org.ruoyi.chat.domain.bo;
import lombok.Data;
/**
* 生成歌词
* 生成歌词
*
* @author ageerle@163.com
* date 2024/6/27

View File

@@ -8,9 +8,9 @@ import lombok.Setter;
@Setter
public abstract class BaseSubmitDTO {
@Schema(description = "自定义参数")
protected String state;
@Schema(description = "自定义参数")
protected String state;
@Schema(description = "回调地址, 为空时使用全局notifyHook")
protected String notifyHook;
@Schema(description = "回调地址, 为空时使用全局notifyHook")
protected String notifyHook;
}

View File

@@ -8,9 +8,9 @@ import lombok.Data;
@Schema(name = "变化任务提交参数")
public class SubmitActionDTO {
private String customId;
private String customId;
private String taskId;
private String taskId;
private String state;

View File

@@ -13,9 +13,9 @@ import java.util.List;
@EqualsAndHashCode(callSuper = true)
public class SubmitBlendDTO extends BaseSubmitDTO {
@ArraySchema(arraySchema = @Schema(description = "图片base64数组", requiredMode = Schema.RequiredMode.REQUIRED), schema = @Schema(example = "data:image/png;base64,xxx1"))
private List<String> base64Array;
@ArraySchema(arraySchema = @Schema(description = "图片base64数组", requiredMode = Schema.RequiredMode.REQUIRED), schema = @Schema(example = "data:image/png;base64,xxx1"))
private List<String> base64Array;
@Schema(description = "比例: PORTRAIT(2:3); SQUARE(1:1); LANDSCAPE(3:2)", example = "SQUARE")
private BlendDimensions dimensions = BlendDimensions.SQUARE;
@Schema(description = "比例: PORTRAIT(2:3); SQUARE(1:1); LANDSCAPE(3:2)", example = "SQUARE")
private BlendDimensions dimensions = BlendDimensions.SQUARE;
}

Some files were not shown because too many files have changed in this diff Show More