@tencent-rtc/trtc-agent-skills 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (205) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +172 -0
  3. package/README.zh.md +173 -0
  4. package/bin/cli.js +434 -0
  5. package/knowledge-base/index.yaml +454 -0
  6. package/knowledge-base/platform-slice-template.md +233 -0
  7. package/knowledge-base/scenario-spec.md +350 -0
  8. package/knowledge-base/scenarios/conference/base/general-conference.md +365 -0
  9. package/knowledge-base/scenarios/conference/base/webinar-conference.md +130 -0
  10. package/knowledge-base/scenarios/conference/medical/1v1-video-consultation.md +145 -0
  11. package/knowledge-base/scenarios/conference/medical/medical-multidoctor-consultation.md +113 -0
  12. package/knowledge-base/scenarios/live/entertainment-live-room.md +118 -0
  13. package/knowledge-base/slice-spec.md +546 -0
  14. package/knowledge-base/slices/conference/web/ai-tools.md +225 -0
  15. package/knowledge-base/slices/conference/web/beauty-effects.md +188 -0
  16. package/knowledge-base/slices/conference/web/device-control.md +338 -0
  17. package/knowledge-base/slices/conference/web/login-auth.md +261 -0
  18. package/knowledge-base/slices/conference/web/network-quality.md +190 -0
  19. package/knowledge-base/slices/conference/web/official-roomkit-api.md +298 -0
  20. package/knowledge-base/slices/conference/web/official-roomkit-login-ui.md +246 -0
  21. package/knowledge-base/slices/conference/web/participant-list.md +238 -0
  22. package/knowledge-base/slices/conference/web/participant-management.md +718 -0
  23. package/knowledge-base/slices/conference/web/prejoin-check.md +293 -0
  24. package/knowledge-base/slices/conference/web/room-call.md +213 -0
  25. package/knowledge-base/slices/conference/web/room-chat.md +426 -0
  26. package/knowledge-base/slices/conference/web/room-lifecycle.md +534 -0
  27. package/knowledge-base/slices/conference/web/room-schedule.md +281 -0
  28. package/knowledge-base/slices/conference/web/screen-share.md +211 -0
  29. package/knowledge-base/slices/conference/web/video-layout.md +675 -0
  30. package/knowledge-base/slices/conference/web/virtual-background.md +197 -0
  31. package/knowledge-base/slices/conference/web/webinar-interaction.md +206 -0
  32. package/knowledge-base/slices/live/anchor-lifecycle.md +122 -0
  33. package/knowledge-base/slices/live/anchor-preview.md +90 -0
  34. package/knowledge-base/slices/live/anchor-room-config.md +104 -0
  35. package/knowledge-base/slices/live/audience-list.md +86 -0
  36. package/knowledge-base/slices/live/audience-manage.md +92 -0
  37. package/knowledge-base/slices/live/audience-watch.md +85 -0
  38. package/knowledge-base/slices/live/audio.md +116 -0
  39. package/knowledge-base/slices/live/barrage.md +88 -0
  40. package/knowledge-base/slices/live/beauty.md +99 -0
  41. package/knowledge-base/slices/live/coguest-apply.md +105 -0
  42. package/knowledge-base/slices/live/device-control.md +91 -0
  43. package/knowledge-base/slices/live/error-codes.md +167 -0
  44. package/knowledge-base/slices/live/gift.md +84 -0
  45. package/knowledge-base/slices/live/ios/.gitkeep +0 -0
  46. package/knowledge-base/slices/live/ios/anchor-lifecycle.md +313 -0
  47. package/knowledge-base/slices/live/ios/anchor-preview.md +228 -0
  48. package/knowledge-base/slices/live/ios/anchor-room-config.md +257 -0
  49. package/knowledge-base/slices/live/ios/audience-list.md +353 -0
  50. package/knowledge-base/slices/live/ios/audience-manage.md +381 -0
  51. package/knowledge-base/slices/live/ios/audience-watch.md +286 -0
  52. package/knowledge-base/slices/live/ios/audio.md +373 -0
  53. package/knowledge-base/slices/live/ios/barrage.md +285 -0
  54. package/knowledge-base/slices/live/ios/beauty.md +323 -0
  55. package/knowledge-base/slices/live/ios/coguest-apply.md +506 -0
  56. package/knowledge-base/slices/live/ios/device-control.md +286 -0
  57. package/knowledge-base/slices/live/ios/error-codes.md +270 -0
  58. package/knowledge-base/slices/live/ios/gift.md +315 -0
  59. package/knowledge-base/slices/live/ios/live-list.md +269 -0
  60. package/knowledge-base/slices/live/ios/login-auth.md +247 -0
  61. package/knowledge-base/slices/live/live-list.md +82 -0
  62. package/knowledge-base/slices/live/login-auth.md +78 -0
  63. package/package.json +34 -0
  64. package/skills/trtc/SKILL.md +326 -0
  65. package/skills/trtc/room-builder/SKILL.md +138 -0
  66. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/README.md +108 -0
  67. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/backend-contract.zh-CN.md +162 -0
  68. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/integration.zh-CN.md +154 -0
  69. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/docs/theme.zh-CN.md +78 -0
  70. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/index.html +12 -0
  71. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/package.json +28 -0
  72. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/postcss.config.js +5 -0
  73. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/App.vue +25 -0
  74. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/ConsultationManagePanel.vue +838 -0
  75. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/LanguageSwitch.vue +102 -0
  76. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/LoadingSpinner.vue +6 -0
  77. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalAlert.vue +34 -0
  78. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalBusinessPanel.vue +148 -0
  79. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalButton.vue +49 -0
  80. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalConfirmDialog.vue +68 -0
  81. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalDataPanel.vue +196 -0
  82. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/MedicalRecordPanel.vue +270 -0
  83. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/components/PrescriptionPanel.vue +363 -0
  84. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/basic-info-config.ts +29 -0
  85. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/lib-generate-test-usersig-es.min.d.ts +4 -0
  86. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/lib-generate-test-usersig-es.min.js +2 -0
  87. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/config/runtime-config.ts +12 -0
  88. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/env.d.ts +32 -0
  89. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationChatPanel.vue +123 -0
  90. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationMembersPanel.vue +230 -0
  91. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationTranscriptionPanel.vue +135 -0
  92. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/ConsultationVideoStage.vue +113 -0
  93. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/InviteDoctorDialog.vue +132 -0
  94. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/components/KickMemberConfirmDialog.vue +50 -0
  95. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/types.ts +77 -0
  96. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationChat.ts +97 -0
  97. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationDevices.ts +48 -0
  98. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationParticipants.ts +121 -0
  99. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/useConsultationPermissions.ts +25 -0
  100. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/features/consultation/utils.ts +70 -0
  101. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/en-US/index.ts +553 -0
  102. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/index.ts +25 -0
  103. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/medicalTranslate.ts +85 -0
  104. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/state.ts +49 -0
  105. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/i18n/zh-CN/index.ts +463 -0
  106. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/main.ts +12 -0
  107. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/mock/appointments.ts +96 -0
  108. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/mock/users.ts +79 -0
  109. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/router/index.ts +63 -0
  110. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/index.ts +25 -0
  111. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/appointmentService.ts +77 -0
  112. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/authService.ts +38 -0
  113. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/launchContext.ts +31 -0
  114. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/integration/userService.ts +35 -0
  115. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/appointmentService.ts +43 -0
  116. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/authService.ts +33 -0
  117. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/mock/userService.ts +43 -0
  118. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/services/adapters/types.ts +135 -0
  119. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/shared/icons.ts +53 -0
  120. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/index.css +106 -0
  121. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/tailwind.css +3 -0
  122. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/styles/theme.css +209 -0
  123. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/auth.ts +50 -0
  124. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/format.ts +24 -0
  125. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/navigation.ts +12 -0
  126. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/utils/session.ts +28 -0
  127. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/DoctorConsultationView.vue +777 -0
  128. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/DoctorDashboardView.vue +678 -0
  129. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/LoginView.vue +441 -0
  130. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientConsultationFinishedView.vue +185 -0
  131. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientConsultationView.vue +1003 -0
  132. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientSelectDoctorView.vue +317 -0
  133. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/src/views/PatientWaitingView.vue +454 -0
  134. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/tsconfig.json +21 -0
  135. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/tsconfig.node.json +8 -0
  136. package/skills/trtc/room-builder/templates/scenarios/medical-consultation/vite.config.ts +17 -0
  137. package/skills/trtc/room-builder/templates/scenarios/medical-consultation//346/216/245/345/205/245/350/257/264/346/230/216.md +6 -0
  138. package/skills/trtc/room-builder/tools/render_ai_instructions.py +226 -0
  139. package/skills/trtc-apply/SKILL.md +97 -0
  140. package/skills/trtc-apply/guardrails/apply_lib/__init__.py +0 -0
  141. package/skills/trtc-apply/guardrails/apply_lib/__pycache__/__init__.cpython-313.pyc +0 -0
  142. package/skills/trtc-apply/guardrails/apply_lib/__pycache__/rule_parser.cpython-313.pyc +0 -0
  143. package/skills/trtc-apply/guardrails/apply_lib/rule_parser.py +268 -0
  144. package/skills/trtc-docs/SKILL.md +207 -0
  145. package/skills/trtc-onboarding/SKILL.md +839 -0
  146. package/skills/trtc-onboarding/reference/path-a1-demo.md +103 -0
  147. package/skills/trtc-onboarding/reference/path-a2-integrate.md +693 -0
  148. package/skills/trtc-onboarding/reference/path-b-troubleshoot.md +115 -0
  149. package/skills/trtc-onboarding/reference/path-c-expand.md +43 -0
  150. package/skills/trtc-onboarding/reference/reporting-protocol.md +174 -0
  151. package/skills/trtc-onboarding/reference/supported-matrix.md +100 -0
  152. package/skills/trtc-onboarding/reference/usersig-handling.md +140 -0
  153. package/skills/trtc-search/SKILL.md +221 -0
  154. package/skills/trtc-topic/SKILL.md +638 -0
  155. package/skills/trtc-topic/guardrails/__pycache__/gate_slice_read.cpython-313.pyc +0 -0
  156. package/skills/trtc-topic/guardrails/__pycache__/gate_slice_write.cpython-313.pyc +0 -0
  157. package/skills/trtc-topic/guardrails/__pycache__/stop_require_apply_evidence.cpython-313.pyc +0 -0
  158. package/skills/trtc-topic/guardrails/gate_slice_read.py +133 -0
  159. package/skills/trtc-topic/guardrails/gate_slice_write.py +169 -0
  160. package/skills/trtc-topic/guardrails/stop_require_apply_evidence.py +97 -0
  161. package/skills/trtc-topic/references/execution-units.yaml +58 -0
  162. package/skills/trtc-topic/runtime/README.md +50 -0
  163. package/skills/trtc-topic/runtime/RUNTIME.md +128 -0
  164. package/skills/trtc-topic/runtime/lib/__init__.py +0 -0
  165. package/skills/trtc-topic/runtime/lib/platforms.py +194 -0
  166. package/skills/trtc-topic/runtime/package-lock.json +1211 -0
  167. package/skills/trtc-topic/runtime/package.json +13 -0
  168. package/skills/trtc-topic/runtime/telemetry-bridge.mjs +339 -0
  169. package/skills/trtc-topic/runtime/telemetry_collector.py +293 -0
  170. package/skills/trtc-topic/scripts/STATE-MACHINE-GUIDE.md +186 -0
  171. package/skills/trtc-topic/scripts/__pycache__/apply.cpython-313.pyc +0 -0
  172. package/skills/trtc-topic/scripts/apply.py +581 -0
  173. package/skills/trtc-topic/scripts/finalize_session.py +113 -0
  174. package/skills/trtc-topic/scripts/init_slice_queue.py +96 -0
  175. package/skills/trtc-topic/scripts/lib/__pycache__/state_machine.cpython-313.pyc +0 -0
  176. package/skills/trtc-topic/scripts/lib/state_machine.py +328 -0
  177. package/skills/trtc-topic/scripts/next_slice.py +137 -0
  178. package/skills/trtc-topic/tests/README.md +70 -0
  179. package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc +0 -0
  180. package/skills/trtc-topic/tests/__pycache__/conftest.cpython-313-pytest-9.0.3.pyc +0 -0
  181. package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.2.pyc +0 -0
  182. package/skills/trtc-topic/tests/__pycache__/test_apply_cli.cpython-313-pytest-9.0.3.pyc +0 -0
  183. package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.2.pyc +0 -0
  184. package/skills/trtc-topic/tests/__pycache__/test_end_to_end.cpython-313-pytest-9.0.3.pyc +0 -0
  185. package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.2.pyc +0 -0
  186. package/skills/trtc-topic/tests/__pycache__/test_finalize_session.cpython-313-pytest-9.0.3.pyc +0 -0
  187. package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.2.pyc +0 -0
  188. package/skills/trtc-topic/tests/__pycache__/test_gates.cpython-313-pytest-9.0.3.pyc +0 -0
  189. package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.2.pyc +0 -0
  190. package/skills/trtc-topic/tests/__pycache__/test_session_resolver.cpython-313-pytest-9.0.3.pyc +0 -0
  191. package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.2.pyc +0 -0
  192. package/skills/trtc-topic/tests/__pycache__/test_state_machine.cpython-313-pytest-9.0.3.pyc +0 -0
  193. package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.2.pyc +0 -0
  194. package/skills/trtc-topic/tests/__pycache__/test_stop_require_apply.cpython-313-pytest-9.0.3.pyc +0 -0
  195. package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.2.pyc +0 -0
  196. package/skills/trtc-topic/tests/__pycache__/test_topic_skill_invariants.cpython-313-pytest-9.0.3.pyc +0 -0
  197. package/skills/trtc-topic/tests/conftest.py +72 -0
  198. package/skills/trtc-topic/tests/test_apply_cli.py +480 -0
  199. package/skills/trtc-topic/tests/test_end_to_end.py +305 -0
  200. package/skills/trtc-topic/tests/test_finalize_session.py +51 -0
  201. package/skills/trtc-topic/tests/test_gates.py +316 -0
  202. package/skills/trtc-topic/tests/test_session_resolver.py +260 -0
  203. package/skills/trtc-topic/tests/test_state_machine.py +414 -0
  204. package/skills/trtc-topic/tests/test_stop_require_apply.py +99 -0
  205. package/skills/trtc-topic/tests/test_topic_skill_invariants.py +130 -0
