From 483342a1d81f537a03a26525a4a13ed7b3899d1f Mon Sep 17 00:00:00 2001 From: iven Date: Sat, 16 May 2026 00:56:26 +0800 Subject: [PATCH] =?UTF-8?q?refactor(mp):=20=E8=BF=81=E7=A7=BB=E5=91=8A?= =?UTF-8?q?=E8=AD=A6=E5=88=97=E8=A1=A8=E9=A1=B5=20=E2=80=94=20=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E7=BB=9F=E4=B8=80=E7=BB=84=E4=BB=B6=E5=BA=93=20PageSh?= =?UTF-8?q?ell/ContentCard/StatusTag/LoadingCard/SearchSection/PaginationB?= =?UTF-8?q?ar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pkg-doctor-clinical/alerts/index.scss | 157 ++++----------- .../pkg-doctor-clinical/alerts/index.tsx | 183 +++++++++--------- 2 files changed, 132 insertions(+), 208 deletions(-) diff --git a/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.scss b/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.scss index a8fa070..c0b7939 100644 --- a/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.scss +++ b/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.scss @@ -1,18 +1,16 @@ @import '../../../styles/variables.scss'; -@import '../../../styles/mixins.scss'; -.alert-list-page { - min-height: 100vh; - background: $bg; - padding: 24px; - padding-bottom: 120px; -} +// PageShell 已接管:min-height, background, padding +// SearchSection 已接管:筛选标签栏 +// ContentCard 已接管:alert-card 背景/圆角/阴影/触摸反馈 +// StatusTag 已接管:告警严重度和状态标签样式 +// PaginationBar 已接管:分页控件 .alert-list-header { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 24px; + margin-bottom: 16px; } .alert-list-title { @@ -29,126 +27,47 @@ .alert-cards { display: flex; flex-direction: column; - gap: 16px; + gap: var(--tk-gap-md); } -.alert-card { - background: $card; - border-radius: $r-lg; - padding: 24px; - box-shadow: $shadow-sm; +// 告警卡片左侧彩色边框 — 业务特有,不归 ContentCard +.alert-card--critical { + border-left: 4px solid $dan; +} + +.alert-card--warning { border-left: 4px solid $wrn; - - &:active { - background: $bd-l; - } - - &--critical { - border-left-color: $dan; - } - - &--info { - border-left-color: $tx3; - } - - &__header { - display: flex; - justify-content: space-between; - align-items: center; - margin-bottom: 12px; - } - - &__title { - font-size: var(--tk-font-body-lg); - font-weight: 500; - color: $tx; - margin-bottom: 8px; - } - - &__footer { - display: flex; - justify-content: space-between; - align-items: center; - } - - &__time { - font-size: var(--tk-font-body); - color: $tx3; - } } -.alert-severity { - font-size: var(--tk-font-body); - font-weight: 600; - padding: 4px 12px; - border-radius: $r-sm; - - &--info { - background: $bd-l; - color: $tx2; - } - - &--warning { - background: $wrn-l; - color: $wrn; - } - - &--critical { - background: $dan-l; - color: $dan; - } - - &--urgent { - background: $dan-l; - color: $dan; - } +.alert-card--info { + border-left: 4px solid $tx3; } -.alert-status { - font-size: var(--tk-font-body); - padding: 4px 12px; - border-radius: $r-sm; - - &--pending { - background: $wrn-l; - color: $wrn; - } - - &--acknowledged { - background: $pri-l; - color: $pri; - } - - &--resolved { - background: $acc-l; - color: $acc; - } - - &--dismissed { - background: $bd-l; - color: $tx3; - } +.alert-card--urgent { + border-left: 4px solid $dan; } -.alert-pagination { +.alert-card__header { display: flex; - justify-content: center; + justify-content: space-between; align-items: center; - gap: 24px; - margin-top: 32px; - - &__btn { - font-size: var(--tk-font-h1); - color: $pri; - padding: 12px 24px; - - &.disabled { - color: $tx3; - } - } - - &__info { - font-size: var(--tk-font-h2); - color: $tx2; - } + margin-bottom: 12px; +} + +.alert-card__title { + font-size: var(--tk-font-body-lg); + font-weight: 500; + color: $tx; + margin-bottom: 8px; +} + +.alert-card__footer { + display: flex; + justify-content: space-between; + align-items: center; +} + +.alert-card__time { + font-size: var(--tk-font-body); + color: $tx3; } diff --git a/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.tsx b/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.tsx index 4e8bd2b..b3d0dfb 100644 --- a/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.tsx +++ b/apps/miniprogram/src/pages/pkg-doctor-clinical/alerts/index.tsx @@ -1,35 +1,53 @@ -import { useState, useEffect, useMemo, useCallback, useRef } from 'react'; -import { View, Text, ScrollView } from '@tarojs/components'; +import { useState, useEffect, useCallback, useRef } from 'react'; +import { View, Text } from '@tarojs/components'; import Taro from '@tarojs/taro'; import { usePageData } from '@/hooks/usePageData'; import { listAlerts, type Alert } from '@/services/doctor/alerts'; -import Loading from '@/components/Loading'; +import PageShell from '@/components/ui/PageShell'; +import ContentCard from '@/components/ui/ContentCard'; +import StatusTag from '@/components/ui/StatusTag'; +import LoadingCard from '@/components/ui/LoadingCard'; +import PaginationBar from '@/components/patterns/PaginationBar'; +import SearchSection from '@/components/patterns/SearchSection'; import ErrorState from '@/components/ErrorState'; import EmptyState from '@/components/EmptyState'; -import SegmentTabs from '@/components/SegmentTabs'; import { useElderClass } from '../../../hooks/useElderClass'; import { safeNavigateTo } from '@/utils/navigate'; import './index.scss'; -const SEVERITY_MAP: Record = { - info: { label: '提示', className: 'alert-severity--info' }, - warning: { label: '警告', className: 'alert-severity--warning' }, - critical: { label: '严重', className: 'alert-severity--critical' }, - urgent: { label: '紧急', className: 'alert-severity--urgent' }, +const SEVERITY_COLOR_MAP: Record = { + info: 'default', + warning: 'warning', + critical: 'error', + urgent: 'error', }; -const STATUS_MAP: Record = { - pending: { label: '待处理', className: 'alert-status--pending' }, - acknowledged: { label: '已确认', className: 'alert-status--acknowledged' }, - resolved: { label: '已恢复', className: 'alert-status--resolved' }, - dismissed: { label: '已忽略', className: 'alert-status--dismissed' }, +const SEVERITY_LABEL: Record = { + info: '提示', + warning: '警告', + critical: '严重', + urgent: '紧急', }; -const STATUS_TABS = [ - { value: '', label: '全部' }, - { value: 'pending', label: '待处理' }, - { value: 'acknowledged', label: '已确认' }, - { value: 'resolved', label: '已恢复' }, +const STATUS_COLOR_MAP: Record = { + pending: 'warning', + acknowledged: 'info', + resolved: 'success', + dismissed: 'default', +}; + +const STATUS_LABEL: Record = { + pending: '待处理', + acknowledged: '已确认', + resolved: '已恢复', + dismissed: '已忽略', +}; + +const STATUS_FILTERS = [ + { key: '', label: '全部' }, + { key: 'pending', label: '待处理' }, + { key: 'acknowledged', label: '已确认' }, + { key: 'resolved', label: '已恢复' }, ]; export default function AlertList() { @@ -42,8 +60,6 @@ export default function AlertList() { const [page, setPage] = useState(1); const mountedRef = useRef(false); - const totalPages = useMemo(() => Math.ceil(total / 20), [total]); - const loadAlerts = useCallback(async () => { setLoading(true); setError(false); @@ -65,7 +81,6 @@ export default function AlertList() { const { trigger } = usePageData(loadAlerts); - // tab/page 变化时重新加载(跳过首次 mount,由 usePageData 的 useDidShow 处理) useEffect(() => { if (mountedRef.current) { trigger(); @@ -94,89 +109,79 @@ export default function AlertList() { return d.toLocaleDateString('zh-CN', { month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' }); }; - if (loading && alerts.length === 0) return ; + if (loading && alerts.length === 0) return ; if (error) { return ( - - - 告警列表 - - - {STATUS_TABS.map((tab) => ( - handleTabChange(tab.value)} - > - {tab.label} - - ))} - + + {}} + filters={STATUS_FILTERS} + activeFilter={activeTab} + onFilterChange={handleTabChange} + /> - + ); } return ( - - - 告警列表 - 共 {total} 条 + + + 告警列表 + 共 {total} 条 - ({ key: t.value, label: t.label }))} activeKey={activeTab} onChange={handleTabChange} variant="pill" /> + {}} + filters={STATUS_FILTERS} + activeFilter={activeTab} + onFilterChange={handleTabChange} + /> {alerts.length === 0 ? ( - + ) : ( - - {alerts.map((alert) => { - const severity = SEVERITY_MAP[alert.severity] ?? SEVERITY_MAP.info; - const status = STATUS_MAP[alert.status] ?? STATUS_MAP.pending; - return ( - handleAlertClick(alert)} - > - - - {severity.label} - - - {status.label} - - - {alert.title} - - {formatTime(alert.created_at)} - + + {alerts.map((alert) => ( + handleAlertClick(alert)} + className={`alert-card--${alert.severity || 'info'}`} + > + + + {SEVERITY_LABEL[alert.severity] || '提示'} + + + {STATUS_LABEL[alert.status] || '未知'} + - ); - })} + {alert.title} + + {formatTime(alert.created_at)} + + + ))} )} - {total > 20 && ( - - page > 1 && setPage(page - 1)} - > - 上一页 - - - {page} / {totalPages} - - = totalPages ? 'disabled' : ''}`} - onClick={() => page < totalPages && setPage(page + 1)} - > - 下一页 - - - )} - + + ); }