@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,96 @@
1
+ import type { MedicalAppointment } from '@/services/adapters/types';
2
+
3
+ const now = new Date();
4
+
5
+ function atToday(hours: number, minutes: number) {
6
+ const value = new Date(now);
7
+ value.setHours(hours, minutes, 0, 0);
8
+ return Math.floor(value.getTime() / 1000);
9
+ }
10
+
11
+ export const mockAppointments: MedicalAppointment[] = [
12
+ {
13
+ id: 'APT001',
14
+ roomId: 'med-room-001',
15
+ doctorId: 'doctor_li',
16
+ patientId: 'patient_zhang',
17
+ scheduleStartTime: atToday(9, 30),
18
+ scheduleEndTime: atToday(10, 0),
19
+ chiefComplaint: 'Medical.Mock.CoughFever',
20
+ allergyHistory: 'Medical.Mock.PenicillinAllergy',
21
+ medicalHistory: 'Medical.Mock.NoMajorHistory',
22
+ patientAge: 35,
23
+ patientGender: 'Medical.Mock.Male',
24
+ patientPhone: '138****5678',
25
+ },
26
+ {
27
+ id: 'APT002',
28
+ roomId: 'med-room-002',
29
+ doctorId: 'doctor_wang',
30
+ patientId: 'patient_zhang',
31
+ scheduleStartTime: atToday(10, 10),
32
+ scheduleEndTime: atToday(10, 40),
33
+ chiefComplaint: 'Medical.Mock.NightCough',
34
+ allergyHistory: 'Medical.Mock.None',
35
+ medicalHistory: 'Medical.Mock.AllergicRhinitis',
36
+ patientAge: 35,
37
+ patientGender: 'Medical.Mock.Male',
38
+ patientPhone: '138****5678',
39
+ },
40
+ {
41
+ id: 'APT003',
42
+ roomId: 'med-room-003',
43
+ doctorId: 'doctor_zhang',
44
+ patientId: 'patient_zhang',
45
+ scheduleStartTime: atToday(11, 0),
46
+ scheduleEndTime: atToday(11, 30),
47
+ chiefComplaint: 'Medical.Mock.Reflux',
48
+ allergyHistory: 'Medical.Mock.None',
49
+ medicalHistory: 'Medical.Mock.ChronicGastritis',
50
+ patientAge: 35,
51
+ patientGender: 'Medical.Mock.Male',
52
+ patientPhone: '138****5678',
53
+ },
54
+ {
55
+ id: 'APT004',
56
+ roomId: 'med-room-004',
57
+ doctorId: 'doctor_li',
58
+ patientId: 'patient_li',
59
+ scheduleStartTime: atToday(14, 0),
60
+ scheduleEndTime: atToday(14, 30),
61
+ chiefComplaint: 'Medical.Mock.DizzyPalpitations',
62
+ allergyHistory: 'Medical.Mock.None',
63
+ medicalHistory: 'Medical.Mock.ThyroidNodule',
64
+ patientAge: 28,
65
+ patientGender: 'Medical.Mock.Female',
66
+ patientPhone: '186****2211',
67
+ },
68
+ {
69
+ id: 'APT005',
70
+ roomId: 'med-room-005',
71
+ doctorId: 'doctor_wang',
72
+ patientId: 'patient_li',
73
+ scheduleStartTime: atToday(15, 0),
74
+ scheduleEndTime: atToday(15, 30),
75
+ chiefComplaint: 'Medical.Mock.ThroatCough',
76
+ allergyHistory: 'Medical.Mock.PollenAllergy',
77
+ medicalHistory: 'Medical.Mock.MildAsthma',
78
+ patientAge: 28,
79
+ patientGender: 'Medical.Mock.Female',
80
+ patientPhone: '186****2211',
81
+ },
82
+ {
83
+ id: 'APT006',
84
+ roomId: 'med-room-006',
85
+ doctorId: 'doctor_zhang',
86
+ patientId: 'patient_li',
87
+ scheduleStartTime: atToday(16, 0),
88
+ scheduleEndTime: atToday(16, 30),
89
+ chiefComplaint: 'Medical.Mock.AbdominalPain',
90
+ allergyHistory: 'Medical.Mock.None',
91
+ medicalHistory: 'Medical.Mock.NoMajorHistory',
92
+ patientAge: 28,
93
+ patientGender: 'Medical.Mock.Female',
94
+ patientPhone: '186****2211',
95
+ },
96
+ ];
@@ -0,0 +1,79 @@
1
+ import type { MedicalUser } from '@/services/adapters/types';
2
+
3
+ export const mockDoctorUsers: MedicalUser[] = [
4
+ {
5
+ userId: 'doctor_li',
6
+ userName: 'Medical.Mock.DoctorLi',
7
+ avatarUrl: '',
8
+ role: 'doctor',
9
+ title: 'Medical.Mock.ChiefPhysician',
10
+ department: 'Medical.Mock.Cardiology',
11
+ hospital: 'Medical.Mock.TertiaryHospital',
12
+ experience: 'Medical.Mock.Years20',
13
+ rating: '98.5',
14
+ consultations: '3248',
15
+ price: '50',
16
+ tags: [
17
+ 'Medical.Mock.Hypertension',
18
+ 'Medical.Mock.Coronary',
19
+ 'Medical.Mock.Arrhythmia',
20
+ ],
21
+ specialty: 'Medical.Mock.ChronicCare',
22
+ status: 'online',
23
+ },
24
+ {
25
+ userId: 'doctor_wang',
26
+ userName: 'Medical.Mock.DoctorWang',
27
+ avatarUrl: '',
28
+ role: 'doctor',
29
+ title: 'Medical.Mock.AssociateChiefPhysician',
30
+ department: 'Medical.Mock.Respiratory',
31
+ hospital: 'Medical.Mock.InternetHospital',
32
+ experience: 'Medical.Mock.Years15',
33
+ rating: '97.2',
34
+ consultations: '2156',
35
+ price: '40',
36
+ tags: [
37
+ 'Medical.Mock.Cough',
38
+ 'Medical.Mock.Asthma',
39
+ 'Medical.Mock.Pneumonia',
40
+ ],
41
+ specialty: 'Medical.Mock.RespiratoryFollowUp',
42
+ status: 'online',
43
+ },
44
+ {
45
+ userId: 'doctor_zhang',
46
+ userName: 'Medical.Mock.DoctorZhang',
47
+ avatarUrl: '',
48
+ role: 'doctor',
49
+ title: 'Medical.Mock.AttendingPhysician',
50
+ department: 'Medical.Mock.Gastroenterology',
51
+ hospital: 'Medical.Mock.SpecialtyHospital',
52
+ experience: 'Medical.Mock.Years10',
53
+ rating: '96.8',
54
+ consultations: '1892',
55
+ price: '30',
56
+ tags: [
57
+ 'Medical.Mock.Gastritis',
58
+ 'Medical.Mock.GastricUlcer',
59
+ 'Medical.Mock.Indigestion',
60
+ ],
61
+ specialty: 'Medical.Mock.GastroFollowUp',
62
+ status: 'busy',
63
+ },
64
+ ];
65
+
66
+ export const mockPatientUsers: MedicalUser[] = [
67
+ {
68
+ userId: 'patient_zhang',
69
+ userName: 'Medical.Mock.PatientZhang',
70
+ avatarUrl: '',
71
+ role: 'patient',
72
+ },
73
+ {
74
+ userId: 'patient_li',
75
+ userName: 'Medical.Mock.PatientLi',
76
+ avatarUrl: '',
77
+ role: 'patient',
78
+ },
79
+ ];
@@ -0,0 +1,63 @@
1
+ import { createRouter, createWebHashHistory } from 'vue-router';
2
+ import { getSession } from '@/utils/session';
3
+
4
+ const router = createRouter({
5
+ history: createWebHashHistory(),
6
+ routes: [
7
+ {
8
+ path: '/',
9
+ redirect: '/login',
10
+ },
11
+ {
12
+ path: '/login',
13
+ component: () => import('@/views/LoginView.vue'),
14
+ },
15
+ {
16
+ path: '/doctor/dashboard',
17
+ component: () => import('@/views/DoctorDashboardView.vue'),
18
+ },
19
+ {
20
+ path: '/doctor/consultation/:appointmentId',
21
+ component: () => import('@/views/DoctorConsultationView.vue'),
22
+ },
23
+ {
24
+ path: '/patient/select-doctor',
25
+ component: () => import('@/views/PatientSelectDoctorView.vue'),
26
+ },
27
+ {
28
+ path: '/patient/waiting/:appointmentId',
29
+ component: () => import('@/views/PatientWaitingView.vue'),
30
+ },
31
+ {
32
+ path: '/patient/consultation/:appointmentId',
33
+ component: () => import('@/views/PatientConsultationView.vue'),
34
+ },
35
+ {
36
+ path: '/patient/consultation-finished/:appointmentId',
37
+ component: () => import('@/views/PatientConsultationFinishedView.vue'),
38
+ },
39
+ ],
40
+ });
41
+
42
+ router.beforeEach(to => {
43
+ if (to.path === '/login') {
44
+ return true;
45
+ }
46
+
47
+ const session = getSession();
48
+ if (!session) {
49
+ return '/login';
50
+ }
51
+
52
+ if (to.path.startsWith('/doctor') && session.role !== 'doctor') {
53
+ return '/login';
54
+ }
55
+
56
+ if (to.path.startsWith('/patient') && session.role !== 'patient') {
57
+ return '/login';
58
+ }
59
+
60
+ return true;
61
+ });
62
+
63
+ export default router;
@@ -0,0 +1,25 @@
1
+ import { MEDICAL_MODE } from '@/config/runtime-config';
2
+ import { integrationAppointmentService } from '@/services/adapters/integration/appointmentService';
3
+ import { integrationAuthService } from '@/services/adapters/integration/authService';
4
+ import { integrationUserService } from '@/services/adapters/integration/userService';
5
+ import { mockAppointmentService } from '@/services/adapters/mock/appointmentService';
6
+ import { mockAuthService } from '@/services/adapters/mock/authService';
7
+ import { mockUserService } from '@/services/adapters/mock/userService';
8
+ import type { MedicalServiceAdapter } from '@/services/adapters/types';
9
+
10
+ const mockServices: MedicalServiceAdapter = {
11
+ auth: mockAuthService,
12
+ user: mockUserService,
13
+ appointment: mockAppointmentService,
14
+ };
15
+
16
+ const integrationServices: MedicalServiceAdapter = {
17
+ auth: integrationAuthService,
18
+ user: integrationUserService,
19
+ appointment: integrationAppointmentService,
20
+ };
21
+
22
+ export const services =
23
+ MEDICAL_MODE === 'integration' ? integrationServices : mockServices;
24
+
25
+ export * from '@/services/adapters/types';
@@ -0,0 +1,77 @@
1
+ import type {
2
+ AppointmentService,
3
+ MedicalAppointment,
4
+ } from '@/services/adapters/types';
5
+ import { medicalT } from '@/i18n/medicalTranslate';
6
+ import { getRequiredLaunchContext } from '@/services/adapters/integration/launchContext';
7
+
8
+ function getLaunchAppointmentId() {
9
+ return getRequiredLaunchContext()?.appointmentId || '';
10
+ }
11
+
12
+ function getLaunchUserContext() {
13
+ const context = getRequiredLaunchContext();
14
+ const role = context?.role;
15
+ const userId = context?.userId || '';
16
+ const doctorId =
17
+ context?.doctorId ||
18
+ (role === 'doctor' ? userId : '') ||
19
+ 'doctor_placeholder';
20
+ const patientId =
21
+ context?.patientId ||
22
+ (role === 'patient' ? userId : '') ||
23
+ 'patient_placeholder';
24
+
25
+ return { doctorId, patientId };
26
+ }
27
+
28
+ function buildIntegrationAppointment(
29
+ appointmentId: string
30
+ ): MedicalAppointment {
31
+ // Customer integration should replace this mapper with data returned by
32
+ // its appointment API, preserving the MedicalAppointment view model shape.
33
+ const now = Math.floor(Date.now() / 1000);
34
+ const { doctorId, patientId } = getLaunchUserContext();
35
+ return {
36
+ id: appointmentId,
37
+ roomId: `room-${appointmentId}`,
38
+ doctorId,
39
+ patientId,
40
+ scheduleStartTime: now,
41
+ scheduleEndTime: now + 30 * 60,
42
+ chiefComplaint: medicalT('Medical.Mock.IntegrationChiefComplaint'),
43
+ allergyHistory: medicalT('Medical.Mock.IntegrationBusinessData'),
44
+ medicalHistory: medicalT('Medical.Mock.IntegrationBusinessData'),
45
+ patientAge: 0,
46
+ patientGender: medicalT('Medical.Mock.Unknown'),
47
+ patientPhone: '',
48
+ };
49
+ }
50
+
51
+ export const integrationAppointmentService: AppointmentService = {
52
+ getAppointmentById(appointmentId) {
53
+ return buildIntegrationAppointment(appointmentId);
54
+ },
55
+ getAppointmentByRoomId(roomId) {
56
+ const appointmentId = roomId.startsWith('room-')
57
+ ? roomId.slice('room-'.length)
58
+ : getLaunchAppointmentId();
59
+ return appointmentId ? buildIntegrationAppointment(appointmentId) : null;
60
+ },
61
+ getAppointmentsByDoctor(doctorId) {
62
+ const appointmentId = getLaunchAppointmentId();
63
+ if (!appointmentId) {
64
+ return [];
65
+ }
66
+ const appointment = buildIntegrationAppointment(appointmentId);
67
+ return appointment.doctorId === doctorId ? [appointment] : [];
68
+ },
69
+ getAppointmentsByPatient(patientId) {
70
+ const appointmentId = getLaunchAppointmentId();
71
+ if (!appointmentId) {
72
+ return [];
73
+ }
74
+ const appointment = buildIntegrationAppointment(appointmentId);
75
+ return appointment.patientId === patientId ? [appointment] : [];
76
+ },
77
+ };
@@ -0,0 +1,38 @@
1
+ import { integrationUserService } from '@/services/adapters/integration/userService';
2
+ import { parseLaunchContextFromUrl } from '@/services/adapters/integration/launchContext';
3
+ import type {
4
+ AuthService,
5
+ LaunchContext,
6
+ SessionData,
7
+ } from '@/services/adapters/types';
8
+
9
+ function buildSession(context: LaunchContext): SessionData {
10
+ const fallbackUser =
11
+ context.role === 'doctor'
12
+ ? integrationUserService.getDoctorById(context.userId)
13
+ : integrationUserService.getPatientById(context.userId);
14
+
15
+ return {
16
+ role: context.role,
17
+ userId: context.userId,
18
+ appointmentId: context.appointmentId,
19
+ token: context.token,
20
+ launchMode: 'integration',
21
+ user: fallbackUser || {
22
+ userId: context.userId,
23
+ userName: context.userName || context.userId,
24
+ avatarUrl: context.avatarUrl || '',
25
+ role: context.role,
26
+ },
27
+ };
28
+ }
29
+
30
+ export const integrationAuthService: AuthService = {
31
+ getLaunchContext() {
32
+ return parseLaunchContextFromUrl();
33
+ },
34
+ async login(context) {
35
+ return buildSession(context);
36
+ },
37
+ async logout() {},
38
+ };
@@ -0,0 +1,31 @@
1
+ import type { LaunchContext, UserRole } from '@/services/adapters/types';
2
+
3
+ function getRole(value: string | null): UserRole | null {
4
+ if (value === 'doctor' || value === 'patient') {
5
+ return value;
6
+ }
7
+ return null;
8
+ }
9
+
10
+ export function parseLaunchContextFromUrl(): LaunchContext | null {
11
+ const params = new URLSearchParams(window.location.search);
12
+ const role = getRole(params.get('role'));
13
+ const userId = params.get('userId')?.trim() || '';
14
+ if (!role || !userId) {
15
+ return null;
16
+ }
17
+ return {
18
+ role,
19
+ userId,
20
+ appointmentId: params.get('appointmentId')?.trim() || undefined,
21
+ token: params.get('token')?.trim() || undefined,
22
+ doctorId: params.get('doctorId')?.trim() || undefined,
23
+ patientId: params.get('patientId')?.trim() || undefined,
24
+ userName: params.get('userName')?.trim() || undefined,
25
+ avatarUrl: params.get('avatarUrl')?.trim() || undefined,
26
+ };
27
+ }
28
+
29
+ export function getRequiredLaunchContext(): LaunchContext | null {
30
+ return parseLaunchContextFromUrl();
31
+ }
@@ -0,0 +1,35 @@
1
+ import type { MedicalUser, UserService } from '@/services/adapters/types';
2
+
3
+ function buildPlaceholderUser(
4
+ role: MedicalUser['role'],
5
+ userId: string
6
+ ): MedicalUser {
7
+ return {
8
+ userId,
9
+ userName: userId,
10
+ avatarUrl: '',
11
+ role,
12
+ };
13
+ }
14
+
15
+ export const integrationUserService: UserService = {
16
+ listDoctors() {
17
+ return [];
18
+ },
19
+ listPatients() {
20
+ return [];
21
+ },
22
+ getUserById(userId) {
23
+ return (
24
+ this.getDoctorById(userId) ||
25
+ this.getPatientById(userId) ||
26
+ buildPlaceholderUser('doctor', userId)
27
+ );
28
+ },
29
+ getDoctorById(userId) {
30
+ return buildPlaceholderUser('doctor', userId);
31
+ },
32
+ getPatientById(userId) {
33
+ return buildPlaceholderUser('patient', userId);
34
+ },
35
+ };
@@ -0,0 +1,43 @@
1
+ import { mockAppointments } from '@/mock/appointments';
2
+ import { medicalTranslate } from '@/i18n/medicalTranslate';
3
+ import type {
4
+ AppointmentService,
5
+ MedicalAppointment,
6
+ } from '@/services/adapters/types';
7
+
8
+ function cloneAppointment(
9
+ appointment: MedicalAppointment | undefined
10
+ ): MedicalAppointment | null {
11
+ return appointment
12
+ ? {
13
+ ...appointment,
14
+ chiefComplaint: medicalTranslate(appointment.chiefComplaint),
15
+ allergyHistory: medicalTranslate(appointment.allergyHistory),
16
+ medicalHistory: medicalTranslate(appointment.medicalHistory),
17
+ patientGender: medicalTranslate(appointment.patientGender),
18
+ }
19
+ : null;
20
+ }
21
+
22
+ export const mockAppointmentService: AppointmentService = {
23
+ getAppointmentById(appointmentId) {
24
+ return cloneAppointment(
25
+ mockAppointments.find(item => item.id === appointmentId)
26
+ );
27
+ },
28
+ getAppointmentByRoomId(roomId) {
29
+ return cloneAppointment(mockAppointments.find(item => item.roomId === roomId));
30
+ },
31
+ getAppointmentsByDoctor(doctorId) {
32
+ return mockAppointments
33
+ .filter(item => item.doctorId === doctorId)
34
+ .map(item => cloneAppointment(item))
35
+ .filter((item): item is MedicalAppointment => !!item);
36
+ },
37
+ getAppointmentsByPatient(patientId) {
38
+ return mockAppointments
39
+ .filter(item => item.patientId === patientId)
40
+ .map(item => cloneAppointment(item))
41
+ .filter((item): item is MedicalAppointment => !!item);
42
+ },
43
+ };
@@ -0,0 +1,33 @@
1
+ import { mockUserService } from '@/services/adapters/mock/userService';
2
+ import type {
3
+ AuthService,
4
+ LaunchContext,
5
+ SessionData,
6
+ } from '@/services/adapters/types';
7
+
8
+ function buildMockSession(context: LaunchContext): SessionData {
9
+ return {
10
+ role: context.role,
11
+ userId: context.userId,
12
+ appointmentId: context.appointmentId,
13
+ token: context.token,
14
+ launchMode: 'mock',
15
+ user:
16
+ mockUserService.getUserById(context.userId) || {
17
+ userId: context.userId,
18
+ userName: context.userName || context.userId,
19
+ avatarUrl: context.avatarUrl || '',
20
+ role: context.role,
21
+ },
22
+ };
23
+ }
24
+
25
+ export const mockAuthService: AuthService = {
26
+ getLaunchContext() {
27
+ return null;
28
+ },
29
+ async login(context) {
30
+ return buildMockSession(context);
31
+ },
32
+ async logout() {},
33
+ };
@@ -0,0 +1,43 @@
1
+ import { mockDoctorUsers, mockPatientUsers } from '@/mock/users';
2
+ import { medicalTranslate, medicalTranslateList } from '@/i18n/medicalTranslate';
3
+ import type { MedicalUser, UserService } from '@/services/adapters/types';
4
+
5
+ function localizeUser(user: MedicalUser): MedicalUser {
6
+ return {
7
+ ...user,
8
+ userName: medicalTranslate(user.userName),
9
+ title: user.title ? medicalTranslate(user.title) : user.title,
10
+ department: user.department ? medicalTranslate(user.department) : user.department,
11
+ hospital: user.hospital ? medicalTranslate(user.hospital) : user.hospital,
12
+ experience: user.experience ? medicalTranslate(user.experience) : user.experience,
13
+ tags: medicalTranslateList(user.tags),
14
+ specialty: user.specialty ? medicalTranslate(user.specialty) : user.specialty,
15
+ };
16
+ }
17
+
18
+ function findUserById(userId: string): MedicalUser | null {
19
+ const user =
20
+ mockDoctorUsers.find(item => item.userId === userId) ||
21
+ mockPatientUsers.find(item => item.userId === userId);
22
+ return user ? localizeUser(user) : null;
23
+ }
24
+
25
+ export const mockUserService: UserService = {
26
+ listDoctors() {
27
+ return mockDoctorUsers.map(localizeUser);
28
+ },
29
+ listPatients() {
30
+ return mockPatientUsers.map(localizeUser);
31
+ },
32
+ getUserById(userId) {
33
+ return findUserById(userId);
34
+ },
35
+ getDoctorById(userId) {
36
+ const user = mockDoctorUsers.find(item => item.userId === userId);
37
+ return user ? localizeUser(user) : null;
38
+ },
39
+ getPatientById(userId) {
40
+ const user = mockPatientUsers.find(item => item.userId === userId);
41
+ return user ? localizeUser(user) : null;
42
+ },
43
+ };