@@ -0,0 +1,426 @@
1
+ ---
2
+ id: conference/room-chat
3
+ name: 会中聊天
4
+ product: conference
5
+ platform: web
6
+ tags: [chat, message, unread, mute, history]
7
+ platforms: [web]
8
+ related: [conference/login-auth, conference/room-lifecycle, conference/participant-management, conference/participant-list]
9
+ api_docs:
10
+ - title: 会中聊天
11
+ url: https://cloud.tencent.com/document/product/647/126933
12
+ ---
13
+
14
+ # 会中聊天
15
+
16
+ ## 功能说明
17
+
18
+ 会中聊天负责把当前会议上下文映射到正确的 IM 群会话,并承接消息展示、发送、历史记录、未读提醒、富媒体消息以及消息权限联动。它解决的是“在当前房间里,消息如何正确收发与展示”,而不是房间创建、成员管理或会控规则本身。
19
+
20
+ 从实现视角看,会中聊天通常由 5 段主链路组成:**会话绑定、消息列表 State、输入 State、历史消息加载、未读与权限联动**。如果业务需要高度自定义的聊天区,优先按这 5 段拆分能力,而不是把聊天理解成单一 UI 面板。
21
+
22
+ ## 典型场景
23
+
24
+ | 场景 | 主要诉求 | 会中聊天的承接重点 |
25
+ |------|----------|--------------------|
26
+ | 在线研讨会 | 观众边看边提问 | 低门槛文本互动、未读提醒、禁言联动 |
27
+ | 远程协作 | 团队同步讨论与补充资料 | 文本、表情、图片、文件等消息流转 |
28
+ | 直播教学 / 培训 | 学员集中提问,老师统一查看 | 历史消息回看、消息列表稳定滚动、输入区禁言控制 |
29
+ | 强管控会议 | 房主或管理员可随时禁言 | 输入区状态、发送结果、成员状态三处保持一致 |
30
+
31
+ ## 核心概念
32
+
33
+ ### 集成路径
34
+
35
+ | 路径 | 适用场景 | 关键特点 |
36
+ |------|----------|----------|
37
+ | 底层 State 自定义集成 | 已有自定义 UI、抽屉聊天、复杂未读逻辑或高级消息能力 | 自行控制消息渲染、输入框、未读数、历史消息、富媒体消息与发送链路,是最完整的实现路径 |
38
+ | 标准聊天区快速封装 | 只需要标准消息区且已有现成组件容器 | 适合低定制场景,但本质上仍依赖同一套会话、消息和输入状态 |
39
+
40
+ ### 能力拆分
41
+
42
+ | 能力段 | 关键职责 | 常见关键接口 / 状态 |
43
+ |--------|----------|---------------------|
44
+ | 会话绑定 | 把当前房间映射到正确群会话 | `roomId`、`setActiveConversation()`、`GROUP${roomId}` |
45
+ | 消息列表 | 承接当前会话消息流与历史分页 | `messageList`、`hasMoreOlderMessage`、`loadMoreOlderMessage()` |
46
+ | 输入与发送 | 维护待发送内容并执行消息发送 | `inputRawValue`、`updateRawValue()`、`sendMessage()` |
47
+ | 权限联动 | 同步全体禁言、单独禁言与真实可发消息状态 | `localParticipant.isMessageDisabled` |
48
+ | 扩展能力 | 处理图片、文件、已读回执、未读提醒等 | `sendMessage(InputContent[])`、`setEnableReadReceipt(true)`、未读计数 |
49
+
50
+ ### 角色与职责
51
+
52
+ | 角色 | 关键职责 | 说明 |
53
+ |------|----------|------|
54
+ | 当前参会人 | 查看和发送消息 | 在当前房间上下文中收发文本、表情、图片、文件等消息 |
55
+ | 聊天模块 | 维护当前会话、消息流与输入态 | 承接消息列表、历史加载、未读角标和发送链路 |
56
+ | 会控模块 | 控制消息权限 | 全体禁言和单独禁言都会影响输入区和真实发送动作 |
57
+ | 成员列表模块 | 展示成员消息相关状态 | 聊天侧与成员侧应对同一成员的禁言状态给出一致表达 |
58
+ | 房间生命周期模块 | 提供 roomId 与进退房时机 | 只有进入真实房间后,聊天才能绑定到对应群会话 |
59
+
60
+ ### 事件流
61
+
62
+ | 阶段 | 参与方 | 关键动作 |
63
+ |------|--------|----------|
64
+ | 登录并进房 | 客户端 | 拿到有效登录态和当前房间 `roomId` |
65
+ | 会话绑定 | 聊天模块 | 把当前活跃会话切到会议对应的群会话 |
66
+ | 消息初始化 | 消息列表 State | 读取当前会话消息、判断是否还有历史消息、按需开启已读回执 |
67
+ | 输入初始化 | 输入 State | 维护输入内容、监听禁言状态、准备发送链路 |
68
+ | 消息流转 | 参会人 | 发送、接收、分页加载历史消息、按类型渲染消息 |
69
+ | 提醒联动 | 聊天入口 / 抽屉状态 | 根据聊天窗口开关态维护未读计数与提示 |
70
+ | 退出清理 | 客户端 | 房间切换、退房或结束会议后收口旧会话上下文和未读状态 |
71
+
72
+ ### 状态与数据
73
+
74
+ | 数据 / 状态 | 说明 |
75
+ |-------------|------|
76
+ | 房间会话标识 | 当前会议对应的唯一会话标识,通常由固定前缀和 `roomId` 组合而成 |
77
+ | 活跃会话 | 当前聊天面板实际绑定的会话 |
78
+ | 消息列表 | 当前会话已加载与正在展示的消息集合 |
79
+ | 历史消息状态 | 是否还有更早消息、是否正在分页加载 |
80
+ | 输入区原始内容 | 当前待发送的文本或组合输入内容 |
81
+ | 输入 API 绑定方式 | 原生输入框通常直接使用 `updateRawValue()`,不依赖富文本编辑器实例 |
82
+ | 未读数 | 用于聊天入口角标与消息提醒 |
83
+ | 房间级消息权限 | 表示当前会议是否处于全体禁言状态 |
84
+ | 当前成员消息权限 | 表示当前成员是否被单独禁言 |
85
+ | 输入区可用态 | 由房间级与成员级消息权限共同决定 |
86
+ | 高级消息能力 | 包括图片、文件、已读回执等扩展能力 |
87
+
88
+ ### 状态机
89
+
90
+ ```text
91
+ idle
92
+ → binding-conversation
93
+ → ready
94
+ → sending / receiving
95
+ → loading-history
96
+ → ready
97
+ → muted
98
+ → ready
99
+ → cleared
100
+ ```
101
+
102
+ ## 前置条件
103
+ **通用依赖**:见 [login-auth 平台 slice](login-auth.md)。
104
+
105
+ **额外依赖**:
106
+ - 已安装 `tuikit-atomicx-vue3@latest`
107
+ - 若采用富文本编辑器集成,可按需接入 `@tiptap/vue-3`;若只使用原生 `<input>` / `<textarea>`,不需要依赖编辑器实例。
108
+
109
+ **前置状态**:
110
+ - 已阅读 `conference/room-chat`,明确当前能力的产品边界。
111
+ - 已完成 `conference/login-auth`,确保当前页面具备稳定登录态。
112
+ - 已根据业务流程接入会议上下文,并能从 `useRoomState()` 获取有效 `currentRoom.roomId`。
113
+
114
+ ## 最佳实践
115
+
116
+ ### ✅ ALWAYS
117
+
118
+ 1. **把聊天上下文与当前房间一一绑定** —— 会议切换后,活跃会话也必须同步切换,避免串房间消息。
119
+ 2. **在进房成功后尽快完成会话绑定** —— 让历史消息、未读数和新消息都围绕同一个房间上下文流转。
120
+ 3. **把消息列表、输入态和发送链路拆开管理** —— 这样业务才能独立控制消息渲染、输入框和未读逻辑。
121
+ 4. **让输入区状态和真实发送结果都受消息权限控制** —— 不仅输入框要禁用,发送链路也必须拦截禁言用户。
122
+ 5. **原生输入框优先使用 `updateRawValue()`** —— 没有绑定编辑器实例时,不要把 `setContent()` 当成普通输入框更新手段。
123
+ 6. **把历史消息加载和滚动位置当成聊天主链路的一部分** —— 否则自定义聊天面板很容易出现跳屏或重复拉取。
124
+ 7. **把未读数设计成“聊天窗口开关态”的伴生状态** —— 抽屉关闭时累计,打开时清零,避免提醒漂移。
125
+ 8. **为文本和富媒体消息预留统一渲染策略** —— 图片、文件、表情等消息不应混入纯文本分支里硬编码处理。
126
+ 9. **让成员列表、聊天区和会控规则共享同一套禁言事实来源** —— 避免一个地方显示可发言、另一个地方显示已禁言。
127
+
128
+ ### ❌ NEVER
129
+
130
+ 1. **不要在会话未绑定前直接发送消息** —— 否则很容易把消息发到错误会话或丢失当前房间上下文。
131
+ 2. **不要把房间聊天绑定成裸 `roomId` 或业务私聊会话** —— 会导致消息进错会话。
132
+ 3. **不要只改输入框样式而不阻止真实发送** —— 禁言必须落到真实发送路径。
133
+ 4. **不要在原生输入场景下依赖富文本编辑器 API** —— 没有 editor 实例时,这些 API 往往不会按预期生效。
134
+ 5. **不要忽略房间切换时的会话、未读和消息流清理** —— 否则会出现消息串场和角标错误。
135
+ 6. **不要把历史消息加载后的滚动跳动当成纯 UI 小问题** —— 这会直接影响会中阅读体验。
136
+ 7. **不要默认所有聊天场景都只发纯文本** —— 远程协作和教学类场景往往需要图片、文件等富媒体能力。
137
+
138
+ ## 接入方式
139
+ 当前文档仅覆盖**无 UI 集成**:聊天列表、输入区、抽屉 / 侧栏样式均由业务自己实现,`tuikit-atomicx-vue3` 负责提供房间聊天相关 Hook、State 与发送能力。以下内容以 `会中聊天(Web).md` 中 **“方案二:使用底层 API 自定义集成”** 为主。
140
+
141
+ > **注意**:
142
+ > `MessageInputState` 默认支持与 `@tiptap/vue-3` 编辑器集成。如果您仅需要简单的文本输入框(例如 `<input>` 或 `<textarea>`),请忽略 `setEditorInstance()`、`setContent()` 等与编辑器实例绑定的 API,直接使用 `updateRawValue()` 和 `sendMessage()` 即可。
143
+
144
+ ## 代码示例
145
+ ### 步骤一:数据初始化
146
+
147
+ 在用户加入房间成功后,需要调用 `setActiveConversation()` 初始化聊天数据。建议监听 `currentRoom` 的变化来自动处理。
148
+
149
+ ```ts
150
+ import { onUnmounted, watch } from 'vue';
151
+ import { useConversationListState } from 'tuikit-atomicx-vue3/chat';
152
+ import { useRoomState } from 'tuikit-atomicx-vue3/room';
153
+
154
+ const { currentRoom } = useRoomState();
155
+ const { setActiveConversation } = useConversationListState();
156
+
157
+ watch(() => currentRoom.value?.roomId, (roomId) => {
158
+ if (!roomId) {
159
+ setActiveConversation('');
160
+ return;
161
+ }
162
+
163
+ setActiveConversation(`GROUP${roomId}`);
164
+ }, { immediate: true });
165
+
166
+ onUnmounted(() => {
167
+ setActiveConversation('');
168
+ });
169
+ ```
170
+
171
+ > **说明**:
172
+ > - `GROUP` 为固定前缀,`setActiveConversation()` 参数必须为 `GROUP${roomId}`,否则无法正常收发消息。
173
+ > - 在房间切换、退房或聊天按钮组件卸载时,应同步 `setActiveConversation('')` 清空旧会话,避免消息错发至错误会话。
174
+
175
+ ### 步骤二:获取消息列表
176
+
177
+ 使用 `useMessageListState()` 获取当前会话的消息列表,`messageList` 是响应式数据,会自动更新新收到的消息。
178
+
179
+ ```ts
180
+ import { useMessageListState } from 'tuikit-atomicx-vue3/chat';
181
+
182
+ const {
183
+ messageList,
184
+ loadMoreOlderMessage,
185
+ hasMoreOlderMessage,
186
+ } = useMessageListState();
187
+
188
+ console.log(messageList.value);
189
+ console.log(hasMoreOlderMessage.value);
190
+ ```
191
+
192
+ ### 步骤三:发送消息
193
+
194
+ 使用 `useMessageInputState()` 管理输入框内容并发送消息。
195
+
196
+ ```ts
197
+ import { computed } from 'vue';
198
+ import { useMessageInputState } from 'tuikit-atomicx-vue3/chat';
199
+ import { useRoomParticipantState } from 'tuikit-atomicx-vue3/room';
200
+
201
+ const {
202
+ inputRawValue,
203
+ updateRawValue,
204
+ sendMessage,
205
+ } = useMessageInputState();
206
+
207
+ const { localParticipant } = useRoomParticipantState();
208
+ const isMessageDisabled = computed(() => Boolean(localParticipant.value?.isMessageDisabled));
209
+ const hasTextInput = computed(() => (
210
+ typeof inputRawValue.value === 'string'
211
+ ? inputRawValue.value.trim().length > 0
212
+ : inputRawValue.value.length > 0
213
+ ));
214
+
215
+ const handleSend = async () => {
216
+ if (isMessageDisabled.value) return;
217
+ if (!hasTextInput.value) return;
218
+
219
+ try {
220
+ await sendMessage();
221
+ updateRawValue('');
222
+ } catch (error) {
223
+ console.error('发送失败', error);
224
+ }
225
+ };
226
+
227
+ // 原生输入框示例
228
+ // <input
229
+ // :value="inputRawValue"
230
+ // @input="(e) => updateRawValue((e.target as HTMLInputElement).value)"
231
+ // @keyup.enter="handleSend"
232
+ // />
233
+ ```
234
+
235
+ > **说明**:
236
+ > - 非富文本模式下,发送成功后请使用 `updateRawValue('')` 清空输入框。
237
+ > - 若当前成员已被禁言,除了输入框应禁用外,发送链路也需要一起拦截。
238
+ > - 若需要直接发送富媒体消息,可通过 `sendMessage(InputContent[])` 传入图片、文件等内容。
239
+
240
+ ### 步骤四:加载历史消息
241
+
242
+ 通过 `loadMoreOlderMessage()` 分页拉取历史消息,通常在滚动到列表顶部时触发。
243
+
244
+ ```ts
245
+ import { nextTick } from 'vue';
246
+ import { useMessageListState } from 'tuikit-atomicx-vue3/chat';
247
+
248
+ const {
249
+ hasMoreOlderMessage,
250
+ loadMoreOlderMessage,
251
+ } = useMessageListState();
252
+
253
+ const loadHistory = async (scrollContainer: HTMLElement) => {
254
+ if (!hasMoreOlderMessage.value) return;
255
+
256
+ const previousHeight = scrollContainer.scrollHeight;
257
+ await loadMoreOlderMessage();
258
+
259
+ await nextTick();
260
+ const currentHeight = scrollContainer.scrollHeight;
261
+ scrollContainer.scrollTop += currentHeight - previousHeight;
262
+ };
263
+ ```
264
+
265
+ > **注意**:
266
+ > 加载历史消息后,通常需要手动调整滚动条位置,以保持当前浏览视角不发生跳变。
267
+
268
+ ### 步骤五:高级功能(已读回执)
269
+
270
+ 如果业务需要已读回执功能,可以通过 `setEnableReadReceipt()` 开启。
271
+
272
+ ```ts
273
+ import { useMessageListState } from 'tuikit-atomicx-vue3/chat';
274
+
275
+ const {
276
+ setEnableReadReceipt,
277
+ } = useMessageListState();
278
+
279
+ setEnableReadReceipt(true);
280
+ ```
281
+
282
+ ## 调用时序
283
+ ```
284
+ 完成 login-auth
285
+
286
+
287
+ 进入 room-lifecycle,拿到 currentRoom.roomId
288
+
289
+
290
+ 调用 setActiveConversation(`GROUP${roomId}`)
291
+
292
+ ├─ 成功 → 获取 messageList / inputRawValue 等状态并渲染业务自定义聊天 UI
293
+ ├─ 房间切换 → 重新绑定新的 GROUP 会话
294
+ └─ 失败 → 提示会话初始化异常并阻止发言入口
295
+
296
+
297
+ 结合 localParticipant.isMessageDisabled 控制输入区与发送链路
298
+
299
+
300
+ 处理发送、历史消息、可选已读回执与富媒体消息
301
+
302
+
303
+ 退房或结束会议后收口聊天入口、旧会话上下文与本地状态
304
+ ```
305
+
306
+ ## 平台特有注意事项
307
+ ### 1. 会议聊天依赖 `GROUP${roomId}` 规则
308
+ 会中聊天基于 IM 群组会话,`setActiveConversation()` 必须使用 `GROUP${roomId}`,不能只传裸 `roomId`。
309
+
310
+ ### 2. 使用原生输入框时优先走 `updateRawValue()`
311
+ 若没有接入富文本编辑器,请直接使用 `updateRawValue()` 和 `sendMessage()`;不要依赖 `setContent()`、`setEditorInstance()` 这类编辑器绑定 API 来维护普通输入框内容。
312
+
313
+ ### 3. 输入区应直接绑定会控禁言状态
314
+ 若 `localParticipant.isMessageDisabled` 已经生效,聊天输入框必须立即转为禁用或只读;自定义输入框同样需要在发送前再次拦截。
315
+
316
+ ### 4. 自定义消息列表容器必须具备稳定高度
317
+ 聊天区通常需要独立滚动容器;如果父容器没有固定高度并且缺少 `overflow: hidden` 或等价约束,消息区容易无限拉长、无法滚动。
318
+
319
+ ### 5. 历史消息加载后要恢复滚动位置
320
+ 自定义聊天面板调用 `loadMoreOlderMessage()` 后,通常需要在 DOM 更新后修正 `scrollTop`,避免阅读位置跳变。
321
+
322
+ ### 6. 抽屉式聊天需要维护未读累积与清零
323
+ 如果聊天面板平时折叠或关闭,应在关闭时累计未读、打开时清零;首次初始化消息列表时不要误计入未读。
324
+
325
+ ### 7. 富媒体消息和已读回执属于可选高级能力
326
+ 图片、文件等消息可通过 `sendMessage(InputContent[])` 发送;如有消息确认诉求,可结合 `setEnableReadReceipt(true)` 开启已读回执。
327
+
328
+ ### 8. 自定义渲染时要覆盖不同消息类型分支
329
+ `messageList` 中通常会出现文本、图片、文件等不同类型消息;自定义聊天 UI 需要按消息类型分别渲染,不要只按纯文本分支处理。
330
+
331
+ ## 常见错误与场景对照
332
+
333
+ | 错误 / 场景 | 常见触发时机 | 建议处理方式 |
334
+ |-------------|--------------|--------------|
335
+ | 会话绑定成裸 `roomId` | 只拿到房间号就直接调用 `setActiveConversation(roomId)` | 改为固定用 `setActiveConversation()` 绑定 `GROUP${roomId}` |
336
+ | 进房前就切会话 | 登录或进房尚未完成时初始化聊天 | 等 `currentRoom.roomId` 有值后再绑定会话 |
337
+ | 原生输入框改了值但发送仍为空 | 直接操作输入框值,没有调用 `updateRawValue()` | 使用 `updateRawValue()` 维护输入内容,再调用 `sendMessage()` |
338
+ | 输入框禁用了但代码仍能发送 | 只做 UI 禁用,没有拦截发送函数 | 发送前再次校验禁言状态,保持 UI 与真实行为一致 |
339
+ | 自定义聊天区没有稳定高度 | 侧栏 / 抽屉只渲染了内容,没有约束滚动区域 | 为消息列表父容器提供固定高度、滚动区或等价布局约束 |
340
+ | 聊天抽屉首次打开就显示未读 | 初次拉取历史消息被误算成新消息 | 仅在窗口关闭且新消息长度增长时累计未读 |
341
+ | 历史消息加载后界面跳动 | 上滑加载更早消息时滚动位置漂移 | 记录加载前高度,加载后按高度差恢复滚动位置 |
342
+ | 富媒体消息显示异常 | 自定义 UI 只按文本消息渲染 | 按消息类型拆分渲染逻辑,覆盖文本、图片、文件等分支 |
343
+
344
+ ## 代码生成约束
345
+ ### 编译必要条件
346
+ - **通用条件**:见 [login-auth 平台 slice](login-auth.md)。
347
+ - **额外导入**:至少需要从 `tuikit-atomicx-vue3/chat` 导入 `useConversationListState`;自定义聊天通常还需要 `useMessageListState` 与 `useMessageInputState`;若输入区需要联动禁言态,通常还需要 `useRoomParticipantState`。
348
+ - **运行前提**:当前用户已完成登录,且已拿到有效 `roomId`。
349
+ - **容器前提**:业务自定义消息列表时,应提供稳定高度与独立滚动区域。
350
+
351
+ ### 生成规则
352
+ #### MUST(生成时必须包含)
353
+
354
+ 1. **用 `currentRoom.roomId` 驱动当前聊天会话** — 这样会议切换时会话才能同步收口。
355
+ **Verify**: 检查是否从 `useRoomState()` 读取 `currentRoom`。
356
+ 2. **通过 `setActiveConversation()` 绑定 `GROUP${roomId}` 群会话** — 这是会中聊天的关键映射关系。
357
+ **Verify**: 搜索是否存在 `GROUP${roomId}` 或等价拼接逻辑。
358
+ 3. **用 `useMessageListState()` 驱动消息列表和历史消息加载** — 保持当前会话数据源一致。
359
+ **Verify**: 检查是否读取 `messageList`,并按需使用 `loadMoreOlderMessage()`。
360
+ 4. **自定义原生输入框时使用 `updateRawValue()` 与 `sendMessage()`** — 保持状态同步和发送行为一致。
361
+ **Verify**: 检查是否通过 `updateRawValue()` 维护输入内容,并在发送后清空。
362
+ 5. **把禁言状态同时接到输入区和真实发送链路** — 不能只做视觉禁用。
363
+ **Verify**: 检查输入区是否联动 `isMessageDisabled`,且发送前有同源校验。
364
+ 6. **为自定义消息列表提供稳定滚动容器** — 否则聊天区很容易出现拉伸和滚动异常。
365
+ **Verify**: 检查聊天区父容器是否具备固定高度、滚动区或等价布局约束。
366
+
367
+ #### MUST NOT(生成时绝不能出现)
368
+
369
+ 1. **不要把房间聊天直接绑定为裸 `roomId` 或私聊会话** — 会导致消息进错会话。
370
+ **Verify**: 检查会话 ID 是否符合 `GROUP${roomId}` 规则。
371
+ 2. **不要忽略禁言状态继续开放输入框或发送动作** — UI 与真实可发言状态会不一致。
372
+ **Verify**: 检查输入区和发送函数是否都联动禁言状态。
373
+ 3. **不要在没有高度约束的容器里渲染自定义消息列表** — 很容易导致列表无法正常滚动。
374
+ **Verify**: 检查父容器是否具备固定高度或 `height: 100%` 等稳定布局。
375
+ 4. **不要把首次历史消息加载误算成未读消息** — 会让角标在初始化后立刻脏掉。
376
+ **Verify**: 检查未读逻辑是否区分初始化加载与真实新消息。
377
+ 5. **不要在原生输入场景下依赖富文本编辑器 API 清空内容** — 没绑定编辑器时不会按预期生效。
378
+ **Verify**: 检查普通输入框场景是否使用 `updateRawValue('')` 而不是 `setContent('')`。
379
+
380
+ ### 集成检查点
381
+ - 当前 slice 强依赖 `conference/room-lifecycle` 与 `conference/login-auth`。
382
+ - 聊天接入通常是新增侧栏、抽屉或右侧协作区,不需要修改 SDK 内部 IM 实现。
383
+ - 如果业务已经有独立 IM 会话体系,需要明确会议群会话与业务私聊的切换边界。
384
+ - 如果产品需要图片、文件、已读回执等高级能力,优先在自定义聊天方案里统一规划消息类型和渲染分支。
385
+
386
+ ## 验证矩阵
387
+ | 层级 | 检查项 | 验证手段 | 预期结果 |
388
+ |------|--------|----------|---------|
389
+ | 1. 编译级 | 已导入房间与聊天相关 Hook | 检查 `import` 语句 | Room / Chat Hook 可解析 |
390
+ | 2. 静态规则级 | 会话 ID 符合 `GROUP${roomId}` 规则 | 搜索 `setActiveConversation` 调用 | 存在群会话绑定逻辑 |
391
+ | 3. 数据流级 | 已读取消息列表、输入内容与禁言状态 | 检查 `useMessageListState`、`useMessageInputState`、`useRoomParticipantState` 调用 | 聊天数据源与权限源清晰 |
392
+ | 4. 结构级 | 自定义聊天列表具备稳定高度容器与滚动区域 | 检查模板结构与样式容器 | 消息列表具备稳定滚动空间 |
393
+ | 5. 运行时级 | 进入会议后聊天面板可展示正确会话 | 进房并打开聊天面板 | 消息收发落在当前会议会话 |
394
+ | 6. 业务行为级 | 禁言、历史消息、富媒体渲染表现正确 | 切换禁言、上滑加载历史、发送图片文件 | 输入区、滚动位置和不同消息类型表现符合预期 |
395
+
396
+ ## 排障指南
397
+
398
+ ### 常见问题
399
+
400
+ | 问题 | 表现 | 处理建议 |
401
+ |------|------|----------|
402
+ | 聊天面板没有消息 | 已在会议中,但列表为空或不刷新 | 检查是否已切到当前房间对应的群会话,以及是否在登录和进房完成后再绑定 |
403
+ | 消息发错会话 | 在 A 房间发送的消息出现在 B 房间 | 检查房间切换时是否重新绑定并清理旧会话上下文 |
404
+ | 原生输入框有值但发送为空 | 输入框显示正常,发送后内容丢失或为空 | 检查是否通过 `updateRawValue()` 维护输入内容,而不是只改本地变量 |
405
+ | 已禁言但仍能尝试发送 | 输入框变灰了,但代码路径仍可触发发送 | 检查输入区禁用和真实发送拦截是否共用同一套权限判断 |
406
+ | 加载历史消息后页面跳动 | 回看历史时滚动位置丢失 | 加载前记录高度,加载后恢复滚动位置 |
407
+ | 未读数不准确 | 聊天抽屉打开后仍显示旧未读 | 检查聊天窗口开关态与未读清零逻辑是否绑定 |
408
+ | 富媒体消息显示异常 | 图片、文件消息展示为空白或格式错乱 | 检查消息类型分支是否覆盖文本、图片、文件等不同 `payload` |
409
+
410
+ ### 排障流程
411
+
412
+ ```text
413
+ 发现 会中聊天 相关问题
414
+ ├── 第 1 步:确认当前问题属于房间聊天上下文,而不是房间生命周期或会控规则本身
415
+ ├── 第 2 步:检查当前活跃会话是否已与当前 roomId 正确绑定
416
+ ├── 第 3 步:确认消息列表 State、输入 State 与禁言状态是否来自同一房间上下文
417
+ ├── 第 4 步:检查历史消息、未读数、富媒体分支和滚动策略是否符合当前聊天入口形态
418
+ └── 第 5 步:若仍异常,再回查 login-auth / room-lifecycle / participant-management / participant-list 的衔接
419
+ ```
420
+
421
+ ## 关联知识
422
+
423
+ - **[conference/login-auth](login-auth.md)** —— 未登录或登录态异常时,聊天会话无法正确建立。
424
+ - **[conference/room-lifecycle](room-lifecycle.md)** —— 只有真正进入房间后,聊天上下文才具备正确的会中绑定基础。
425
+ - **[conference/participant-management](participant-management.md)** —— 全体禁言、单独禁言等消息权限由这里驱动。
426
+ - **[conference/participant-list](participant-list.md)** —— 成员身份、昵称和禁言状态会同步影响聊天侧展示。