fix(web,miniprogram): 端到端测试修复 + 小程序接口字段对齐
## 前端修复 - 修复 9 个 TypeScript 编译错误(未使用变量/undefined 守卫/vitest 类型) - 重写 E2E auth fixture 使用真实 API 登录替代 mock token - 更新 E2E 测试选择器适配当前 UI 布局 - Playwright 改为串行执行避免 token 唯一约束冲突 - E2E 测试从 0/10 通过提升到 10/10 通过 ## 小程序接口一致性修复(P0-P3) - P0: consultation.ts type→consultation_type, unread_count→unread_count_patient - P0: followup.ts task_type→follow_up_type, due_date→planned_date, description→content_template - P1: appointment.ts calendarView 展平嵌套结构, available_count 计算 max-current - P1: doctor.ts HealthSummary 适配后台实际返回结构 - P2: doctor.ts PatientStats/ConsultationStats/FollowUpStats 字段名对齐 - P3: article.ts 新增 buildCategoryTree 工具函数
This commit is contained in:
@@ -5,28 +5,17 @@ import { listConsultations, ConsultationSession } from '@/services/consultation'
|
||||
import Loading from '../../components/Loading';
|
||||
import './index.scss';
|
||||
|
||||
function getStatusLabel(status: string): string {
|
||||
const map: Record<string, string> = {
|
||||
pending: '等待接诊',
|
||||
active: '进行中',
|
||||
closed: '已结束',
|
||||
cancelled: '已取消',
|
||||
};
|
||||
return map[status] || status;
|
||||
}
|
||||
|
||||
function getStatusClass(status: string): string {
|
||||
if (status === 'active') return 'session-status-active';
|
||||
if (status === 'pending') return 'session-status-pending';
|
||||
return 'session-status-closed';
|
||||
function getStatusTag(status: string) {
|
||||
if (status === 'active') return { label: '进行中', cls: 'tag-ok' };
|
||||
if (status === 'pending') return { label: '等待接诊', cls: 'tag-warn' };
|
||||
return { label: { closed: '已结束', cancelled: '已取消' }[status] || status, cls: 'tag-default' };
|
||||
}
|
||||
|
||||
function formatTime(iso: string): string {
|
||||
if (!iso) return '';
|
||||
const d = new Date(iso);
|
||||
const now = new Date();
|
||||
const diffMs = now.getTime() - d.getTime();
|
||||
const diffMin = Math.floor(diffMs / 60000);
|
||||
const diffMin = Math.floor((now.getTime() - d.getTime()) / 60000);
|
||||
|
||||
if (diffMin < 1) return '刚刚';
|
||||
if (diffMin < 60) return `${diffMin}分钟前`;
|
||||
@@ -76,60 +65,65 @@ export default function Consultation() {
|
||||
|
||||
return (
|
||||
<View className='consultation-page'>
|
||||
{/* 页头 */}
|
||||
<View className='consultation-header'>
|
||||
<Text className='consultation-header-title'>在线咨询</Text>
|
||||
<Text className='consultation-header-desc'>随时随地,连接专业医生</Text>
|
||||
<Text className='consultation-title'>在线咨询</Text>
|
||||
<Text className='consultation-subtitle'>随时随地,连接专业医生</Text>
|
||||
</View>
|
||||
|
||||
{/* 内容区 */}
|
||||
{loading ? (
|
||||
<View className='consultation-loading'>
|
||||
<View className='consultation-center'>
|
||||
<Loading text='加载中...' />
|
||||
</View>
|
||||
) : error ? (
|
||||
<View className='consultation-error'>
|
||||
<Text className='consultation-error-text'>{error}</Text>
|
||||
<View className='consultation-center'>
|
||||
<Text className='consultation-error'>{error}</Text>
|
||||
</View>
|
||||
) : sessions.length === 0 ? (
|
||||
<View className='consultation-empty'>
|
||||
<Text className='consultation-empty-icon'>💬</Text>
|
||||
<Text className='consultation-empty-text'>暂无咨询记录</Text>
|
||||
<Text className='consultation-empty-hint'>发起咨询后即可在这里与医生交流</Text>
|
||||
<View className='empty-icon'>
|
||||
<Text className='empty-char'>问</Text>
|
||||
</View>
|
||||
<Text className='empty-title'>暂无咨询记录</Text>
|
||||
<Text className='empty-hint'>发起咨询后即可在这里与医生交流</Text>
|
||||
</View>
|
||||
) : (
|
||||
<View className='consultation-list'>
|
||||
{sessions.map((session) => (
|
||||
<View
|
||||
key={session.id}
|
||||
className='consultation-session'
|
||||
onClick={() => handleTapSession(session)}
|
||||
>
|
||||
<View className='session-left'>
|
||||
<View className='session-top'>
|
||||
<Text className='session-subject'>
|
||||
{session.subject || '在线咨询'}
|
||||
<View className='session-list'>
|
||||
{sessions.map((session) => {
|
||||
const tag = getStatusTag(session.status);
|
||||
return (
|
||||
<View
|
||||
key={session.id}
|
||||
className='session-card'
|
||||
onClick={() => handleTapSession(session)}
|
||||
>
|
||||
<View className='session-main'>
|
||||
<View className='session-top'>
|
||||
<Text className='session-subject'>
|
||||
{session.subject || '在线咨询'}
|
||||
</Text>
|
||||
<Text className={`session-tag ${tag.cls}`}>{tag.label}</Text>
|
||||
</View>
|
||||
<Text className='session-message'>
|
||||
{session.last_message || '暂无消息'}
|
||||
</Text>
|
||||
<Text className={getStatusClass(session.status)}>
|
||||
{getStatusLabel(session.status)}
|
||||
<Text className='session-time'>
|
||||
{session.last_message_at
|
||||
? formatTime(session.last_message_at)
|
||||
: formatTime(session.created_at)}
|
||||
</Text>
|
||||
</View>
|
||||
<Text className='session-message'>
|
||||
{session.last_message || '暂无消息'}
|
||||
</Text>
|
||||
<Text className='session-time'>
|
||||
{session.last_message_at
|
||||
? formatTime(session.last_message_at)
|
||||
: formatTime(session.created_at)}
|
||||
</Text>
|
||||
{session.unread_count_patient > 0 && (
|
||||
<View className='session-badge'>
|
||||
<Text className='session-badge-text'>
|
||||
{session.unread_count_patient > 99 ? '99+' : session.unread_count_patient}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
{session.unread_count > 0 && (
|
||||
<View className='session-badge'>
|
||||
<Text className='session-badge-text'>
|
||||
{session.unread_count > 99 ? '99+' : session.unread_count}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user