From d56ee78dc354318e9fd8355f78a0901907fa9f8e Mon Sep 17 00:00:00 2001 From: Lexcubia Date: Sun, 27 Apr 2025 15:28:04 +0800 Subject: [PATCH] =?UTF-8?q?feat(vioce):=20=E6=B7=BB=E5=8A=A0=E8=AF=AD?= =?UTF-8?q?=E9=9F=B3=E8=BE=93=E5=85=A5=E5=8A=9F=E8=83=BD=E5=B9=B6=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=9B=B8=E5=85=B3=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 VoiceInputSettings 组件用于语音输入设置 - 在 SettingsPanel 中集成语音输入设置选项 - 修改 ChatInterface 以支持语音输入功能 - 优化 WebSocketClient 发送数据逻辑 - 更新相关组件以适应新的语音输入功能 --- .cursor/rules/cusorrules.mdc | 77 ++++++++++++ src/components/settings/SettingsPanel.vue | 3 + .../settings/VoiceInputSettings.vue | 44 +++++++ src/store/chat.js | 4 +- src/store/settings.js | 24 +++- src/utils/websocket.js | 21 +++- src/views/chat/ChatInterface.vue | 107 ++++++++++++----- src/views/chat/components/ChatInput.vue | 24 ++-- src/views/chat/components/VoiceInput.vue | 110 ++++++++++-------- src/views/settings/SettingsPanel.vue | 60 ++++++++++ yarn.lock | 93 +++++++++++++++ 11 files changed, 479 insertions(+), 88 deletions(-) create mode 100644 .cursor/rules/cusorrules.mdc create mode 100644 src/components/settings/VoiceInputSettings.vue create mode 100644 src/views/settings/SettingsPanel.vue diff --git a/.cursor/rules/cusorrules.mdc b/.cursor/rules/cusorrules.mdc new file mode 100644 index 0000000..cece049 --- /dev/null +++ b/.cursor/rules/cusorrules.mdc @@ -0,0 +1,77 @@ +--- +description: +globs: +alwaysApply: false +--- +### 技术栈 +- Javascript +- Vue3 +- vite +- axios +- element +- pinia +- mockjs +- sass + +### 文件目录 + +- src/ + - assets/ # 静态资源文件 + - components/ # 公共组件 + - views/ # 页面视图组件 + - router/ # 路由配置 + - store/ # Pinia状态管理 + - api/ # API接口封装 + - utils/ # 工具函数 + - styles/ # 全局样式 + - mock/ # Mock数据 + - App.vue # 根组件 + - main.js # 入口文件 + +### 开发规范 + +1. 命名规范 + - 组件名:大驼峰命名法,如 `UserProfile.vue` + - 变量名:小驼峰命名法,如 `userInfo` + - 常量名:全大写,下划线分隔,如 `API_BASE_URL` + - 文件夹名:小写,中划线分隔,如 `user-center` + +2. 代码风格 + - 使用 ESLint + Prettier 进行代码格式化 + - 组件内使用 ` \ No newline at end of file diff --git a/src/store/chat.js b/src/store/chat.js index b4ac1fb..7442e9b 100644 --- a/src/store/chat.js +++ b/src/store/chat.js @@ -31,7 +31,7 @@ const chatModes = { **车牌号**: 闽C12345 **车辆信息**:拥有一辆行驶4年的大众途观L,购买价格约25万,主要用于商务出行及家庭使用。 **投保信息**:在其他保司购买交强险及商业险(三者险、车损险),还有1个月到期。有过一次轻微追尾事故,已通过保司处理。王先生对成本控制非常敏感,但也能意识到保险的重要性。他希望得到保障全面、价格合理的产品和优质的服务。`, - chatBackground: '现在你将扮演坐席专员,与系统扮演的客户针对报价中的各类异议开展对练,着重训练处理“报价中异议”的能力。按照“保全保足”原则给出险种推荐方案。', + chatBackground: '现在你将扮演坐席专员,与系统扮演的客户针对报价中的各类异议开展对练,着重训练处理"报价中异议"的能力。按照"保全保足"原则给出险种推荐方案。', }, post_quote_objection: { name: '报价后异议', @@ -45,7 +45,7 @@ const chatModes = { **车牌号**: 粤B56789 **车辆信息**:拥有一辆行驶4年多的本田思域,1.5T,CVT燃动版,购买价格约15万,用于日常通勤及周末短途出行。 **投保信息**:在其他保司购买交强险及商业险(三者险、车损险、不计免赔险、车上人员责任险),还有2个月到期。无事故记录,仅有两次违章停车记录。张女士注重性价比和服务质量,希望保险的保障全面、价格合理、服务贴心。`, - chatBackground: '现在你将扮演坐席专员,与系统扮演的客户针对报价后的各类异议开展对练,着重训练处理“报价后异议”的能力。按照“保全保足”原则给出险种推荐方案。', + chatBackground: '现在你将扮演坐席专员,与系统扮演的客户针对报价后的各类异议开展对练,着重训练处理"报价后异议"的能力。按照"保全保足"原则给出险种推荐方案。', } } // 返回示例 diff --git a/src/store/settings.js b/src/store/settings.js index 282719a..b0440d8 100644 --- a/src/store/settings.js +++ b/src/store/settings.js @@ -29,12 +29,20 @@ export const useSettingsStore = defineStore('settings', { theme: 'default', // 动画效果开关 animationsEnabled: true, + // 语音输入设置 + voiceInputSettings: { + sendDirectly: true, // 语音转文字后直接发送 + }, }), persist: { - key: 'settings', - // Persist displayMode and theme - paths: ['sidebarCollapsed', 'displayMode', 'theme', 'animationsEnabled'] + enabled: true, + strategies: [ + { + key: 'settings', + storage: localStorage, + }, + ], }, actions: { @@ -109,7 +117,15 @@ export const useSettingsStore = defineStore('settings', { applyDisplayMode(this.displayMode); this.toggleAnimations(this.animationsEnabled); // Fallback } - } + }, + + // 更新语音输入设置 + updateVoiceInputSettings(settings) { + this.voiceInputSettings = { + ...this.voiceInputSettings, + ...settings + } + }, } }) diff --git a/src/utils/websocket.js b/src/utils/websocket.js index a751ca9..2d82c49 100644 --- a/src/utils/websocket.js +++ b/src/utils/websocket.js @@ -67,10 +67,27 @@ class WebSocketClient { } try { - if (typeof data === 'object') { + // 如果是ArrayBuffer或TypedArray,直接发送二进制 + if (data instanceof ArrayBuffer) { + this.socket.send(data); + } else if ( + data instanceof Int8Array || + data instanceof Uint8Array || + data instanceof Int16Array || + data instanceof Uint16Array || + data instanceof Int32Array || + data instanceof Uint32Array || + data instanceof Float32Array || + data instanceof Float64Array + ) { + this.socket.send(data.buffer); + } else if (typeof data === 'object') { + // 仅普通对象才转JSON data = JSON.stringify(data); + this.socket.send(data); + } else { + this.socket.send(data); } - this.socket.send(data); } catch (error) { console.error('发送数据失败:', error); } diff --git a/src/views/chat/ChatInterface.vue b/src/views/chat/ChatInterface.vue index ad9fadc..26edad9 100644 --- a/src/views/chat/ChatInterface.vue +++ b/src/views/chat/ChatInterface.vue @@ -58,9 +58,11 @@ -
-
- +
+ + + +
@@ -90,7 +92,8 @@ @@ -110,13 +113,12 @@ + + \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 7ffd8c3..10a2a08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1342,11 +1342,34 @@ browserslist@^4.23.1, browserslist@^4.24.0, browserslist@^4.24.4: node-releases "^2.0.19" update-browserslist-db "^1.1.1" +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.npmmirror.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.1.0: + version "1.2.0" + resolved "https://registry.npmmirror.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-builder@^0.2.0: version "0.2.0" resolved "https://registry.npmmirror.com/buffer-builder/-/buffer-builder-0.2.0.tgz#3322cd307d8296dab1f604618593b261a3fade8f" integrity sha512-7VPMEPuYznPSoR21NE1zvd2Xna6c/CloiZCfcMXR1Jny6PjX0N4Nsa38zcBFo/FMK+BlA+FLKbJCQ0i2yxp+Xg== +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.npmmirror.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha512-T7zexNBwiiaCOGDg9xNX9PBmjrubblRkENuptryuI64URkXDFum9il/JGL8Lm8wYfAXpredVXXZz7eMHilimiQ== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + bundle-name@^4.1.0: version "4.1.0" resolved "https://registry.npmmirror.com/bundle-name/-/bundle-name-4.1.0.tgz#f3b96b34160d6431a19d7688135af7cfb8797889" @@ -1448,6 +1471,11 @@ copy-anything@^3.0.2: dependencies: is-what "^4.1.8" +core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.npmmirror.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + cross-spawn@^7.0.3: version "7.0.6" resolved "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" @@ -1503,6 +1531,13 @@ de-indent@^1.0.2: resolved "https://registry.npmmirror.com/de-indent/-/de-indent-1.0.2.tgz#b2038e846dc33baa5796128d0804b455b8c1e21d" integrity sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg== +debug@2, debug@^2.2.0: + version "2.6.9" + resolved "https://registry.npmmirror.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@^4.1.0, debug@^4.3.1, debug@^4.3.7, debug@^4.4.0: version "4.4.0" resolved "https://registry.npmmirror.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" @@ -1930,6 +1965,11 @@ immutable@^5.0.2: resolved "https://registry.npmmirror.com/immutable/-/immutable-5.1.1.tgz#d4cb552686f34b076b3dcf23c4384c04424d8354" integrity sha512-3jatXi9ObIsPGr3N5hGw/vWWcTkq6hUYhpQz4k0wLC+owqWi/LiugIw9x0EdNZ2yGedKN/HzePiBvaJRXa0Ujg== +inherits@~2.0.1: + version "2.0.4" + resolved "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + is-core-module@^2.16.0: version "2.16.1" resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" @@ -1993,6 +2033,11 @@ is-wsl@^3.1.0: dependencies: is-inside-container "^1.0.0" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.npmmirror.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + isexe@^2.0.0: version "2.0.0" resolved "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -2159,6 +2204,11 @@ mrmime@^2.0.0: resolved "https://registry.npmmirror.com/mrmime/-/mrmime-2.0.1.tgz#bc3e87f7987853a54c9850eeb1f1078cd44adddc" integrity sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ== +ms@2.0.0: + version "2.0.0" + resolved "https://registry.npmmirror.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + ms@^2.1.3: version "2.1.3" resolved "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" @@ -2273,6 +2323,11 @@ pathe@^2.0.1, pathe@^2.0.2, pathe@^2.0.3: resolved "https://registry.npmmirror.com/pathe/-/pathe-2.0.3.tgz#3ecbec55421685b70a9da872b2cff3e1cbed1716" integrity sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w== +pcm@^1.0.3: + version "1.0.3" + resolved "https://registry.npmmirror.com/pcm/-/pcm-1.0.3.tgz#8e9508ab321f93ca61cd4ab44cc846530a185f24" + integrity sha512-N/qULxlCd++KuA4gAi9+wG9HpPmSOHowYj6KumrGsaoDVrcswut6K/GomqoFcbVXSnAnAf2SevVn1ehTQgFdHA== + perfect-debounce@^1.0.0: version "1.0.0" resolved "https://registry.npmmirror.com/perfect-debounce/-/perfect-debounce-1.0.0.tgz#9c2e8bc30b169cc984a58b7d5b28049839591d2a" @@ -2658,11 +2713,26 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" +readable-stream@^1.1.14: + version "1.1.14" + resolved "https://registry.npmmirror.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@^4.0.1: version "4.1.2" resolved "https://registry.npmmirror.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== +recorder-core@^1.3.25011100: + version "1.3.25011100" + resolved "https://registry.npmmirror.com/recorder-core/-/recorder-core-1.3.25011100.tgz#128ee11f2d24547b82605a5383274226b3a20a65" + integrity sha512-trXsCH0zurhoizT4Z22C0OsM0SDOW+2OvtgRxeLQFwxoFeqFjDjYZsbZEZUiKMJLhBvamI4K7Ic+qZ2LBo74TA== + resolve@^1.1.7: version "1.22.10" resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" @@ -2937,6 +3007,18 @@ std-env@^3.8.1: resolved "https://registry.npmmirror.com/std-env/-/std-env-3.9.0.tgz#1a6f7243b339dca4c9fd55e1c7504c77ef23e8f1" integrity sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw== +stream-parser@^0.3.1: + version "0.3.1" + resolved "https://registry.npmmirror.com/stream-parser/-/stream-parser-0.3.1.tgz#1618548694420021a1182ff0af1911c129761773" + integrity sha512-bJ/HgKq41nlKvlhccD5kaCr/P+Hu0wPNKPJOH7en+YrJu/9EgqUF+88w5Jb6KNcjOFMhfX4B2asfeAtIGuHObQ== + dependencies: + debug "2" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.npmmirror.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + strip-final-newline@^4.0.0: version "4.0.0" resolved "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-4.0.0.tgz#35a369ec2ac43df356e3edd5dcebb6429aa1fa5c" @@ -3224,6 +3306,17 @@ vue@^3.5.13: "@vue/server-renderer" "3.5.13" "@vue/shared" "3.5.13" +wav@^1.0.2: + version "1.0.2" + resolved "https://registry.npmmirror.com/wav/-/wav-1.0.2.tgz#bdbf3fa0d9b4519e9dfd2f603299ead0a2f22060" + integrity sha512-viHtz3cDd/Tcr/HbNqzQCofKdF6kWUymH9LGDdskfWFoIy/HJ+RTihgjEcHfnsy1PO4e9B+y4HwgTwMrByquhg== + dependencies: + buffer-alloc "^1.1.0" + buffer-from "^1.0.0" + debug "^2.2.0" + readable-stream "^1.1.14" + stream-parser "^0.3.1" + webpack-virtual-modules@^0.6.2: version "0.6.2" resolved "https://registry.npmmirror.com/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz#057faa9065c8acf48f24cb57ac0e77739ab9a7e8"