999 lines
24 KiB
Vue
999 lines
24 KiB
Vue
<template>
|
||
<view class="learning-page">
|
||
<view class="learning-shell">
|
||
<view class="assistant-header">
|
||
<view class="header-left">
|
||
<button class="icon-button" aria-label="返回" @click="emit('go-home')">
|
||
<view class="history-icon"></view>
|
||
</button>
|
||
<text class="page-title">AI 学习助手</text>
|
||
</view>
|
||
<view class="header-actions">
|
||
<button class="director-chip" @click="modalVisible = true">
|
||
<image class="director-thumb" src="/static/config-doctor.png" mode="aspectFill"></image>
|
||
<text>咨询王主任</text>
|
||
</button>
|
||
<button class="icon-button muted" aria-label="更多" @click="showToast('更多功能即将开放')">
|
||
<view class="more-icon"></view>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<scroll-view class="chat-canvas" scroll-y :scroll-top="scrollTop">
|
||
<view class="time-row">
|
||
<text>今天 10:42 AM</text>
|
||
</view>
|
||
|
||
<view
|
||
v-for="message in messages"
|
||
:key="message.id"
|
||
class="message-block"
|
||
:class="`message-${message.role}`"
|
||
>
|
||
<view v-if="message.role === 'user'" class="user-bubble">
|
||
<text>{{ message.content }}</text>
|
||
</view>
|
||
|
||
<view v-else class="assistant-message">
|
||
<view class="assistant-meta">
|
||
<view class="robot-badge">
|
||
<view class="robot-icon"></view>
|
||
</view>
|
||
<text>AI 临床助理</text>
|
||
</view>
|
||
|
||
<view v-if="message.variant === 'acs-pathway'" class="assistant-card">
|
||
<text class="response-intro">急性冠脉综合征(ACS)临床路径:</text>
|
||
|
||
<view class="pathway-card">
|
||
<view
|
||
v-for="step in pathwaySteps"
|
||
:key="step.title"
|
||
class="pathway-step"
|
||
>
|
||
<text class="step-index">{{ step.index }}</text>
|
||
<view class="step-copy">
|
||
<text class="step-title">{{ step.title }}</text>
|
||
<text class="step-desc">{{ step.description }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="evidence-box">
|
||
<view class="evidence-heading">
|
||
<view class="verified-icon"></view>
|
||
<text>循证来源</text>
|
||
</view>
|
||
<text class="evidence-item">[1] 2023 AHA/ACC ACS 管理指南</text>
|
||
<text class="evidence-item">[2] 《临床诊疗常规:心血管分册》</text>
|
||
</view>
|
||
</view>
|
||
|
||
<view v-else class="assistant-card simple-card">
|
||
<text>{{ message.content }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="typing-row" :class="{ visible: typingVisible }">
|
||
<view class="typing-dots">
|
||
<view class="dot dot-one"></view>
|
||
<view class="dot dot-two"></view>
|
||
<view class="dot dot-three"></view>
|
||
</view>
|
||
<text>正在思考中...</text>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<view class="input-panel">
|
||
<scroll-view class="quick-actions" scroll-x>
|
||
<view class="quick-row">
|
||
<button
|
||
v-for="action in quickActions"
|
||
:key="action"
|
||
class="quick-chip"
|
||
@click="useQuickAction(action)"
|
||
>
|
||
{{ action }}
|
||
</button>
|
||
</view>
|
||
</scroll-view>
|
||
|
||
<view class="composer">
|
||
<textarea
|
||
class="message-input"
|
||
v-model="draft"
|
||
auto-height
|
||
maxlength="500"
|
||
placeholder="请输入您的问题..."
|
||
placeholder-class="input-placeholder"
|
||
@confirm="handleSend"
|
||
></textarea>
|
||
<view class="composer-actions">
|
||
<button class="attach-button" aria-label="附件" @click="showToast('附件上传即将开放')">
|
||
<view class="attach-icon"></view>
|
||
</button>
|
||
<button class="send-button" aria-label="发送" @click="handleSend">
|
||
<view class="send-icon"></view>
|
||
</button>
|
||
</view>
|
||
</view>
|
||
|
||
<text class="disclaimer">AI 生成内容仅供临床参考,最终医疗决策请咨询资深医师。</text>
|
||
</view>
|
||
|
||
<view v-if="modalVisible" class="modal-mask" @click="modalVisible = false">
|
||
<view class="wang-modal" @click.stop>
|
||
<view class="modal-header">
|
||
<view class="modal-doctor">
|
||
<image class="modal-avatar" src="/static/config-doctor.png" mode="aspectFill"></image>
|
||
<view class="modal-title-group">
|
||
<text class="modal-title">王主任</text>
|
||
<text class="modal-subtitle">临床教育首席专家</text>
|
||
</view>
|
||
</view>
|
||
<button class="icon-button muted" aria-label="关闭" @click="modalVisible = false">
|
||
<view class="close-icon"></view>
|
||
</button>
|
||
</view>
|
||
|
||
<view class="modal-body">
|
||
<view class="quote-card">
|
||
<text>“对于 ACS 患者,请务必牢记:时间就是心肌。虽然 AI 提供了标准的临床路径,但结合患者个体化风险特征的临床判断仍是您最关键的工具。”</text>
|
||
</view>
|
||
|
||
<view class="mentor-grid">
|
||
<button class="mentor-card" @click="showToast('已选择查房带教')">
|
||
<view class="school-small-icon"></view>
|
||
<text>查房带教</text>
|
||
</button>
|
||
<button class="mentor-card" @click="showToast('已选择疑难会诊')">
|
||
<view class="notes-small-icon"></view>
|
||
<text>疑难会诊</text>
|
||
</button>
|
||
</view>
|
||
|
||
<button class="guidance-button" @click="showToast('一对一指导即将开始')">
|
||
开始一对一指导
|
||
</button>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="toast" :class="{ visible: toastVisible }">{{ toastMessage }}</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { nextTick, onMounted, onUnmounted, ref } from 'vue'
|
||
|
||
type AssistantMessage = {
|
||
id: string
|
||
role: 'user' | 'assistant'
|
||
content: string
|
||
variant?: 'acs-pathway' | 'simple'
|
||
}
|
||
|
||
const emit = defineEmits<{
|
||
(event: 'go-home'): void
|
||
(event: 'open-settings'): void
|
||
(event: 'open-profile'): void
|
||
}>()
|
||
|
||
const quickActions = ['更新指南', '风险评估量表', '药理学详情', '病例研讨']
|
||
|
||
const pathwaySteps = [
|
||
{ index: '1', title: '早期识别', description: '10分钟内完成12导联心电图。' },
|
||
{ index: '2', title: '药物干预', description: '阿司匹林、氯吡格雷。' },
|
||
{ index: '3', title: '再灌注策略', description: 'STEMI需紧急PCI。' }
|
||
]
|
||
|
||
const messages = ref<AssistantMessage[]>([
|
||
{
|
||
id: 'sample-user',
|
||
role: 'user',
|
||
content: '你能解释一下急性冠脉综合征(ACS)的最新临床路径吗?'
|
||
},
|
||
{
|
||
id: 'sample-ai',
|
||
role: 'assistant',
|
||
content: '',
|
||
variant: 'acs-pathway'
|
||
}
|
||
])
|
||
|
||
const draft = ref('')
|
||
const modalVisible = ref(false)
|
||
const typingVisible = ref(false)
|
||
const toastMessage = ref('')
|
||
const toastVisible = ref(false)
|
||
const scrollTop = ref(0)
|
||
|
||
let typingTimer: ReturnType<typeof setTimeout> | null = null
|
||
let pulseTimer: ReturnType<typeof setInterval> | null = null
|
||
let toastTimer: ReturnType<typeof setTimeout> | null = null
|
||
|
||
function useQuickAction(action: string) {
|
||
const prompts: Record<string, string> = {
|
||
更新指南: '请帮我梳理 ACS 最新指南中需要重点关注的更新。',
|
||
风险评估量表: '请列出 ACS 常用风险评估量表及适用场景。',
|
||
药理学详情: '请说明 ACS 常用抗血小板药物的适应证和注意事项。',
|
||
病例研讨: '请用病例研讨形式带我复盘一例胸痛患者。'
|
||
}
|
||
draft.value = prompts[action] || action
|
||
}
|
||
|
||
function handleSend() {
|
||
const value = draft.value.trim()
|
||
if (!value) {
|
||
showToast('请输入问题')
|
||
return
|
||
}
|
||
|
||
messages.value.push({
|
||
id: `user-${Date.now()}`,
|
||
role: 'user',
|
||
content: value
|
||
})
|
||
draft.value = ''
|
||
typingVisible.value = true
|
||
scrollToBottom()
|
||
|
||
if (typingTimer) clearTimeout(typingTimer)
|
||
typingTimer = setTimeout(() => {
|
||
typingVisible.value = false
|
||
messages.value.push({
|
||
id: `assistant-${Date.now()}`,
|
||
role: 'assistant',
|
||
variant: 'simple',
|
||
content: '已收到。我会结合医院知识库、临床路径和指南证据,为你整理成可用于带教复盘的要点。'
|
||
})
|
||
scrollToBottom()
|
||
}, 900)
|
||
}
|
||
|
||
function scrollToBottom() {
|
||
nextTick(() => {
|
||
scrollTop.value += 1000
|
||
})
|
||
}
|
||
|
||
function showToast(message: string) {
|
||
if (toastTimer) clearTimeout(toastTimer)
|
||
toastMessage.value = message
|
||
toastVisible.value = true
|
||
uni.showToast({
|
||
title: message,
|
||
icon: 'none'
|
||
})
|
||
toastTimer = setTimeout(() => {
|
||
toastVisible.value = false
|
||
}, 1800)
|
||
}
|
||
|
||
onMounted(() => {
|
||
pulseTimer = setInterval(() => {
|
||
if (typingVisible.value) return
|
||
typingVisible.value = true
|
||
setTimeout(() => {
|
||
typingVisible.value = false
|
||
}, 2400)
|
||
}, 12000)
|
||
})
|
||
|
||
onUnmounted(() => {
|
||
if (typingTimer) clearTimeout(typingTimer)
|
||
if (pulseTimer) clearInterval(pulseTimer)
|
||
if (toastTimer) clearTimeout(toastTimer)
|
||
})
|
||
</script>
|
||
|
||
<style>
|
||
page {
|
||
min-height: 100%;
|
||
background: #f2f3fb;
|
||
}
|
||
|
||
.learning-page {
|
||
min-height: 100vh;
|
||
background: #f2f3fb;
|
||
color: #191c21;
|
||
font-family: Inter, -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', Arial, sans-serif;
|
||
-webkit-tap-highlight-color: transparent;
|
||
}
|
||
|
||
.learning-shell {
|
||
position: relative;
|
||
min-height: 100vh;
|
||
background: #ffffff;
|
||
overflow: hidden;
|
||
display: flex;
|
||
flex-direction: column;
|
||
}
|
||
|
||
.assistant-header {
|
||
position: relative;
|
||
z-index: 10;
|
||
box-sizing: border-box;
|
||
height: 56px;
|
||
padding: 0 16px;
|
||
border-bottom: 1px solid #c2c6d4;
|
||
background: #ffffff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.header-left,
|
||
.header-actions,
|
||
.director-chip,
|
||
.assistant-meta,
|
||
.evidence-heading,
|
||
.composer-actions,
|
||
.modal-doctor {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.header-left,
|
||
.header-actions {
|
||
gap: 12px;
|
||
}
|
||
|
||
.page-title {
|
||
color: #191c21;
|
||
font-size: 18px;
|
||
line-height: 28px;
|
||
font-weight: 600;
|
||
letter-spacing: 0;
|
||
}
|
||
|
||
.icon-button,
|
||
.director-chip,
|
||
.quick-chip,
|
||
.attach-button,
|
||
.send-button,
|
||
.mentor-card,
|
||
.guidance-button {
|
||
padding: 0;
|
||
border: 0;
|
||
background: transparent;
|
||
}
|
||
|
||
.icon-button::after,
|
||
.director-chip::after,
|
||
.quick-chip::after,
|
||
.attach-button::after,
|
||
.send-button::after,
|
||
.mentor-card::after,
|
||
.guidance-button::after {
|
||
border: 0;
|
||
}
|
||
|
||
.icon-button {
|
||
width: 32px;
|
||
height: 32px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.icon-button:active {
|
||
background: rgba(25, 28, 33, 0.05);
|
||
}
|
||
|
||
.director-chip {
|
||
box-sizing: border-box;
|
||
min-height: 32px;
|
||
padding: 4px 8px;
|
||
border: 1px solid #c2c6d4;
|
||
border-radius: 12px;
|
||
background: #f2f3fb;
|
||
gap: 8px;
|
||
color: #00478d;
|
||
font-size: 12px;
|
||
line-height: 16px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.director-thumb {
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 50%;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.history-icon,
|
||
.more-icon,
|
||
.robot-icon,
|
||
.verified-icon,
|
||
.attach-icon,
|
||
.send-icon,
|
||
.close-icon,
|
||
.school-small-icon,
|
||
.notes-small-icon {
|
||
background: #424752;
|
||
-webkit-mask-position: center;
|
||
-webkit-mask-repeat: no-repeat;
|
||
-webkit-mask-size: contain;
|
||
mask-position: center;
|
||
mask-repeat: no-repeat;
|
||
mask-size: contain;
|
||
}
|
||
|
||
.history-icon {
|
||
width: 24px;
|
||
height: 24px;
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M13%203a9%209%200%201%201-8.95%2010H2l3-3%203%203H6.07A7%207%200%201%200%208.1%208.05L6.68%206.63A8.96%208.96%200%200%201%2013%203zm-1%205h1.5v5l4%202-.75%201.23L12%2013.75V8z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M13%203a9%209%200%201%201-8.95%2010H2l3-3%203%203H6.07A7%207%200%201%200%208.1%208.05L6.68%206.63A8.96%208.96%200%200%201%2013%203zm-1%205h1.5v5l4%202-.75%201.23L12%2013.75V8z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.more-icon {
|
||
width: 24px;
|
||
height: 24px;
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%208a2%202%200%201%200%200-4%202%202%200%200%200%200%204zm0%202a2%202%200%201%200%200%204%202%202%200%200%200%200-4zm0%206a2%202%200%201%200%200%204%202%202%200%200%200%200-4z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%208a2%202%200%201%200%200-4%202%202%200%200%200%200%204zm0%202a2%202%200%201%200%200%204%202%202%200%200%200%200-4zm0%206a2%202%200%201%200%200%204%202%202%200%200%200%200-4z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.chat-canvas {
|
||
box-sizing: border-box;
|
||
flex: 1 1 auto;
|
||
min-height: 0;
|
||
padding: 16px;
|
||
background: #ffffff;
|
||
}
|
||
|
||
.time-row {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-bottom: 32px;
|
||
}
|
||
|
||
.time-row text {
|
||
padding: 4px 16px;
|
||
border-radius: 12px;
|
||
background: #f2f3fb;
|
||
color: #727783;
|
||
font-size: 12px;
|
||
line-height: 16px;
|
||
font-weight: 500;
|
||
letter-spacing: 0;
|
||
}
|
||
|
||
.message-block {
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.message-user {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.user-bubble {
|
||
box-sizing: border-box;
|
||
max-width: 85%;
|
||
padding: 12px 16px;
|
||
border-radius: 8px 8px 0 8px;
|
||
background: #00478d;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||
color: #ffffff;
|
||
font-size: 16px;
|
||
line-height: 24px;
|
||
}
|
||
|
||
.assistant-message {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
gap: 12px;
|
||
}
|
||
|
||
.assistant-meta {
|
||
gap: 8px;
|
||
color: #00478d;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.robot-badge {
|
||
width: 28px;
|
||
height: 28px;
|
||
border-radius: 8px;
|
||
background: #00478d;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.robot-icon {
|
||
width: 18px;
|
||
height: 18px;
|
||
background: #ffffff;
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%202a2%202%200%200%201%201%203.73V7h4a3%203%200%200%201%203%203v7a3%203%200%200%201-3%203H7a3%203%200%200%201-3-3v-7a3%203%200%200%201%203-3h4V5.73A2%202%200%200%201%2012%202zM7%2010a1%201%200%200%200-1%201v6a1%201%200%200%200%201%201h10a1%201%200%200%200%201-1v-6a1%201%200%200%200-1-1H7zm2.5%203.5a1.5%201.5%200%201%201%200-3%201.5%201.5%200%200%201%200%203zm5%200a1.5%201.5%200%201%201%200-3%201.5%201.5%200%200%201%200%203z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%202a2%202%200%200%201%201%203.73V7h4a3%203%200%200%201%203%203v7a3%203%200%200%201-3%203H7a3%203%200%200%201-3-3v-7a3%203%200%200%201%203-3h4V5.73A2%202%200%200%201%2012%202zM7%2010a1%201%200%200%200-1%201v6a1%201%200%200%200%201%201h10a1%201%200%200%200%201-1v-6a1%201%200%200%200-1-1H7zm2.5%203.5a1.5%201.5%200%201%201%200-3%201.5%201.5%200%200%201%200%203zm5%200a1.5%201.5%200%201%201%200-3%201.5%201.5%200%200%201%200%203z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.assistant-card {
|
||
box-sizing: border-box;
|
||
max-width: 90%;
|
||
padding: 16px;
|
||
border: 1px solid #c2c6d4;
|
||
border-radius: 0 8px 8px 8px;
|
||
background: #ffffff;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 12px;
|
||
}
|
||
|
||
.response-intro,
|
||
.simple-card {
|
||
color: #191c21;
|
||
font-size: 16px;
|
||
line-height: 24px;
|
||
}
|
||
|
||
.pathway-card {
|
||
box-sizing: border-box;
|
||
padding: 16px;
|
||
border: 1px solid rgba(194, 198, 212, 0.3);
|
||
border-radius: 8px;
|
||
background: #f2f3fb;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
}
|
||
|
||
.pathway-step {
|
||
display: flex;
|
||
align-items: flex-start;
|
||
gap: 12px;
|
||
}
|
||
|
||
.step-index {
|
||
width: 20px;
|
||
height: 20px;
|
||
border-radius: 50%;
|
||
background: #00478d;
|
||
color: #ffffff;
|
||
font-size: 10px;
|
||
line-height: 20px;
|
||
text-align: center;
|
||
font-weight: 600;
|
||
flex: 0 0 auto;
|
||
margin-top: 2px;
|
||
}
|
||
|
||
.step-copy {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
}
|
||
|
||
.step-title {
|
||
color: #00478d;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.step-desc {
|
||
color: #424752;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
}
|
||
|
||
.evidence-box {
|
||
padding-top: 16px;
|
||
border-top: 1px solid #c2c6d4;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 4px;
|
||
}
|
||
|
||
.evidence-heading {
|
||
gap: 8px;
|
||
margin-bottom: 4px;
|
||
color: #006970;
|
||
font-size: 12px;
|
||
line-height: 16px;
|
||
font-weight: 700;
|
||
letter-spacing: 0;
|
||
}
|
||
|
||
.verified-icon {
|
||
width: 16px;
|
||
height: 16px;
|
||
background: #006970;
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%202l2.39%202.42%203.37-.49.6%203.35%203.02%201.57-1.55%203.03%201.55%203.03-3.02%201.57-.6%203.35-3.37-.49L12%2022l-2.39-2.42-3.37.49-.6-3.35-3.02-1.57%201.55-3.03-1.55-3.03%203.02-1.57.6-3.35%203.37.49L12%202zm-1.1%2013.2l5.66-5.66-1.42-1.42-4.24%204.24-2.12-2.12-1.42%201.42%203.54%203.54z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%202l2.39%202.42%203.37-.49.6%203.35%203.02%201.57-1.55%203.03%201.55%203.03-3.02%201.57-.6%203.35-3.37-.49L12%2022l-2.39-2.42-3.37.49-.6-3.35-3.02-1.57%201.55-3.03-1.55-3.03%203.02-1.57.6-3.35%203.37.49L12%202zm-1.1%2013.2l5.66-5.66-1.42-1.42-4.24%204.24-2.12-2.12-1.42%201.42%203.54%203.54z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.evidence-item {
|
||
color: #424752;
|
||
font-size: 13px;
|
||
line-height: 20px;
|
||
font-style: italic;
|
||
}
|
||
|
||
.typing-row {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
color: #727783;
|
||
font-size: 12px;
|
||
line-height: 16px;
|
||
font-style: italic;
|
||
opacity: 0;
|
||
transition: opacity 0.3s ease;
|
||
}
|
||
|
||
.typing-row.visible {
|
||
opacity: 1;
|
||
}
|
||
|
||
.typing-dots {
|
||
display: flex;
|
||
gap: 4px;
|
||
}
|
||
|
||
.dot {
|
||
width: 6px;
|
||
height: 6px;
|
||
border-radius: 50%;
|
||
background: #727783;
|
||
animation: typing-bounce 1s ease-in-out infinite;
|
||
}
|
||
|
||
.dot-two {
|
||
animation-delay: 0.12s;
|
||
}
|
||
|
||
.dot-three {
|
||
animation-delay: 0.24s;
|
||
}
|
||
|
||
.input-panel {
|
||
box-sizing: border-box;
|
||
padding: 12px 16px 16px;
|
||
border-top: 1px solid #c2c6d4;
|
||
background: #ffffff;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.quick-actions {
|
||
width: 100%;
|
||
margin-bottom: 12px;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.quick-row {
|
||
display: flex;
|
||
gap: 8px;
|
||
padding-bottom: 4px;
|
||
}
|
||
|
||
.quick-chip {
|
||
box-sizing: border-box;
|
||
min-height: 32px;
|
||
padding: 6px 16px;
|
||
border: 1px solid #c2c6d4;
|
||
border-radius: 12px;
|
||
background: #ecedf6;
|
||
color: #424752;
|
||
font-size: 12px;
|
||
line-height: 16px;
|
||
font-weight: 500;
|
||
letter-spacing: 0;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.quick-chip:active {
|
||
background: #e7e8f0;
|
||
}
|
||
|
||
.composer {
|
||
box-sizing: border-box;
|
||
padding: 8px;
|
||
border: 1px solid #c2c6d4;
|
||
border-radius: 8px;
|
||
background: #f2f3fb;
|
||
display: flex;
|
||
align-items: flex-end;
|
||
gap: 8px;
|
||
}
|
||
|
||
.composer:focus-within {
|
||
border-color: #00478d;
|
||
}
|
||
|
||
.message-input {
|
||
flex: 1;
|
||
min-height: 44px;
|
||
max-height: 128px;
|
||
padding: 8px 0;
|
||
border: 0;
|
||
background: transparent;
|
||
color: #191c21;
|
||
font-size: 16px;
|
||
line-height: 24px;
|
||
}
|
||
|
||
.input-placeholder {
|
||
color: #727783;
|
||
}
|
||
|
||
.composer-actions {
|
||
gap: 4px;
|
||
flex: 0 0 auto;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.attach-button,
|
||
.send-button {
|
||
width: 40px;
|
||
height: 40px;
|
||
border-radius: 8px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
.attach-icon {
|
||
width: 22px;
|
||
height: 22px;
|
||
background: #727783;
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M16.5%206.5v9a4.5%204.5%200%200%201-9%200v-10a3%203%200%200%201%206%200v9a1.5%201.5%200%200%201-3%200v-8h2v8a.5.5%200%200%200%201%200v-9a2%202%200%200%200-4%200v10a2.5%202.5%200%200%200%205%200v-9h2z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M16.5%206.5v9a4.5%204.5%200%200%201-9%200v-10a3%203%200%200%201%206%200v9a1.5%201.5%200%200%201-3%200v-8h2v8a.5.5%200%200%200%201%200v-9a2%202%200%200%200-4%200v10a2.5%202.5%200%200%200%205%200v-9h2z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.send-button {
|
||
background: #00478d;
|
||
}
|
||
|
||
.send-button:active {
|
||
transform: scale(0.95);
|
||
}
|
||
|
||
.send-icon {
|
||
width: 20px;
|
||
height: 20px;
|
||
background: #ffffff;
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M2%2021l21-9L2%203v7l15%202-15%202v7z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M2%2021l21-9L2%203v7l15%202-15%202v7z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.disclaimer {
|
||
display: block;
|
||
margin-top: 8px;
|
||
text-align: center;
|
||
color: #727783;
|
||
font-size: 11px;
|
||
line-height: 16px;
|
||
}
|
||
|
||
.modal-mask {
|
||
position: absolute;
|
||
inset: 0;
|
||
z-index: 60;
|
||
background: rgba(0, 0, 0, 0.2);
|
||
backdrop-filter: blur(2px);
|
||
-webkit-backdrop-filter: blur(2px);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 20px;
|
||
}
|
||
|
||
.wang-modal {
|
||
width: 100%;
|
||
max-width: 340px;
|
||
border: 1px solid #c2c6d4;
|
||
border-radius: 8px;
|
||
background: #ffffff;
|
||
box-shadow: 0 18px 48px rgba(25, 28, 33, 0.2);
|
||
overflow: hidden;
|
||
animation: fade-in 0.2s ease-out forwards;
|
||
}
|
||
|
||
.modal-header {
|
||
box-sizing: border-box;
|
||
padding: 24px;
|
||
border-bottom: 1px solid #c2c6d4;
|
||
background: #ffffff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
}
|
||
|
||
.modal-doctor {
|
||
gap: 16px;
|
||
}
|
||
|
||
.modal-avatar {
|
||
width: 56px;
|
||
height: 56px;
|
||
border: 2px solid #00478d;
|
||
border-radius: 50%;
|
||
}
|
||
|
||
.modal-title-group {
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 2px;
|
||
}
|
||
|
||
.modal-title {
|
||
color: #191c21;
|
||
font-size: 20px;
|
||
line-height: 28px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.modal-subtitle {
|
||
color: #727783;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
}
|
||
|
||
.close-icon {
|
||
width: 22px;
|
||
height: 22px;
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M18.3%205.71L12%2012l6.3%206.29-1.41%201.41L10.59%2013.41%204.29%2019.7%202.88%2018.29%209.17%2012%202.88%205.71%204.29%204.3l6.3%206.29%206.3-6.29%201.41%201.41z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M18.3%205.71L12%2012l6.3%206.29-1.41%201.41L10.59%2013.41%204.29%2019.7%202.88%2018.29%209.17%2012%202.88%205.71%204.29%204.3l6.3%206.29%206.3-6.29%201.41%201.41z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.modal-body {
|
||
padding: 24px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 16px;
|
||
}
|
||
|
||
.quote-card {
|
||
padding: 16px;
|
||
border: 1px solid rgba(0, 71, 141, 0.1);
|
||
border-radius: 8px;
|
||
background: rgba(0, 94, 184, 0.06);
|
||
text-align: center;
|
||
color: #191c21;
|
||
font-size: 16px;
|
||
line-height: 24px;
|
||
font-style: italic;
|
||
}
|
||
|
||
.mentor-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||
gap: 12px;
|
||
}
|
||
|
||
.mentor-card {
|
||
box-sizing: border-box;
|
||
min-height: 96px;
|
||
padding: 16px;
|
||
border: 1px solid rgba(194, 198, 212, 0.3);
|
||
border-radius: 8px;
|
||
background: #f2f3fb;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 8px;
|
||
color: #191c21;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.school-small-icon,
|
||
.notes-small-icon {
|
||
width: 24px;
|
||
height: 24px;
|
||
background: #00478d;
|
||
}
|
||
|
||
.school-small-icon {
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%203L1%209l11%206%209-4.91V17h2V9L12%203zm0%2014L5%2013.18V17l7%204%207-4v-3.82L12%2017z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M12%203L1%209l11%206%209-4.91V17h2V9L12%203zm0%2014L5%2013.18V17l7%204%207-4v-3.82L12%2017z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.notes-small-icon {
|
||
-webkit-mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M6%202h9l5%205v15H6a2%202%200%200%201-2-2V4a2%202%200%200%201%202-2zm8%201.5V8h4.5L14%203.5zM8%2011v2h8v-2H8zm0%204v2h8v-2H8zm0%204h5v-2H8v2z'/%3E%3C/svg%3E");
|
||
mask-image: url("data:image/svg+xml,%3Csvg%20viewBox='0%200%2024%2024'%20xmlns='http://www.w3.org/2000/svg'%3E%3Cpath%20d='M6%202h9l5%205v15H6a2%202%200%200%201-2-2V4a2%202%200%200%201%202-2zm8%201.5V8h4.5L14%203.5zM8%2011v2h8v-2H8zm0%204v2h8v-2H8zm0%204h5v-2H8v2z'/%3E%3C/svg%3E");
|
||
}
|
||
|
||
.guidance-button {
|
||
width: 100%;
|
||
min-height: 44px;
|
||
border-radius: 8px;
|
||
background: #00478d;
|
||
color: #ffffff;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.guidance-button:active {
|
||
transform: scale(0.98);
|
||
}
|
||
|
||
.toast {
|
||
position: absolute;
|
||
left: 50%;
|
||
bottom: 96px;
|
||
z-index: 100;
|
||
max-width: 300px;
|
||
padding: 10px 18px;
|
||
border-radius: 12px;
|
||
background: #2e3037;
|
||
color: #eff0f8;
|
||
font-size: 14px;
|
||
line-height: 20px;
|
||
font-weight: 600;
|
||
text-align: center;
|
||
pointer-events: none;
|
||
opacity: 0;
|
||
transform: translate(-50%, 16px);
|
||
transition: opacity 0.3s ease, transform 0.3s ease;
|
||
}
|
||
|
||
.toast.visible {
|
||
opacity: 1;
|
||
transform: translate(-50%, 0);
|
||
}
|
||
|
||
@keyframes typing-bounce {
|
||
0%,
|
||
100% {
|
||
transform: translateY(0);
|
||
}
|
||
50% {
|
||
transform: translateY(-4px);
|
||
}
|
||
}
|
||
|
||
@keyframes fade-in {
|
||
from {
|
||
opacity: 0;
|
||
transform: scale(0.95);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: scale(1);
|
||
}
|
||
}
|
||
|
||
@media (min-width: 768px) {
|
||
.learning-page {
|
||
display: flex;
|
||
justify-content: center;
|
||
background: #d8dae2;
|
||
}
|
||
|
||
.learning-shell {
|
||
width: 390px;
|
||
min-height: 100vh;
|
||
box-shadow: 0 24px 64px rgba(25, 28, 33, 0.18);
|
||
}
|
||
}
|
||
|
||
@media (max-height: 760px) {
|
||
.chat-canvas {
|
||
padding: 12px 16px;
|
||
}
|
||
|
||
.time-row {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.input-panel {
|
||
padding-bottom: 12px;
|
||
}
|
||
}
|
||
</style>
|