@@ -119,24 +119,33 @@ export default {
});
},
+ // 封装输入验证逻辑
+ validateInput(input, message) {
+ if (!input.trim()) {
+ showDanger(message);
+ return false;
+ }
+ return true;
+ },
// 注册逻辑
register() {
- if (!this.form.username.trim()) {
- showDanger('用户名不能为空')
- return
+ // 验证用户名
+ if (!this.validateInput(this.form.username, '用户名不能为空')) {
+ return;
}
- if (!this.form.password.trim()) {
- showDanger('密码不能为空')
- return
+ // 验证密码
+ if (!this.validateInput(this.form.password, '密码不能为空')) {
+ return;
}
if (this.form.password !== this.form.confirmPassword) {
showDanger('两次输入的密码不一致')
return
}
- if (!this.form.captcha.trim()) {
- showDanger('验证码不能为空')
- return
+ // 验证验证码
+ if (!this.validateInput(this.form.captcha, '验证码不能为空')) {
+ return;
}
+
Api.user.register(this.form, ({data}) => {
console.log(data)
if (data.code === 0) {
@@ -159,6 +168,6 @@ export default {
}
-
\ No newline at end of file
+
From 1ad93ce1fdeafffea3e227fba2200aea0d602b37 Mon Sep 17 00:00:00 2001
From: bobo <2602109904@qq.com>
Date: Thu, 20 Mar 2025 16:57:38 +0800
Subject: [PATCH 02/16] =?UTF-8?q?=E5=8F=B3=E4=B8=8A=E8=A7=92=E7=94=A8?=
=?UTF-8?q?=E6=88=B7=E5=90=8D=E6=98=BE=E7=A4=BA=EF=BC=8C=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E4=B8=8B=E6=8B=89=E8=8F=9C=E5=8D=95=E6=A0=B7=E5=BC=8F=20?=
=?UTF-8?q?=E6=8E=A5=E6=94=B6username=E5=AD=97=E6=AE=B5=E5=B9=B6=E6=98=BE?=
=?UTF-8?q?=E7=A4=BA=E5=9C=A8=E5=8F=B3=E4=B8=8A=E8=A7=92=E3=80=82=20?=
=?UTF-8?q?=E5=8F=B3=E4=B8=8A=E8=A7=92=E6=B7=BB=E5=8A=A0=E4=BA=86=E4=B8=8B?=
=?UTF-8?q?=E6=8B=89=E8=8F=9C=E5=8D=95=E6=A0=B7=E5=BC=8F=EF=BC=8C=E5=8C=85?=
=?UTF-8?q?=E5=90=AB=E4=B8=AA=E4=BA=BA=E4=B8=AD=E5=BF=83=EF=BC=8C=E4=BF=AE?=
=?UTF-8?q?=E6=94=B9=E5=AF=86=E7=A0=81=E4=BB=A5=E5=8F=8A=E9=80=80=E5=87=BA?=
=?UTF-8?q?=E7=99=BB=E5=BD=95=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/manager-web/src/components/HeaderBar.vue | 48 +++++++++++++------
1 file changed, 34 insertions(+), 14 deletions(-)
diff --git a/main/manager-web/src/components/HeaderBar.vue b/main/manager-web/src/components/HeaderBar.vue
index acc0e981..afd1e1bb 100644
--- a/main/manager-web/src/components/HeaderBar.vue
+++ b/main/manager-web/src/components/HeaderBar.vue
@@ -2,31 +2,39 @@
@@ -43,6 +51,7 @@ export default {
return {
serach: '',
userInfo: {
+ username: '',
mobile: ''
}
}
@@ -71,7 +80,7 @@ export default {
// 当搜索内容为空时,显示原始完整列表
filteredDevices = this.$parent.originalDevices;
} else {
- // 过滤逻辑
+ // 过滤逻辑
filteredDevices = this.devices.filter(device => {
return device.agentName.includes(searchValue) ||
device.ttsModelName.includes(searchValue) ||
@@ -158,6 +167,7 @@ export default {
text-align: left;
color: #3d4566;
}
+
.console {
width: 90px;
height: 22px;
@@ -172,4 +182,14 @@ export default {
gap: 7px;
margin-left: 15px;
}
-
\ No newline at end of file
+
+.el-dropdown-link {
+ cursor: pointer;
+ color: #5778ff;
+}
+
+.el-icon-arrow-down {
+ font-size: 12px;
+}
+
+
From fcba384a15caec1d6850373917c945f044684797 Mon Sep 17 00:00:00 2001
From: caixypromise
Date: Thu, 20 Mar 2025 21:10:04 +0800
Subject: [PATCH 03/16] =?UTF-8?q?fix(tts.base):=20=E4=BF=AE=E5=A4=8D=20Aud?=
=?UTF-8?q?ioSegment.from=5Ffile=20=E8=AF=BB=E5=8F=96=E9=9F=B3=E9=A2=91?=
=?UTF-8?q?=E6=97=B6=E9=98=BB=E5=A1=9E=E7=9A=84=E9=97=AE=E9=A2=98=20?=
=?UTF-8?q?=E6=B7=BB=E5=8A=A0=20`-nostdin`=20=E5=8F=82=E6=95=B0=EF=BC=8C?=
=?UTF-8?q?=E9=98=B2=E6=AD=A2=20FFmpeg=20=E5=9C=A8=20Windows=20=E7=8E=AF?=
=?UTF-8?q?=E5=A2=83=E4=B8=8B=E7=AD=89=E5=BE=85=E6=A0=87=E5=87=86=E8=BE=93?=
=?UTF-8?q?=E5=85=A5=EF=BC=8C=E5=AF=BC=E8=87=B4=E9=98=BB=E5=A1=9E=E6=89=A7?=
=?UTF-8?q?=E8=A1=8C=E3=80=82?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/xiaozhi-server/core/providers/tts/base.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/main/xiaozhi-server/core/providers/tts/base.py b/main/xiaozhi-server/core/providers/tts/base.py
index d4a059f8..4c080c95 100644
--- a/main/xiaozhi-server/core/providers/tts/base.py
+++ b/main/xiaozhi-server/core/providers/tts/base.py
@@ -47,7 +47,8 @@ class TTSProviderBase(ABC):
file_type = os.path.splitext(audio_file_path)[1]
if file_type:
file_type = file_type.lstrip('.')
- audio = AudioSegment.from_file(audio_file_path, format=file_type)
+ # 读取音频文件,-nostdin 参数:不要从标准输入读取数据,否则FFmpeg会阻塞
+ audio = AudioSegment.from_file(audio_file_path, format=file_type, parameters=["-nostdin"])
# 转换为单声道/16kHz采样率/16位小端编码(确保与编码器匹配)
audio = audio.set_channels(1).set_frame_rate(16000).set_sample_width(2)
From 5ebc62a084686f9e33ada3cb26cf0e10b8988a9d Mon Sep 17 00:00:00 2001
From: caixypromise
Date: Thu, 20 Mar 2025 21:29:53 +0800
Subject: [PATCH 04/16] =?UTF-8?q?feature(#377):=20=E5=AE=9E=E7=8E=B0?=
=?UTF-8?q?=E6=B8=85=E7=90=86=E5=A4=A7=E6=A8=A1=E5=9E=8BAI=E7=9A=84Markdow?=
=?UTF-8?q?n=E8=AF=AD=E6=B3=95=E5=8A=9F=E8=83=BD=EF=BC=8C=E4=BC=98?=
=?UTF-8?q?=E5=8C=96TTS=E8=87=AA=E7=84=B6=E5=BA=A6=E3=80=82=E5=85=B3?=
=?UTF-8?q?=E8=81=94Issue=20#377?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
close #377
---
.../xiaozhi-server/core/providers/tts/base.py | 2 +
main/xiaozhi-server/core/utils/tts.py | 97 ++++++++++++++++++-
2 files changed, 98 insertions(+), 1 deletion(-)
diff --git a/main/xiaozhi-server/core/providers/tts/base.py b/main/xiaozhi-server/core/providers/tts/base.py
index 4c080c95..3146dc06 100644
--- a/main/xiaozhi-server/core/providers/tts/base.py
+++ b/main/xiaozhi-server/core/providers/tts/base.py
@@ -5,6 +5,7 @@ import numpy as np
import opuslib_next
from pydub import AudioSegment
from abc import ABC, abstractmethod
+from core.utils.tts import MarkdownCleaner
TAG = __name__
logger = setup_logging()
@@ -23,6 +24,7 @@ class TTSProviderBase(ABC):
tmp_file = self.generate_filename()
try:
max_repeat_time = 5
+ text = MarkdownCleaner.clean_markdown(text)
while not os.path.exists(tmp_file) and max_repeat_time > 0:
asyncio.run(self.text_to_speak(text, tmp_file))
if not os.path.exists(tmp_file):
diff --git a/main/xiaozhi-server/core/utils/tts.py b/main/xiaozhi-server/core/utils/tts.py
index 7f71536e..eb383667 100644
--- a/main/xiaozhi-server/core/utils/tts.py
+++ b/main/xiaozhi-server/core/utils/tts.py
@@ -1,4 +1,5 @@
import os
+import re
import sys
from config.logger import setup_logging
import importlib
@@ -14,4 +15,98 @@ def create_instance(class_name, *args, **kwargs):
sys.modules[lib_name] = importlib.import_module(f'{lib_name}')
return sys.modules[lib_name].TTSProvider(*args, **kwargs)
- raise ValueError(f"不支持的TTS类型: {class_name},请检查该配置的type是否设置正确")
\ No newline at end of file
+ raise ValueError(f"不支持的TTS类型: {class_name},请检查该配置的type是否设置正确")
+
+
+class MarkdownCleaner:
+ """
+ 封装 Markdown 清理逻辑:直接用 MarkdownCleaner.clean_markdown(text) 即可
+ """
+ # 公式字符
+ NORMAL_FORMULA_CHARS = re.compile(r'[a-zA-Z\\^_{}\+\-\(\)\[\]=]')
+
+ @staticmethod
+ def _replace_inline_dollar(m: re.Match) -> str:
+ """
+ 只要捕获到完整的 "$...$":
+ - 如果内部有典型公式字符 => 去掉两侧 $
+ - 否则 (纯数字/货币等) => 保留 "$...$"
+ """
+ content = m.group(1)
+ if MarkdownCleaner.NORMAL_FORMULA_CHARS.search(content):
+ return content
+ else:
+ return m.group(0)
+
+ @staticmethod
+ def _replace_table_block(match: re.Match) -> str:
+ """
+ 当匹配到一个整段表格块时,回调该函数。
+ """
+ block_text = match.group('table_block')
+ lines = block_text.strip('\n').split('\n')
+
+ parsed_table = []
+ for line in lines:
+ line_stripped = line.strip()
+ if re.match(r'^\|\s*[-:]+\s*(\|\s*[-:]+\s*)+\|?$', line_stripped):
+ continue
+ columns = [col.strip() for col in line_stripped.split('|') if col.strip() != '']
+ if columns:
+ parsed_table.append(columns)
+
+ if not parsed_table:
+ return ""
+
+ headers = parsed_table[0]
+ data_rows = parsed_table[1:] if len(parsed_table) > 1 else []
+
+ lines_for_tts = []
+ if len(parsed_table) == 1:
+ # 只有一行
+ only_line_str = ", ".join(parsed_table[0])
+ lines_for_tts.append(f"单行表格:{only_line_str}")
+ else:
+ lines_for_tts.append(f"表头是:{', '.join(headers)}")
+ for i, row in enumerate(data_rows, start=1):
+ row_str_list = []
+ for col_index, cell_val in enumerate(row):
+ if col_index < len(headers):
+ row_str_list.append(f"{headers[col_index]} = {cell_val}")
+ else:
+ row_str_list.append(cell_val)
+ lines_for_tts.append(f"第 {i} 行:{', '.join(row_str_list)}")
+
+ return "\n".join(lines_for_tts) + "\n"
+
+ # 预编译所有正则表达式(按执行频率排序)
+ # 这里要把 replace_xxx 的静态方法放在最前定义,以便在列表里能正确引用它们。
+ REGEXES = [
+ (re.compile(r'```.*?```', re.DOTALL), ''), # 代码块
+ (re.compile(r'^#+\s*', re.MULTILINE), ''), # 标题
+ (re.compile(r'(\*\*|__)(.*?)\1'), r'\2'), # 粗体
+ (re.compile(r'(\*|_)(?=\S)(.*?)(?<=\S)\1'), r'\2'), # 斜体
+ (re.compile(r'!\[.*?\]\(.*?\)'), ''), # 图片
+ (re.compile(r'\[(.*?)\]\(.*?\)'), r'\1'), # 链接
+ (re.compile(r'^\s*>+\s*', re.MULTILINE), ''), # 引用
+ (
+ re.compile(r'(?P(?:^[^\n]*\|[^\n]*\n)+)', re.MULTILINE),
+ _replace_table_block
+ ),
+ (re.compile(r'^\s*[*+-]\s*', re.MULTILINE), '- '), # 列表
+ (re.compile(r'\$\$.*?\$\$', re.DOTALL), ''), # 块级公式
+ (
+ re.compile(r'(? str:
+ """
+ 主入口方法:依序执行所有正则,移除或替换 Markdown 元素
+ """
+ for regex, replacement in MarkdownCleaner.REGEXES:
+ text = regex.sub(replacement, text)
+ return text.strip()
\ No newline at end of file
From 649246dc6aae2cc2864afe07889d1c67bf5c6543 Mon Sep 17 00:00:00 2001
From: yanyige
Date: Thu, 20 Mar 2025 21:55:07 +0800
Subject: [PATCH 05/16] =?UTF-8?q?feat:=20=E6=96=B0=E9=97=BB=E6=8F=92?=
=?UTF-8?q?=E4=BB=B6=E5=BC=80=E5=8F=91,=20=E4=BD=BF=E7=94=A8function=5Fcal?=
=?UTF-8?q?l=E6=94=AF=E6=8C=81=E6=92=AD=E6=94=BE=E5=BD=93=E5=A4=A9?=
=?UTF-8?q?=E6=96=B0=E9=97=BB=20#403?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/xiaozhi-server/config.yaml | 11 +-
.../plugins_func/functions/get_news.py | 205 ++++++++++++++++++
2 files changed, 215 insertions(+), 1 deletion(-)
create mode 100644 main/xiaozhi-server/plugins_func/functions/get_news.py
diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml
index 27a2f6c1..c8505c7b 100644
--- a/main/xiaozhi-server/config.yaml
+++ b/main/xiaozhi-server/config.yaml
@@ -94,10 +94,11 @@ Intent:
type: nointent
# plugins_func/functions下的模块,可以通过配置,选择加载哪个模块,加载后对话支持相应的function调用
# 系统默认已经记载“handle_exit_intent(退出识别)”、“play_music(音乐播放)”插件,请勿重复加载
- # 下面是加载查天气、角色切换的插件示例
+ # 下面是加载查天气、角色切换、加载查新闻的插件示例
functions:
- change_role
- get_weather
+ - get_news
# 插件的基础配置
plugins:
@@ -106,6 +107,14 @@ plugins:
# 想稳定一点就自行申请替换,每天有1000次免费调用
# 申请地址:https://console.qweather.com/#/apps/create-key/over
get_weather: { "api_key": "a861d0d5e7bf4ee1a83d9a9e4f96d4da", "default_location": "广州" }
+ # 获取新闻插件的配置,这里根据需要的新闻类型传入对应的url链接,默认支持社会、科技、财经新闻
+ # 更多类型的新闻列表查看 https://www.chinanews.com.cn/rss/
+ get_news:
+ default_rss_url: "https://www.chinanews.com.cn/rss/society.xml"
+ category_urls:
+ society: "https://www.chinanews.com.cn/rss/society.xml"
+ world: "https://www.chinanews.com.cn/rss/world.xml"
+ finance: "https://www.chinanews.com.cn/rss/finance.xml"
Memory:
mem0ai:
diff --git a/main/xiaozhi-server/plugins_func/functions/get_news.py b/main/xiaozhi-server/plugins_func/functions/get_news.py
new file mode 100644
index 00000000..43f8ea48
--- /dev/null
+++ b/main/xiaozhi-server/plugins_func/functions/get_news.py
@@ -0,0 +1,205 @@
+import random
+import requests
+import xml.etree.ElementTree as ET
+from bs4 import BeautifulSoup
+from config.logger import setup_logging
+from plugins_func.register import register_function, ToolType, ActionResponse, Action
+
+TAG = __name__
+logger = setup_logging()
+
+GET_NEWS_FUNCTION_DESC = {
+ "type": "function",
+ "function": {
+ "name": "get_news",
+ "description": (
+ "获取最新新闻,随机选择一条新闻进行播报。"
+ "用户可以指定新闻类型,如社会新闻、科技新闻、国际新闻等。"
+ "如果没有指定,默认播报社会新闻。"
+ "用户可以要求获取详细内容,此时会获取新闻的详细内容。"
+ ),
+ "parameters": {
+ "type": "object",
+ "properties": {
+ "category": {
+ "type": "string",
+ "description": "新闻类别,例如社会、科技、国际。可选参数,如果不提供则使用默认类别"
+ },
+ "detail": {
+ "type": "boolean",
+ "description": "是否获取详细内容,默认为false。如果为true,则获取上一条新闻的详细内容"
+ },
+ "lang": {
+ "type": "string",
+ "description": "返回用户使用的语言code,例如zh_CN/zh_HK/en_US/ja_JP等,默认zh_CN"
+ }
+ },
+ "required": ["lang"]
+ }
+ }
+}
+
+
+def fetch_news_from_rss(rss_url):
+ """从RSS源获取新闻列表"""
+ try:
+ response = requests.get(rss_url)
+ response.raise_for_status()
+
+ # 解析XML
+ root = ET.fromstring(response.content)
+
+ # 查找所有item元素(新闻条目)
+ news_items = []
+ for item in root.findall('.//item'):
+ title = item.find('title').text if item.find('title') is not None else "无标题"
+ link = item.find('link').text if item.find('link') is not None else "#"
+ description = item.find('description').text if item.find('description') is not None else "无描述"
+ pubDate = item.find('pubDate').text if item.find('pubDate') is not None else "未知时间"
+
+ news_items.append({
+ 'title': title,
+ 'link': link,
+ 'description': description,
+ 'pubDate': pubDate
+ })
+
+ return news_items
+ except Exception as e:
+ logger.bind(tag=TAG).error(f"获取RSS新闻失败: {e}")
+ return []
+
+
+def fetch_news_detail(url):
+ """获取新闻详情页内容并总结"""
+ try:
+ response = requests.get(url)
+ response.raise_for_status()
+
+ soup = BeautifulSoup(response.content, 'html.parser')
+
+ # 尝试提取正文内容 (这里的选择器需要根据实际网站结构调整)
+ content_div = soup.select_one('.content_desc, .content, article, .article-content')
+ if content_div:
+ paragraphs = content_div.find_all('p')
+ content = '\n'.join([p.get_text().strip() for p in paragraphs if p.get_text().strip()])
+ return content
+ else:
+ # 如果找不到特定的内容区域,尝试获取所有段落
+ paragraphs = soup.find_all('p')
+ content = '\n'.join([p.get_text().strip() for p in paragraphs if p.get_text().strip()])
+ return content[:2000] # 限制长度
+ except Exception as e:
+ logger.bind(tag=TAG).error(f"获取新闻详情失败: {e}")
+ return "无法获取详细内容"
+
+
+def map_category(category_text):
+ """将用户输入的中文类别映射到配置文件中的类别键"""
+ if not category_text:
+ return None
+
+ # 类别映射字典,目前支持社会、国际、财经新闻,如需更多类型,参见配置文件
+ category_map = {
+ # 社会新闻
+ "社会": "society",
+ "社会新闻": "society",
+ # 国际新闻
+ "国际": "world",
+ "国际新闻": "world",
+ # 财经新闻
+ "财经": "finance",
+ "财经新闻": "finance",
+ "金融": "finance",
+ "经济": "finance"
+ }
+
+ # 转换为小写并去除空格
+ normalized_category = category_text.lower().strip()
+
+ # 返回映射结果,如果没有匹配项则返回原始输入
+ return category_map.get(normalized_category, category_text)
+
+
+@register_function('get_news', GET_NEWS_FUNCTION_DESC, ToolType.SYSTEM_CTL)
+def get_news(conn, category: str = None, detail: bool = False, lang: str = "zh_CN"):
+ """获取新闻并随机选择一条进行播报,或获取上一条新闻的详细内容"""
+ try:
+ # 如果detail为True,获取上一条新闻的详细内容
+ if detail:
+ if not hasattr(conn, 'last_news_link') or not conn.last_news_link or 'link' not in conn.last_news_link:
+ return ActionResponse(Action.REQLLM, "抱歉,没有找到最近查询的新闻,请先获取一条新闻。", None)
+
+ link = conn.last_news_link.get('link')
+ title = conn.last_news_link.get('title', '未知标题')
+
+ if link == '#':
+ return ActionResponse(Action.REQLLM, "抱歉,该新闻没有可用的链接获取详细内容。", None)
+
+ logger.bind(tag=TAG).debug(f"获取新闻详情: {title}, URL={link}")
+
+ # 获取新闻详情
+ detail_content = fetch_news_detail(link)
+
+ if not detail_content or detail_content == "无法获取详细内容":
+ return ActionResponse(Action.REQLLM, f"抱歉,无法获取《{title}》的详细内容,可能是链接已失效或网站结构发生变化。", None)
+
+ # 构建详情报告
+ detail_report = (
+ f"根据下列数据,用{lang}回应用户的新闻详情查询请求:\n\n"
+ f"新闻标题: {title}\n"
+ f"详细内容: {detail_content}\n\n"
+ f"(请对上述新闻内容进行总结,提取关键信息,以自然、流畅的方式向用户播报,"
+ f"不要提及这是总结,就像是在讲述一个完整的新闻故事)"
+ )
+
+ return ActionResponse(Action.REQLLM, detail_report, None)
+
+ # 否则,获取新闻列表并随机选择一条
+ # 从配置中获取RSS URL
+ rss_config = conn.config["plugins"]["get_news"]
+ default_rss_url = rss_config.get("default_rss_url", "https://www.chinanews.com.cn/rss/society.xml")
+
+ # 将用户输入的类别映射到配置中的类别键
+ mapped_category = map_category(category)
+
+ # 如果提供了类别,尝试从配置中获取对应的URL
+ rss_url = default_rss_url
+ if mapped_category and mapped_category in rss_config.get("category_urls", {}):
+ rss_url = rss_config["category_urls"][mapped_category]
+
+ logger.bind(tag=TAG).info(f"获取新闻: 原始类别={category}, 映射类别={mapped_category}, URL={rss_url}")
+
+ # 获取新闻列表
+ news_items = fetch_news_from_rss(rss_url)
+
+ if not news_items:
+ return ActionResponse(Action.REQLLM, "抱歉,未能获取到新闻信息,请稍后再试。", None)
+
+ # 随机选择一条新闻
+ selected_news = random.choice(news_items)
+
+ # 保存当前新闻链接到连接对象,以便后续查询详情
+ if not hasattr(conn, 'last_news_link'):
+ conn.last_news_link = {}
+ conn.last_news_link = {
+ 'link': selected_news.get('link', '#'),
+ 'title': selected_news.get('title', '未知标题')
+ }
+
+ # 构建新闻报告
+ news_report = (
+ f"根据下列数据,用{lang}回应用户的新闻查询请求:\n\n"
+ f"新闻标题: {selected_news['title']}\n"
+ f"发布时间: {selected_news['pubDate']}\n"
+ f"新闻内容: {selected_news['description']}\n"
+ f"(请以自然、流畅的方式向用户播报这条新闻,可以适当总结内容,"
+ f"直接读出新闻即可,不需要额外多余的内容。"
+ f"如果用户询问更多详情,告知用户可以说'请详细介绍这条新闻'获取更多内容)"
+ )
+
+ return ActionResponse(Action.REQLLM, news_report, None)
+
+ except Exception as e:
+ logger.bind(tag=TAG).error(f"获取新闻出错: {e}")
+ return ActionResponse(Action.REQLLM, "抱歉,获取新闻时发生错误,请稍后再试。", None)
\ No newline at end of file
From c45e1faf42715d73e4fd832a2f708f84c977c3d8 Mon Sep 17 00:00:00 2001
From: Huang <32005838+openrz@users.noreply.github.com>
Date: Thu, 20 Mar 2025 23:19:31 +0800
Subject: [PATCH 06/16] =?UTF-8?q?update:=E9=BB=98=E8=AE=A4=E5=BC=80?=
=?UTF-8?q?=E5=90=AF=E6=84=8F=E5=9B=BE=E8=AF=86=E5=88=AB=20(#460)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/xiaozhi-server/config.yaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml
index 8047bc38..587543dc 100644
--- a/main/xiaozhi-server/config.yaml
+++ b/main/xiaozhi-server/config.yaml
@@ -74,11 +74,11 @@ selected_module:
TTS: EdgeTTS
# 记忆模块,默认不开启记忆;如果想使用超长记忆,推荐使用mem0ai;如果注重隐私,请使用本地的mem_local_short
Memory: nomem
- # 意图识别模块,默认不开启。开启后,可以播放音乐、控制音量、识别退出指令
+ # 意图识别模块,默认使用function_call。开启后,可以播放音乐、控制音量、识别退出指令
# 意图识别使用intent_llm,优点:通用性强,缺点:增加串行前置意图识别模块,会增加处理时间
# 意图识别使用function_call,缺点:需要所选择的LLM支持function_call,优点:按需调用工具、速度快
- # 如果意图识别设置成 function_call,建议把LLM设置成:DoubaoLLM,使用的具体model_name是:doubao-pro-32k-functioncall-241028
- Intent: nointent
+ # 默认免费的ChatGLMLLM就已经支持function_call,但是如果像追求稳定建议把LLM设置成:DoubaoLLM,使用的具体model_name是:doubao-pro-32k-functioncall-241028
+ Intent: function_call
# 意图识别,是用于理解用户意图的模块,例如:播放音乐
Intent:
From 06cbffdea4d314df9e1b0af0913c1b0a7351d734 Mon Sep 17 00:00:00 2001
From: Miyokiss
Date: Fri, 21 Mar 2025 03:12:18 +0800
Subject: [PATCH 07/16] =?UTF-8?q?Add=EF=BC=9AAliAppLLM?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/xiaozhi-server/config.yaml | 12 +++++
.../core/providers/llm/AliBL/AliBL.py | 52 +++++++++++++++++++
2 files changed, 64 insertions(+)
create mode 100644 main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml
index 587543dc..75426572 100644
--- a/main/xiaozhi-server/config.yaml
+++ b/main/xiaozhi-server/config.yaml
@@ -165,6 +165,18 @@ LLM:
top_p: 1
top_k: 50
frequency_penalty: 0 # 频率惩罚
+ AliAppLLM:
+ # 定义LLM API类型
+ type: AliBL
+ base_url: https://dashscope.aliyuncs.com/compatible-mode/v1
+ app_id: 你的app_id
+ # 可在这里找到你的 api_key https://bailian.console.aliyun.com/?apiKey=1#/api-key
+ api_key: 你的api_key
+ # 是否不使用本地prompt:true|false (默不用请在百练应用中设置prompt)
+ is_No_prompt: true
+ # Ali_memory_id:false(不使用)|你的memory_id(请在百练应用中设置中获取)
+ # Tips!:Ali_memory未实现多用户存储记忆(记忆按id调用)
+ Ali_memory_id: false
DoubaoLLM:
# 定义LLM API类型
type: openai
diff --git a/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py b/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
new file mode 100644
index 00000000..074d8f8d
--- /dev/null
+++ b/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
@@ -0,0 +1,52 @@
+from config.logger import setup_logging
+from http import HTTPStatus
+from dashscope import Application
+from core.providers.llm.base import LLMProviderBase
+
+TAG = __name__
+logger = setup_logging()
+
+class LLMProvider(LLMProviderBase):
+ def __init__(self, config):
+ self.api_key = config["api_key"]
+ self.app_id = config["app_id"]
+ self.base_url = config.get("base_url")
+ self.is_No_prompt = config.get("is_No_prompt")
+ self.memory_id = config.get("Ali_memory_id")
+
+ def response(self, session_id, dialogue):
+ try:
+ # 处理dialogue
+ if self.is_No_prompt:
+ dialogue.pop(0)
+ logger.bind(tag=TAG).debug(f"【阿里百练API服务】处理后的dialogue: {dialogue}")
+
+ # 构造调用参数
+ call_params = {
+ "api_key": self.api_key,
+ "app_id": self.app_id,
+ "session_id": session_id,
+ "messages": dialogue
+ }
+ if self.memory_id != False:
+ # 百练memory需要prompt参数
+ prompt = dialogue[-1].get("content")
+ call_params["memory_id"] = self.memory_id
+ call_params["prompt"] = prompt
+ logger.bind(tag=TAG).debug(f"【阿里百练API服务】处理后的prompt: {prompt}")
+
+ responses = Application.call(**call_params)
+ if responses.status_code != HTTPStatus.OK:
+ logger.bind(tag=TAG).error(
+ f"code={responses.status_code}, "
+ f"message={responses.message}, "
+ f"请参考文档:https://help.aliyun.com/zh/model-studio/developer-reference/error-code"
+ )
+ yield "【阿里百练API服务响应异常】"
+ else:
+ logger.bind(tag=TAG).debug(f"【阿里百练API服务】构造参数: {call_params}")
+ yield responses.output.text
+
+ except Exception as e:
+ logger.bind(tag=TAG).error(f"【阿里百练API服务】响应异常: {e}")
+ yield "【LLM服务响应异常】"
\ No newline at end of file
From a1730b2d5289adad98f8ca5f42e5966028ba60c0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com>
Date: Fri, 21 Mar 2025 14:57:22 +0800
Subject: [PATCH 08/16] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=9F=B3=E8=89=B2?=
=?UTF-8?q?=E7=AE=A1=E7=90=86=E7=9A=84=E5=8A=9F=E8=83=BD=20--TimbreControl?=
=?UTF-8?q?ler.java=20=E9=9F=B3=E8=89=B2=E6=8E=A7=E5=88=B6=E5=B1=82?=
=?UTF-8?q?=EF=BC=8C=E6=B7=BB=E5=8A=A0=E4=BA=86=E5=88=86=E9=A1=B5=EF=BC=8C?=
=?UTF-8?q?=E5=88=A0=E9=99=A4=EF=BC=8C=E4=BF=9D=E5=AD=98=EF=BC=8C=E4=BF=AE?=
=?UTF-8?q?=E6=94=B9=E6=8E=A5=E5=8F=A3=20--TimbreDetailsVO.java=20?=
=?UTF-8?q?=E9=9F=B3=E8=89=B2=E8=AF=A6=E6=83=85=E5=B1=95=E7=A4=BA=E5=AF=B9?=
=?UTF-8?q?=E8=B1=A1=20--TimbrePageDTO.java=20=E9=9F=B3=E8=89=B2=E5=88=86?=
=?UTF-8?q?=E9=A1=B5=E5=8F=82=E6=95=B0=20--TimbreDataDTO.java=20=E9=9F=B3?=
=?UTF-8?q?=E8=89=B2=E4=BF=9D=E5=AD=98=E6=95=B0=E6=8D=AE=E5=8F=82=E6=95=B0?=
=?UTF-8?q?=20--TimbreDao.java=20=E9=9F=B3=E8=89=B2=E6=8C=81=E4=B9=85?=
=?UTF-8?q?=E5=AE=9A=E4=B9=89=20--TimbreService.java=20=E9=9F=B3=E8=89=B2?=
=?UTF-8?q?=E4=B8=9A=E5=8A=A1=E5=B1=82=E5=AE=9A=E4=B9=89=EF=BC=8C=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E4=BA=86=E5=88=86=E9=A1=B5=EF=BC=8C=E5=88=A0=E9=99=A4?=
=?UTF-8?q?=EF=BC=8C=E4=BF=9D=E5=AD=98=EF=BC=8C=E4=BF=AE=E6=94=B9=EF=BC=8C?=
=?UTF-8?q?=E8=8E=B7=E5=8F=96=E8=AF=A6=E6=83=85=20--TimbreServiceImpl.java?=
=?UTF-8?q?=20--TimbreEntity.java=20=E9=9F=B3=E8=89=B2=E8=A1=A8=E5=AF=B9?=
=?UTF-8?q?=E5=BA=94=E7=9A=84=E5=AE=9E=E4=BD=93?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Timbre/controller/TimbreController.java | 57 +++++++++++++
.../xiaozhi/modules/Timbre/dao/TimbreDao.java | 14 +++
.../modules/Timbre/dto/TimbreDataDTO.java | 36 ++++++++
.../modules/Timbre/dto/TimbrePageDTO.java | 26 ++++++
.../modules/Timbre/entity/TimbreEntity.java | 48 +++++++++++
.../modules/Timbre/service/TimbreService.java | 49 +++++++++++
.../service/impl/TimbreServiceImpl.java | 85 +++++++++++++++++++
.../modules/Timbre/vo/TimbreDetailsVO.java | 35 ++++++++
8 files changed, 350 insertions(+)
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/dao/TimbreDao.java
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/entity/TimbreEntity.java
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/TimbreService.java
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/impl/TimbreServiceImpl.java
create mode 100644 main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
new file mode 100644
index 00000000..41972f27
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
@@ -0,0 +1,57 @@
+package xiaozhi.modules.Timbre.controller;
+
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+import xiaozhi.common.page.PageData;
+import xiaozhi.common.utils.Result;
+import xiaozhi.modules.Timbre.dto.TimbreDataDTO;
+import xiaozhi.modules.Timbre.dto.TimbrePageDTO;
+import xiaozhi.modules.Timbre.service.TimbreService;
+import xiaozhi.modules.Timbre.vo.TimbreDetailsVO;
+
+/**
+ * 音色控制层
+ * @author zjy
+ * @since 2025-3-21
+ */
+@AllArgsConstructor
+@RestController
+@RequestMapping("/ttsVoice")
+@Tag(name = "音色管理")
+public class TimbreController {
+ private final TimbreService timbreService;
+
+ @GetMapping
+ @Operation(summary = "分页查找")
+// @RequiresPermissions("sys:role:normal")
+ public Result> page(@RequestParam TimbrePageDTO dto) {
+ PageData page = timbreService.page(dto);
+ return new Result>().ok(page);
+ }
+ @PostMapping
+ @Operation(summary = "音色保存")
+// @RequiresPermissions("sys:role:normal")
+ public Result save(@RequestBody TimbreDataDTO dto) {
+ timbreService.save(dto);
+ return new Result<>();
+ }
+ @PutMapping("/{id}")
+ @Operation(summary = "音色修改")
+// @RequiresPermissions("sys:role:normal")
+ public Result update(@PathVariable Long id,@RequestBody TimbreDataDTO dto) {
+ timbreService.update(id,dto);
+ return new Result<>();
+ }
+ @DeleteMapping("/{id}")
+ @Operation(summary = "音色删除")
+// @RequiresPermissions("sys:role:normal")
+ public Result delete(@PathVariable Long id) {
+ timbreService.delete(new Long[]{id});
+ return new Result<>();
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dao/TimbreDao.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dao/TimbreDao.java
new file mode 100644
index 00000000..d3273eed
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dao/TimbreDao.java
@@ -0,0 +1,14 @@
+package xiaozhi.modules.Timbre.dao;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import xiaozhi.modules.Timbre.entity.TimbreEntity;
+
+/**
+ * 音色持久层定义
+ * @author zjy
+ * @since 2025-3-21
+ */
+@Mapper
+public interface TimbreDao extends BaseMapper {
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
new file mode 100644
index 00000000..6ba7c47e
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
@@ -0,0 +1,36 @@
+package xiaozhi.modules.Timbre.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+
+/**
+ * 音色表数据DTO
+ * @author zjy
+ * @since 2025-3-21
+ */
+@Data
+@Schema(description = "音色表信息")
+public class TimbreDataDTO {
+
+ @Schema(description = "语言")
+ private String languages;
+
+ @Schema(description = "音色名称")
+ private String name;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "排序")
+ private long sort;
+
+ @Schema(description = "对应 TTS 模型主键")
+ private String ttsModelId;
+
+ @Schema(description = "音色编码")
+ private String ttsVoice;
+
+ @Schema(description = "音频播放地址")
+ private String voiceDemo;
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
new file mode 100644
index 00000000..958d6d47
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
@@ -0,0 +1,26 @@
+package xiaozhi.modules.Timbre.dto;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+/**
+ * 音色分页参数DTO
+ * @author zjy
+ * @since 2025-3-21
+ */
+@Data
+@Schema(description = "音色分页参数")
+public class TimbrePageDTO {
+
+ @Schema(description = "对应 TTS 模型主键")
+ private String ttsModelId;
+
+ @Schema(description = "音色名称")
+ private String name;
+
+ @Schema(description = "页数")
+ private Long page;
+
+ @Schema(description = "显示列数")
+ private Long limit;
+}
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/entity/TimbreEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/entity/TimbreEntity.java
new file mode 100644
index 00000000..23f71c59
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/entity/TimbreEntity.java
@@ -0,0 +1,48 @@
+package xiaozhi.modules.Timbre.entity;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import xiaozhi.common.entity.BaseEntity;
+
+import java.util.Date;
+
+/**
+ * 音色表实体类
+ * @author zjy
+ * @since 2025-3-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@TableName("ai_tts_voice")
+@Schema(description = "音色信息")
+public class TimbreEntity extends BaseEntity {
+
+ @Schema(description = "语言")
+ private String languages;
+
+ @Schema(description = "音色名称")
+ private String name;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "排序")
+ private long sort;
+
+ @Schema(description = "对应 TTS 模型主键")
+ private String ttsModelId;
+
+ @Schema(description = "音色编码")
+ private String ttsVoice;
+
+ @Schema(description = "音频播放地址")
+ private String voiceDemo;
+
+ @Schema(description = "更新者")
+ private Long updater;
+
+ @Schema(description = "更新时间")
+ private Date updateDate;
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/TimbreService.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/TimbreService.java
new file mode 100644
index 00000000..7166c9c3
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/TimbreService.java
@@ -0,0 +1,49 @@
+package xiaozhi.modules.Timbre.service;
+
+import xiaozhi.common.page.PageData;
+import xiaozhi.common.service.BaseService;
+import xiaozhi.modules.Timbre.dto.TimbreDataDTO;
+import xiaozhi.modules.Timbre.dto.TimbrePageDTO;
+import xiaozhi.modules.Timbre.entity.TimbreEntity;
+import xiaozhi.modules.Timbre.vo.TimbreDetailsVO;
+
+
+/**
+ * 音色的业务层的定义
+ * @author zjy
+ * @since 2025-3-21
+ */
+public interface TimbreService extends BaseService {
+ /**
+ * 分页获取音色指定tts的下的音色
+ * @param dto 分页查找参数
+ * @return 音色列表分页数据
+ */
+ PageData page(TimbrePageDTO dto);
+
+ /**
+ * 获取音色指定id的详情信息
+ * @param timbreId 音色表id
+ * @return 音色信息
+ */
+ TimbreDetailsVO get(Long timbreId);
+
+ /**
+ * 保存音色信息
+ * @param dto 需要保存数据
+ */
+ void save(TimbreDataDTO dto);
+
+ /**
+ * 保存音色信息
+ * @param timbreId 需要修改的id
+ * @param dto 需要修改的数据
+ */
+ void update(Long timbreId,TimbreDataDTO dto);
+
+ /**
+ * 批量删除音色
+ * @param ids 需要被删除的音色id列表
+ */
+ void delete(Long[] ids);
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/impl/TimbreServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/impl/TimbreServiceImpl.java
new file mode 100644
index 00000000..dddd0103
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/impl/TimbreServiceImpl.java
@@ -0,0 +1,85 @@
+package xiaozhi.modules.Timbre.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import xiaozhi.common.constant.Constant;
+import xiaozhi.common.page.PageData;
+import xiaozhi.common.service.impl.BaseServiceImpl;
+import xiaozhi.common.utils.ConvertUtils;
+import xiaozhi.modules.Timbre.dao.TimbreDao;
+import xiaozhi.modules.Timbre.dto.TimbreDataDTO;
+import xiaozhi.modules.Timbre.dto.TimbrePageDTO;
+import xiaozhi.modules.Timbre.service.TimbreService;
+import xiaozhi.modules.Timbre.entity.TimbreEntity;
+import xiaozhi.modules.Timbre.vo.TimbreDetailsVO;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 音色的业务层的实现
+ * @author zjy
+ * @since 2025-3-21
+ */
+@Service
+public class TimbreServiceImpl extends BaseServiceImpl implements TimbreService {
+
+
+ @Override
+ public PageData page(TimbrePageDTO dto) {
+ Map params = new HashMap();
+ params.put(Constant.PAGE, dto.getPage());
+ params.put(Constant.LIMIT,dto.getLimit());
+ IPage page = baseDao.selectPage(
+ getPage(params, "sort", true),
+ //定义查询条件
+ new QueryWrapper()
+ //必须按照ttsID查找
+ .eq("tts_model_id",dto.getTtsModelId())
+ //如果有音色名字,按照音色名模糊查找
+ .like(StringUtils.isNotBlank(dto.getName()),"name",dto.getName())
+ );
+
+ return getPageData(page, TimbreDetailsVO.class);
+ }
+
+ @Override
+ public TimbreDetailsVO get(Long timbreId) {
+ TimbreEntity entity = baseDao.selectById(timbreId);
+ return ConvertUtils.sourceToTarget(entity, TimbreDetailsVO.class);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void save(TimbreDataDTO dto) {
+ isTtsModelId(dto.getTtsModelId());
+ TimbreEntity timbreEntity = ConvertUtils.sourceToTarget(dto, TimbreEntity.class);
+ baseDao.insert(timbreEntity);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void update(Long timbreId, TimbreDataDTO dto) {
+ isTtsModelId(dto.getTtsModelId());
+ TimbreEntity timbreEntity = ConvertUtils.sourceToTarget(dto, TimbreEntity.class);
+ timbreEntity.setId(timbreId);
+ baseDao.updateById(timbreEntity);
+ }
+
+ @Override
+ @Transactional(rollbackFor = Exception.class)
+ public void delete(Long[] ids) {
+ baseDao.deleteBatchIds(Arrays.asList(ids));
+ }
+
+ /**
+ * 处理是不是tts模型的id
+ */
+ private void isTtsModelId(String ttsModelId){
+ //等模型配置那边写好调用方法判断
+ }
+}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
new file mode 100644
index 00000000..5384d356
--- /dev/null
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
@@ -0,0 +1,35 @@
+package xiaozhi.modules.Timbre.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+
+/**
+ * 音色详情展示VO
+ * @author zjy
+ * @since 2025-3-21
+ */
+public class TimbreDetailsVO {
+ @Schema(description = "音色id")
+ private Long id;
+
+ @Schema(description = "语言")
+ private String languages;
+
+ @Schema(description = "音色名称")
+ private String name;
+
+ @Schema(description = "备注")
+ private String remark;
+
+ @Schema(description = "排序")
+ private long sort;
+
+ @Schema(description = "对应 TTS 模型主键")
+ private String ttsModelId;
+
+ @Schema(description = "音色编码")
+ private String ttsVoice;
+
+ @Schema(description = "音频播放地址")
+ private String voiceDemo;
+
+}
From 4c99b40257f9557aa40fc2099451b8d18a337fc9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com>
Date: Fri, 21 Mar 2025 15:58:39 +0800
Subject: [PATCH 09/16] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E9=94=99=E8=AF=AF=20--?=
=?UTF-8?q?TimbreController.java=20=E4=BF=AE=E5=A4=8D=E5=88=86=E9=A1=B5?=
=?UTF-8?q?=E8=8E=B7=E5=8F=96=E4=B8=8D=E5=88=B0=E8=AF=B7=E6=B1=82=E5=8F=82?=
=?UTF-8?q?=E6=95=B0=E7=9A=84=E9=94=99=E8=AF=AF=20--TimbreDetailsVO.java?=
=?UTF-8?q?=20=E7=BB=9F=E4=B8=80=E5=88=86=E9=A1=B5=E5=8F=82=E6=95=B0?=
=?UTF-8?q?=E4=B8=BAstring=20--TimbrePageDTO.java=20=E5=BA=8F=E5=88=97?=
=?UTF-8?q?=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../xiaozhi/modules/Timbre/controller/TimbreController.java | 2 +-
.../main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java | 4 ++--
.../java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java | 6 +++++-
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
index 41972f27..4a3875e2 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
@@ -26,7 +26,7 @@ public class TimbreController {
@GetMapping
@Operation(summary = "分页查找")
// @RequiresPermissions("sys:role:normal")
- public Result> page(@RequestParam TimbrePageDTO dto) {
+ public Result> page(@ModelAttribute TimbrePageDTO dto) {
PageData page = timbreService.page(dto);
return new Result>().ok(page);
}
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
index 958d6d47..baa6416d 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
@@ -19,8 +19,8 @@ public class TimbrePageDTO {
private String name;
@Schema(description = "页数")
- private Long page;
+ private String page;
@Schema(description = "显示列数")
- private Long limit;
+ private String limit;
}
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
index 5384d356..2918af41 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
@@ -1,13 +1,17 @@
package xiaozhi.modules.Timbre.vo;
import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.io.Serializable;
/**
* 音色详情展示VO
* @author zjy
* @since 2025-3-21
*/
-public class TimbreDetailsVO {
+@Data
+public class TimbreDetailsVO implements Serializable {
@Schema(description = "音色id")
private Long id;
From a1e959420dd14d29f5644a3c2da9a258ed21affe Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com>
Date: Fri, 21 Mar 2025 16:07:17 +0800
Subject: [PATCH 10/16] =?UTF-8?q?=E4=B8=BA=E6=8E=A5=E5=8F=A3=E6=B7=BB?=
=?UTF-8?q?=E5=8A=A0=E6=9D=83=E9=99=90=E6=8E=A7=E5=88=B6=20--TimbreControl?=
=?UTF-8?q?ler.java=20=E6=B7=BB=E5=8A=A0=E6=9D=83=E9=99=90?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../modules/Timbre/controller/TimbreController.java | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
index 4a3875e2..766b13b6 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
@@ -3,6 +3,7 @@ package xiaozhi.modules.Timbre.controller;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
+import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.page.PageData;
import xiaozhi.common.utils.Result;
@@ -25,28 +26,28 @@ public class TimbreController {
@GetMapping
@Operation(summary = "分页查找")
-// @RequiresPermissions("sys:role:normal")
+ @RequiresPermissions("sys:ttsVoice:select")
public Result> page(@ModelAttribute TimbrePageDTO dto) {
PageData page = timbreService.page(dto);
return new Result>().ok(page);
}
@PostMapping
@Operation(summary = "音色保存")
-// @RequiresPermissions("sys:role:normal")
+ @RequiresPermissions("sys:ttsVoice:save")
public Result save(@RequestBody TimbreDataDTO dto) {
timbreService.save(dto);
return new Result<>();
}
@PutMapping("/{id}")
@Operation(summary = "音色修改")
-// @RequiresPermissions("sys:role:normal")
+ @RequiresPermissions("sys:ttsVoice:update")
public Result update(@PathVariable Long id,@RequestBody TimbreDataDTO dto) {
timbreService.update(id,dto);
return new Result<>();
}
@DeleteMapping("/{id}")
@Operation(summary = "音色删除")
-// @RequiresPermissions("sys:role:normal")
+ @RequiresPermissions("sys:ttsVoice:delete")
public Result delete(@PathVariable Long id) {
timbreService.delete(new Long[]{id});
return new Result<>();
From 7fe797d44dceb547e1dc198532b5497381aa821e Mon Sep 17 00:00:00 2001
From: sunweigong <2771605@qq.com>
Date: Fri, 21 Mar 2025 16:42:00 +0800
Subject: [PATCH 11/16] Update vue.config.js
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bug 修复:在启动manger-web连接服务端时,默认为8080端口。此处应按main/README.md文档说明,指定端口为 8001。
---
main/manager-web/vue.config.js | 1 +
1 file changed, 1 insertion(+)
diff --git a/main/manager-web/vue.config.js b/main/manager-web/vue.config.js
index 9e72e068..c10f5e55 100644
--- a/main/manager-web/vue.config.js
+++ b/main/manager-web/vue.config.js
@@ -7,6 +7,7 @@ dotenv.config();
module.exports = defineConfig({
devServer: {
// Bug 修复:将代理配置为环境变量中定义的 API 基础 URL
+ port: 8001, // 指定端口为 8001
proxy: {
'/xiaozhi-esp32-api': {
target: process.env.VUE_APP_API_BASE_URL || 'http://localhost:8002', // 后端 API 的基础 URL
From 36d13707209e166960ca3d5a22f9cd90986f0eee Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=89=91=E9=9B=A8?= <2375294554@qq.com>
Date: Fri, 21 Mar 2025 17:26:16 +0800
Subject: [PATCH 12/16] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BA=86=E8=AF=B7?=
=?UTF-8?q?=E6=B1=82=E5=8F=82=E6=95=B0=E9=AA=8C=E8=AF=81=20--TimbreControl?=
=?UTF-8?q?ler.java=20=E9=AA=8C=E8=AF=81=E5=8F=82=E6=95=B0=20--TimbreDataD?=
=?UTF-8?q?TO.java=20--TimbreDataDTO.java=20=E5=AE=9A=E4=B9=89=E5=8F=82?=
=?UTF-8?q?=E6=95=B0=E9=AA=8C=E8=AF=81=20--validation.properties=20--valid?=
=?UTF-8?q?ation=5Fen=5FUS.properties=20--validation=5Fzh=5FCN.properties?=
=?UTF-8?q?=20--validation=5Fzh=5FTW.properties=20=E5=AE=9A=E4=B9=89?=
=?UTF-8?q?=E5=8F=82=E6=95=B0=E9=AA=8C=E8=AF=81=E5=A4=B1=E8=B4=A5=E5=90=8E?=
=?UTF-8?q?=E7=9A=84=E9=94=99=E8=AF=AF=E8=AF=B4=E6=98=8E?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../modules/Timbre/controller/TimbreController.java | 8 +++++++-
.../java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java | 9 +++++++++
.../java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java | 2 ++
.../src/main/resources/i18n/validation.properties | 9 +++++++++
.../src/main/resources/i18n/validation_en_US.properties | 8 ++++++++
.../src/main/resources/i18n/validation_zh_CN.properties | 7 +++++++
.../src/main/resources/i18n/validation_zh_TW.properties | 7 +++++++
7 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
index 766b13b6..bba48abf 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
@@ -7,6 +7,7 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
import xiaozhi.common.page.PageData;
import xiaozhi.common.utils.Result;
+import xiaozhi.common.validator.ValidatorUtils;
import xiaozhi.modules.Timbre.dto.TimbreDataDTO;
import xiaozhi.modules.Timbre.dto.TimbrePageDTO;
import xiaozhi.modules.Timbre.service.TimbreService;
@@ -28,6 +29,7 @@ public class TimbreController {
@Operation(summary = "分页查找")
@RequiresPermissions("sys:ttsVoice:select")
public Result> page(@ModelAttribute TimbrePageDTO dto) {
+ ValidatorUtils.validateEntity(dto);
PageData page = timbreService.page(dto);
return new Result>().ok(page);
}
@@ -35,13 +37,17 @@ public class TimbreController {
@Operation(summary = "音色保存")
@RequiresPermissions("sys:ttsVoice:save")
public Result save(@RequestBody TimbreDataDTO dto) {
+ ValidatorUtils.validateEntity(dto);
timbreService.save(dto);
return new Result<>();
}
@PutMapping("/{id}")
@Operation(summary = "音色修改")
@RequiresPermissions("sys:ttsVoice:update")
- public Result update(@PathVariable Long id,@RequestBody TimbreDataDTO dto) {
+ public Result update(
+ @PathVariable Long id,
+ @RequestBody TimbreDataDTO dto) {
+ ValidatorUtils.validateEntity(dto);
timbreService.update(id,dto);
return new Result<>();
}
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
index 6ba7c47e..70d44df1 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
@@ -1,6 +1,8 @@
package xiaozhi.modules.Timbre.dto;
import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.Min;
+import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@@ -14,23 +16,30 @@ import lombok.Data;
public class TimbreDataDTO {
@Schema(description = "语言")
+ @NotBlank(message = "{timbre.languages.require}")
private String languages;
@Schema(description = "音色名称")
+ @NotBlank(message = "{timbre.name.require}")
private String name;
@Schema(description = "备注")
+ @NotBlank(message = "{timbre.remark.require}")
private String remark;
@Schema(description = "排序")
+ @Min(value = 0, message = "{sort.number}")
private long sort;
@Schema(description = "对应 TTS 模型主键")
+ @NotBlank(message = "{timbre.ttsModelId.require}")
private String ttsModelId;
@Schema(description = "音色编码")
+ @NotBlank(message = "{timbre.ttsVoice.require}")
private String ttsVoice;
@Schema(description = "音频播放地址")
+ @NotBlank(message = "{timbre.voiceDemo.require}")
private String voiceDemo;
}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
index baa6416d..55789c88 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
@@ -1,6 +1,7 @@
package xiaozhi.modules.Timbre.dto;
import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotBlank;
import lombok.Data;
/**
@@ -13,6 +14,7 @@ import lombok.Data;
public class TimbrePageDTO {
@Schema(description = "对应 TTS 模型主键")
+ @NotBlank(message = "{timbre.ttsModelId.require}")
private String ttsModelId;
@Schema(description = "音色名称")
diff --git a/main/manager-api/src/main/resources/i18n/validation.properties b/main/manager-api/src/main/resources/i18n/validation.properties
index 947f89cc..e7452e47 100644
--- a/main/manager-api/src/main/resources/i18n/validation.properties
+++ b/main/manager-api/src/main/resources/i18n/validation.properties
@@ -20,3 +20,12 @@ sysuser.deptId.require=\u90E8\u95E8\u4E0D\u80FD\u4E3A\u7A7A
sysuser.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1
sysuser.captcha.require=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A
sysuser.uuid.require=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A
+
+
+timbre.languages.require=\u97F3\u8272\u7684\u8BED\u8A00\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.name.require=\u97F3\u8272\u7684\u540D\u79F0\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.remark.require=\u97F3\u8272\u7684\u5907\u6CE8\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.ttsModelId.require=\u97F3\u8272\u7684tts\u4E3B\u952E\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.ttsVoice.require=\u97F3\u8272\u7684\u7F16\u7801\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.voiceDemo.require=\u97F3\u8272\u7684\u64AD\u653EDemo\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+
diff --git a/main/manager-api/src/main/resources/i18n/validation_en_US.properties b/main/manager-api/src/main/resources/i18n/validation_en_US.properties
index f8bb6e94..37bebf18 100644
--- a/main/manager-api/src/main/resources/i18n/validation_en_US.properties
+++ b/main/manager-api/src/main/resources/i18n/validation_en_US.properties
@@ -20,3 +20,11 @@ sysuser.deptId.require=Departments cannot be empty
sysuser.status.range=State ranges from 0 to 1
sysuser.captcha.require=The captcha cannot be empty
sysuser.uuid.require=The unique identifier cannot be empty
+
+timbre.languages.require=The language of the timbre cannot be empty
+timbre.name.require=The name of the timbre cannot be empty
+timbre.remark.require=The remark of the timbre cannot be empty
+timbre.ttsModelId.require=The TTS model ID of the timbre cannot be empty
+timbre.ttsVoice.require=The TTS voice of the timbre cannot be empty
+timbre.voiceDemo.require=The voice demo of the timbre cannot be empty
+
diff --git a/main/manager-api/src/main/resources/i18n/validation_zh_CN.properties b/main/manager-api/src/main/resources/i18n/validation_zh_CN.properties
index ba350d05..41bf1e69 100644
--- a/main/manager-api/src/main/resources/i18n/validation_zh_CN.properties
+++ b/main/manager-api/src/main/resources/i18n/validation_zh_CN.properties
@@ -21,3 +21,10 @@ sysuser.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1
sysuser.captcha.require=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A
sysuser.uuid.require=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A
+timbre.languages.require=\u97F3\u8272\u7684\u8A9E\u8A00\u4E0D\u53EF\u4EE5\u70BA\u7A7A
+timbre.name.require=\u97F3\u8272\u7684\u540D\u7A31\u4E0D\u53EF\u4EE5\u70BA\u7A7A
+timbre.remark.require=\u97F3\u8272\u7684\u5099\u6CE8\u4E0D\u53EF\u4EE5\u70BA\u7A7A
+timbre.ttsModelId.require=\u97F3\u8272\u7684tts\u4E3B\u9375\u4E0D\u53EF\u4EE5\u70BA\u7A7A
+timbre.ttsVoice.require=\u97F3\u8272\u7684\u7DE8\u78BC\u4E0D\u53EF\u4EE5\u70BA\u7A7A
+timbre.voiceDemo.require=\u97F3\u8272\u7684\u64AD\u653E\u5730\u5740\u4E0D\u53EF\u4EE5\u70BA\u7A7A
+
diff --git a/main/manager-api/src/main/resources/i18n/validation_zh_TW.properties b/main/manager-api/src/main/resources/i18n/validation_zh_TW.properties
index 947f89cc..9241c97a 100644
--- a/main/manager-api/src/main/resources/i18n/validation_zh_TW.properties
+++ b/main/manager-api/src/main/resources/i18n/validation_zh_TW.properties
@@ -20,3 +20,10 @@ sysuser.deptId.require=\u90E8\u95E8\u4E0D\u80FD\u4E3A\u7A7A
sysuser.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1
sysuser.captcha.require=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A
sysuser.uuid.require=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A
+
+timbre.languages.require=\u97F3\u8272\u7684\u8BED\u8A00\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.name.require=\u97F3\u8272\u7684\u540D\u79F0\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.remark.require=\u97F3\u8272\u7684\u5907\u6CE8\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.ttsModelId.require=\u97F3\u8272\u7684tts\u4E3B\u952E\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.ttsVoice.require=\u97F3\u8272\u7684\u7F16\u7801\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
+timbre.voiceDemo.require=\u97F3\u8272\u7684\u64AD\u653EDemo\u4E0D\u53EF\u4EE5\u4E3A\u7A7A
From 8bb0cf02ad2340d3de9631f88ef6b627ab1957c6 Mon Sep 17 00:00:00 2001
From: Huang <32005838+openrz@users.noreply.github.com>
Date: Fri, 21 Mar 2025 21:08:50 +0800
Subject: [PATCH 13/16] =?UTF-8?q?update:=E9=85=8D=E7=BD=AE=E5=AD=97?=
=?UTF-8?q?=E6=AE=B5=E7=BB=9F=E4=B8=80=E5=B0=8F=E5=86=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py b/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
index 074d8f8d..ec0fb939 100644
--- a/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
+++ b/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
@@ -12,7 +12,7 @@ class LLMProvider(LLMProviderBase):
self.app_id = config["app_id"]
self.base_url = config.get("base_url")
self.is_No_prompt = config.get("is_No_prompt")
- self.memory_id = config.get("Ali_memory_id")
+ self.memory_id = config.get("ali_memory_id")
def response(self, session_id, dialogue):
try:
@@ -49,4 +49,4 @@ class LLMProvider(LLMProviderBase):
except Exception as e:
logger.bind(tag=TAG).error(f"【阿里百练API服务】响应异常: {e}")
- yield "【LLM服务响应异常】"
\ No newline at end of file
+ yield "【LLM服务响应异常】"
From 8e605dd1d4cfb8e74ee8f82ab2d0f9d6b93fd5f0 Mon Sep 17 00:00:00 2001
From: Huang <32005838+openrz@users.noreply.github.com>
Date: Fri, 21 Mar 2025 21:09:32 +0800
Subject: [PATCH 14/16] =?UTF-8?q?update:=E9=85=8D=E7=BD=AE=E5=AD=97?=
=?UTF-8?q?=E6=AE=B5=E7=BB=9F=E4=B8=80=E5=B0=8F=E5=86=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/xiaozhi-server/config.yaml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml
index 75426572..ac62f988 100644
--- a/main/xiaozhi-server/config.yaml
+++ b/main/xiaozhi-server/config.yaml
@@ -173,10 +173,10 @@ LLM:
# 可在这里找到你的 api_key https://bailian.console.aliyun.com/?apiKey=1#/api-key
api_key: 你的api_key
# 是否不使用本地prompt:true|false (默不用请在百练应用中设置prompt)
- is_No_prompt: true
+ is_no_prompt: true
# Ali_memory_id:false(不使用)|你的memory_id(请在百练应用中设置中获取)
# Tips!:Ali_memory未实现多用户存储记忆(记忆按id调用)
- Ali_memory_id: false
+ ali_memory_id: false
DoubaoLLM:
# 定义LLM API类型
type: openai
From 69630c2be044500c2af35d6ee7bf93ad671f5706 Mon Sep 17 00:00:00 2001
From: Huang <32005838+openrz@users.noreply.github.com>
Date: Fri, 21 Mar 2025 21:09:54 +0800
Subject: [PATCH 15/16] =?UTF-8?q?update:=E9=85=8D=E7=BD=AE=E5=AD=97?=
=?UTF-8?q?=E6=AE=B5=E7=BB=9F=E4=B8=80=E5=B0=8F=E5=86=99?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py b/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
index ec0fb939..51efdc06 100644
--- a/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
+++ b/main/xiaozhi-server/core/providers/llm/AliBL/AliBL.py
@@ -11,7 +11,7 @@ class LLMProvider(LLMProviderBase):
self.api_key = config["api_key"]
self.app_id = config["app_id"]
self.base_url = config.get("base_url")
- self.is_No_prompt = config.get("is_No_prompt")
+ self.is_No_prompt = config.get("is_no_prompt")
self.memory_id = config.get("ali_memory_id")
def response(self, session_id, dialogue):
From ec6ab983f7d9b8e64b8add2d1e5e99eac49a60b3 Mon Sep 17 00:00:00 2001
From: hrz <1710360675@qq.com>
Date: Fri, 21 Mar 2025 21:44:40 +0800
Subject: [PATCH 16/16] =?UTF-8?q?udate:=E8=A7=84=E8=8C=83=E5=8C=85?=
=?UTF-8?q?=E5=90=8D=EF=BC=8C=E5=B0=8F=E5=86=99=E5=8C=85=E5=90=8D?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../modules/security/oauth2/Oauth2Realm.java | 3 +-
.../security/service/ShiroService.java | 8 ----
.../service/impl/ShiroServiceImpl.java | 16 -------
.../controller/TimbreController.java | 45 ++++++++++++++-----
.../{Timbre => timbre}/dao/TimbreDao.java | 4 +-
.../{Timbre => timbre}/dto/TimbreDataDTO.java | 2 +-
.../{Timbre => timbre}/dto/TimbrePageDTO.java | 2 +-
.../entity/TimbreEntity.java | 2 +-
.../service/TimbreService.java | 10 ++---
.../service/impl/TimbreServiceImpl.java | 14 +++---
.../vo/TimbreDetailsVO.java | 2 +-
11 files changed, 53 insertions(+), 55 deletions(-)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/controller/TimbreController.java (51%)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/dao/TimbreDao.java (73%)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/dto/TimbreDataDTO.java (97%)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/dto/TimbrePageDTO.java (94%)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/entity/TimbreEntity.java (96%)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/service/TimbreService.java (80%)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/service/impl/TimbreServiceImpl.java (88%)
rename main/manager-api/src/main/java/xiaozhi/modules/{Timbre => timbre}/vo/TimbreDetailsVO.java (95%)
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java b/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java
index b7d6c278..6b04bb08 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/security/oauth2/Oauth2Realm.java
@@ -19,6 +19,7 @@ import xiaozhi.modules.security.service.ShiroService;
import xiaozhi.modules.sys.entity.SysUserEntity;
import xiaozhi.modules.sys.enums.SuperAdminEnum;
+import java.util.HashSet;
import java.util.Set;
/**
@@ -47,7 +48,7 @@ public class Oauth2Realm extends AuthorizingRealm {
UserDetail user = (UserDetail) principals.getPrimaryPrincipal();
//用户权限列表
- Set permsSet = shiroService.getUserPermissions(user);
+ Set permsSet = new HashSet<>();
if (user.getSuperAdmin() == SuperAdminEnum.YES.value()) {
permsSet.add("sys:role:superAdmin");
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/service/ShiroService.java b/main/manager-api/src/main/java/xiaozhi/modules/security/service/ShiroService.java
index 980645d6..b9d18889 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/security/service/ShiroService.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/security/service/ShiroService.java
@@ -1,22 +1,14 @@
package xiaozhi.modules.security.service;
-import xiaozhi.common.user.UserDetail;
import xiaozhi.modules.security.entity.SysUserTokenEntity;
import xiaozhi.modules.sys.entity.SysUserEntity;
-import java.util.List;
-import java.util.Set;
-
/**
* shiro相关接口
* Copyright (c) 人人开源 All rights reserved.
* Website: https://www.renren.io
*/
public interface ShiroService {
- /**
- * 获取用户权限列表
- */
- Set getUserPermissions(UserDetail user);
SysUserTokenEntity getByToken(String token);
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/ShiroServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/ShiroServiceImpl.java
index 128d9b9d..97d16eaa 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/ShiroServiceImpl.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/security/service/impl/ShiroServiceImpl.java
@@ -19,22 +19,6 @@ public class ShiroServiceImpl implements ShiroService {
private final SysUserDao sysUserDao;
private final SysUserTokenDao sysUserTokenDao;
- @Override
- public Set getUserPermissions(UserDetail user) {
- //系统管理员,拥有最高权限
- // TODO: 暂时写死,后续改成从数据库查询
- List permissionsList = new ArrayList<>();
- //用户权限列表
- Set permsSet = new HashSet<>();
- for (String permissions : permissionsList) {
- if (StringUtils.isBlank(permissions)) {
- continue;
- }
- permsSet.addAll(Arrays.asList(permissions.trim().split(",")));
- }
-
- return permsSet;
- }
@Override
public SysUserTokenEntity getByToken(String token) {
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/controller/TimbreController.java
similarity index 51%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/controller/TimbreController.java
index bba48abf..dc6ccca7 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/controller/TimbreController.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/controller/TimbreController.java
@@ -1,20 +1,26 @@
-package xiaozhi.modules.Timbre.controller;
+package xiaozhi.modules.timbre.controller;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.AllArgsConstructor;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.web.bind.annotation.*;
+import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.PageData;
import xiaozhi.common.utils.Result;
import xiaozhi.common.validator.ValidatorUtils;
-import xiaozhi.modules.Timbre.dto.TimbreDataDTO;
-import xiaozhi.modules.Timbre.dto.TimbrePageDTO;
-import xiaozhi.modules.Timbre.service.TimbreService;
-import xiaozhi.modules.Timbre.vo.TimbreDetailsVO;
+import xiaozhi.modules.timbre.dto.TimbreDataDTO;
+import xiaozhi.modules.timbre.dto.TimbrePageDTO;
+import xiaozhi.modules.timbre.service.TimbreService;
+import xiaozhi.modules.timbre.vo.TimbreDetailsVO;
+
+import java.util.Map;
/**
* 音色控制层
+ *
* @author zjy
* @since 2025-3-21
*/
@@ -27,38 +33,53 @@ public class TimbreController {
@GetMapping
@Operation(summary = "分页查找")
- @RequiresPermissions("sys:ttsVoice:select")
- public Result> page(@ModelAttribute TimbrePageDTO dto) {
+ @RequiresPermissions("sys:role:superAdmin")
+ @Parameters({
+ @Parameter(name = "ttsModelId", description = "对应 TTS 模型主键", required = true),
+ @Parameter(name = "name", description = "音色名称"),
+ @Parameter(name = Constant.PAGE, description = "当前页码,从1开始", required = true),
+ @Parameter(name = Constant.LIMIT, description = "每页显示记录数", required = true),
+ })
+ public Result> page(
+ @Parameter(hidden = true) @RequestParam Map params) {
+ TimbrePageDTO dto = new TimbrePageDTO();
+ dto.setTtsModelId((String) params.get("ttsModelId"));
+ dto.setName((String) params.get("name"));
+ dto.setLimit((String) params.get(Constant.LIMIT));
+ dto.setPage((String) params.get(Constant.PAGE));
+
ValidatorUtils.validateEntity(dto);
PageData page = timbreService.page(dto);
return new Result>().ok(page);
}
+
@PostMapping
@Operation(summary = "音色保存")
- @RequiresPermissions("sys:ttsVoice:save")
+ @RequiresPermissions("sys:role:superAdmin")
public Result save(@RequestBody TimbreDataDTO dto) {
ValidatorUtils.validateEntity(dto);
timbreService.save(dto);
return new Result<>();
}
+
@PutMapping("/{id}")
@Operation(summary = "音色修改")
- @RequiresPermissions("sys:ttsVoice:update")
+ @RequiresPermissions("sys:role:superAdmin")
public Result update(
@PathVariable Long id,
@RequestBody TimbreDataDTO dto) {
ValidatorUtils.validateEntity(dto);
- timbreService.update(id,dto);
+ timbreService.update(id, dto);
return new Result<>();
}
+
@DeleteMapping("/{id}")
@Operation(summary = "音色删除")
- @RequiresPermissions("sys:ttsVoice:delete")
+ @RequiresPermissions("sys:role:superAdmin")
public Result delete(@PathVariable Long id) {
timbreService.delete(new Long[]{id});
return new Result<>();
}
-
}
\ No newline at end of file
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dao/TimbreDao.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/dao/TimbreDao.java
similarity index 73%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/dao/TimbreDao.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/dao/TimbreDao.java
index d3273eed..62afa358 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dao/TimbreDao.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/dao/TimbreDao.java
@@ -1,8 +1,8 @@
-package xiaozhi.modules.Timbre.dao;
+package xiaozhi.modules.timbre.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
-import xiaozhi.modules.Timbre.entity.TimbreEntity;
+import xiaozhi.modules.timbre.entity.TimbreEntity;
/**
* 音色持久层定义
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/dto/TimbreDataDTO.java
similarity index 97%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/dto/TimbreDataDTO.java
index 70d44df1..08ed9b18 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbreDataDTO.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/dto/TimbreDataDTO.java
@@ -1,4 +1,4 @@
-package xiaozhi.modules.Timbre.dto;
+package xiaozhi.modules.timbre.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Min;
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/dto/TimbrePageDTO.java
similarity index 94%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/dto/TimbrePageDTO.java
index 55789c88..72ed68b1 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/dto/TimbrePageDTO.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/dto/TimbrePageDTO.java
@@ -1,4 +1,4 @@
-package xiaozhi.modules.Timbre.dto;
+package xiaozhi.modules.timbre.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/entity/TimbreEntity.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/entity/TimbreEntity.java
similarity index 96%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/entity/TimbreEntity.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/entity/TimbreEntity.java
index 23f71c59..71bd58a9 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/entity/TimbreEntity.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/entity/TimbreEntity.java
@@ -1,4 +1,4 @@
-package xiaozhi.modules.Timbre.entity;
+package xiaozhi.modules.timbre.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/TimbreService.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/TimbreService.java
similarity index 80%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/TimbreService.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/service/TimbreService.java
index 7166c9c3..9b6c73eb 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/TimbreService.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/TimbreService.java
@@ -1,11 +1,11 @@
-package xiaozhi.modules.Timbre.service;
+package xiaozhi.modules.timbre.service;
import xiaozhi.common.page.PageData;
import xiaozhi.common.service.BaseService;
-import xiaozhi.modules.Timbre.dto.TimbreDataDTO;
-import xiaozhi.modules.Timbre.dto.TimbrePageDTO;
-import xiaozhi.modules.Timbre.entity.TimbreEntity;
-import xiaozhi.modules.Timbre.vo.TimbreDetailsVO;
+import xiaozhi.modules.timbre.dto.TimbreDataDTO;
+import xiaozhi.modules.timbre.dto.TimbrePageDTO;
+import xiaozhi.modules.timbre.entity.TimbreEntity;
+import xiaozhi.modules.timbre.vo.TimbreDetailsVO;
/**
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/impl/TimbreServiceImpl.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/impl/TimbreServiceImpl.java
similarity index 88%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/impl/TimbreServiceImpl.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/service/impl/TimbreServiceImpl.java
index dddd0103..ce3c2b7b 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/service/impl/TimbreServiceImpl.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/service/impl/TimbreServiceImpl.java
@@ -1,4 +1,4 @@
-package xiaozhi.modules.Timbre.service.impl;
+package xiaozhi.modules.timbre.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -9,12 +9,12 @@ import xiaozhi.common.constant.Constant;
import xiaozhi.common.page.PageData;
import xiaozhi.common.service.impl.BaseServiceImpl;
import xiaozhi.common.utils.ConvertUtils;
-import xiaozhi.modules.Timbre.dao.TimbreDao;
-import xiaozhi.modules.Timbre.dto.TimbreDataDTO;
-import xiaozhi.modules.Timbre.dto.TimbrePageDTO;
-import xiaozhi.modules.Timbre.service.TimbreService;
-import xiaozhi.modules.Timbre.entity.TimbreEntity;
-import xiaozhi.modules.Timbre.vo.TimbreDetailsVO;
+import xiaozhi.modules.timbre.dao.TimbreDao;
+import xiaozhi.modules.timbre.dto.TimbreDataDTO;
+import xiaozhi.modules.timbre.dto.TimbrePageDTO;
+import xiaozhi.modules.timbre.service.TimbreService;
+import xiaozhi.modules.timbre.entity.TimbreEntity;
+import xiaozhi.modules.timbre.vo.TimbreDetailsVO;
import java.util.Arrays;
import java.util.HashMap;
diff --git a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java b/main/manager-api/src/main/java/xiaozhi/modules/timbre/vo/TimbreDetailsVO.java
similarity index 95%
rename from main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
rename to main/manager-api/src/main/java/xiaozhi/modules/timbre/vo/TimbreDetailsVO.java
index 2918af41..fc82a5d0 100644
--- a/main/manager-api/src/main/java/xiaozhi/modules/Timbre/vo/TimbreDetailsVO.java
+++ b/main/manager-api/src/main/java/xiaozhi/modules/timbre/vo/TimbreDetailsVO.java
@@ -1,4 +1,4 @@
-package xiaozhi.modules.Timbre.vo;
+package xiaozhi.modules.timbre.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;