DoctorSelectionCard.vue 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <section class="doc-list">
  3. <div
  4. v-for="(doc, idx) in doctors"
  5. :key="doc.doctorId"
  6. :class="['doc-card', { rec: idx === 0 }]"
  7. @click="select(doc)"
  8. >
  9. <div class="doc-av">{{ doc.name.charAt(0) }}</div>
  10. <div class="doc-info">
  11. <div class="doc-name">{{ doc.name }}</div>
  12. <div class="doc-dept">{{ doc.title }}</div>
  13. <div v-if="doc.specialty" class="doc-skill">擅长:{{ doc.specialty }}</div>
  14. </div>
  15. <span v-if="idx === 0" class="doc-rec-badge">推荐</span>
  16. </div>
  17. </section>
  18. </template>
  19. <script setup lang="ts">
  20. import { computed } from 'vue';
  21. import { useTerminalStore } from '../state/terminalStore';
  22. import type { CardInstance } from '../api/types';
  23. const props = defineProps<{ card: CardInstance }>();
  24. const emit = defineEmits<{ action: [data: { actionName: string; payload: Record<string, unknown> }] }>();
  25. const store = useTerminalStore();
  26. interface DoctorOption {
  27. doctorId: string;
  28. name: string;
  29. title: string;
  30. specialty?: string;
  31. room?: string;
  32. }
  33. const doctors = computed(() => (props.card.cardData.doctors as DoctorOption[]) ?? []);
  34. function select(doc: DoctorOption) {
  35. if (store.cardActionSubmitting) return;
  36. emit('action', {
  37. actionName: 'select_doctor',
  38. payload: { doctorId: doc.doctorId, doctorName: doc.name, doctorTitle: doc.title },
  39. });
  40. }
  41. </script>
  42. <style scoped>
  43. .doc-list {
  44. display: flex;
  45. flex-direction: column;
  46. gap: 8px;
  47. }
  48. .doc-card {
  49. display: flex;
  50. align-items: center;
  51. gap: 12px;
  52. padding: 14px;
  53. border: 1px solid var(--border);
  54. border-radius: var(--radius-md);
  55. cursor: pointer;
  56. transition: border-color 0.15s ease, background 0.15s ease;
  57. }
  58. .doc-card:hover {
  59. border-color: var(--accent);
  60. }
  61. .doc-card.rec {
  62. border-color: var(--accent);
  63. background: var(--accent-faint);
  64. }
  65. .doc-av {
  66. width: 44px;
  67. height: 44px;
  68. border-radius: var(--radius-sm);
  69. background: var(--accent-soft);
  70. display: grid;
  71. place-items: center;
  72. font-size: 16px;
  73. color: var(--accent);
  74. font-weight: 600;
  75. flex-shrink: 0;
  76. font-family: var(--font-display);
  77. }
  78. .doc-info {
  79. flex: 1;
  80. min-width: 0;
  81. }
  82. .doc-name {
  83. font-size: var(--fs-body);
  84. font-weight: 500;
  85. }
  86. .doc-dept {
  87. font-size: var(--fs-xs);
  88. color: var(--muted);
  89. }
  90. .doc-skill {
  91. font-size: 11px;
  92. color: var(--muted);
  93. margin-top: 1px;
  94. }
  95. .doc-rec-badge {
  96. font-size: 10px;
  97. padding: 2px 7px;
  98. border-radius: var(--radius-pill);
  99. background: var(--accent);
  100. color: var(--surface);
  101. font-weight: 500;
  102. white-space: nowrap;
  103. }
  104. </style>