手搓智能音箱——语音识别及调用大模型回应
一、代码概述
此 Python 代码实现了一个语音交互系统,主要功能为监听唤醒词,在唤醒后接收用户语音问题,利用百度语音识别将语音转换为文本,再调用 DeepSeek API 获取智能回复,最后使用文本转语音功能将回复朗读出来。
二、环境依赖
在运行此代码前,需要安装以下 Python 库:
baidu-aip:用于调用百度语音识别服务。pyttsx3:实现文本转语音功能。dotenv:用于加载环境变量。pyaudio:用于录制音频。wave:用于处理音频文件。requests:用于发送 HTTP 请求。json:用于处理 JSON 数据。
可以使用以下命令进行安装:
bash
pip install baidu-aip pyttsx3 python-dotenv pyaudio requests
三、环境变量配置
需要在项目根目录下创建一个 .env 文件,并添加以下环境变量:
plaintext
BAIDU_APP_ID=your_baidu_app_id
BAIDU_API_KEY=your_baidu_api_key
BAIDU_SECRET_KEY=your_baidu_secret_key
DEEPSEEK_API_KEY=your_deepseek_api_key
请将 your_baidu_app_id、your_baidu_api_key、your_baidu_secret_key 替换为你在百度语音平台申请的应用 ID、API 密钥和 Secret 密钥,将 your_deepseek_api_key 替换为你在 DeepSeek 平台申请的 API 密钥。
四、代码模块详细解释
1. 导入必要的库
python
from aip import AipSpeech
import pyttsx3
import os
from dotenv import load_dotenv
import wave
import pyaudio
import requests
import json
from datetime import datetime
AipSpeech:用于调用百度语音识别服务。pyttsx3:实现文本转语音功能。os:用于操作环境变量。load_dotenv:从.env文件中加载环境变量。wave:用于处理音频文件。pyaudio:用于录制音频。requests:用于发送 HTTP 请求。json:用于处理 JSON 数据。datetime:虽然代码中未实际使用,但可用于后续添加时间相关功能。
2. 加载环境变量并初始化客户端
python
# Load environment variables
load_dotenv()
APP_ID = os.getenv("BAIDU_APP_ID")
API_KEY = os.getenv("BAIDU_API_KEY")
SECRET_KEY = os.getenv("BAIDU_SECRET_KEY")# Initialize Baidu Speech client
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
load_dotenv():从.env文件中加载环境变量。AipSpeech:使用百度提供的应用 ID、API 密钥和 Secret 密钥初始化百度语音识别客户端。
3. 初始化文本转语音引擎
python
# Initialize text-to-speech
engine = pyttsx3.init()# Set Chinese voice if available, and choose a gentle female voice
voices = engine.getProperty('voices')
for voice in voices:# 检查音色是否为中文,并且音色名称中包含“female”或“woman”等关键词if 'chinese' in voice.name.lower() and ('female' in voice.name.lower() or 'woman' in voice.name.lower()):engine.setProperty('voice', voice.id)break
pyttsx3.init():初始化文本转语音引擎。- 通过遍历可用语音,选择支持中文且为女性的语音。
4. 调用 DeepSeek API 获取智能回复
python
def call_deepseek_api(prompt):"""Call DeepSeek API for intelligent response"""url = "https://api.deepseek.com/v1/chat/completions"headers = {"Content-Type": "application/json","Authorization": f"Bearer {os.getenv('DEEPSEEK_API_KEY')}"}data = {"model": "deepseek-chat","messages": [{"role": "user","content": prompt}],"temperature": 0.7,"max_tokens": 200}try:response = requests.post(url, headers=headers, json=data)response.raise_for_status()result = response.json()return result['choices'][0]['message']['content'].strip()except Exception as e:print(f"Error calling DeepSeek API: {str(e)}")return "抱歉,我暂时无法回答这个问题"
call_deepseek_api函数:接收用户的问题prompt,向 DeepSeek API 发送请求,获取智能回复。requests.post:发送 HTTP POST 请求。response.raise_for_status():检查请求是否成功。- 若请求失败,捕获异常并返回错误提示信息。
5. 录制音频
python
def record_audio(filename, record_seconds=5):"""Record audio from microphone"""CHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 1RATE = 16000p = pyaudio.PyAudio()stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)print("开始录音...")frames = []for _ in range(0, int(RATE / CHUNK * record_seconds)):data = stream.read(CHUNK)frames.append(data)print("录音结束")stream.stop_stream()stream.close()p.terminate()wf = wave.open(filename, 'wb')wf.setnchannels(CHANNELS)wf.setsampwidth(p.get_sample_size(FORMAT))wf.setframerate(RATE)wf.writeframes(b''.join(frames))wf.close()
record_audio函数:用于录制音频,将录制的音频保存为指定文件名的.wav文件。pyaudio.PyAudio():初始化 PyAudio 对象。p.open:打开音频输入流。wave.open:打开音频文件进行写入操作。
6. 监听唤醒词
python
def listen_for_wake_word(wake_word="小绿同学"):"""Listen for the wake word using Baidu Speech Recognition"""temp_file = "temp.wav"record_audio(temp_file, 3)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537 # Mandarin})if result.get('err_no') == 0:text = result['result'][0]if wake_word in text:return Truereturn False
listen_for_wake_word函数:录制 3 秒音频,使用百度语音识别将音频转换为文本,检查文本中是否包含唤醒词。client.asr:调用百度语音识别服务。
7. 获取回复
python
def get_response(prompt):"""Generate response using DeepSeek API"""return call_deepseek_api(prompt)
get_response函数:调用call_deepseek_api函数获取智能回复。
8. 文本转语音
python
def speak(text):"""Convert text to speech"""engine.say(text)engine.runAndWait()
speak函数:使用pyttsx3引擎将文本转换为语音并朗读出来。
9. 主函数
python
def main():print("小绿同学已启动,等待唤醒...")while True:if listen_for_wake_word():print("唤醒成功!请说出你的问题...")speak("您好,需要什么帮助")temp_file = "question.wav"record_audio(temp_file, 5)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537 # Mandarin})if result.get('err_no') == 0:user_input = result['result'][0]print(f"你说: {user_input}")response = get_response(user_input)print(f"小绿同学: {response}")speak(response)else:print("抱歉,我没有听清楚")speak("抱歉,我没有听清楚")if __name__ == "__main__":main()
main函数:程序的入口点,不断监听唤醒词,唤醒后录制用户问题,进行语音识别,调用 DeepSeek API 获取回复,并将回复朗读出来。
五、注意事项
- 确保
.env文件中的环境变量配置正确。 - 若网络连接不稳定或 DeepSeek API 服务不可用,可能会导致获取回复失败。
- 录音设备需要正常工作,否则可能无法录制音频。
完整代码
from aip import AipSpeech
import pyttsx3
import os
from dotenv import load_dotenv
import wave
import pyaudio
import requests
import json
from datetime import datetime# Load environment variables
load_dotenv()
APP_ID = os.getenv("BAIDU_APP_ID")
API_KEY = os.getenv("BAIDU_API_KEY")
SECRET_KEY = os.getenv("BAIDU_SECRET_KEY")# Initialize Baidu Speech client
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)# Initialize text-to-speech
engine = pyttsx3.init()# Set Chinese voice if available, and choose a gentle female voice
voices = engine.getProperty('voices')
for voice in voices:# 检查音色是否为中文,并且音色名称中包含“female”或“woman”等关键词if 'chinese' in voice.name.lower() and ('female' in voice.name.lower() or 'woman' in voice.name.lower()):engine.setProperty('voice', voice.id)break
def call_deepseek_api(prompt):"""Call DeepSeek API for intelligent response"""url = "https://api.deepseek.com/v1/chat/completions"headers = {"Content-Type": "application/json","Authorization": f"Bearer {os.getenv('DEEPSEEK_API_KEY')}"}data = {"model": "deepseek-chat","messages": [{"role": "user","content": prompt}],"temperature": 0.7,"max_tokens": 200}try:response = requests.post(url, headers=headers, json=data)response.raise_for_status()result = response.json()return result['choices'][0]['message']['content'].strip()except Exception as e:print(f"Error calling DeepSeek API: {str(e)}")return "抱歉,我暂时无法回答这个问题"def record_audio(filename, record_seconds=5):"""Record audio from microphone"""CHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 1RATE = 16000p = pyaudio.PyAudio()stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)print("开始录音...")frames = []for _ in range(0, int(RATE / CHUNK * record_seconds)):data = stream.read(CHUNK)frames.append(data)print("录音结束")stream.stop_stream()stream.close()p.terminate()wf = wave.open(filename, 'wb')wf.setnchannels(CHANNELS)wf.setsampwidth(p.get_sample_size(FORMAT))wf.setframerate(RATE)wf.writeframes(b''.join(frames))wf.close()def listen_for_wake_word(wake_word="小绿"):"""Listen for the wake word using Baidu Speech Recognition"""temp_file = "temp.wav"record_audio(temp_file, 3)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537 # Mandarin})if result.get('err_no') == 0:text = result['result'][0]if wake_word in text:return Truereturn Falsedef get_response(prompt):"""Generate response using DeepSeek API"""return call_deepseek_api(prompt)def speak(text):"""Convert text to speech"""engine.say(text)engine.runAndWait()def main():print("小绿已启动,等待唤醒...")while True:if listen_for_wake_word():print("唤醒成功!请说出你的问题...")speak("您好,需要什么帮助")temp_file = "question.wav"record_audio(temp_file, 5)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537 # Mandarin})if result.get('err_no') == 0:user_input = result['result'][0]print(f"你说: {user_input}")response = get_response(user_input)print(f"小绿: {response}")speak(response)else:print("抱歉,我没有听清楚")speak("抱歉,我没有听清楚")if __name__ == "__main__":main()
修改了一些,调用百度进行了语音合成输出,回答更自然一些
from aip import AipSpeech
import os
from dotenv import load_dotenv
import wave
import pyaudio
import requests
import json
from datetime import datetime
import pygame # 用于播放音频
import tempfile# Load environment variables
load_dotenv()
APP_ID = os.getenv("BAIDU_APP_ID")
API_KEY = os.getenv("BAIDU_API_KEY")
SECRET_KEY = os.getenv("BAIDU_SECRET_KEY")# Initialize Baidu Speech client
client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)def call_deepseek_api(prompt):"""Call DeepSeek API for intelligent response"""url = "https://api.deepseek.com/v1/chat/completions"headers = {"Content-Type": "application/json","Authorization": f"Bearer {os.getenv('DEEPSEEK_API_KEY')}"}data = {"model": "deepseek-chat","messages": [{"role": "user","content": prompt}],"temperature": 0.7,"max_tokens": 200}try:response = requests.post(url, headers=headers, json=data)response.raise_for_status()result = response.json()return result['choices'][0]['message']['content'].strip()except Exception as e:print(f"Error calling DeepSeek API: {str(e)}")return "抱歉,我暂时无法回答这个问题"def record_audio(filename, record_seconds=5):"""Record audio from microphone"""CHUNK = 1024FORMAT = pyaudio.paInt16CHANNELS = 1RATE = 16000p = pyaudio.PyAudio()stream = p.open(format=FORMAT,channels=CHANNELS,rate=RATE,input=True,frames_per_buffer=CHUNK)print("开始录音...")frames = []for _ in range(0, int(RATE / CHUNK * record_seconds)):data = stream.read(CHUNK)frames.append(data)print("录音结束")stream.stop_stream()stream.close()p.terminate()wf = wave.open(filename, 'wb')wf.setnchannels(CHANNELS)wf.setsampwidth(p.get_sample_size(FORMAT))wf.setframerate(RATE)wf.writeframes(b''.join(frames))wf.close()def listen_for_wake_word(wake_word="小绿"):"""Listen for the wake word using Baidu Speech Recognition"""temp_file = "temp.wav"record_audio(temp_file, 3)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537 # Mandarin})if result.get('err_no') == 0:text = result['result'][0]if wake_word in text:return Truereturn Falsedef get_response(prompt):"""Generate response using DeepSeek API"""return call_deepseek_api(prompt)def speak(text):"""Convert text to speech using Baidu TTS"""result = client.synthesis(text, 'zh', 1, {'vol': 5, # 音量,取值0-15,默认为5中音量'spd': 4, # 语速,取值0-9,默认为5中语速'pit': 5, # 音调,取值0-9,默认为5中语调'per': 4 # 发音人选择,0为女声,1为男声,3为度逍遥,4为度丫丫})if not isinstance(result, dict):# 使用临时文件with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as f:f.write(result)temp_path = f.name# 播放语音文件pygame.mixer.init()pygame.mixer.music.load(temp_path)pygame.mixer.music.play()# 等待播放完成while pygame.mixer.music.get_busy():pygame.time.Clock().tick(10) # 控制循环频率,避免占用过多 CPU# 强制释放资源pygame.mixer.music.stop()pygame.mixer.quit()# 播放完成后删除临时文件os.remove(temp_path)else:print(f"语音合成失败: {result}")def main():print("小绿已启动,等待唤醒...")while True:if listen_for_wake_word():print("您好,需要什么帮助....")speak("您好,需要什么帮助")temp_file = "question.wav"record_audio(temp_file, 5)with open(temp_file, 'rb') as f:audio_data = f.read()result = client.asr(audio_data, 'wav', 16000, {'dev_pid': 1537 # Mandarin})if result.get('err_no') == 0:user_input = result['result'][0]print(f"你说: {user_input}")response = get_response(user_input)print(f"小绿: {response}")speak(response)else:print("抱歉,我没有听清楚")speak("抱歉,我没有听清楚")if __name__ == "__main__":main()
相关文章:
手搓智能音箱——语音识别及调用大模型回应
一、代码概述 此 Python 代码实现了一个语音交互系统,主要功能为监听唤醒词,在唤醒后接收用户语音问题,利用百度语音识别将语音转换为文本,再调用 DeepSeek API 获取智能回复,最后使用文本转语音功能将回复朗读出来。 …...
Modbus通信协议基础知识总结
1. 数据类型与存储区分类 Modbus协议将数据分为四类存储区,通过存储区代号区分: 输出线圈(0x):可读写,对应二进制开关量(如继电器状态),地址范围000001-065536ÿ…...
vue3 + css 列表无限循环滚动+鼠标移入停止滚动+移出继续滚动
1.动画文件.vue <template><div class"dashboard" click"setFullScreen"><div class"warp-box"><el-scrollbar ref"scrollRef" height"100%" scroll"handelScroll"><div class"…...
使用 CryptoJS 实现 AES 解密:动态数据解密示例
在现代加密应用中,AES(高级加密标准)是一种广泛使用的对称加密算法。它的安全性高、效率好,适合用于各种加密任务。今天,我们将通过一个实际的示例,展示如何使用 CryptoJS 实现 AES 解密,解密动态数据。CryptoJS 是一个基于 JavaScript 的加密库,它支持 AES、DES 等多种…...
Go语言对于MySQL的基本操作
一.下载依赖 终端中输入: go get -u github.com/go-sql-driver/mysql 导入包 import ("database/sql"_ "github.com/go-sql-driver/mysql" ) 二.案例 package main//go get-u github.com/go-sql-driver/mysql 获取驱动 import ("databa…...
AndroidStudio下载安装,环境部署以及常见问题解决教程(亲测)
AndroidStudio下载安装,环境部署以及常见问题解决!!! 文章目录 前言 一、Android Studio 下载与安装 1.1 系统要求 1.2 下载 Android Studio 1.3 安装 Android Studio Windows 系统 1.4 初始配置 二、环境部署 2.1 安装 …...
开源免费一句话生成儿童故事视频核心思想解析
再看一个演示视频,学会核心思想后,可以打造自己的内容生成工具,后文有基于飞书多维表格的实现效果: 一句话灵感生成儿童故事视频演示 这是一款专门为内容素材创作打造的创新工具,可根据用户输入的主题,快速…...
数据结构——最短路(BFS,Dijkstra,Floyd)
完整版可以看我的最短路问题模版总结_稠密图最短路-CSDN博客 考研数据结构只考BFS,Dijkstra和Floyd 下面代码以Acwing模板题为例 BFS代码 适用类型: 1.单源最短路径 2.无权图 3.不适用于带权图和负权回路图 //Acwing走迷宫bfs #include<bits/stdc.h>usi…...
Kali Linux汉化教程:轻松设置中文界面
1.打开终端 2.输入sudo dpkg-reconfigure locales,回车,输入密码,回车 sudo dpkg-reconfigure locales 3.往下滑,滑到底,找到‘zh_CN.UTF-8 UTF-8’,回车 4.选择‘zh_CN.UTF-8’,回车 5.没有 ‘zh_CN.UTF-8’选项的特…...
分布式锁: 并发时,redis如何避免删别人的锁
在使用Redis实现分布式锁的时候,如何避免在并发情况下误删别人的锁。首先,分布式锁的基本概念:是多个客户端在访问共享资源时,通过某种机制来确保同一时间只有一个客户端能持有锁。 Redis通常用SET命令加上NX选项来创建锁…...
Leetcode 160 Intersection of Two Linked Lists
题意 给定两个链表,找这两个链表第一个公共节点,如果没有返回nullptr 题目链接 https://leetcode.com/problems/intersection-of-two-linked-lists/description/ 题解 两个指针分别从两个链表(记录为表A,表B)的表…...
【八股文】从浏览器输入一个url到服务器的流程
1.url解析与DNS解析 浏览器解析用户输入的URL,提取协议(HTTP\HTTPS)、域名、端口及路径等信息 浏览器首先检查本地DNS缓存和系统DNS缓存,若未命中,查询本地hosts文件 最后递归查询向本地DNS服务器发起请求ÿ…...
C++和标准库速成(八)——指针、动态数组、const、constexpr和consteval
目录 1. 指针和动态数组1.1 栈和自由存储区1.2 使用指针1.3 动态分配的数组1.4 空指针常量 2. const2.1 const修饰类型2.2 const与指针2.3 使用const保护参数2.4 const方法(建议) 3. constexpr4. consteval参考 1. 指针和动态数组 动态内存允许所创建的程序具有在编…...
超声重建,3D重建 超声三维重建,三维可视化平台 UR 3D Reconstruction
1. 超声波3D重建技术的实现方法与算法 技术概述 3D超声重建是一种基于2D超声图像生成3D体积数据的技术,广泛应用于医学影像领域。通过重建和可视化三维结构,3D超声能够显著提高诊断精度和效率,同时减少医生的脑力负担。本技术文档将详细阐述…...
[HelloCTF]PHPinclude-labs超详细WP-Level 6Level 7Level 8Level 9-php://协议
由于Level 6-9 关的原理都是通用的, 这里就拿第6关举例, 其他的关卡同理 源码分析 定位到代码 isset($_GET[wrappers]) ? include("php://".$_GET[wrappers]) : ; 与前几关发生变化的就是 php:// 解题分析 这一关要求我们使用 php协议 php:// 协议 php://filte…...
【Linux】Bash是什么?怎么使用?
李升伟 整理 什么是 Bash? Bash(Bourne Again Shell)是一种 命令行解释器(Shell),广泛用于 Unix 和 Linux 操作系统。它是 Bourne Shell(sh) 的增强版,提供了更多的功能…...
cmake结合qt开发界面程序实例
在使用 CMake 构建 Qt 界面应用程序时,你需要设置 CMakeLists.txt 文件来指定项目配置、源文件、库依赖等。以下是一个简单的示例,展示了如何创建一个包含 Qt 界面(使用 QWidget)的 Qt 项目,并使用 CMake 进行构建。 …...
vue3二次封装tooltip实现el-table中的show-overflow-tooltip效果
开发过程中遇到需要根据后端返回的数据长度来判断是否需要使用el-tooltip的情况,想到el-table里面就有这种交互效果,如果不论文字是否超出容器长度都展示tooltip的话,交互效果难免会差很多,所以二次封装了这个组件: 给…...
如何创建并保存HTML文件?零基础入门教程
原文:如何创建并保存HTML文件?零基础入门教程 | w3cschool笔记 本文将以Windows系统为例,教你用最简单的记事本创建并保存第一个HTML网页。 📝 第一步:准备工具 文本编辑器:使用系统自带的记事本ÿ…...
React19源码系列之FiberRoot节点和Fiber节点
在上一篇文章,看了createRoot函数的大致流程。 createContainer函数创建并返回了FiberRoot 。FiberRoot是由createFiberRoot函数创建, createFiberRoot函数还将 FiberRoot和 根Fiber 通过current属性建立起了联系。将FiberRoot作为参数传给 ReactDOMRoo…...
每天看一篇漏洞报告
前言: 内容来源于乌云漏洞 今日思考xss漏洞, 今天看到一篇文章,里面详细说了xss的绕过技巧,虽然时间久了,没有去尝试,待会有时间去测试一下 以下是整理后的文章,原文在下面 文章链接&#…...
采用贝塞尔函数,进行恒定束宽波束形成算法
matlab采用贝塞尔函数,进行恒定束宽波束形成算法 beselle.m , 1452 20191225160928.png , 43700 20191225160935.png , 45238 20191225161010.png , 76862...
TCP协议的多线程应用、多线程下的网络编程
DAY13.2 Java核心基础 多线程下的网络编程 基于单点连接的方式,一个服务端对应一个客户端,实际运行环境中是一个服务端需要对应多个客户端 创建ServerSocketNable类,多线程接收socket对象 public class ServerSocketNable implements Run…...
华为中小型企业项目案例
实验目的(1) 熟悉华为交换机和路由器的应用场景 (2) 掌握华为交换机和路由器的配置方法 实验拓扑实验拓扑如图所示。 华为中小型企业项目案例拓扑图 实验配置市场部和技术部的配置创建VLANLSW1的配置 [LSW1]vlan batch 10 20 [LSW1]q…...
LabVIEW VI Scripting随机数波形图自动生成
通过LabVIEW VI Scripting 技术,实现从零开始编程化创建并运行一个随机数波形监测VI。核心功能包括自动化生成VI框架、添加控件与函数、配置数据流逻辑及界面布局优化,适用于批量生成测试工具、教学模板开发或复杂系统的模块化构建。通过脚本化操作&…...
MATLAB 控制系统设计与仿真 - 26
状态空间控制系统概述 状态空间描述 现代控制理论是建立在状态空间基础上的控制系统分析和设计理论,它用状态变量来刻画系统的内部特征,用‘一节微分方程组’来描述系统的动态特性。系统的状态空间模型描述了系统输入/输出与内部状态之间的关系&#x…...
Python----计算机视觉处理(Opencv:图像镜像旋转)
一、图像镜像旋转 图像的旋转是围绕一个特定点进行的,而图像的镜像旋转则是围绕坐标轴进行的。图像镜像旋转,也可 以叫做图像翻转,分为水平翻转、垂直翻转、水平垂直翻转三种。 通俗的理解为,当以图片的中垂线为x轴和y轴时&#x…...
C++从入门到入土(八)——多态的原理
目录 前言 多态的原理 动态绑定与静态绑定 虚函数表 小结 前言 在前面的文章中,我们介绍了C三大特性之一的多态,我们主要介绍了多态的构成条件,但是对于多态的原理我们探讨的是不够深入的,下面这这一篇文章,我们将…...
国产编辑器EverEdit - 语法着色文件的语法
1 语法着色定义(官方文档) 1.1 概述 EverEdit有着优异的语法着色引擎,可以高亮现存的绝大多数的编程语言。在EverEdit的语法着色中有Region和Item两个概念,Region表示着不同的区块。而Item则代表着这些区块中不同的部分。一般情况下,Region…...
vue3当中使用Pinia的store的组件化开发模式
一、安装与初始化 安装Pinia npm install pinia # 或 yarn add pinia目的:引入Pinia核心库,为状态管理提供基础支持。 挂载Pinia实例 在main.js中初始化并注入Vue应用: import { createApp } from vue import { createPinia } from pinia i…...
