From 224d59d50d549c3d818631b647e27fade275307e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A3=E5=8D=97=E7=A7=91=E6=8A=80?= Date: Mon, 10 Mar 2025 15:56:28 +0800 Subject: [PATCH 01/14] =?UTF-8?q?fix:=E5=A3=B0=E9=9F=B3=E5=8D=A1=E9=A1=BF?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20(#262)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hrz <1710360675@qq.com> --- docs/Deployment.md | 14 +++++------ .../core/handle/sendAudioHandle.py | 25 +++++++++++++------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/docs/Deployment.md b/docs/Deployment.md index 97a11c84..0dfd93b5 100644 --- a/docs/Deployment.md +++ b/docs/Deployment.md @@ -93,7 +93,7 @@ docker logs -f xiaozhi-esp32-server ``` docker stop xiaozhi-esp32-server docker rm xiaozhi-esp32-server -docker rmi ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:latest +docker rmi ghcr.nju.edu.cn/xinnan-tech/xiaozhi-esp32-server:server_latest ``` 3、重新按docker方式部署 @@ -299,14 +299,14 @@ LLM: 以下是一些常见问题,供参考: -[1、为什么我说的话,小智识别出来很多韩文、日文、英文](../README.md#1tts-%E7%BB%8F%E5%B8%B8%E5%A4%B1%E8%B4%A5%E7%BB%8F%E5%B8%B8%E8%B6%85%E6%97%B6-) +[1、为什么我说的话,小智识别出来很多韩文、日文、英文](../README.md#1%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E8%AF%B4%E7%9A%84%E8%AF%9D%E5%B0%8F%E6%99%BA%E8%AF%86%E5%88%AB%E5%87%BA%E6%9D%A5%E5%BE%88%E5%A4%9A%E9%9F%A9%E6%96%87%E6%97%A5%E6%96%87%E8%8B%B1%E6%96%87) -[2、为什么会出现“TTS 任务出错 文件不存在”?](../README.md#1tts-%E7%BB%8F%E5%B8%B8%E5%A4%B1%E8%B4%A5%E7%BB%8F%E5%B8%B8%E8%B6%85%E6%97%B6-) +[2、为什么会出现“TTS 任务出错 文件不存在”?](../README.md#1%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E8%AF%B4%E7%9A%84%E8%AF%9D%E5%B0%8F%E6%99%BA%E8%AF%86%E5%88%AB%E5%87%BA%E6%9D%A5%E5%BE%88%E5%A4%9A%E9%9F%A9%E6%96%87%E6%97%A5%E6%96%87%E8%8B%B1%E6%96%87) -[3、TTS 经常失败,经常超时](../README.md#1tts-%E7%BB%8F%E5%B8%B8%E5%A4%B1%E8%B4%A5%E7%BB%8F%E5%B8%B8%E8%B6%85%E6%97%B6-) +[3、TTS 经常失败,经常超时](../README.md#1%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E8%AF%B4%E7%9A%84%E8%AF%9D%E5%B0%8F%E6%99%BA%E8%AF%86%E5%88%AB%E5%87%BA%E6%9D%A5%E5%BE%88%E5%A4%9A%E9%9F%A9%E6%96%87%E6%97%A5%E6%96%87%E8%8B%B1%E6%96%87) -[4、如何提高小智对话响应速度?](../README.md#1tts-%E7%BB%8F%E5%B8%B8%E5%A4%B1%E8%B4%A5%E7%BB%8F%E5%B8%B8%E8%B6%85%E6%97%B6-) +[4、如何提高小智对话响应速度?](../README.md#1%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E8%AF%B4%E7%9A%84%E8%AF%9D%E5%B0%8F%E6%99%BA%E8%AF%86%E5%88%AB%E5%87%BA%E6%9D%A5%E5%BE%88%E5%A4%9A%E9%9F%A9%E6%96%87%E6%97%A5%E6%96%87%E8%8B%B1%E6%96%87) -[5、我说话很慢,停顿时小智老是抢话](../README.md#1tts-%E7%BB%8F%E5%B8%B8%E5%A4%B1%E8%B4%A5%E7%BB%8F%E5%B8%B8%E8%B6%85%E6%97%B6-) +[5、我说话很慢,停顿时小智老是抢话](../README.md#1%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E8%AF%B4%E7%9A%84%E8%AF%9D%E5%B0%8F%E6%99%BA%E8%AF%86%E5%88%AB%E5%87%BA%E6%9D%A5%E5%BE%88%E5%A4%9A%E9%9F%A9%E6%96%87%E6%97%A5%E6%96%87%E8%8B%B1%E6%96%87) -[6、我想通过小智控制电灯、空调、远程开关机等操作](../README.md#1tts-%E7%BB%8F%E5%B8%B8%E5%A4%B1%E8%B4%A5%E7%BB%8F%E5%B8%B8%E8%B6%85%E6%97%B6-) +[6、我想通过小智控制电灯、空调、远程开关机等操作](../README.md#1%E4%B8%BA%E4%BB%80%E4%B9%88%E6%88%91%E8%AF%B4%E7%9A%84%E8%AF%9D%E5%B0%8F%E6%99%BA%E8%AF%86%E5%88%AB%E5%87%BA%E6%9D%A5%E5%BE%88%E5%A4%9A%E9%9F%A9%E6%96%87%E6%97%A5%E6%96%87%E8%8B%B1%E6%96%87) diff --git a/main/xiaozhi-server/core/handle/sendAudioHandle.py b/main/xiaozhi-server/core/handle/sendAudioHandle.py index 1cce98b4..8999bf08 100644 --- a/main/xiaozhi-server/core/handle/sendAudioHandle.py +++ b/main/xiaozhi-server/core/handle/sendAudioHandle.py @@ -13,28 +13,37 @@ async def sendAudioMessage(conn, audios, text, text_index=0): logger.bind(tag=TAG).info(f"发送第一段语音: {text}") await send_tts_message(conn, "sentence_start", text) - # 初始化流控参数 - frame_duration = 60 # 毫秒 - start_time = time.perf_counter() # 使用高精度计时器 - play_position = 0 # 已播放的时长(毫秒) + # 流控参数优化 + original_frame_duration = 60 # 原始帧时长(毫秒) + adjusted_frame_duration = int(original_frame_duration * 0.8) # 缩短20% + total_frames = len(audios) # 获取总帧数 + compensation = total_frames * (original_frame_duration - adjusted_frame_duration) / 1000 # 补偿时间(秒) + + start_time = time.perf_counter() + play_position = 0 # 已播放时长(毫秒) for opus_packet in audios: if conn.client_abort: return - # 计算当前包的预期发送时间 + # 计算带加速因子的预期时间 expected_time = start_time + (play_position / 1000) current_time = time.perf_counter() - # 等待直到预期时间 + # 流控等待(使用加速后的帧时长) delay = expected_time - current_time if delay > 0: await asyncio.sleep(delay) - # 发送音频包 await conn.websocket.send(opus_packet) - play_position += frame_duration # 更新播放位置 + play_position += adjusted_frame_duration # 使用调整后的帧时长 + + # 补偿因加速损失的时长 + if compensation > 0: + await asyncio.sleep(compensation) + await send_tts_message(conn, "sentence_end", text) + # 发送结束消息(如果是最后一个文本) if conn.llm_finish_task and text_index == conn.tts_last_text_index: await send_tts_message(conn, 'stop', None) From 16601a67e334f8e183c39be73dd44cef93e9aaf2 Mon Sep 17 00:00:00 2001 From: CGD <3030332422@qq.com> Date: Mon, 10 Mar 2025 18:21:59 +0800 Subject: [PATCH 02/14] =?UTF-8?q?=E5=AE=8C=E6=88=90=E8=A7=A3=E7=BB=91?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20(#264)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/manager-web/src/apis/module/user.js | 15 ++++++ main/manager-web/src/utils/constant.js | 3 ++ main/manager-web/src/views/home.vue | 66 +++++++++++++++++++----- 3 files changed, 70 insertions(+), 14 deletions(-) diff --git a/main/manager-web/src/apis/module/user.js b/main/manager-web/src/apis/module/user.js index b59959cd..7a6815b2 100755 --- a/main/manager-web/src/apis/module/user.js +++ b/main/manager-web/src/apis/module/user.js @@ -43,4 +43,19 @@ export default { }) }).send() }, + // 解绑设备 + unbindDevice(device_id, callback) { + RequestService.sendRequest() + .url(`${getServiceUrl()}/api/v1/user/device/unbind/${device_id}`) + .method('PUT') + .success((res) => { + RequestService.clearRequestTime(); + callback(res); + }) + .fail(() => { + RequestService.reAjaxFun(() => { + this.unbindDevice(device_id, callback); + }); + }).send() + }, } diff --git a/main/manager-web/src/utils/constant.js b/main/manager-web/src/utils/constant.js index f34abb32..460ea8ef 100755 --- a/main/manager-web/src/utils/constant.js +++ b/main/manager-web/src/utils/constant.js @@ -1,6 +1,9 @@ const HAVE_NO_RESULT = '暂无' export default { HAVE_NO_RESULT, // 项目的配置信息 + PAGE: { + LOGIN: '/login', + }, STORAGE_KEY: { TOKEN: 'TOKEN', PUBLIC_KEY: 'PUBLIC_KEY', diff --git a/main/manager-web/src/views/home.vue b/main/manager-web/src/views/home.vue index 12ab7689..2ed345d6 100644 --- a/main/manager-web/src/views/home.vue +++ b/main/manager-web/src/views/home.vue @@ -21,9 +21,9 @@
- + + style="width: 12px;height: 12px;margin-right: 11px;cursor: pointer;" @click="handleSearch" />
-
-
+ style="display: flex;flex-wrap: wrap;margin-top: 15px;gap: 15px;justify-content: flex-start;box-sizing: border-box;"> +
+
{{item.list[0]?.mac_address}}
-
+
+ style="width: 18px;height: 18px;margin-right: 8px;" @click="unbindDevice(item.list[0]?.id)" />
@@ -229,7 +229,9 @@ export default { name: 'home', data() { return { - serach: '', + serach: '', // 搜索框输入内容 + deviceList: [], // 原始设备列表 + filteredDeviceList: [], // 过滤后的设备列表 switchValue: false, addDeviceDialogVisible: false, deviceCode: "", @@ -250,8 +252,7 @@ export default { }], userInfo: { mobile: '' // 初始化用户信息 - }, - deviceList:[] + } }; }, methods: { @@ -270,14 +271,51 @@ export default { // 获取已绑设备 getList(){ Api.user.getHomeList(({data})=>{ - console.log(data.data) - this.deviceList = data.data + this.deviceList = data.data; // 保存原始设备列表 + this.filteredDeviceList = data.data; // 初始化过滤后的设备列表 }) - } + }, + // 处理搜索 + handleSearch() { + if (this.serach.trim() === '') { + // 如果搜索框为空,显示全部设备 + this.filteredDeviceList = this.deviceList; + } else { + // 过滤设备列表 + this.filteredDeviceList = this.deviceList.filter(device => { + return ( + device.list[0]?.mac_address?.includes(this.serach) || // 匹配MAC地址 + device.list[0]?.device_type?.includes(this.serach) || // 匹配设备型号 + device.list[0]?.app_version?.includes(this.serach) // 匹配APP版本 + ); + }); + } + }, + // 解绑设备 + unbindDevice(device_id) { + this.$confirm('确定要解绑该设备吗?', '提示', { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning' + }).then(() => { + // 调用解绑设备的接口 + Api.user.unbindDevice(device_id, ({ data }) => { + if (data.code === 0) { + this.$message.success('解绑成功'); + this.getList(); + } else { + this.$message.error(data.msg || '解绑失败'); + } + }); + }).catch(() => { + // 用户取消操作 + this.$message.info('已取消解绑'); + }); + }, }, mounted() { this.fetchUserInfo(); // 组件加载时获取用户信息 - this.getList() + this.getList(); // 初始化设备列表 } } From 7b266ad7c071747830a6d028fb4601e6932d9d30 Mon Sep 17 00:00:00 2001 From: CGD <3030332422@qq.com> Date: Mon, 10 Mar 2025 18:29:08 +0800 Subject: [PATCH 03/14] =?UTF-8?q?=E5=AE=8C=E6=88=90=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=BC=80=E5=8F=91=20(#263)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: 欣南科技 From 4f3fae81c19730b71c4db02d2685c04c7f1564c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A3=E5=8D=97=E7=A7=91=E6=8A=80?= Date: Mon, 10 Mar 2025 22:45:03 +0800 Subject: [PATCH 04/14] =?UTF-8?q?fix:=E4=BF=AE=E5=A4=8D=E9=95=BF=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E4=B8=8D=E8=AF=B4=E8=AF=9D=E5=85=B3=E9=97=AD=E6=84=8F?= =?UTF-8?q?=E5=9B=BEbug=20(#267)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hrz <1710360675@qq.com> --- main/xiaozhi-server/core/handle/receiveAudioHandle.py | 1 + 1 file changed, 1 insertion(+) diff --git a/main/xiaozhi-server/core/handle/receiveAudioHandle.py b/main/xiaozhi-server/core/handle/receiveAudioHandle.py index 97624898..e97c17ca 100644 --- a/main/xiaozhi-server/core/handle/receiveAudioHandle.py +++ b/main/xiaozhi-server/core/handle/receiveAudioHandle.py @@ -70,5 +70,6 @@ async def no_voice_close_connect(conn): if no_voice_time > 1000 * close_connection_no_voice_time: conn.client_abort = False conn.asr_server_receive = False + conn.close_after_chat = True prompt = "时间过得真快,我都好久没说话了。请你用十个字左右话跟我告别,以“再见”或“拜拜”为结尾" await startToChat(conn, prompt) From 2b662d3a14d8eb35777887fdcb7581e509d7ade9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A3=E5=8D=97=E7=A7=91=E6=8A=80?= Date: Tue, 11 Mar 2025 00:25:33 +0800 Subject: [PATCH 05/14] fix:function call bug (#268) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 优化function call消息处理 * fix:用户说话重复记录bug * 2025-3-10-优化llm intent (#254) Co-authored-by: 欣南科技 * update:回复上版提示词,无需再二次识别歌曲名 --------- Co-authored-by: 玄凤科技 Co-authored-by: hrz <1710360675@qq.com> Co-authored-by: Jiao Haoyang <108573524+XuSenfeng@users.noreply.github.com> --- main/xiaozhi-server/core/connection.py | 129 +++++++++++------- .../core/handle/intentHandler.py | 6 +- .../core/handle/receiveAudioHandle.py | 6 +- .../core/providers/intent/base.py | 5 +- .../providers/intent/intent_llm/intent_llm.py | 5 +- .../providers/intent/nointent/nointent.py | 4 +- .../core/providers/llm/ollama/ollama.py | 24 +--- .../core/providers/llm/openai/openai.py | 24 +--- main/xiaozhi-server/core/utils/util.py | 9 ++ 9 files changed, 106 insertions(+), 106 deletions(-) diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 570c3105..80c62336 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -11,7 +11,7 @@ import websockets from typing import Dict, Any from core.utils.dialogue import Message, Dialogue from core.handle.textHandle import handleTextMessage -from core.utils.util import get_string_no_punctuation_or_emoji +from core.utils.util import get_string_no_punctuation_or_emoji, extract_json_from_string from concurrent.futures import ThreadPoolExecutor, TimeoutError from core.handle.sendAudioHandle import sendAudioMessage from core.handle.receiveAudioHandle import handleAudioMessage @@ -307,8 +307,7 @@ class ConnectionHandler: response_message = [] processed_chars = 0 # 跟踪已处理的字符位置 - function_call_data = None # 存储function call数据 - + try: start_time = time.time() @@ -316,7 +315,7 @@ class ConnectionHandler: future = asyncio.run_coroutine_threadsafe(self.memory.query_memory(query), self.loop) memory_str = future.result() - # self.logger.bind(tag=TAG).info(f"记忆内容: {memory_str}") + #self.logger.bind(tag=TAG).info(f"对话记录: {self.dialogue.get_llm_dialogue_with_memory(memory_str)}") # 使用支持functions的streaming接口 llm_responses = self.llm.response_with_functions( @@ -332,48 +331,61 @@ class ConnectionHandler: text_index = 0 # 处理流式响应 + tool_call_flag = False + function_name = None + function_id = None + function_arguments = "" + content_arguments = "" for response in llm_responses: - if response["type"] == "content": - content = response["content"] - response_message.append(content) + content, tools_call = response + if content is not None and len(content)>0: + if len(response_message)<=0 and content=="```": + tool_call_flag = True - if self.client_abort: - break + if tools_call is not None: + tool_call_flag = True + if tools_call[0].id is not None: + function_id = tools_call[0].id + if tools_call[0].function.name is not None: + function_name = tools_call[0].function.name + if tools_call[0].function.arguments is not None: + function_arguments += tools_call[0].function.arguments - end_time = time.time() - self.logger.bind(tag=TAG).debug(f"大模型返回时间: {end_time - start_time} 秒, 生成token={content}") + if content is not None and len(content) > 0: + if tool_call_flag: + content_arguments+=content + else: + response_message.append(content) - # 处理文本分段和TTS逻辑 - # 合并当前全部文本并处理未分割部分 - full_text = "".join(response_message) - current_text = full_text[processed_chars:] # 从未处理的位置开始 + if self.client_abort: + break - # 查找最后一个有效标点 - punctuations = ("。", "?", "!", ";", ":") - last_punct_pos = -1 - for punct in punctuations: - pos = current_text.rfind(punct) - if pos > last_punct_pos: - last_punct_pos = pos + end_time = time.time() + self.logger.bind(tag=TAG).debug(f"大模型返回时间: {end_time - start_time} 秒, 生成token={content}") - # 找到分割点则处理 - if last_punct_pos != -1: - segment_text_raw = current_text[:last_punct_pos + 1] - segment_text = get_string_no_punctuation_or_emoji(segment_text_raw) - if segment_text: - text_index += 1 - self.recode_first_last_text(segment_text, text_index) - future = self.executor.submit(self.speak_and_play, segment_text, text_index) - self.tts_queue.put(future) - processed_chars += len(segment_text_raw) # 更新已处理字符位置 + # 处理文本分段和TTS逻辑 + # 合并当前全部文本并处理未分割部分 + full_text = "".join(response_message) + current_text = full_text[processed_chars:] # 从未处理的位置开始 - elif response["type"] == "function_call": - # Extract function call data - function_call_data = { - "name": response["function_call"]["function"]["name"], - "arguments": response["function_call"]["function"]["arguments"] - } - self.logger.bind(tag=TAG).info(f"Function call detected: {function_call_data}") + # 查找最后一个有效标点 + punctuations = ("。", "?", "!", ";", ":") + last_punct_pos = -1 + for punct in punctuations: + pos = current_text.rfind(punct) + if pos > last_punct_pos: + last_punct_pos = pos + + # 找到分割点则处理 + if last_punct_pos != -1: + segment_text_raw = current_text[:last_punct_pos + 1] + segment_text = get_string_no_punctuation_or_emoji(segment_text_raw) + if segment_text: + text_index += 1 + self.recode_first_last_text(segment_text, text_index) + future = self.executor.submit(self.speak_and_play, segment_text, text_index) + self.tts_queue.put(future) + processed_chars += len(segment_text_raw) # 更新已处理字符位置 # 处理最后剩余的文本 full_text = "".join(response_message) @@ -387,23 +399,46 @@ class ConnectionHandler: self.tts_queue.put(future) # 存储对话内容 - self.dialogue.put(Message(role="assistant", content="".join(response_message))) + if len(response_message)>0: + self.dialogue.put(Message(role="assistant", content="".join(response_message))) # 处理function call - if function_call_data: + if tool_call_flag: + if function_id is None: + a = extract_json_from_string(content_arguments) + if a is not None: + content_arguments_json = json.loads(a) + function_name = content_arguments_json["function_name"] + function_arguments = json.dumps(content_arguments_json["args"], ensure_ascii=False) + function_id = str(uuid.uuid4().hex) + else: + return [] + function_arguments = json.loads(function_arguments) + self.logger.bind(tag=TAG).info(f"function_name={function_name}, function_id={function_id}, function_arguments={function_arguments}") + function_call_data = { + "name": function_name, + "id": function_id, + "arguments": function_arguments + } result = handle_llm_function_call(self, function_call_data) - if result.action == Action.RESPONSE: - text = result.response - text_index += 1 - self.recode_first_last_text(text, text_index) - future = self.executor.submit(self.speak_and_play, text, text_index) - self.tts_queue.put(future) + self._handle_function_result(result, function_call_data, text_index+1) self.llm_finish_task = True self.logger.bind(tag=TAG).debug(json.dumps(self.dialogue.get_llm_dialogue(), indent=4, ensure_ascii=False)) return True + def _handle_function_result(self, result, function_call_data, text_index): + if result.action == Action.RESPONSE: # 直接回复前端 + text = result.response + self.recode_first_last_text(text, text_index) + future = self.executor.submit(self.speak_and_play, text, text_index) + self.tts_queue.put(future) + self.dialogue.put(Message(role="assistant", content=text)) + if result.action == Action.REQLLM: # 调用函数后再请求llm生成回复 + text = result.response + + def _tts_priority_thread(self): while not self.stop_event.is_set(): text = None diff --git a/main/xiaozhi-server/core/handle/intentHandler.py b/main/xiaozhi-server/core/handle/intentHandler.py index cae22b2c..2dde6255 100644 --- a/main/xiaozhi-server/core/handle/intentHandler.py +++ b/main/xiaozhi-server/core/handle/intentHandler.py @@ -122,12 +122,10 @@ async def analyze_intent_with_llm(conn, text): logger.bind(tag=TAG).warning("意图识别服务未初始化") return None - # 创建对话历史记录 + # 对话历史记录 dialogue = conn.dialogue - dialogue.put(Message(role="user", content=text)) - try: - intent_result = await conn.intent.detect_intent(dialogue.dialogue) + intent_result = await conn.intent.detect_intent(dialogue.dialogue, text) logger.bind(tag=TAG).info(f"意图识别结果: {intent_result}") # 尝试解析JSON结果 diff --git a/main/xiaozhi-server/core/handle/receiveAudioHandle.py b/main/xiaozhi-server/core/handle/receiveAudioHandle.py index e97c17ca..bf6d4c36 100644 --- a/main/xiaozhi-server/core/handle/receiveAudioHandle.py +++ b/main/xiaozhi-server/core/handle/receiveAudioHandle.py @@ -67,9 +67,9 @@ async def no_voice_close_connect(conn): else: no_voice_time = time.time() * 1000 - conn.client_no_voice_last_time close_connection_no_voice_time = conn.config.get("close_connection_no_voice_time", 120) - if no_voice_time > 1000 * close_connection_no_voice_time: + if not conn.close_after_chat and no_voice_time > 1000 * close_connection_no_voice_time: + conn.close_after_chat = True conn.client_abort = False conn.asr_server_receive = False - conn.close_after_chat = True - prompt = "时间过得真快,我都好久没说话了。请你用十个字左右话跟我告别,以“再见”或“拜拜”为结尾" + prompt = "请你以“时间过得真快”未来头,用富有感情、依依不舍的话来结束这场对话吧。" await startToChat(conn, prompt) diff --git a/main/xiaozhi-server/core/providers/intent/base.py b/main/xiaozhi-server/core/providers/intent/base.py index 1333f620..9726f1be 100644 --- a/main/xiaozhi-server/core/providers/intent/base.py +++ b/main/xiaozhi-server/core/providers/intent/base.py @@ -5,6 +5,7 @@ from config.logger import setup_logging TAG = __name__ logger = setup_logging() + class IntentProviderBase(ABC): def __init__(self, config): self.config = config @@ -17,9 +18,9 @@ class IntentProviderBase(ABC): def set_llm(self, llm): self.llm = llm logger.bind(tag=TAG).debug("Set LLM for intent provider") - + @abstractmethod - async def detect_intent(self, dialogue_history: List[Dict]) -> str: + async def detect_intent(self, dialogue_history: List[Dict], text: str) -> str: """ 检测用户最后一句话的意图 Args: diff --git a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py index c3930296..191f73df 100644 --- a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py +++ b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py @@ -37,7 +37,7 @@ class IntentProvider(IntentProviderBase): ) return prompt - async def detect_intent(self, dialogue_history: List[Dict]) -> str: + async def detect_intent(self, dialogue_history: List[Dict], text:str) -> str: if not self.llm: raise ValueError("LLM provider not set") @@ -48,9 +48,8 @@ class IntentProvider(IntentProviderBase): msgStr += f"User: {msg.content}\n" elif msg.role== "assistant": msgStr += f"Assistant: {msg.content}\n" - + msgStr += f"User: {text}\n" user_prompt = f"请分析用户的意图:\n{msgStr}" - # 使用LLM进行意图识别 intent = self.llm.response_no_stream( system_prompt=self.promot, diff --git a/main/xiaozhi-server/core/providers/intent/nointent/nointent.py b/main/xiaozhi-server/core/providers/intent/nointent/nointent.py index 9feadaad..70ea96fb 100644 --- a/main/xiaozhi-server/core/providers/intent/nointent/nointent.py +++ b/main/xiaozhi-server/core/providers/intent/nointent/nointent.py @@ -5,12 +5,14 @@ from config.logger import setup_logging TAG = __name__ logger = setup_logging() + class IntentProvider(IntentProviderBase): - async def detect_intent(self, dialogue_history: List[Dict]) -> str: + async def detect_intent(self, dialogue_history: List[Dict], text: str) -> str: """ 默认的意图识别实现,始终返回继续聊天 Args: dialogue_history: 对话历史记录列表 + text: 本次对话记录 Returns: 固定返回"继续聊天" """ diff --git a/main/xiaozhi-server/core/providers/llm/ollama/ollama.py b/main/xiaozhi-server/core/providers/llm/ollama/ollama.py index 86d0f6ee..aa5184a4 100644 --- a/main/xiaozhi-server/core/providers/llm/ollama/ollama.py +++ b/main/xiaozhi-server/core/providers/llm/ollama/ollama.py @@ -51,30 +51,8 @@ class LLMProvider(LLMProviderBase): tools=functions, ) - current_function_call = None - current_content = "" - for chunk in stream: - delta = chunk.choices[0].delta - - if delta.content: - current_content += delta.content - yield {"type": "content", "content": delta.content} - - if delta.tool_calls: - tool_call = delta.tool_calls[0] - # Handle the function call data using proper attribute access - if not current_function_call: - current_function_call = { - "function": { - "name": tool_call.function.name, - "arguments": tool_call.function.arguments - } - } - - if current_function_call: - logger.bind(tag=TAG).debug(f"ollama Function call detected: {current_function_call}") - yield {"type": "function_call", "function_call": current_function_call} + yield chunk.choices[0].delta.content, chunk.choices[0].delta.tool_calls except Exception as e: logger.bind(tag=TAG).error(f"Error in Ollama function call: {e}") diff --git a/main/xiaozhi-server/core/providers/llm/openai/openai.py b/main/xiaozhi-server/core/providers/llm/openai/openai.py index 33ef10eb..95cd85f9 100644 --- a/main/xiaozhi-server/core/providers/llm/openai/openai.py +++ b/main/xiaozhi-server/core/providers/llm/openai/openai.py @@ -53,30 +53,8 @@ class LLMProvider(LLMProviderBase): tools=functions, ) - current_function_call = None - current_content = "" - for chunk in stream: - delta = chunk.choices[0].delta - - if delta.content: - current_content += delta.content - yield {"type": "content", "content": delta.content} - - if delta.tool_calls: - tool_call = delta.tool_calls[0] - # Handle the function call data using proper attribute access - if not current_function_call: - current_function_call = { - "function": { - "name": tool_call.function.name, - "arguments": tool_call.function.arguments - } - } - - if current_function_call: - logger.bind(tag=TAG).debug(f"openai Function call detected: {current_function_call}") - yield {"type": "function_call", "function_call": current_function_call} + yield chunk.choices[0].delta.content, chunk.choices[0].delta.tool_calls except Exception as e: self.logger.bind(tag=TAG).error(f"Error in function call streaming: {e}") diff --git a/main/xiaozhi-server/core/utils/util.py b/main/xiaozhi-server/core/utils/util.py index 8a8dac95..60b98665 100644 --- a/main/xiaozhi-server/core/utils/util.py +++ b/main/xiaozhi-server/core/utils/util.py @@ -4,6 +4,7 @@ import yaml import socket import subprocess import logging +import re def get_project_dir(): @@ -119,3 +120,11 @@ def check_ffmpeg_installed(): error_msg += "1、按照项目的安装文档,正确进入conda环境\n" error_msg += "2、查阅安装文档,如何在conda环境中安装ffmpeg\n" raise ValueError(error_msg) + +def extract_json_from_string(input_string): + """提取字符串中的 JSON 部分""" + pattern = r'(\{.*\})' + match = re.search(pattern, input_string) + if match: + return match.group(1) # 返回提取的 JSON 字符串 + return None \ No newline at end of file From 7d737ad3122fba0009a2634fc2db71cf83c2e4c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A3=E5=8D=97=E7=A7=91=E6=8A=80?= Date: Tue, 11 Mar 2025 17:28:33 +0800 Subject: [PATCH 06/14] =?UTF-8?q?update:=E5=A2=9E=E5=8A=A0=E5=BC=80?= =?UTF-8?q?=E5=8F=91=E8=80=85=E8=B4=A1=E7=8C=AE=E6=8C=87=E5=8D=97=20(#279)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hrz <1710360675@qq.com> --- README.md | 2 ++ docs/contributor_open_letter.md | 51 +++++++++++++++++++++++++++++++++ main/README.md | 2 +- 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 docs/contributor_open_letter.md diff --git a/README.md b/README.md index ece6f772..57c8241a 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,8 @@ - [小智安卓端](https://github.com/TOM88812/xiaozhi-android-client) - [小智电脑端](https://github.com/Huang-junsen/py-xiaozhi) +如果你是一名软件开发者,这里有一份[《致开发者的公开信》](docs/contributor_open_letter.md),欢迎加入! + --- ## 警告 ⚠️ diff --git a/docs/contributor_open_letter.md b/docs/contributor_open_letter.md new file mode 100644 index 00000000..1be3da28 --- /dev/null +++ b/docs/contributor_open_letter.md @@ -0,0 +1,51 @@ +# 致开发者的公开信 + +"春江水暖鸭先知,正是河豚欲上时!" + +亲爱的朋友,今天,我怀着无比真挚的心情,向热爱AI技术与创新的你发出这封公开信。 + +我们的开源项目 **xiaozhi-esp32-server** 正处在发展的阶段,它承载着我们对智能硬件和低成本民用贾维斯解决方案的美好憧憬,也希望借助每一位开发者的智慧,共同开创技术的新局面。 + +## 项目目标 + +1. **民用低成本贾维斯解决方案** + +2. **智能联动周边硬件的解决方案** + +## 加入我们 + +我们热忱欢迎志同道合的朋友加入,共同为项目贡献力量。参与方式如下: + +### 1、成为普通贡献者 + +Fork 项目,提交 PR,由开发者审核后合入主分支。 + +### 2、成为开发者 + +当你累计提交 3 次有效 PR 后,可以联系群主申请成为开发者,群主将邀请你加入独立的开发者群,共同探讨项目未来。 + +## 开发者开发流程 + +1. **创建新分支** + 每个功能点请以新分支方式开发,分支名称应简洁明了,让人一眼看出所实现的功能,避免功能撞车。 + +2. **提交 PR 审核** + 功能开发完成后,请在 GitHub 上提交 PR,由其他开发者审核,审核通过后合并入主分支。 + +## 功能点的来源 + +- **创新的点子与功能** + 你的每一个灵感都可能成为项目的突破点,欢迎大胆提出前沿的创意与功能建议。 + +- **代码优化** + 如果你发现代码中存在改进的空间,欢迎提交优化方案,让我们的代码更加高效、易读。 + +- **解决 Issues 问题** + Issues 中有很多问题需要解决,我们一同完善、打造产品。 + +亲爱的开发者们, +每一次提交、每一份建议,都是对我们共同梦想的加持。每一代人有每一代人的使命,让我们共同书写智能生活的新篇章! + +期待与你携手前行,共创未来。 + +John,2025.3.11,广州 \ No newline at end of file diff --git a/main/README.md b/main/README.md index 2e164954..6f330023 100644 --- a/main/README.md +++ b/main/README.md @@ -3,7 +3,7 @@ # 项目目录介绍 当你看到这份文件的时候,这个这个项目还没完善好。我们还有很多东西要做。 -如果你会开发,我们非常欢迎您的加入。 +如果你是一名软件开发者,这里有一份[《致开发者的公开信》](../docs/contributor_open_letter.md),欢迎归队! ``` xiaozhi-esp32-server From 442eef36baba5f9583c1483487e084af2e63ccb6 Mon Sep 17 00:00:00 2001 From: gitjianyu <57935053+gitjianyu@users.noreply.github.com> Date: Tue, 11 Mar 2025 20:58:37 +0800 Subject: [PATCH 07/14] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20(#277)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 改正自定义错误编码和i18n国际化错误说明对应 --ErrorCode.java 自定义编码 --messages.properties 默认错误说明 --messages_en_US.properties 英文错误说明 --messages_zh_CN.properties 中文简体说明 --messages_zh_TW.properties 中文繁体说明 * i18n国际化剔除自定义参数验证不符合条件的情况说明 --validation.properties 默认说明 --validation_en_US.properties 英文说明 --validation_zh_CN.properties 中文简体说明 --validation_zh_TW.properties 中文繁体说明 --- .../xiaozhi/common/exception/ErrorCode.java | 8 +- .../main/resources/i18n/messages.properties | 25 +--- .../resources/i18n/messages_en_US.properties | 36 ++--- .../resources/i18n/messages_zh_CN.properties | 36 ++--- .../resources/i18n/messages_zh_TW.properties | 36 ++--- .../main/resources/i18n/validation.properties | 97 +------------- .../i18n/validation_en_US.properties | 98 +------------- .../i18n/validation_zh_CN.properties | 96 +------------- .../i18n/validation_zh_TW.properties | 124 +++--------------- 9 files changed, 64 insertions(+), 492 deletions(-) diff --git a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java index 1c1c09f5..e2e5de5d 100644 --- a/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java +++ b/main/manager-api/src/main/java/xiaozhi/common/exception/ErrorCode.java @@ -22,24 +22,24 @@ public interface ErrorCode { int CAPTCHA_ERROR = 10007; int SUB_MENU_EXIST = 10008; int PASSWORD_ERROR = 10009; + int SUPERIOR_DEPT_ERROR = 10011; int SUPERIOR_MENU_ERROR = 10012; int DATA_SCOPE_PARAMS_ERROR = 10013; int DEPT_SUB_DELETE_ERROR = 10014; int DEPT_USER_DELETE_ERROR = 10015; + int UPLOAD_FILE_EMPTY = 10019; int TOKEN_NOT_EMPTY = 10020; int TOKEN_INVALID = 10021; int ACCOUNT_LOCK = 10022; + int OSS_UPLOAD_FILE_ERROR = 10024; + int REDIS_ERROR = 10027; int JOB_ERROR = 10028; int INVALID_SYMBOL = 10029; - - // 密码相关错误码 int PASSWORD_LENGTH_ERROR = 10030; int PASSWORD_WEAK_ERROR = 10031; int DEL_MYSELF_ERROR = 10032; - // 验证码错误 - int VERIFICATION_CODE = 10033; } diff --git a/main/manager-api/src/main/resources/i18n/messages.properties b/main/manager-api/src/main/resources/i18n/messages.properties index c4e78e94..53851b2d 100644 --- a/main/manager-api/src/main/resources/i18n/messages.properties +++ b/main/manager-api/src/main/resources/i18n/messages.properties @@ -9,7 +9,6 @@ 10005=\u8D26\u53F7\u5DF2\u88AB\u505C\u7528 10006=\u552F\u4E00\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A 10007=\u9A8C\u8BC1\u7801\u4E0D\u6B63\u786E -10008=\u5148\u5220\u9664\u5B50\u83DC\u5355\u6216\u6309\u94AE 10009=\u539F\u5BC6\u7801\u4E0D\u6B63\u786E 10010=\u8D26\u53F7\u6216\u5BC6\u7801\u4E0D\u6B63\u786E,\u60A8\u8FD8\u6709\u53EF\u4EE5\u5C1D\u8BD5{0}\u6B21 10011=\u4E0A\u7EA7\u90E8\u95E8\u9009\u62E9\u9519\u8BEF @@ -31,24 +30,6 @@ 10027=Redis\u670D\u52A1\u5F02\u5E38 10028=\u5B9A\u65F6\u4EFB\u52A1\u5931\u8D25 10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26 -10030=\u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u8BF7\u4F7F\u7528JSON\u683C\u5F0F -10031=\u8BF7\u5148\u5B8C\u6210\u77ED\u4FE1\u914D\u7F6E -10032=\u4EFB\u52A1\u5DF2\u88AB\u7B7E\u6536\uFF0C\u64CD\u4F5C\u5931\u8D25 -10033=\u4E0D\u5B58\u5728\u7684\u6D41\u7A0B\u5B9A\u4E49 -10034=\u4E0A\u7EA7\u8282\u70B9\u4E0D\u5B58\u5728 -10035=\u9A73\u56DE -10036=\u56DE\u9000 -10037=\u4EFB\u52A1\u6CA1\u6709\u5206\u7EC4\uFF0C\u65E0\u6CD5\u53D6\u6D88\u8BA4\u9886 -10038=\u4E0A\u7EA7\u533A\u57DF\u9009\u62E9\u9519\u8BEF -10039=\u8BF7\u5148\u5220\u9664\u4E0B\u7EA7\u533A\u57DF -10040=\u6D41\u7A0B\u5DF2\u6302\u8D77\uFF0C\u4E0D\u80FD\u542F\u52A8\u5B9E\u4F8B -10041=\u591A\u5B9E\u4F8B\u4EFB\u52A1\u4E0D\u80FD\u9A73\u56DE -10042=\u5B58\u5728\u591A\u4E2A\u5904\u7406\u4E2D\u7684\u4EFB\u52A1\uFF0C\u4E0D\u80FD\u9A73\u56DE -10043=\u591A\u5B9E\u4F8B\u4EFB\u52A1\u4E0D\u80FD\u7EC8\u6B62 -10044=\u5B58\u5728\u591A\u4E2A\u5904\u7406\u4E2D\u7684\u4EFB\u52A1\uFF0C\u4E0D\u80FD\u7EC8\u6B62\u6D41\u7A0B -10045=\u7EC8\u6B62 -10046=\u591A\u5B9E\u4F8B\u4EFB\u52A1\u4E0D\u80FD\u56DE\u9000 -10047=\u5B58\u5728\u591A\u4E2A\u5E76\u884C\u6267\u884C\u7684\u4EFB\u52A1\uFF0C\u4E0D\u80FD\u56DE\u9000 -10048=\u767B\u5F55\u8D26\u53F7\uFF0C\u65E0\u6743\u5220\u9664 -10055=\u60A8\u7684\u5BC6\u7801\u957F\u5EA6\u4E0D\u591F8\u4F4D -10056=\u60A8\u7684\u5BC6\u7801\u590D\u6742\u5EA6\u4E0D\u591F\uFF0C\u9700\u8981\u540C\u65F6\u5305\u542B\u6570\u5B57,\u5C0F\u5199\u82F1\u6587,\u5927\u5199\u82F1\u6587 \ No newline at end of file +10030=\u5BC6\u7801\u957F\u5EA6\u4E0D\u8DB3{0}\u4F4D +10031=\u5F31\u5BC6\u7801 +10032=\u5220\u9664\u672C\u6570\u636E\u5F02\u5E38 diff --git a/main/manager-api/src/main/resources/i18n/messages_en_US.properties b/main/manager-api/src/main/resources/i18n/messages_en_US.properties index 573e038a..1c7208c0 100644 --- a/main/manager-api/src/main/resources/i18n/messages_en_US.properties +++ b/main/manager-api/src/main/resources/i18n/messages_en_US.properties @@ -11,44 +11,24 @@ 10007=The verification code is incorrect 10008=First delete submenu or button 10009=The original password is incorrect -10010=password error,you can try {0} times + 10011=The superior department made a wrong choice 10012=Upper menu cannot be for itself 10013=Data permission interface, which can only be a Map type parameter. 10014=Please delete the subordinate department first 10015=Please delete the user under the department first -10016=Deployment failed, no process -10017=Model diagram is incorrect, please check -10018=The export failed with the model ID {0} + 10019=Please upload a file 10020=token cannot be empty 10021=token is invalid, please log in again 10022=The account has been locked -10023=Please upload zip, bar, bpmn, bpmn20.xml format file + 10024=Failed to upload file {0} -10025=Failed to send SMS {0} -10026=Mail template does not exist + 10027=Redis service exception 10028=Timed task failed 10029=Cannot contain illegal characters -10030=The parameter format is incorrect. Please use JSON format. -10031=Please complete the SMS configuration first. -10032=Task has been signed and operation failed -10033=Non-existent process definition -10034=Superior node does not exist -10035=Reject -10036=Rollback -10037=Tasks are not grouped and cannot be cancelled -10038=Upper area selection error -10039=Please delete the subordinate area first -10040=The process has been suspended and the instance cannot be started -10041=Multi-instance tasks cannot be rejected -10042=Tasks in multiple processes cannot be rejected -10043=Multi-instance tasks cannot be terminated -10044=There are tasks in multiple processes that cannot terminate the process -10045=END -10046=Multi-instance tasks cannot be rolled back -10047=There are multiple parallel tasks that cannot be rolled back -10048 = Login account, no right to delete -10055=Your password length is less than 8 digits -10056=Your password is not complex enough and needs to include both numbers, lowercase English, and uppercase English \ No newline at end of file + +10030=The password is less than {0} digits. +10031=Weak password. The password must contain {0} of uppercase letters, lowercase letters, symbols and numbers. +10032=Exception in deleting this data diff --git a/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties b/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties index de062fd4..dde25078 100644 --- a/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties +++ b/main/manager-api/src/main/resources/i18n/messages_zh_CN.properties @@ -2,6 +2,7 @@ 500=\u670D\u52A1\u5668\u5185\u90E8\u5F02\u5E38 401=\u672A\u6388\u6743 403=\u62D2\u7EDD\u8BBF\u95EE\uFF0C\u6CA1\u6709\u6743\u9650 + 10001={0}\u4E0D\u80FD\u4E3A\u7A7A 10002=\u6570\u636E\u5E93\u4E2D\u5DF2\u5B58\u5728\u8BE5\u8BB0\u5F55 10003=\u83B7\u53D6\u53C2\u6570\u5931\u8D25 @@ -11,44 +12,23 @@ 10007=\u9A8C\u8BC1\u7801\u4E0D\u6B63\u786E 10008=\u5148\u5220\u9664\u5B50\u83DC\u5355\u6216\u6309\u94AE 10009=\u539F\u5BC6\u7801\u4E0D\u6B63\u786E -10010=\u8D26\u53F7\u6216\u5BC6\u7801\u4E0D\u6B63\u786E,\u60A8\u8FD8\u6709\u53EF\u4EE5\u5C1D\u8BD5{0}\u6B21 + 10011=\u4E0A\u7EA7\u90E8\u95E8\u9009\u62E9\u9519\u8BEF 10012=\u4E0A\u7EA7\u83DC\u5355\u4E0D\u80FD\u4E3A\u81EA\u8EAB 10013=\u6570\u636E\u6743\u9650\u63A5\u53E3\uFF0C\u53EA\u80FD\u662FMap\u7C7B\u578B\u53C2\u6570 10014=\u8BF7\u5148\u5220\u9664\u4E0B\u7EA7\u90E8\u95E8 10015=\u8BF7\u5148\u5220\u9664\u90E8\u95E8\u4E0B\u7684\u7528\u6237 -10016=\u90E8\u7F72\u5931\u8D25\uFF0C\u6CA1\u6709\u6D41\u7A0B -10017=\u6A21\u578B\u56FE\u4E0D\u6B63\u786E\uFF0C\u8BF7\u68C0\u67E5 -10018=\u5BFC\u51FA\u5931\u8D25\uFF0C\u6A21\u578BID\u4E3A{0} + 10019=\u8BF7\u4E0A\u4F20\u6587\u4EF6 10020=token\u4E0D\u80FD\u4E3A\u7A7A 10021=token\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 10022=\u8D26\u53F7\u5DF2\u88AB\u9501\u5B9A -10023=\u8BF7\u4E0A\u4F20zip\u3001bar\u3001bpmn\u3001bpmn20.xml\u683C\u5F0F\u6587\u4EF6 + 10024=\u4E0A\u4F20\u6587\u4EF6\u5931\u8D25{0} -10025=\u53D1\u9001\u77ED\u4FE1\u5931\u8D25{0} -10026=\u90AE\u4EF6\u6A21\u677F\u4E0D\u5B58\u5728 + 10027=Redis\u670D\u52A1\u5F02\u5E38 10028=\u5B9A\u65F6\u4EFB\u52A1\u5931\u8D25 10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26 -10030=\u53C2\u6570\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u8BF7\u4F7F\u7528JSON\u683C\u5F0F -10031=\u8BF7\u5148\u5B8C\u6210\u77ED\u4FE1\u914D\u7F6E -10032=\u4EFB\u52A1\u5DF2\u88AB\u7B7E\u6536\uFF0C\u64CD\u4F5C\u5931\u8D25 -10033=\u4E0D\u5B58\u5728\u7684\u6D41\u7A0B\u5B9A\u4E49 -10034=\u4E0A\u7EA7\u8282\u70B9\u4E0D\u5B58\u5728 -10035=\u9A73\u56DE -10036=\u56DE\u9000 -10037=\u4EFB\u52A1\u6CA1\u6709\u5206\u7EC4\uFF0C\u65E0\u6CD5\u53D6\u6D88\u8BA4\u9886 -10038=\u4E0A\u7EA7\u533A\u57DF\u9009\u62E9\u9519\u8BEF -10039=\u8BF7\u5148\u5220\u9664\u4E0B\u7EA7\u533A\u57DF -10040=\u6D41\u7A0B\u5DF2\u6302\u8D77\uFF0C\u4E0D\u80FD\u542F\u52A8\u5B9E\u4F8B -10041=\u591A\u5B9E\u4F8B\u4EFB\u52A1\u4E0D\u80FD\u9A73\u56DE -10042=\u5B58\u5728\u591A\u4E2A\u5904\u7406\u4E2D\u7684\u4EFB\u52A1\uFF0C\u4E0D\u80FD\u9A73\u56DE -10043=\u591A\u5B9E\u4F8B\u4EFB\u52A1\u4E0D\u80FD\u7EC8\u6B62 -10044=\u5B58\u5728\u591A\u4E2A\u5904\u7406\u4E2D\u7684\u4EFB\u52A1\uFF0C\u4E0D\u80FD\u7EC8\u6B62\u6D41\u7A0B -10045=\u7EC8\u6B62 -10046=\u591A\u5B9E\u4F8B\u4EFB\u52A1\u4E0D\u80FD\u56DE\u9000 -10047=\u5B58\u5728\u591A\u4E2A\u5E76\u884C\u6267\u884C\u7684\u4EFB\u52A1\uFF0C\u4E0D\u80FD\u56DE\u9000 -10048=\u767B\u5F55\u8D26\u53F7\uFF0C\u65E0\u6743\u5220\u9664 -10055=\u60A8\u7684\u5BC6\u7801\u957F\u5EA6\u4E0D\u591F8\u4F4D -10056=\u60A8\u7684\u5BC6\u7801\u590D\u6742\u5EA6\u4E0D\u591F\uFF0C\u9700\u8981\u540C\u65F6\u5305\u542B\u6570\u5B57,\u5C0F\u5199\u82F1\u6587,\u5927\u5199\u82F1\u6587 \ No newline at end of file +10030=\u5BC6\u7801\u957F\u5EA6\u4E0D\u8DB3{0}\u4F4D +10031=\u5F31\u5BC6\u7801 +10032=\u5220\u9664\u672C\u6570\u636E\u5F02\u5E38\u5EA6\u4E0D\u591F\uFF0C\u9700\u8981\u540C\u65F6\u5305\u542B\u6570\u5B57,\u5C0F\u5199\u82F1\u6587,\u5927\u5199\u82F1\u6587 \ No newline at end of file diff --git a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties index bd67d5b3..f8ee58cf 100644 --- a/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties +++ b/main/manager-api/src/main/resources/i18n/messages_zh_TW.properties @@ -2,6 +2,7 @@ 500=\u670D\u52D9\u5668\u5167\u90E8\u7570\u5E38 401=\u672A\u6388\u6B0A 403=\u62D2\u7D55\u8A2A\u554F\uFF0C\u6C92\u6709\u6B0A\u9650 + 10001={0}\u4E0D\u80FD\u70BA\u7A7A 10002=\u6578\u64DA\u5EAB\u4E2D\u5DF2\u5B58\u5728\u8A72\u8A18\u9304 10003=\u7372\u53D6\u53C3\u6578\u5931\u6557 @@ -11,44 +12,23 @@ 10007=\u9A57\u8B49\u78BC\u4E0D\u6B63\u78BA 10008=\u5148\u522A\u9664\u5B50\u83DC\u55AE\u6216\u6309\u9215 10009=\u539F\u5BC6\u78BC\u4E0D\u6B63\u78BA -10010=\u8CEC\u865F\u6216\u5BC6\u78BC\u4E0D\u6B63\u78BA,\u60A8\u9084\u6709\u53EF\u4EE5\u5617\u8A66{0}\u6B21 + 10011=\u4E0A\u7D1A\u90E8\u9580\u9078\u64C7\u932F\u8AA4 10012=\u4E0A\u7D1A\u83DC\u55AE\u4E0D\u80FD\u70BA\u81EA\u8EAB 10013=\u6578\u64DA\u6B0A\u9650\u63A5\u53E3\uFF0C\u53EA\u80FD\u662FMap\u985E\u578B\u53C3\u6578 10014=\u8ACB\u5148\u522A\u9664\u4E0B\u7D1A\u90E8\u9580 10015=\u8ACB\u5148\u522A\u9664\u90E8\u9580\u4E0B\u7684\u7528\u6236 -10016=\u90E8\u7F72\u5931\u6557\uFF0C\u6C92\u6709\u6D41\u7A0B -10017=\u6A21\u578B\u5716\u4E0D\u6B63\u78BA\uFF0C\u8ACB\u6AA2\u67E5 -10018=\u5C0E\u51FA\u5931\u6557\uFF0C\u6A21\u578BID\u70BA{0} + 10019=\u8ACB\u4E0A\u50B3\u6587\u4EF6 10020=token\u4E0D\u80FD\u70BA\u7A7A 10021=token\u5931\u6548\uFF0C\u8ACB\u91CD\u65B0\u767B\u9304 10022=\u8CEC\u865F\u5DF2\u88AB\u9396\u5B9A -10023=\u8ACB\u4E0A\u50B3zip\u3001bar\u3001bpmn\u3001bpmn20.xml\u683C\u5F0F\u6587\u4EF6 + 10024=\u4E0A\u50B3\u6587\u4EF6\u5931\u6557{0} -10025=\u767C\u9001\u77ED\u4FE1\u5931\u6557{0} -10026=\u90F5\u4EF6\u6A21\u677F\u4E0D\u5B58\u5728 + 10027=Redis\u670D\u52D9\u7570\u5E38 10028=\u5B9A\u6642\u4EFB\u52D9\u5931\u6557 10029=\u4E0D\u80FD\u5305\u542B\u975E\u6CD5\u5B57\u7B26 -10030=\u53C3\u6578\u683C\u5F0F\u4E0D\u6B63\u78BA\uFF0C\u8ACB\u4F7F\u7528JSON\u683C\u5F0F -10031=\u8ACB\u5148\u5B8C\u6210\u77ED\u4FE1\u914D\u7F6E -10032=\u4EFB\u52D9\u5DF2\u88AB\u7C3D\u6536\uFF0C\u64CD\u4F5C\u5931\u6557 -10033=\u4E0D\u5B58\u5728\u7684\u6D41\u7A0B\u5B9A\u7FA9 -10034=\u4E0A\u7D1A\u7BC0\u9EDE\u4E0D\u5B58\u5728 -10035=\u99C1\u56DE -10036=\u56DE\u9000 -10037=\u4EFB\u52D9\u6C92\u6709\u5206\u7D44\uFF0C\u7121\u6CD5\u53D6\u6D88\u8A8D\u9818 -10038=\u4E0A\u7D1A\u5340\u57DF\u9078\u64C7\u932F\u8AA4 -10039=\u8ACB\u5148\u522A\u9664\u4E0B\u7D1A\u5340\u57DF -10040=\u6D41\u7A0B\u5DF2\u639B\u8D77\uFF0C\u4E0D\u80FD\u555F\u52D5\u5BE6\u4F8B -10041=\u591A\u5BE6\u4F8B\u4EFB\u52D9\u4E0D\u80FD\u99C1\u56DE -10042=\u5B58\u5728\u591A\u500B\u8655\u7406\u4E2D\u7684\u4EFB\u52D9\uFF0C\u4E0D\u80FD\u99C1\u56DE -10043=\u591A\u5BE6\u4F8B\u4EFB\u52D9\u4E0D\u80FD\u7D42\u6B62 -10044=\u5B58\u5728\u591A\u500B\u8655\u7406\u4E2D\u7684\u4EFB\u52D9\uFF0C\u4E0D\u80FD\u7D42\u6B62\u6D41\u7A0B -10045=\u7D42\u6B62 -10046=\u591A\u5BE6\u4F8B\u4EFB\u52D9\u4E0D\u80FD\u56DE\u9000 -10047=\u5B58\u5728\u591A\u500B\u4E26\u884C\u57F7\u884C\u7684\u4EFB\u52D9\uFF0C\u4E0D\u80FD\u56DE\u9000 -10048=\u767B\u5165\u5E33\u865F\uFF0C\u7121\u6B0A\u5220\u9664 -10055=\u60A8\u7684\u5BC6\u78BC\u9577\u5EA6\u4E0D\u59208\u4F4D -10056=\u60A8\u7684\u5BC6\u78BC\u5FA9\u96DC\u5EA6\u4E0D\u5920\uFF0C\u9700\u8981\u540C\u6642\u5305\u542B\u6578\u5B57,\u5C0F\u5BEB\u82F1\u6587,\u5927\u5BEB\u82F1\u6587 \ No newline at end of file +10030=\u5BC6\u78BC\u9577\u5EA6\u4E0D\u8DB3{0}\u4F4D +10031=\u5F31\u5BC6\u78BC\uFF0C\u5BC6\u78BC\u9700\u8981\u5305\u542B\u5927\u5BEB\u5B57\u6BCD\uFF0C\u5C0F\u5BEB\u5B57\u6BCD\uFF0C\u7B26\u865F\uFF0C\u6578\u5B57\u5176\u4E2D{0}\u7A2E +10032=\u522A\u9664\u6B64\u6578\u64DA\u7570\u5E38 \ No newline at end of file diff --git a/main/manager-api/src/main/resources/i18n/validation.properties b/main/manager-api/src/main/resources/i18n/validation.properties index 66d95744..947f89cc 100644 --- a/main/manager-api/src/main/resources/i18n/validation.properties +++ b/main/manager-api/src/main/resources/i18n/validation.properties @@ -1,9 +1,13 @@ #\u7B80\u4F53\u4E2D\u6587 id.require=ID\u4E0D\u80FD\u4E3A\u7A7A id.null=ID\u5FC5\u987B\u4E3A\u7A7A -pid.require=\u4E0A\u7EA7ID\uFF0C\u4E0D\u80FD\u4E3A\u7A7A + sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u4E8E0 +sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +sysdict.label.require=\u5B57\u5178\u6807\u7B7E\u4E0D\u80FD\u4E3A\u7A7A + sysparams.paramcode.require=\u53C2\u6570\u7F16\u7801\u4E0D\u80FD\u4E3A\u7A7A sysparams.paramvalue.require=\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A @@ -11,99 +15,8 @@ sysuser.username.require=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A sysuser.password.require=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A sysuser.gender.range=\u6027\u522B\u53D6\u503C\u8303\u56F40~2 -sysuser.email.require=\u90AE\u7BB1\u4E0D\u80FD\u4E3A\u7A7A sysuser.email.error=\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E -sysuser.mobile.require=\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A sysuser.deptId.require=\u90E8\u95E8\u4E0D\u80FD\u4E3A\u7A7A -sysuser.superadmin.range=\u8D85\u7EA7\u7BA1\u7406\u5458\u53D6\u503C\u8303\u56F40~1 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 - -sysmenu.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u83DC\u5355 -sysmenu.name.require=\u83DC\u5355\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -sysmenu.type.range=\u83DC\u5355\u7C7B\u578B\u53D6\u503C\u8303\u56F40~1 -sysmenu.openstyle.range=\u83DC\u5355\u6253\u5F00\u65B9\u5F0F\u53D6\u503C\u8303\u56F40~1 - -sysdept.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u90E8\u95E8 -sysdept.name.require=\u90E8\u95E8\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -sysrole.name.require=\u89D2\u8272\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A -sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -sysdict.label.require=\u5B57\u5178\u6807\u7B7E\u4E0D\u80FD\u4E3A\u7A7A - -schedule.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 -schedule.cron.require=cron\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A -schedule.bean.require=bean\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -oss.type.range=\u7C7B\u578B\u53D6\u503C\u8303\u56F41~5 - -aliyun.accesskeyid.require=\u963F\u91CC\u4E91AccessKeyId\u4E0D\u80FD\u4E3A\u7A7A -aliyun.accesskeysecret.require=\u963F\u91CC\u4E91AccessKeySecret\u4E0D\u80FD\u4E3A\u7A7A -aliyun.signname.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A -aliyun.templatecode.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u6A21\u677F\u4E0D\u80FD\u4E3A\u7A7A -aliyun.domain.require=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -aliyun.domain.url=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -aliyun.endPoint.require=\u963F\u91CC\u4E91EndPoint\u4E0D\u80FD\u4E3A\u7A7A -aliyun.bucketname.require=\u963F\u91CC\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A - -qcloud.appid.require=\u817E\u8BAF\u4E91AppId\u4E0D\u80FD\u4E3A\u7A7A -qcloud.appkey.require=\u817E\u8BAF\u4E91AppKey\u4E0D\u80FD\u4E3A\u7A7A -qcloud.secretId.require=\u817E\u8BAF\u4E91SecretId\u4E0D\u80FD\u4E3A\u7A7A -qcloud.secretkey.require=\u817E\u8BAF\u4E91SecretKey\u4E0D\u80FD\u4E3A\u7A7A -qcloud.signname.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A -qcloud.templateid.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A -qcloud.domain.require=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -qcloud.domain.url=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -qcloud.bucketname.require=\u817E\u8BAF\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A -qcloud.region.require=\u6240\u5C5E\u5730\u533A\u4E0D\u80FD\u4E3A\u7A7A - -qiniu.domain.require=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -qiniu.domain.url=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -qiniu.accesskey.require=\u4E03\u725BAccessKey\u4E0D\u80FD\u4E3A\u7A7A -qiniu.secretkey.require=\u4E03\u725BSecretKey\u4E0D\u80FD\u4E3A\u7A7A -qiniu.bucketname.require=\u4E03\u725B\u7A7A\u95F4\u540D\u4E0D\u80FD\u4E3A\u7A7A -qiniu.templateId.require=\u4E03\u725B\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A - -fastdfs.domain.require=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -fastdfs.domain.url=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E - -local.domain.require=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -local.domain.url=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -local.path.url=\u5B58\u50A8\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A - -minio.endPoint.require=Minio EndPoint\u4E0D\u80FD\u4E3A\u7A7A -minio.accesskey.require=Minio AccessKey\u4E0D\u80FD\u4E3A\u7A7A -minio.secretkey.require=Minio SecretKey\u4E0D\u80FD\u4E3A\u7A7A -minio.bucketname.require=Minio BucketName\u4E0D\u80FD\u4E3A\u7A7A - -sms.platform.range=\u5E73\u53F0\u7C7B\u578B\u53D6\u503C\u8303\u56F41~2 -email.smtp.require=SMTP\u4E0D\u80FD\u4E3A\u7A7A -email.port.require=\u7AEF\u53E3\u53F7\u4E0D\u80FD\u4E3A\u7A7A -email.username.require=\u90AE\u7BB1\u8D26\u53F7\u4E0D\u80FD\u4E3A\u7A7A -email.password.require=\u90AE\u7BB1\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A - -mail.name.require=\u6A21\u677F\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -mail.subject.require=\u90AE\u4EF6\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A -mail.content.require=\u90AE\u4EF6\u6B63\u6587\u4E0D\u80FD\u4E3A\u7A7A - -model.name.require=\u6A21\u578B\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -model.key.require=\u6A21\u578B\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A - -news.title.require=\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A -news.content.require=\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A -news.pubdate.require=\u53D1\u5E03\u65F6\u95F4\u4E0D\u80FD\u4E3A\u7A7A - -region.id.require=\u533A\u57DF\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A -region.pid.require=\u4E0A\u7EA7\u533A\u57DF\u4E0D\u80FD\u4E3A\u7A7A -region.name.require=\u533A\u57DF\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -processBizRoute.procDefId.require=\u6D41\u7A0B\u5B9A\u4E49ID\u4E0D\u80FD\u4E3A\u7A7A -processBizRoute.bizRoute.require=\u4E1A\u52A1\u8DEF\u7531\u4E0D\u80FD\u4E3A\u7A7A -processBizRoute.procDefKey.require=\u6D41\u7A0B\u5B9A\u4E49KEY\u4E0D\u80FD\u4E3A\u7A7A -processBizRoute.version.require=\u6D41\u7A0B\u5B9A\u4E49\u7248\u672C\u53F7\u4E0D\u80FD\u4E3A\u7A7A - -ProcessStart.processDefinitionKey.require=\u6D41\u7A0B\u5B9A\u4E49KEY\u4E0D\u80FD\u4E3A\u7A7A -ProcessStart.businessKey.require=\u4E1A\u52A1KEY\u4E0D\u80FD\u4E3A\u7A7A \ No newline at end of file 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 2de9b22c..f8bb6e94 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 @@ -1,9 +1,13 @@ #English id.require=ID can not be empty id.null=ID has to be empty -pid.require=Parent ID, cannot be empty + sort.number=The sort value cannot be less than 0 +sysdict.type.require=The dictionary type cannot be empty +sysdict.name.require=The dictionary name cannot be empty +sysdict.label.require=Dictionary tag cannot be empty + sysparams.paramcode.require=Parameter encoding cannot be empty sysparams.paramvalue.require=Parameter values cannot be empty @@ -11,100 +15,8 @@ sysuser.username.require=The username cannot be empty sysuser.password.require=The password cannot be empty sysuser.realname.require=The realname cannot be empty sysuser.gender.range=Gender ranges from 0 to 2 -sysuser.email.require=Mailbox cannot be empty sysuser.email.error=Incorrect email format -sysuser.mobile.require=The phone number cannot be empty sysuser.deptId.require=Departments cannot be empty -sysuser.superadmin.range=Super administrator values range from 0 to 1 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 - -sysmenu.pid.require=Please select superior menu -sysmenu.name.require=Menu name cannot be empty -sysmenu.type.range=Menu type ranges from 0 to 1 -sysmenu.openstyle.range=Menu open style ranges from 0 to 1 - -sysdept.pid.require=Please select superior department -sysdept.name.require=The department name cannot be empty - -sysrole.name.require=The role name cannot be empty - -sysdict.type.require=The dictionary type cannot be empty -sysdict.name.require=The dictionary name cannot be empty -sysdict.label.require=Dictionary tag cannot be empty - -schedule.status.range=Status ranges from 0 to 1 -schedule.cron.require=Cron expression cannot be empty -schedule.bean.require=Bean name cannot be empty - -oss.type.range=Type ranges from 1 to 5 - -aliyun.accesskeyid.require=Aliyun AccessKeyId cannot be empty -aliyun.accesskeysecret.require=Aliyun AccessKeySecret cannot be empty -aliyun.signname.require=Aliyun message signature cannot be empty -aliyun.templatecode.require=Aliyun message template cannot be empty -aliyun.domain.require=Aliyun bound domain name cannot be empty -aliyun.domain.url=Aliyun binding domain name format is incorrect -aliyun.endPoint.require=The aliyun EndPoint cannot be empty -aliyun.bucketname.require=Aliyun BucketName cannot be empty - -qcloud.appid.require=Tencent cloud AppId cannot be empty -qcloud.appkey.require=Tencent cloud AppKey cannot be empty -qcloud.secretId.require=Tencent cloud SecretId cannot be empty -qcloud.secretkey.require=Tencent cloud SecretKey cannot be empty -qcloud.signname.require=Tencent cloud SMS signature cannot be empty -qcloud.templateid.require=Tencent cloud SMS template ID cannot be empty -qcloud.domain.require=Tencent cloud bound domain name cannot be empty -qcloud.domain.url=Tencent cloud binding domain name format is incorrect -qcloud.bucketname.require=Tencent cloud BucketName cannot be empty -qcloud.region.require=The region cannot be empty - -qiniu.domain.require=Bound domain name cannot be empty -qiniu.domain.url=Binding domain name format is incorrect -qiniu.accesskey.require=The AccessKey cannot be empty -qiniu.secretkey.require=The SecretKey of seven cows cannot be empty -qiniu.bucketname.require=Space names cannot be empty -qiniu.templateId.require=Template ID cannot be empty - -fastdfs.domain.require=FastDFS bound domain name cannot be empty -fastdfs.domain.url=FastDFS bound domain name format is incorrect - -local.domain.require=Local upload bound domain name cannot be empty -local.domain.url=The domain name bound for local upload is not formatted correctly -local.path.url=The storage directory cannot be empty - -minio.endPoint.require=Minio EndPoint cannot be empty -minio.accesskey.require=Minio AccessKey cannot be empty -minio.secretkey.require=Minio SecretKey cannot be empty -minio.bucketname.require=Minio BucketName cannot be empty - -sms.platform.range=Platform type ranges from 1 to 2 - -email.smtp.require=SMTP cannot be empty -email.port.require=Port number cannot be empty -email.username.require=The email account cannot be empty -email.password.require=The password cannot be empty - -mail.name.require=The template name cannot be empty -mail.subject.require=Mail subject cannot be empty -mail.content.require=Message text cannot be empty - -model.name.require=The model name cannot be empty -model.key.require=The model key cannot be empty - -news.title.require=The title cannot be empty -news.content.require=Content cannot be empty -news.pubdate.require=The release time cannot be empty - -region.id.require=Region ID cannot be empty -region.pid.require=Upper area cannot be empty -region.name.require=Region name cannot be empty - -processBizRoute.procDefId.require=Process Definition ID cannot be empty -processBizRoute.bizRoute.require=Service routing cannot be empty -processBizRoute.procDefKey.require=Process Definition KEY cannot be empty -processBizRoute.version.require=Process Definition Version number cannot be empty - -ProcessStart.processDefinitionKey.require=Process Definition KEY cannot be empty -ProcessStart.businessKey.require=Business KEY cannot be empty \ No newline at end of file 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 66d95744..ba350d05 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 @@ -1,9 +1,13 @@ #\u7B80\u4F53\u4E2D\u6587 id.require=ID\u4E0D\u80FD\u4E3A\u7A7A id.null=ID\u5FC5\u987B\u4E3A\u7A7A -pid.require=\u4E0A\u7EA7ID\uFF0C\u4E0D\u80FD\u4E3A\u7A7A + sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u4E8E0 +sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +sysdict.label.require=\u5B57\u5178\u6807\u7B7E\u4E0D\u80FD\u4E3A\u7A7A + sysparams.paramcode.require=\u53C2\u6570\u7F16\u7801\u4E0D\u80FD\u4E3A\u7A7A sysparams.paramvalue.require=\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A @@ -11,99 +15,9 @@ sysuser.username.require=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A sysuser.password.require=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A sysuser.gender.range=\u6027\u522B\u53D6\u503C\u8303\u56F40~2 -sysuser.email.require=\u90AE\u7BB1\u4E0D\u80FD\u4E3A\u7A7A sysuser.email.error=\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E -sysuser.mobile.require=\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A sysuser.deptId.require=\u90E8\u95E8\u4E0D\u80FD\u4E3A\u7A7A -sysuser.superadmin.range=\u8D85\u7EA7\u7BA1\u7406\u5458\u53D6\u503C\u8303\u56F40~1 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 -sysmenu.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u83DC\u5355 -sysmenu.name.require=\u83DC\u5355\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -sysmenu.type.range=\u83DC\u5355\u7C7B\u578B\u53D6\u503C\u8303\u56F40~1 -sysmenu.openstyle.range=\u83DC\u5355\u6253\u5F00\u65B9\u5F0F\u53D6\u503C\u8303\u56F40~1 - -sysdept.pid.require=\u8BF7\u9009\u62E9\u4E0A\u7EA7\u90E8\u95E8 -sysdept.name.require=\u90E8\u95E8\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -sysrole.name.require=\u89D2\u8272\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A -sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -sysdict.label.require=\u5B57\u5178\u6807\u7B7E\u4E0D\u80FD\u4E3A\u7A7A - -schedule.status.range=\u72B6\u6001\u53D6\u503C\u8303\u56F40~1 -schedule.cron.require=cron\u8868\u8FBE\u5F0F\u4E0D\u80FD\u4E3A\u7A7A -schedule.bean.require=bean\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -oss.type.range=\u7C7B\u578B\u53D6\u503C\u8303\u56F41~5 - -aliyun.accesskeyid.require=\u963F\u91CC\u4E91AccessKeyId\u4E0D\u80FD\u4E3A\u7A7A -aliyun.accesskeysecret.require=\u963F\u91CC\u4E91AccessKeySecret\u4E0D\u80FD\u4E3A\u7A7A -aliyun.signname.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A -aliyun.templatecode.require=\u963F\u91CC\u4E91\u77ED\u4FE1\u6A21\u677F\u4E0D\u80FD\u4E3A\u7A7A -aliyun.domain.require=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -aliyun.domain.url=\u963F\u91CC\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -aliyun.endPoint.require=\u963F\u91CC\u4E91EndPoint\u4E0D\u80FD\u4E3A\u7A7A -aliyun.bucketname.require=\u963F\u91CC\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A - -qcloud.appid.require=\u817E\u8BAF\u4E91AppId\u4E0D\u80FD\u4E3A\u7A7A -qcloud.appkey.require=\u817E\u8BAF\u4E91AppKey\u4E0D\u80FD\u4E3A\u7A7A -qcloud.secretId.require=\u817E\u8BAF\u4E91SecretId\u4E0D\u80FD\u4E3A\u7A7A -qcloud.secretkey.require=\u817E\u8BAF\u4E91SecretKey\u4E0D\u80FD\u4E3A\u7A7A -qcloud.signname.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u7B7E\u540D\u4E0D\u80FD\u4E3A\u7A7A -qcloud.templateid.require=\u817E\u8BAF\u4E91\u77ED\u4FE1\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A -qcloud.domain.require=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -qcloud.domain.url=\u817E\u8BAF\u4E91\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -qcloud.bucketname.require=\u817E\u8BAF\u4E91BucketName\u4E0D\u80FD\u4E3A\u7A7A -qcloud.region.require=\u6240\u5C5E\u5730\u533A\u4E0D\u80FD\u4E3A\u7A7A - -qiniu.domain.require=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -qiniu.domain.url=\u4E03\u725B\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -qiniu.accesskey.require=\u4E03\u725BAccessKey\u4E0D\u80FD\u4E3A\u7A7A -qiniu.secretkey.require=\u4E03\u725BSecretKey\u4E0D\u80FD\u4E3A\u7A7A -qiniu.bucketname.require=\u4E03\u725B\u7A7A\u95F4\u540D\u4E0D\u80FD\u4E3A\u7A7A -qiniu.templateId.require=\u4E03\u725B\u6A21\u677FID\u4E0D\u80FD\u4E3A\u7A7A - -fastdfs.domain.require=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -fastdfs.domain.url=FastDFS\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E - -local.domain.require=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u4E3A\u7A7A -local.domain.url=\u672C\u5730\u4E0A\u4F20\u7ED1\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u786E -local.path.url=\u5B58\u50A8\u76EE\u5F55\u4E0D\u80FD\u4E3A\u7A7A - -minio.endPoint.require=Minio EndPoint\u4E0D\u80FD\u4E3A\u7A7A -minio.accesskey.require=Minio AccessKey\u4E0D\u80FD\u4E3A\u7A7A -minio.secretkey.require=Minio SecretKey\u4E0D\u80FD\u4E3A\u7A7A -minio.bucketname.require=Minio BucketName\u4E0D\u80FD\u4E3A\u7A7A - -sms.platform.range=\u5E73\u53F0\u7C7B\u578B\u53D6\u503C\u8303\u56F41~2 -email.smtp.require=SMTP\u4E0D\u80FD\u4E3A\u7A7A -email.port.require=\u7AEF\u53E3\u53F7\u4E0D\u80FD\u4E3A\u7A7A -email.username.require=\u90AE\u7BB1\u8D26\u53F7\u4E0D\u80FD\u4E3A\u7A7A -email.password.require=\u90AE\u7BB1\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A - -mail.name.require=\u6A21\u677F\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -mail.subject.require=\u90AE\u4EF6\u4E3B\u9898\u4E0D\u80FD\u4E3A\u7A7A -mail.content.require=\u90AE\u4EF6\u6B63\u6587\u4E0D\u80FD\u4E3A\u7A7A - -model.name.require=\u6A21\u578B\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A -model.key.require=\u6A21\u578B\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A - -news.title.require=\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A -news.content.require=\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A -news.pubdate.require=\u53D1\u5E03\u65F6\u95F4\u4E0D\u80FD\u4E3A\u7A7A - -region.id.require=\u533A\u57DF\u6807\u8BC6\u4E0D\u80FD\u4E3A\u7A7A -region.pid.require=\u4E0A\u7EA7\u533A\u57DF\u4E0D\u80FD\u4E3A\u7A7A -region.name.require=\u533A\u57DF\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A - -processBizRoute.procDefId.require=\u6D41\u7A0B\u5B9A\u4E49ID\u4E0D\u80FD\u4E3A\u7A7A -processBizRoute.bizRoute.require=\u4E1A\u52A1\u8DEF\u7531\u4E0D\u80FD\u4E3A\u7A7A -processBizRoute.procDefKey.require=\u6D41\u7A0B\u5B9A\u4E49KEY\u4E0D\u80FD\u4E3A\u7A7A -processBizRoute.version.require=\u6D41\u7A0B\u5B9A\u4E49\u7248\u672C\u53F7\u4E0D\u80FD\u4E3A\u7A7A - -ProcessStart.processDefinitionKey.require=\u6D41\u7A0B\u5B9A\u4E49KEY\u4E0D\u80FD\u4E3A\u7A7A -ProcessStart.businessKey.require=\u4E1A\u52A1KEY\u4E0D\u80FD\u4E3A\u7A7A \ No newline at end of file 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 6680e10a..947f89cc 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 @@ -1,110 +1,22 @@ -#\u7E41\u4F53\u4E2D\u6587 -id.require=ID\u4E0D\u80FD\u70BA\u7A7A -id.null=ID\u5FC5\u9808\u70BA\u7A7A -pid.require=\u4E0A\u7D1AID\uFF0C\u4E0D\u80FD\u70BA\u7A7A -sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u65BC0 +#\u7B80\u4F53\u4E2D\u6587 +id.require=ID\u4E0D\u80FD\u4E3A\u7A7A +id.null=ID\u5FC5\u987B\u4E3A\u7A7A -sysparams.paramcode.require=\u53C3\u6578\u7DE8\u78BC\u4E0D\u80FD\u70BA\u7A7A -sysparams.paramvalue.require=\u53C3\u6578\u503C\u4E0D\u80FD\u70BA\u7A7A +sort.number=\u6392\u5E8F\u503C\u4E0D\u80FD\u5C0F\u4E8E0 -sysuser.username.require=\u7528\u6236\u540D\u4E0D\u80FD\u70BA\u7A7A -sysuser.password.require=\u5BC6\u78BC\u4E0D\u80FD\u70BA\u7A7A -sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u70BA\u7A7A -sysuser.gender.range=\u6027\u5225\u53D6\u503C\u7BC4\u570D0~2 -sysuser.email.require=\u90F5\u7BB1\u4E0D\u80FD\u70BA\u7A7A -sysuser.email.error=\u90F5\u7BB1\u683C\u5F0F\u4E0D\u6B63\u78BA -sysuser.mobile.require=\u624B\u6A5F\u865F\u4E0D\u80FD\u70BA\u7A7A -sysuser.deptId.require=\u90E8\u9580\u4E0D\u80FD\u70BA\u7A7A -sysuser.superadmin.range=\u8D85\u7D1A\u7BA1\u7406\u54E1\u53D6\u503C\u7BC4\u570D0~1 -sysuser.status.range=\u72C0\u614B\u53D6\u503C\u7BC4\u570D0~1 -sysuser.captcha.require=\u9A57\u8B49\u78BC\u4E0D\u80FD\u70BA\u7A7A -sysuser.uuid.require=\u552F\u4E00\u6A19\u8B58\u4E0D\u80FD\u70BA\u7A7A +sysdict.type.require=\u5B57\u5178\u7C7B\u578B\u4E0D\u80FD\u4E3A\u7A7A +sysdict.name.require=\u5B57\u5178\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A +sysdict.label.require=\u5B57\u5178\u6807\u7B7E\u4E0D\u80FD\u4E3A\u7A7A -sysmenu.pid.require=\u8ACB\u9078\u64C7\u4E0A\u7D1A\u83DC\u55AE -sysmenu.name.require=\u83DC\u55AE\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A -sysmenu.type.range=\u83DC\u55AE\u985E\u578B\u53D6\u503C\u7BC4\u570D0~1 -sysmenu.openstyle.range=\u83DC\u55AE\u6253\u958B\u65B9\u5F0F\u53D6\u503C\u7BC4\u570D0~1 +sysparams.paramcode.require=\u53C2\u6570\u7F16\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysparams.paramvalue.require=\u53C2\u6570\u503C\u4E0D\u80FD\u4E3A\u7A7A -sysdept.pid.require=\u8ACB\u9078\u64C7\u4E0A\u7D1A\u90E8\u9580 -sysdept.name.require=\u90E8\u9580\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A - -sysrole.name.require=\u89D2\u8272\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A - -sysdict.type.require=\u5B57\u5178\u985E\u578B\u4E0D\u80FD\u70BA\u7A7A -sysdict.name.require=\u5B57\u5178\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A -sysdict.label.require=\u5B57\u5178\u6A19\u7C64\u4E0D\u80FD\u70BA\u7A7A - -schedule.status.range=\u72C0\u614B\u53D6\u503C\u7BC4\u570D0~1 -schedule.cron.require=cron\u8868\u9054\u5F0F\u4E0D\u80FD\u70BA\u7A7A -schedule.bean.require=bean\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A - -oss.type.range=\u985E\u578B\u53D6\u503C\u7BC4\u570D1~5 - -aliyun.accesskeyid.require=\u963F\u91CC\u96F2AccessKeyId\u4E0D\u80FD\u70BA\u7A7A -aliyun.accesskeysecret.require=\u963F\u91CC\u96F2AccessKeySecret\u4E0D\u80FD\u70BA\u7A7A -aliyun.signname.require=\u963F\u91CC\u96F2\u77ED\u4FE1\u7C3D\u540D\u4E0D\u80FD\u70BA\u7A7A -aliyun.templatecode.require=\u963F\u91CC\u96F2\u77ED\u4FE1\u6A21\u677F\u4E0D\u80FD\u70BA\u7A7A -aliyun.domain.require=\u963F\u91CC\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A -aliyun.domain.url=\u963F\u91CC\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA -aliyun.endPoint.require=\u963F\u91CC\u96F2EndPoint\u4E0D\u80FD\u70BA\u7A7A -aliyun.bucketname.require=\u963F\u91CC\u96F2BucketName\u4E0D\u80FD\u70BA\u7A7A - -qcloud.appid.require=\u9A30\u8A0A\u96F2AppId\u4E0D\u80FD\u70BA\u7A7A -qcloud.appkey.require=\u9A30\u8A0A\u96F2AppKey\u4E0D\u80FD\u70BA\u7A7A -qcloud.secretId.require=\u9A30\u8A0A\u96F2SecretId\u4E0D\u80FD\u70BA\u7A7A -qcloud.secretkey.require=\u9A30\u8A0A\u96F2SecretKey\u4E0D\u80FD\u70BA\u7A7A -qcloud.signname.require=\u9A30\u8A0A\u96F2\u77ED\u4FE1\u7C3D\u540D\u4E0D\u80FD\u70BA\u7A7A -qcloud.templateid.require=\u9A30\u8A0A\u96F2\u77ED\u4FE1\u6A21\u677FID\u4E0D\u80FD\u70BA\u7A7A -qcloud.domain.require=\u9A30\u8A0A\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A -qcloud.domain.url=\u9A30\u8A0A\u96F2\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA -qcloud.bucketname.require=\u9A30\u8A0A\u96F2BucketName\u4E0D\u80FD\u70BA\u7A7A -qcloud.region.require=\u6240\u5C6C\u5730\u5340\u4E0D\u80FD\u70BA\u7A7A - -qiniu.domain.require=\u4E03\u725B\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A -qiniu.domain.url=\u4E03\u725B\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA -qiniu.accesskey.require=\u4E03\u725BAccessKey\u4E0D\u80FD\u70BA\u7A7A -qiniu.secretkey.require=\u4E03\u725BSecretKey\u4E0D\u80FD\u70BA\u7A7A -qiniu.bucketname.require=\u4E03\u725B\u7A7A\u9593\u540D\u4E0D\u80FD\u70BA\u7A7A -qiniu.templateId.require=\u4E03\u725B\u6A21\u677FID\u4E0D\u80FD\u70BA\u7A7A - -fastdfs.domain.require=FastDFS\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A -fastdfs.domain.url=FastDFS\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA - -local.domain.require=\u672C\u5730\u4E0A\u50B3\u7D81\u5B9A\u7684\u57DF\u540D\u4E0D\u80FD\u70BA\u7A7A -local.domain.url=\u672C\u5730\u4E0A\u50B3\u7D81\u5B9A\u7684\u57DF\u540D\u683C\u5F0F\u4E0D\u6B63\u78BA -local.path.url=\u5B58\u5132\u76EE\u9304\u4E0D\u80FD\u70BA\u7A7A - -minio.endPoint.require=Minio EndPoint\u4E0D\u80FD\u70BA\u7A7A -minio.accesskey.require=Minio AccessKey\u4E0D\u80FD\u70BA\u7A7A -minio.secretkey.require=Minio SecretKey\u4E0D\u80FD\u70BA\u7A7A -minio.bucketname.require=Minio BucketName\u4E0D\u80FD\u70BA\u7A7A - -sms.platform.range=\u5E73\u53F0\u985E\u578B\u53D6\u503C\u7BC4\u570D1~2 - -email.smtp.require=SMTP\u4E0D\u80FD\u70BA\u7A7A -email.port.require=\u7AEF\u53E3\u865F\u4E0D\u80FD\u70BA\u7A7A -email.username.require=\u90F5\u7BB1\u8CEC\u865F\u4E0D\u80FD\u70BA\u7A7A -email.password.require=\u90F5\u7BB1\u5BC6\u78BC\u4E0D\u80FD\u70BA\u7A7A - -mail.name.require=\u6A21\u677F\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A -mail.subject.require=\u90F5\u4EF6\u4E3B\u984C\u4E0D\u80FD\u70BA\u7A7A -mail.content.require=\u90F5\u4EF6\u6B63\u6587\u4E0D\u80FD\u70BA\u7A7A - -model.name.require=\u6A21\u578B\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A -model.key.require=\u6A21\u578B\u6A19\u8B58\u4E0D\u80FD\u70BA\u7A7A - -news.title.require=\u6A19\u984C\u4E0D\u80FD\u70BA\u7A7A -news.content.require=\u5167\u5BB9\u4E0D\u80FD\u70BA\u7A7A -news.pubdate.require=\u767C\u4F48\u6642\u9593\u4E0D\u80FD\u70BA\u7A7A - -region.id.require=\u5340\u57DF\u6A19\u8B58\u4E0D\u80FD\u70BA\u7A7A -region.pid.require=\u4E0A\u7D1A\u5340\u57DF\u4E0D\u80FD\u70BA\u7A7A -region.name.require=\u5340\u57DF\u540D\u7A31\u4E0D\u80FD\u70BA\u7A7A - -processBizRoute.procDefId.require=\u6D41\u7A0B\u5B9A\u7FA9ID\u4E0D\u80FD\u70BA\u7A7A -processBizRoute.bizRoute.require=\u696D\u52D9\u8DEF\u7531\u4E0D\u80FD\u70BA\u7A7A -processBizRoute.procDefKey.require=\u6D41\u7A0B\u5B9A\u7FA9KEY\u4E0D\u80FD\u70BA\u7A7A -processBizRoute.version.require=\u6D41\u7A0B\u5B9A\u7FA9\u7248\u672C\u865F\u4E0D\u80FD\u70BA\u7A7A - -ProcessStart.processDefinitionKey.require=\u6D41\u7A0B\u5B9A\u7FA9KEY\u4E0D\u80FD\u70BA\u7A7A -ProcessStart.businessKey.require=\u696D\u52D9KEY\u4E0D\u80FD\u70BA\u7A7A \ No newline at end of file +sysuser.username.require=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.password.require=\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A +sysuser.realname.require=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A +sysuser.gender.range=\u6027\u522B\u53D6\u503C\u8303\u56F40~2 +sysuser.email.error=\u90AE\u7BB1\u683C\u5F0F\u4E0D\u6B63\u786E +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 From f8ece2d984307d14620c48b1a4c30c70db702135 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A6=99=E8=8D=89=E5=91=B3=E7=9A=84=E7=BA=B3=E8=A5=BF?= =?UTF-8?q?=E5=A6=B2?= <151599587+NyaOH-Nahida@users.noreply.github.com> Date: Tue, 11 Mar 2025 21:04:04 +0800 Subject: [PATCH 08/14] =?UTF-8?q?add:=20GSV=E6=9C=AC=E5=9C=B0=E8=AF=AD?= =?UTF-8?q?=E9=9F=B3=E5=90=88=E6=88=90=E7=9B=B8=E5=85=B3=20(#266)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/xiaozhi-server/config.yaml | 30 +++++ main/xiaozhi-server/core/providers/tts/GSV.py | 123 ++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 main/xiaozhi-server/core/providers/tts/GSV.py diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index a441930f..c8fbdb9f 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -311,6 +311,36 @@ TTS: media_type: "wav" streaming_mode: false threshold: 30 + GSV: + # GSV原神本地语音合成 + # 整合包下载:https://pan.ai-hobbyist.com/Infer%20Packs/TTS + # 国内镜像:https://alist.hancat.work/d/cdn/GPT-Sovits%E8%AF%AD%E9%9F%B3%E5%90%88%E6%88%90%E6%95%B4%E5%90%88%E5%8C%85%EF%BC%8C%E6%94%AF%E6%8C%81%E5%A4%9A%E4%BA%BA%E5%AF%B9%E8%AF%9D%E3%80%82%E6%B0%B8%E4%B9%85%E5%85%8D%E8%B4%B9%EF%BC%8C%E4%B8%A5%E7%A6%81%E5%80%92%E5%8D%96%EF%BC%81.7z + # 本TTS需要配合模型来使用,模型可以去这里下载: + # 二次元 & 游戏角色 GPT-Sovits V2 语音合成模型:https://www.modelscope.cn/models/aihobbyist/Anime_GPT-Sovits_Models + # 下载后将其解压到model文件夹 + # URL需要修改批处理文件才可生效,默认WebUI端口号为8080,API端口号为WebUI端口号+1 + url: "http://127.0.0.1:9881/infer_single" + app_key: "" + audio_dl_url: "http://127.0.0.1:9881" + model_name: "【原神】须弥" + speaker_name: "纳西妲" + prompt_text_lang: "中文" + emocton: "中立_neutral" + text_lang: "中文" + top_k: 10 + top_p: 1 + temperature: 1 + text_split_method: "按标点符号切" + batch_size: 10 + batch_size: 0.75 + split_bucket: true + speed_facter: 1 + fragment_interval: 0.3 + media_type: "wav" + parallel_infer: true + repetition_penalty: 1.35 + seed: -1 + output_file: tmp/ MinimaxTTS: # Minimax语音合成服务,需要先在minimax平台创建账户充值,并获取登录信息 # 平台地址:https://platform.minimaxi.com/ diff --git a/main/xiaozhi-server/core/providers/tts/GSV.py b/main/xiaozhi-server/core/providers/tts/GSV.py new file mode 100644 index 00000000..7a156c29 --- /dev/null +++ b/main/xiaozhi-server/core/providers/tts/GSV.py @@ -0,0 +1,123 @@ +import os +import uuid +import requests +from config.logger import setup_logging +from datetime import datetime +from core.providers.tts.base import TTSProviderBase + +TAG = __name__ +logger = setup_logging() + +class TTSProvider(TTSProviderBase): + def __init__(self, config, delete_audio_file): + super().__init__(config, delete_audio_file) + # POST请求地址 + self.url = config.get("url") + # 从配置中加载所有参数 + self.app_key = config.get("app_key") + self.audio_dl_url = config.get("audio_dl_url") + self.model_name = config.get("model_name") + self.speaker_name = config.get("speaker_name") + self.prompt_text_lang = config.get("prompt_text_lang") + self.emotion = config.get("emotion") + self.text_lang = config.get("text_lang") + self.top_k = config.get("top_k") + self.top_p = config.get("top_p") + self.temperature = config.get("temperature") + self.text_split_method = config.get("text_split_method") + self.batch_size = config.get("batch_size") + self.batch_threshold = config.get("batch_size") + self.split_bucket = config.get("split_bucket") + self.speed_facter = config.get("speed_facter") + self.fragment_interval = config.get("fragment_interval") + self.media_type = config.get("media_type") + self.parallel_infer = config.get("parallel_infer") + self.repetition_penalty = config.get("repetition_penalty") + self.seed = config.get("seed") + + def generate_filename(self): + """根据媒体类型生成文件名""" + extension = f".{self.media_type}" + return os.path.join( + self.output_file, + f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}" + ) + + async def text_to_speak(self, text, output_file): + """文本转语音并保存音频文件""" + # 构造请求体 + request_body = { + "app_key": self.app_key, + "audio_dl_url": self.audio_dl_url, + "model_name": self.model_name, + "speaker_name": self.speaker_name, + "prompt_text_lang": self.prompt_text_lang, + "emotion": self.emotion, + "text": text, + "text_lang": self.text_lang, + "top_k": self.top_k, + "top_p": self.top_p, + "temperature": self.temperature, + "text_split_method": self.text_split_method, + "batch_size": self.batch_size, + "batch_threshold": self.batch_threshold, + "split_bucket": self.split_bucket, + "speed_facter": self.speed_facter, + "fragment_interval": self.fragment_interval, + "media_type": self.media_type, + "parallel_infer": self.parallel_infer, + "repetition_penalty": self.repetition_penalty, + "seed": self.seed + } + + body = { + "app_key": "", + "audio_dl_url": "http://127.0.0.1:9881", + "model_name": "【原神】须弥", + "speaker_name": "纳西妲", + "prompt_text_lang": "中文", + "emotion": "中立_neutral", + "text": text, + "text_lang": "中文", + "top_k": 10, + "top_p": 1, + "temperature": 1, + "text_split_method": "按标点符号切", + "batch_size": 10, + "batch_threshold": 0.75, + "split_bucket": True, + "speed_facter": 1, + "fragment_interval": 0.3, + "media_type": "wav", + "parallel_infer": True, + "repetition_penalty": 1.35, + "seed": -1 + } + + try: + # 发送POST请求 + resp = requests.post(self.url, json=body) + resp.raise_for_status() + + # 解析响应 + result = resp.json() + if "audio_url" not in result: + logger.bind(tag=TAG).error("响应中缺少音频地址") + return + + # 下载音频文件 + audio_resp = requests.get(result["audio_url"]) + audio_resp.raise_for_status() + + # 保存文件 + with open(output_file, "wb") as f: + f.write(audio_resp.content) + + logger.bind(tag=TAG).info(f"音频文件已保存至: {output_file}") + + except requests.exceptions.HTTPError as e: + logger.bind(tag=TAG).error(f"HTTP请求失败: {str(e)}") + except requests.exceptions.JSONDecodeError: + logger.bind(tag=TAG).error("响应解析失败,无效的JSON格式") + except Exception as e: + logger.bind(tag=TAG).error(f"语音合成失败: {str(e)}") \ No newline at end of file From 8064e84276d809b3a27197d599052e154fdfc277 Mon Sep 17 00:00:00 2001 From: gitjianyu <57935053+gitjianyu@users.noreply.github.com> Date: Tue, 11 Mar 2025 21:06:03 +0800 Subject: [PATCH 09/14] =?UTF-8?q?=E7=99=BB=E5=BD=95=E3=80=82=E6=B3=A8?= =?UTF-8?q?=E5=86=8C=E3=80=82=E9=AA=8C=E8=AF=81=E7=A0=81=20(#271)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修改shiro配置,对/user/*的请求不继续登录验证拦截 --ShiroConfig.java * 添加了注册,登录接口 --LoginController.java 修改登录请求dto,使得符合Apifox定义接口请求属性 --LoginDTO.java * 为数据库sys_user表补全创建者的字段 --202503101631.sql --db.changelog-master.yaml * 修改系统上下文路径的前缀,使得符合Apifox的接口请求前缀 --application.yml * 注册接口补上验证码判断 --LoginController.java --- .../modules/security/config/ShiroConfig.java | 1 + .../security/controller/LoginController.java | 63 ++++++++++++++----- .../modules/security/dto/LoginDTO.java | 6 +- .../src/main/resources/application.yml | 2 +- .../resources/db/changelog/202503101631.sql | 2 + .../db/changelog/db.changelog-master.yaml | 9 ++- 6 files changed, 62 insertions(+), 21 deletions(-) create mode 100644 main/manager-api/src/main/resources/db/changelog/202503101631.sql diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java b/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java index 678c546e..29f6b706 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/config/ShiroConfig.java @@ -69,6 +69,7 @@ public class ShiroConfig { filterMap.put("/captcha", "anon"); filterMap.put("/favicon.ico", "anon"); filterMap.put("/mobile/**", "anon"); + filterMap.put("/user/**", "anon"); filterMap.put("/**", "oauth2"); shiroFilter.setFilterChainDefinitionMap(filterMap); diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java b/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java index 82051dab..3f549ffb 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/controller/LoginController.java @@ -2,41 +2,37 @@ package xiaozhi.modules.security.controller; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import lombok.AllArgsConstructor; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import xiaozhi.common.exception.ErrorCode; -import xiaozhi.common.redis.RedisUtils; -import xiaozhi.common.utils.PropertiesUtils; +import xiaozhi.common.exception.RenException; import xiaozhi.common.utils.Result; import xiaozhi.common.validator.AssertUtils; import xiaozhi.modules.security.dto.LoginDTO; +import xiaozhi.modules.security.password.PasswordUtils; import xiaozhi.modules.security.service.CaptchaService; import xiaozhi.modules.security.service.SysUserTokenService; -import xiaozhi.modules.sys.service.SysParamsService; +import xiaozhi.modules.sys.dto.SysUserDTO; import xiaozhi.modules.sys.service.SysUserService; import java.io.IOException; /** - * 登录 + * 登录控制层 */ +@Tag(name = "登录管理") @AllArgsConstructor @RestController +@RequestMapping("/user") @Tag(name = "登录管理") public class LoginController { private final SysUserService sysUserService; private final SysUserTokenService sysUserTokenService; private final CaptchaService captchaService; - private final RedisUtils redisUtils; - private final SysParamsService sysParamsService; - private final PropertiesUtils propertiesUtils; - @GetMapping("captcha") + + @GetMapping("/captcha") @Operation(summary = "验证码") public void captcha(HttpServletResponse response, String uuid) throws IOException { //uuid不能为空 @@ -46,10 +42,45 @@ public class LoginController { captchaService.create(response, uuid); } - @PostMapping("login") + @PostMapping("/login") @Operation(summary = "登录") - public Result login(HttpServletRequest request, @RequestBody LoginDTO login) { - return sysUserTokenService.createToken(1L); + public Result login( @RequestBody LoginDTO login) { + // 验证是否正确输入验证码 + boolean validate = captchaService.validate(login.getCaptchaId(), login.getCaptcha()); + if (!validate) { + throw new RenException("验证码错误,请重新获取"); + } + // 按照用户名获取用户 + SysUserDTO userDTO = sysUserService.getByUsername(login.getMobile()); + // 判断用户是否存在 + if (userDTO == null) { + throw new RenException("请检测用户和密码是否输入错误"); + } + // 判断密码是否正确,不一样则进入if + if (!PasswordUtils.matches(login.getPassword(), userDTO.getPassword())) { + throw new RenException("请检测用户和密码是否输入错误"); + } + return sysUserTokenService.createToken(userDTO.getId()); + } + + @PostMapping("/register") + @Operation(summary = "注册") + public Result register(@RequestBody LoginDTO login) { + // 验证是否正确输入验证码 + boolean validate = captchaService.validate(login.getCaptchaId(), login.getCaptcha()); + if (!validate) { + throw new RenException("验证码错误,请重新获取"); + } + // 按照用户名获取用户 + SysUserDTO userDTO = sysUserService.getByUsername(login.getMobile()); + if (userDTO != null){ + throw new RenException("此手机号码已经注册过"); + } + userDTO = new SysUserDTO(); + userDTO.setUsername(login.getMobile()); + userDTO.setPassword(login.getPassword()); + sysUserService.save(userDTO); + return new Result(); } } \ No newline at end of file diff --git a/main/manager-api/src/main/java/xiaozhi/modules/security/dto/LoginDTO.java b/main/manager-api/src/main/java/xiaozhi/modules/security/dto/LoginDTO.java index 67f50f19..076324ef 100644 --- a/main/manager-api/src/main/java/xiaozhi/modules/security/dto/LoginDTO.java +++ b/main/manager-api/src/main/java/xiaozhi/modules/security/dto/LoginDTO.java @@ -13,9 +13,9 @@ import java.io.Serializable; @Schema(description = "登录表单") public class LoginDTO implements Serializable { - @Schema(description = "用户名", required = true) + @Schema(description = "手机号码") @NotBlank(message = "{sysuser.username.require}") - private String username; + private String mobile; @Schema(description = "密码") @NotBlank(message = "{sysuser.password.require}") @@ -27,6 +27,6 @@ public class LoginDTO implements Serializable { @Schema(description = "唯一标识") @NotBlank(message = "{sysuser.uuid.require}") - private String uuid; + private String captchaId; } \ No newline at end of file diff --git a/main/manager-api/src/main/resources/application.yml b/main/manager-api/src/main/resources/application.yml index 0b0e6281..967f610e 100644 --- a/main/manager-api/src/main/resources/application.yml +++ b/main/manager-api/src/main/resources/application.yml @@ -7,7 +7,7 @@ server: min-spare: 30 port: 8002 servlet: - context-path: /xiaozhi-esp32-api + context-path: /xiaozhi-esp32-api/api/v1 session: cookie: http-only: true diff --git a/main/manager-api/src/main/resources/db/changelog/202503101631.sql b/main/manager-api/src/main/resources/db/changelog/202503101631.sql new file mode 100644 index 00000000..4055cad5 --- /dev/null +++ b/main/manager-api/src/main/resources/db/changelog/202503101631.sql @@ -0,0 +1,2 @@ +-- 给用户表添加一个创建者 +ALTER TABLE sys_user ADD COLUMN creator BIGINT COMMENT '创建者'; \ No newline at end of file diff --git a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml index 73d916fa..563858cc 100755 --- a/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml +++ b/main/manager-api/src/main/resources/db/changelog/db.changelog-master.yaml @@ -8,4 +8,11 @@ databaseChangeLog: changes: - sqlFile: encoding: utf8 - path: classpath:db/changelog/001create_sys.sql \ No newline at end of file + path: classpath:db/changelog/001create_sys.sql + - changeSet: + id: 202503101631 + author: zjy + changes: + - sqlFile: + encoding: utf8 + path: classpath:db/changelog/202503101631.sql From 3d6bd0e23e0c8fa6a1c09c4feea57711769f1183 Mon Sep 17 00:00:00 2001 From: vonweller <154695311+vonweller@users.noreply.github.com> Date: Tue, 11 Mar 2025 21:10:44 +0800 Subject: [PATCH 10/14] =?UTF-8?q?=E4=BF=AE=E5=A4=8DActionResponse=E4=B8=BA?= =?UTF-8?q?NOTFOUND=E6=97=B6=E5=80=99=E5=8D=A1=E4=BD=8F=E4=B8=BB=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E7=9A=84bug=20(#285)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复ActionResponse为NOTFOUND时候卡住主线程的bug --- main/xiaozhi-server/core/connection.py | 3 +++ main/xiaozhi-server/core/handle/intentHandler.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 80c62336..65696403 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -437,6 +437,9 @@ class ConnectionHandler: self.dialogue.put(Message(role="assistant", content=text)) if result.action == Action.REQLLM: # 调用函数后再请求llm生成回复 text = result.response + if result.action == Action.NOTFOUND: + text = result.response + def _tts_priority_thread(self): diff --git a/main/xiaozhi-server/core/handle/intentHandler.py b/main/xiaozhi-server/core/handle/intentHandler.py index 2dde6255..da0f5c91 100644 --- a/main/xiaozhi-server/core/handle/intentHandler.py +++ b/main/xiaozhi-server/core/handle/intentHandler.py @@ -67,7 +67,7 @@ def handle_llm_function_call(conn, function_call_data): except Exception as e: logger.bind(tag=TAG).error(f"处理音乐意图错误: {e}") else: - return ActionResponse(action=Action.NOTFOUND, result="没有找到对应的函数", response="") + return ActionResponse(action=Action.NOTFOUND, result="没有找到对应的函数", response="没有找到对应的函数处理相对于的功能呢,你可以需要添加预设的对应函数处理呢") except Exception as e: logger.bind(tag=TAG).error(f"处理function call错误: {e}") From 7c5f2d95a40fed2c0b2a5de7fb50678ffe80fc4d Mon Sep 17 00:00:00 2001 From: kalicyh <34980061+kalicyh@users.noreply.github.com> Date: Wed, 12 Mar 2025 10:57:25 +0800 Subject: [PATCH 11/14] =?UTF-8?q?=F0=9F=8E=88=20perf:=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E6=96=87=E6=A1=A3+=E4=BC=98=E9=9B=85=E7=9A=84=E9=80=80?= =?UTF-8?q?=E5=87=BA=20(#292)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 🎈 perf: 更新文档+优雅的退出 * update:gsv代码可以使用gpt_sovits_v2适配器代码拓展,不需要单独。如果需要定义模型名称,可以在gpt_sovits_v2代码中添加扩展 --------- Co-authored-by: hrz <1710360675@qq.com> --- docs/Deployment.md | 22 +--- .../main/java/xiaozhi/AdminApplication.java | 2 +- main/xiaozhi-server/app.py | 33 ++++- main/xiaozhi-server/config.yaml | 30 ----- main/xiaozhi-server/core/providers/tts/GSV.py | 123 ------------------ 5 files changed, 33 insertions(+), 177 deletions(-) delete mode 100644 main/xiaozhi-server/core/providers/tts/GSV.py diff --git a/docs/Deployment.md b/docs/Deployment.md index 0dfd93b5..94b6e363 100644 --- a/docs/Deployment.md +++ b/docs/Deployment.md @@ -117,7 +117,7 @@ docker run -it --name xiaozhi-env --restart always --security-opt seccomp:unconf -p 8000:8000 \ -p 8002:8002 \ -v ./:/app \ - kalicyh/poetry:v3.10_xiaozhi + kalicyh/python:xiaozhi ``` 然后就和正常开发一样了 @@ -127,29 +127,13 @@ docker run -it --name xiaozhi-env --restart always --security-opt seccomp:unconf 在刚刚的打开的终端运行 ```sh -poetry install --no-root -``` - -```sh -apt-get update -apt-get install -y --no-install-recommends libopus0 ffmpeg -``` - -速度慢可以尝试使用清华镜像 - -```sh -echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list -echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list -echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware" >> /etc/apt/sources.list -echo "deb https://mirrors.tuna.tsinghua.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list -apt-get update -apt-get install -y --no-install-recommends libopus0 ffmpeg +pip install -r requirements.txt ``` ## 6.运行项目 ```sh -poetry run python app.py +python app.py ``` # 方式三:本地源码运行 diff --git a/main/manager-api/src/main/java/xiaozhi/AdminApplication.java b/main/manager-api/src/main/java/xiaozhi/AdminApplication.java index 87edd510..8a96edb2 100644 --- a/main/manager-api/src/main/java/xiaozhi/AdminApplication.java +++ b/main/manager-api/src/main/java/xiaozhi/AdminApplication.java @@ -8,6 +8,6 @@ public class AdminApplication { public static void main(String[] args) { SpringApplication.run(AdminApplication.class, args); - System.out.println("http://localhost:8002/xiaozhi-esp32-api/doc.html"); + System.out.println("http://localhost:8002/xiaozhi-esp32-api/api/v1/doc.html"); } } \ No newline at end of file diff --git a/main/xiaozhi-server/app.py b/main/xiaozhi-server/app.py index bd23c7bc..ca3ab545 100644 --- a/main/xiaozhi-server/app.py +++ b/main/xiaozhi-server/app.py @@ -1,10 +1,27 @@ import asyncio +import sys +import signal from config.settings import load_config, check_config_file from core.websocket_server import WebSocketServer from core.utils.util import check_ffmpeg_installed TAG = __name__ +async def wait_for_exit(): + """Windows 和 Linux 兼容的退出监听""" + loop = asyncio.get_running_loop() + stop_event = asyncio.Event() + + if sys.platform == "win32": + # Windows: 用 sys.stdin.read() 监听 Ctrl + C + await loop.run_in_executor(None, sys.stdin.read) + else: + # Linux/macOS: 用 signal 监听 Ctrl + C + def stop(): + stop_event.set() + loop.add_signal_handler(signal.SIGINT, stop) + loop.add_signal_handler(signal.SIGTERM, stop) # 支持 kill 进程 + await stop_event.wait() async def main(): check_config_file() @@ -16,11 +33,19 @@ async def main(): ws_task = asyncio.create_task(ws_server.start()) try: - # 等待 WebSocket 服务器运行 - await ws_task + await wait_for_exit() # 监听退出信号 + except asyncio.CancelledError: + print("任务被取消,清理资源中...") finally: ws_task.cancel() - + try: + await ws_task + except asyncio.CancelledError: + pass + print("服务器已关闭,程序退出。") if __name__ == "__main__": - asyncio.run(main()) + try: + asyncio.run(main()) + except KeyboardInterrupt: + print("手动中断,程序终止。") diff --git a/main/xiaozhi-server/config.yaml b/main/xiaozhi-server/config.yaml index c8fbdb9f..a441930f 100644 --- a/main/xiaozhi-server/config.yaml +++ b/main/xiaozhi-server/config.yaml @@ -311,36 +311,6 @@ TTS: media_type: "wav" streaming_mode: false threshold: 30 - GSV: - # GSV原神本地语音合成 - # 整合包下载:https://pan.ai-hobbyist.com/Infer%20Packs/TTS - # 国内镜像:https://alist.hancat.work/d/cdn/GPT-Sovits%E8%AF%AD%E9%9F%B3%E5%90%88%E6%88%90%E6%95%B4%E5%90%88%E5%8C%85%EF%BC%8C%E6%94%AF%E6%8C%81%E5%A4%9A%E4%BA%BA%E5%AF%B9%E8%AF%9D%E3%80%82%E6%B0%B8%E4%B9%85%E5%85%8D%E8%B4%B9%EF%BC%8C%E4%B8%A5%E7%A6%81%E5%80%92%E5%8D%96%EF%BC%81.7z - # 本TTS需要配合模型来使用,模型可以去这里下载: - # 二次元 & 游戏角色 GPT-Sovits V2 语音合成模型:https://www.modelscope.cn/models/aihobbyist/Anime_GPT-Sovits_Models - # 下载后将其解压到model文件夹 - # URL需要修改批处理文件才可生效,默认WebUI端口号为8080,API端口号为WebUI端口号+1 - url: "http://127.0.0.1:9881/infer_single" - app_key: "" - audio_dl_url: "http://127.0.0.1:9881" - model_name: "【原神】须弥" - speaker_name: "纳西妲" - prompt_text_lang: "中文" - emocton: "中立_neutral" - text_lang: "中文" - top_k: 10 - top_p: 1 - temperature: 1 - text_split_method: "按标点符号切" - batch_size: 10 - batch_size: 0.75 - split_bucket: true - speed_facter: 1 - fragment_interval: 0.3 - media_type: "wav" - parallel_infer: true - repetition_penalty: 1.35 - seed: -1 - output_file: tmp/ MinimaxTTS: # Minimax语音合成服务,需要先在minimax平台创建账户充值,并获取登录信息 # 平台地址:https://platform.minimaxi.com/ diff --git a/main/xiaozhi-server/core/providers/tts/GSV.py b/main/xiaozhi-server/core/providers/tts/GSV.py deleted file mode 100644 index 7a156c29..00000000 --- a/main/xiaozhi-server/core/providers/tts/GSV.py +++ /dev/null @@ -1,123 +0,0 @@ -import os -import uuid -import requests -from config.logger import setup_logging -from datetime import datetime -from core.providers.tts.base import TTSProviderBase - -TAG = __name__ -logger = setup_logging() - -class TTSProvider(TTSProviderBase): - def __init__(self, config, delete_audio_file): - super().__init__(config, delete_audio_file) - # POST请求地址 - self.url = config.get("url") - # 从配置中加载所有参数 - self.app_key = config.get("app_key") - self.audio_dl_url = config.get("audio_dl_url") - self.model_name = config.get("model_name") - self.speaker_name = config.get("speaker_name") - self.prompt_text_lang = config.get("prompt_text_lang") - self.emotion = config.get("emotion") - self.text_lang = config.get("text_lang") - self.top_k = config.get("top_k") - self.top_p = config.get("top_p") - self.temperature = config.get("temperature") - self.text_split_method = config.get("text_split_method") - self.batch_size = config.get("batch_size") - self.batch_threshold = config.get("batch_size") - self.split_bucket = config.get("split_bucket") - self.speed_facter = config.get("speed_facter") - self.fragment_interval = config.get("fragment_interval") - self.media_type = config.get("media_type") - self.parallel_infer = config.get("parallel_infer") - self.repetition_penalty = config.get("repetition_penalty") - self.seed = config.get("seed") - - def generate_filename(self): - """根据媒体类型生成文件名""" - extension = f".{self.media_type}" - return os.path.join( - self.output_file, - f"tts-{datetime.now().date()}@{uuid.uuid4().hex}{extension}" - ) - - async def text_to_speak(self, text, output_file): - """文本转语音并保存音频文件""" - # 构造请求体 - request_body = { - "app_key": self.app_key, - "audio_dl_url": self.audio_dl_url, - "model_name": self.model_name, - "speaker_name": self.speaker_name, - "prompt_text_lang": self.prompt_text_lang, - "emotion": self.emotion, - "text": text, - "text_lang": self.text_lang, - "top_k": self.top_k, - "top_p": self.top_p, - "temperature": self.temperature, - "text_split_method": self.text_split_method, - "batch_size": self.batch_size, - "batch_threshold": self.batch_threshold, - "split_bucket": self.split_bucket, - "speed_facter": self.speed_facter, - "fragment_interval": self.fragment_interval, - "media_type": self.media_type, - "parallel_infer": self.parallel_infer, - "repetition_penalty": self.repetition_penalty, - "seed": self.seed - } - - body = { - "app_key": "", - "audio_dl_url": "http://127.0.0.1:9881", - "model_name": "【原神】须弥", - "speaker_name": "纳西妲", - "prompt_text_lang": "中文", - "emotion": "中立_neutral", - "text": text, - "text_lang": "中文", - "top_k": 10, - "top_p": 1, - "temperature": 1, - "text_split_method": "按标点符号切", - "batch_size": 10, - "batch_threshold": 0.75, - "split_bucket": True, - "speed_facter": 1, - "fragment_interval": 0.3, - "media_type": "wav", - "parallel_infer": True, - "repetition_penalty": 1.35, - "seed": -1 - } - - try: - # 发送POST请求 - resp = requests.post(self.url, json=body) - resp.raise_for_status() - - # 解析响应 - result = resp.json() - if "audio_url" not in result: - logger.bind(tag=TAG).error("响应中缺少音频地址") - return - - # 下载音频文件 - audio_resp = requests.get(result["audio_url"]) - audio_resp.raise_for_status() - - # 保存文件 - with open(output_file, "wb") as f: - f.write(audio_resp.content) - - logger.bind(tag=TAG).info(f"音频文件已保存至: {output_file}") - - except requests.exceptions.HTTPError as e: - logger.bind(tag=TAG).error(f"HTTP请求失败: {str(e)}") - except requests.exceptions.JSONDecodeError: - logger.bind(tag=TAG).error("响应解析失败,无效的JSON格式") - except Exception as e: - logger.bind(tag=TAG).error(f"语音合成失败: {str(e)}") \ No newline at end of file From 81fee53085f6dde12ec6d7909f09b645e0f5a480 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A3=E5=8D=97=E7=A7=91=E6=8A=80?= Date: Wed, 12 Mar 2025 12:44:25 +0800 Subject: [PATCH 12/14] =?UTF-8?q?=E7=BB=91=E5=AE=9A=E8=AE=BE=E5=A4=87?= =?UTF-8?q?=E5=8A=9F=E8=83=BD=20(#294)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: CGD <3030332422@qq.com> --- main/manager-web/src/apis/module/user.js | 16 ++++++++++++++++ main/manager-web/src/views/home.vue | 23 ++++++++++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/main/manager-web/src/apis/module/user.js b/main/manager-web/src/apis/module/user.js index 7a6815b2..3326d4d4 100755 --- a/main/manager-web/src/apis/module/user.js +++ b/main/manager-web/src/apis/module/user.js @@ -58,4 +58,20 @@ export default { }); }).send() }, + // 绑定设备 + bindDevice(deviceCode, callback) { + RequestService.sendRequest() + .url(`${getServiceUrl()}/api/v1/user/device/bind/${deviceCode}`) + .method('POST') + .success((res) => { + RequestService.clearRequestTime(); + callback(res); + }) + .fail((err) => { + console.error('绑定设备失败:', err); + RequestService.reAjaxFun(() => { + this.bindDevice(deviceCode, callback); + }); + }).send(); + } } diff --git a/main/manager-web/src/views/home.vue b/main/manager-web/src/views/home.vue index 2ed345d6..4d0181f5 100644 --- a/main/manager-web/src/views/home.vue +++ b/main/manager-web/src/views/home.vue @@ -210,7 +210,7 @@
-
确定
+
确定
@@ -234,7 +234,7 @@ export default { filteredDeviceList: [], // 过滤后的设备列表 switchValue: false, addDeviceDialogVisible: false, - deviceCode: "", + deviceCode: "", // 设备验证码 settingDevice: false, form: { name: "", @@ -257,7 +257,7 @@ export default { }, methods: { showAddDialog() { - this.addDeviceDialogVisible = true; + this.addDeviceDialogVisible = true; }, clickSettingDevice() { this.settingDevice = true @@ -312,6 +312,23 @@ export default { this.$message.info('已取消解绑'); }); }, + // 添加设备 + addDevice() { + if (!this.deviceCode) { + this.$message.warning('请输入设备验证码'); + return; + } + + Api.user.bindDevice(this.deviceCode, ({ data }) => { + if (data.code === 0) { + this.$message.success('设备绑定成功'); + this.addDeviceDialogVisible = false; + this.getList(); // 刷新设备列表 + } else { + this.$message.error(data.msg || '设备绑定失败'); + } + }); + } }, mounted() { this.fetchUserInfo(); // 组件加载时获取用户信息 From a8c6c7cb36688d36ea63574a58662da0305314ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AC=A3=E5=8D=97=E7=A7=91=E6=8A=80?= Date: Wed, 12 Mar 2025 12:46:29 +0800 Subject: [PATCH 13/14] =?UTF-8?q?update:=E4=BC=98=E5=8C=96=E6=97=A0?= =?UTF-8?q?=E6=84=8F=E5=9B=BE=E8=AF=86=E5=88=AB=E7=9A=84=E6=97=A5=E5=BF=97?= =?UTF-8?q?=E8=BE=93=E5=87=BA=20(#295)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: hrz <1710360675@qq.com> --- main/xiaozhi-server/core/connection.py | 2 -- main/xiaozhi-server/core/handle/intentHandler.py | 3 --- .../core/providers/intent/intent_llm/intent_llm.py | 7 ++++--- main/xiaozhi-server/core/websocket_server.py | 2 ++ 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/main/xiaozhi-server/core/connection.py b/main/xiaozhi-server/core/connection.py index 65696403..0ff1ac0e 100644 --- a/main/xiaozhi-server/core/connection.py +++ b/main/xiaozhi-server/core/connection.py @@ -95,8 +95,6 @@ class ConnectionHandler: if self.config["selected_module"]["Intent"] == 'function_call': self.use_function_call_mode = True - self.logger.bind(tag=TAG).info(f"use_function_call_mode:{self.use_function_call_mode}") - async def handle_connection(self, ws): try: # 获取并验证headers diff --git a/main/xiaozhi-server/core/handle/intentHandler.py b/main/xiaozhi-server/core/handle/intentHandler.py index da0f5c91..d651cc05 100644 --- a/main/xiaozhi-server/core/handle/intentHandler.py +++ b/main/xiaozhi-server/core/handle/intentHandler.py @@ -93,8 +93,6 @@ async def handle_user_intent(conn, text): # 使用支持function calling的聊天方法,不再进行意图分析 return False - logger.bind(tag=TAG).info(f"分析用户意图: {text}") - # 使用LLM进行意图分析 intent = await analyze_intent_with_llm(conn, text) @@ -126,7 +124,6 @@ async def analyze_intent_with_llm(conn, text): dialogue = conn.dialogue try: intent_result = await conn.intent.detect_intent(dialogue.dialogue, text) - logger.bind(tag=TAG).info(f"意图识别结果: {intent_result}") # 尝试解析JSON结果 try: diff --git a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py index 191f73df..198fa59f 100644 --- a/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py +++ b/main/xiaozhi-server/core/providers/intent/intent_llm/intent_llm.py @@ -38,6 +38,7 @@ class IntentProvider(IntentProviderBase): return prompt async def detect_intent(self, dialogue_history: List[Dict], text:str) -> str: + logger.bind(tag=TAG).info(f"分析用户意图: {text}") if not self.llm: raise ValueError("LLM provider not set") @@ -55,6 +56,6 @@ class IntentProvider(IntentProviderBase): system_prompt=self.promot, user_prompt=user_prompt ) - - logger.bind(tag=TAG).info(f"Detected intent: {intent}") - return intent.strip() + intent_result = intent.strip() + logger.bind(tag=TAG).info(f"意图识别结果: {intent_result}") + return intent_result diff --git a/main/xiaozhi-server/core/websocket_server.py b/main/xiaozhi-server/core/websocket_server.py index 14d16497..9bb2963f 100644 --- a/main/xiaozhi-server/core/websocket_server.py +++ b/main/xiaozhi-server/core/websocket_server.py @@ -65,6 +65,8 @@ class WebSocketServer: server_config = self.config["server"] host = server_config["ip"] port = server_config["port"] + selected_module = self.config.get("selected_module") + self.logger.bind(tag=TAG).info(f"selected_module: {selected_module}") self.logger.bind(tag=TAG).info("Server is running at ws://{}:{}", get_local_ip(), port) self.logger.bind(tag=TAG).info("=======上面的地址是websocket协议地址,请勿用浏览器访问=======") From 0a26ad89254b78888ad865c5568d7f6ff08083d5 Mon Sep 17 00:00:00 2001 From: lucky_feng Date: Wed, 12 Mar 2025 13:38:44 +0800 Subject: [PATCH 14/14] Manager code login (#276) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * update:增加前端设计图 * 前端代码优化 * update:底部信息纠正 * 增加:flyio * update:去除org.quartz * update:登陆功能 * aliyunTTS常联token * 新增aliyunTTS长期Token方式 * 超时错误处理 * 本地编译文件 * 验证码获取 * 验证码获取测试 * 验证码展示 * 登录成功 * delete 测试代码 * 注册页面 * Register 风格统一 * web验证码登录注册 * 登录注册功能 * update:登陆注册api结果优化 * delete:删除未用到的代码 --------- Co-authored-by: hrz <1710360675@qq.com> Co-authored-by: CGD <3030332422@qq.com> Co-authored-by: 欣南科技 --- main/manager-web/package-lock.json | 260 +---------------------- main/manager-web/package.json | 1 - main/manager-web/public/favicon.ico | Bin 4286 -> 4286 bytes main/manager-web/public/index.html | 2 +- main/manager-web/src/apis/api.js | 5 +- main/manager-web/src/apis/httpRequest.js | 24 ++- main/manager-web/src/apis/module/user.js | 33 ++- main/manager-web/src/router/index.js | 15 +- main/manager-web/src/views/auth.scss | 132 ++++++++++++ main/manager-web/src/views/login.vue | 188 ++++------------ main/manager-web/src/views/register.vue | 162 ++++++++++++++ main/manager-web/vue.config.js | 14 ++ 12 files changed, 429 insertions(+), 407 deletions(-) create mode 100644 main/manager-web/src/views/auth.scss create mode 100644 main/manager-web/src/views/register.vue create mode 100644 main/manager-web/vue.config.js diff --git a/main/manager-web/package-lock.json b/main/manager-web/package-lock.json index f3044557..cbfc40df 100644 --- a/main/manager-web/package-lock.json +++ b/main/manager-web/package-lock.json @@ -8,7 +8,6 @@ "name": "xiaozhi", "version": "0.1.0", "dependencies": { - "axios": "^1.8.1", "element-ui": "^2.15.14", "flyio": "^0.6.14", "normalize.css": "^8.0.1", @@ -325,48 +324,6 @@ "@parcel/watcher-win32-x64": "2.5.1" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/watcher-darwin-x64": { "version": "2.5.1", "resolved": "https://registry.npmmirror.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", @@ -388,216 +345,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", - "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", - "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", - "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", - "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", - "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmmirror.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", - "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@polka/url": { "version": "1.0.0-next.28", "resolved": "https://registry.npmmirror.com/@polka/url/-/url-1.0.0-next.28.tgz", @@ -1777,6 +1524,7 @@ "resolved": "https://registry.npmmirror.com/axios/-/axios-1.8.2.tgz", "integrity": "sha512-ls4GYBm5aig9vWx8AWDSGLpnpDQRtWAfrjU+EuytuODrFBkqesN2RkOQCBzrA1RQNHw1SmRMSDDDSwzNAYQ6Rg==", "license": "MIT", + "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -3488,6 +3236,7 @@ "resolved": "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", "license": "MIT", + "peer": true, "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", @@ -3934,6 +3683,7 @@ "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.2.tgz", "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "license": "MIT", + "peer": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -4256,6 +4006,7 @@ "resolved": "https://registry.npmmirror.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", "license": "MIT", + "peer": true, "dependencies": { "has-symbols": "^1.0.3" }, @@ -7031,7 +6782,8 @@ "version": "1.1.0", "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/pseudomap": { "version": "1.0.2", diff --git a/main/manager-web/package.json b/main/manager-web/package.json index 05c696ca..e1423d6a 100644 --- a/main/manager-web/package.json +++ b/main/manager-web/package.json @@ -7,7 +7,6 @@ "build": "vue-cli-service build" }, "dependencies": { - "axios": "^1.8.1", "element-ui": "^2.15.14", "flyio": "^0.6.14", "normalize.css": "^8.0.1", diff --git a/main/manager-web/public/favicon.ico b/main/manager-web/public/favicon.ico index df36fcfb72584e00488330b560ebcf34a41c64c2..5f285a58d806c28b8c597f8e6fff3b7d3e720a49 100644 GIT binary patch literal 4286 zcmbtXcYIYv8l9H}0jY|D{zQndB4Lq$4FQoViog$CVO5Z|;1+2jARVMCHG(t&0cAsp zR0$m=21o)4g!GVv6jI(xc}ZSgyYJSs=e|c+{lhJKlP_~KcV^D{%FOqT5ElM~h6?kq zIM7mv)kcju#BcWzKa}`gi62f0BX(P; zN;4>Ki=T&LVsnnk16~mn6!bsQ7{XB|V>oO4+_|QJ;bfUQ7zWx!v*;t#*hCccSXVH1Yg z`n(+|GvRfv*9%f3q(dtY_%22!D>;`cl#t({|ao#1Tohgx1PR6L& zvFi+b=@jBlBA;QjL5uphgcgV+Lfw5#&-n38%(`l!o2|#$&2ZH&H%e|sNKwo8*3Ee_ zw{~Kf;#@ZtQo=#_Zk&cMxM zKMy(eEQQ$o-Q_&hVwwXq5(kkWBfeZ4rg7Tc@suqw-bSv?p?J-s8t_(bkWD7rW9bkd+z2aidX~wp`1* zdP*zHk~RBn=rv`~YpoR9&!h}Wbpbp@=ituY52^Axxa`jo2tY!A3uI+p+I4N5S;d5C`?_Tm*?Fy>MCJ)96U~{;i<@lGxs8#X(!;x zI0f&mi;zmL!D~%{BjW^WuI_@XBoUsfba?EU@YNJTtuBF9kw;skLAib$@{v`#eDzSV zcIEIiT!?&_xE4RYskh`drKM408?P6ot*4zO!&?WLI=a%%qHNbfq|Sc>@gEIF!nFQK zS@be;*Ns5Q&atS7dLNFn)8UMr5BIe-@T7kQDK84XvN-rEb0Jsc2V$fkk+!%1CF$r6 zL~nTvbKeQ};}>NIa)#vYU{u_GTesy!8SWZrk{j;yACWR=3^w*`g9V*JF!ynR`A-OZ z+QoupT|=xWJ6Z1U_mfFqQIg2Z2vGX3moWbNOv4$3{+Qh{A*6aA)p8;m900vu-kfqb44_>$bVzY&Cpq2&8CxslJ-5e;CA8UPn#MlPWZa$;Rt?4EI0 zIIIb#P8P^c6-c@ggqrejE$+}rB{4cp_jzcy6lBdFjn6ta#AjUl^rx**n*A)wD;_{a zNq1b`*$x{9&>!Tsvmm?8>mk%7?SNF44J9wm zP?L@<#FDYi(2ENrSzzsqU}VKVsYh@8lY0Ghx+Y89)5M?qHdc0NgtfHg<&Eu7PF$hx~$qzWO&Pqa64iizUuV|R&&_#8I4d7 z_dF_!pF>GTFT|{FfiJoKGU~VaWr1svk27tB!DbIaxwQ-8cRYfXw9lNb0*Q+sfaA&* z_-uLp^HIHVatYRqZ-U8vLon_6dojLkE92t+*LluWLvpgblKCsae)UomxX15EDG6!QnSH@1J&*GM=r!*G;aLEp1>fWaTBrV_TJ`;ok0 zGLF634gVb39N&xx##fC0b#&cw?#HE!`xSo_*fdz+;KUG|Uepv(9|j|WW9D%$?0Mr} z*ba<?s->S_qm^W2>NQpe_o2>w4b}`ij#;r#WVaKJ z8wn_n+JVA|SxBEZ8VQs7;oP`z92)uwlUOZ&P?r&}GJ?;AOfoe%wmCkeBJm&+t%Xjci^Z*B)uZrYh zOq9ZtpAJ__44jt^qW07#R7EX*|U-U=b=I*%lT^AIe?1hT+@1i#4C}evH z)N-E1g-LcT^TKGHifq88g_ihzTh>pziC^u^826lQ-Ft|v$QiZz%D@f(bcpIT%6atq?3 z#RhWFubpnDTW|Jd?5!}I_AAUebuf9DabR-cUNBUZr6pZMku}YaEh{SVW%ztP3VBEp zB(E1?OcdZ@XI>R6roiVAAhr(7-6v)Ju<$7!{vFRVT3tpF*w;a%jt=ACSmg7;2 zZtT25P@aLxT)!Zd;?ebck-vS)^P) zlc#20q8@qBX=|PNLFXB*k(b7}P`xgw^n*-npR)#PZ8>YDJZL59sakRB6vLX+5grfg zXjo8fXPuKS(7Z(e-{doZ2bd*T;29p;BY2<`Bngz3vlewUHmv!ryqhQXcP|+p>G^z& zUE0E0;=pn!XLdlnatvA)c@^C7i+YPSPuc~j@rTRQi~F}|X%~9K?RbcWYr=T5&`1I< zr@;Gf5%rgk-yiJ4#18|tP!;jrUJISvh;v(NnU^2+u6%R2XXXp*J=1!|d8YR&_Ri{8 zCoLT6_AP(i;afGfP+s?5jJ#>$N_F3|Ax2?(JI;H6fn&}WPWciNV0&HjeG|Co2gz&!sw zknjHoc0CXO8s<7xRRXoOcXhbaZy}B;LA0%fnhWAsRY_2rlA2{E4GXS^O))?%(tjaed+hYs90E+y4tFIc#45 literal 4286 zcmds*O-Phc6o&64GDVCEQHxsW(p4>LW*W<827=Unuo8sGpRux(DN@jWP-e29Wl%wj zY84_aq9}^Am9-cWTD5GGEo#+5Fi2wX_P*bo+xO!)p*7B;iKlbFd(U~_d(U?#hLj56 zPhFkj-|A6~Qk#@g^#D^U0XT1cu=c-vu1+SElX9NR;kzAUV(q0|dl0|%h|dI$%VICy zJnu2^L*Te9JrJMGh%-P79CL0}dq92RGU6gI{v2~|)p}sG5x0U*z<8U;Ij*hB9z?ei z@g6Xq-pDoPl=MANPiR7%172VA%r)kevtV-_5H*QJKFmd;8yA$98zCxBZYXTNZ#QFk2(TX0;Y2dt&WitL#$96|gJY=3xX zpCoi|YNzgO3R`f@IiEeSmKrPSf#h#Qd<$%Ej^RIeeYfsxhPMOG`S`Pz8q``=511zm zAm)MX5AV^5xIWPyEu7u>qYs?pn$I4nL9J!=K=SGlKLXpE<5x+2cDTXq?brj?n6sp= zphe9;_JHf40^9~}9i08r{XM$7HB!`{Ys~TK0kx<}ZQng`UPvH*11|q7&l9?@FQz;8 zx!=3<4seY*%=OlbCbcae?5^V_}*K>Uo6ZWV8mTyE^B=DKy7-sdLYkR5Z?paTgK-zyIkKjIcpyO z{+uIt&YSa_$QnN_@t~L014dyK(fOOo+W*MIxbA6Ndgr=Y!f#Tokqv}n<7-9qfHkc3 z=>a|HWqcX8fzQCT=dqVbogRq!-S>H%yA{1w#2Pn;=e>JiEj7Hl;zdt-2f+j2%DeVD zsW0Ab)ZK@0cIW%W7z}H{&~yGhn~D;aiP4=;m-HCo`BEI+Kd6 z={Xwx{TKxD#iCLfl2vQGDitKtN>z|-AdCN|$jTFDg0m3O`WLD4_s#$S diff --git a/main/manager-web/public/index.html b/main/manager-web/public/index.html index 3e5a1396..40f0613c 100644 --- a/main/manager-web/public/index.html +++ b/main/manager-web/public/index.html @@ -5,7 +5,7 @@ - <%= htmlWebpackPlugin.options.title %> + 小智-智控台
-
- - +
+
+ + +
+ 验证码
-
新用户注册
+
新用户注册
@@ -55,8 +63,9 @@ diff --git a/main/manager-web/src/views/register.vue b/main/manager-web/src/views/register.vue new file mode 100644 index 00000000..43de61e4 --- /dev/null +++ b/main/manager-web/src/views/register.vue @@ -0,0 +1,162 @@ + + + + + \ No newline at end of file diff --git a/main/manager-web/vue.config.js b/main/manager-web/vue.config.js new file mode 100644 index 00000000..01e210fa --- /dev/null +++ b/main/manager-web/vue.config.js @@ -0,0 +1,14 @@ +const { defineConfig } = require('@vue/cli-service'); +const dotenv = require('dotenv'); + +dotenv.config(); + +module.exports = defineConfig({ + devServer: { + // Bug 修复:将代理配置为环境变量中定义的 API 基础 URL + proxy: process.env.VUE_APP_API_BASE_URL, + client: { + overlay: false, + }, + } +})