feat: medication reminders, follow-up/visit separation, health record page

Backend:
- MedicationService: today-summary with missed detection (local time)
- FollowUpService: doctor-initiated follow-ups filter, AddAsync supports Notes
- FollowUpController: type query param (followup/recheck)
- MedicationController: today-summary endpoint
- Auth: UpdateProfileRequest→class, StentDate/StentType, soft-delete fix

Patient frontend:
- HomePage: date display, medication reminder cards with missed status
- MedicationListPage: beautified with delete button, slot preview
- MedicationDetailPage: redesigned with progress bars, new CSS
- ProfilePage: beautified menu icons, health record link
- HealthRecordPage: new page with indicators, history, meds, reports
- ServicesHub: added doctor-visit card
- VisitListPage: doctor-initiated follow-ups view
- EditProfilePage: removed height/weight, added stent fields
- Fixed getProfile field mappings (nickname, height, weight, stent)

Doctor frontend:
- Layout: added 随访管理 sidebar item with SVG icon
- FollowUpListPage: recheck-only filter, complete/delete buttons, collapsed completed
- VisitListPage/EditPage: doctor follow-up management
- PatientListPage: added stentType column
- Dashboard: fixed pending reports endpoint
- ReportListPage/DetailPage: fixed uploadedAt field
- ChatPage: SignalR real-time, dynamic hostname
This commit is contained in:
MingNian
2026-05-25 14:48:05 +08:00
parent db443b258e
commit 39ab6062b5
33 changed files with 1657 additions and 238 deletions

View File

@@ -0,0 +1,191 @@
.profileCard {
margin-bottom: 14px;
padding: 18px;
display: flex;
align-items: center;
gap: 14px;
}
.avatar {
width: 52px;
height: 52px;
border-radius: 16px;
background: var(--color-primary-gradient);
color: #fff;
font-size: 22px;
font-weight: 700;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.profileInfo {
flex: 1;
}
.name {
font-size: 17px;
font-weight: 700;
color: var(--color-text-primary);
}
.phone {
font-size: 13px;
color: var(--color-text-tertiary);
margin-top: 2px;
}
.arrow {
font-size: 24px;
color: var(--color-text-tertiary);
}
.detailCard {
margin-bottom: 14px;
padding: 20px;
}
.cardTitle {
font-size: 16px;
font-weight: 700;
color: var(--color-text-primary);
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.cardTitle::before {
content: '';
width: 4px;
height: 16px;
border-radius: 2px;
background: var(--color-primary);
}
.cardCount {
margin-left: auto;
font-size: 12px;
font-weight: 500;
color: var(--color-text-tertiary);
background: var(--color-bg);
padding: 2px 10px;
border-radius: 12px;
}
.historyTags {
display: flex;
flex-wrap: wrap;
gap: 8px;
}
.historyTag {
padding: 5px 12px;
border-radius: 20px;
font-size: 12px;
font-weight: 500;
color: var(--color-primary);
background: var(--color-primary-bg);
}
.stentInfo {
margin-top: 12px;
font-size: 13px;
color: var(--color-text-secondary);
}
.indicatorsGrid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 12px;
}
.indicatorItem {
text-align: center;
padding: 12px 8px;
background: var(--color-bg);
border-radius: 12px;
}
.indicatorValue {
font-size: 20px;
font-weight: 800;
}
.indicatorLabel {
font-size: 12px;
color: var(--color-text-secondary);
margin-top: 4px;
}
.indicatorUnit {
font-size: 10px;
color: var(--color-text-tertiary);
margin-left: 2px;
}
.medItem {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid var(--color-divider);
cursor: pointer;
}
.medItem:last-child {
border-bottom: none;
}
.medName {
font-size: 14px;
font-weight: 500;
color: var(--color-text-primary);
}
.medMeta {
font-size: 12px;
color: var(--color-text-tertiary);
}
.reportItem {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid var(--color-divider);
cursor: pointer;
}
.reportItem:last-child {
border-bottom: none;
}
.reportName {
font-size: 14px;
font-weight: 500;
color: var(--color-text-primary);
}
.reportStatus {
font-size: 11px;
font-weight: 600;
padding: 3px 10px;
border-radius: 12px;
}
.reportDone {
background: var(--color-success-bg);
color: #0D8A5E;
}
.reportPending {
background: var(--color-warning-bg);
color: #D67E0B;
}
.emptyText {
text-align: center;
padding: 16px;
color: var(--color-text-tertiary);
font-size: 13px;
}