feat(web): 家庭健康代理 + 知情同意 Web UI — Phase 2c
Some checks failed
CI / rust-check (push) Has been cancelled
CI / rust-test (push) Has been cancelled
CI / frontend-build (push) Has been cancelled
CI / security-audit (push) Has been cancelled

家庭代理:关联患者列表 + 健康摘要查看 + 授权/撤销访问
知情同意:患者范围 CRUD 列表页(类型/范围/签署/撤销)
This commit is contained in:
iven
2026-05-05 00:02:39 +08:00
parent 0774dd75ad
commit 888fa108ef
6 changed files with 667 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
import client from '../client';
import type { PaginatedResponse } from '../types';
// --- Types ---
export interface Consent {
id: string;
patient_id: string;
consent_type: string;
consent_scope: string;
status: string;
granted_at?: string;
revoked_at?: string;
expiry_date?: string;
consent_method?: string;
witness_name?: string;
notes?: string;
created_at: string;
updated_at: string;
version: number;
}
export interface CreateConsentReq {
patient_id: string;
consent_type: string;
consent_scope: string;
expiry_date?: string;
consent_method?: string;
witness_name?: string;
notes?: string;
}
export interface RevokeConsentReq {
notes?: string;
version: number;
}
// --- Constants ---
export const CONSENT_TYPE_OPTIONS = [
{ label: '治疗同意', value: 'treatment' },
{ label: '数据共享', value: 'data_sharing' },
{ label: '隐私政策', value: 'privacy' },
{ label: '研究参与', value: 'research' },
];
export const CONSENT_SCOPE_OPTIONS = [
{ label: '全部', value: 'all' },
{ label: '健康数据', value: 'health_data' },
{ label: '基本信息', value: 'basic_info' },
{ label: '体检报告', value: 'examination' },
];
export const CONSENT_STATUS_COLOR: Record<string, string> = {
active: 'green',
revoked: 'red',
expired: 'default',
};
export const CONSENT_STATUS_LABEL: Record<string, string> = {
active: '生效中',
revoked: '已撤销',
expired: '已过期',
};
// --- API ---
export const consentApi = {
list: async (patientId: string, params?: { page?: number; page_size?: number }) => {
const { data } = await client.get<{
success: boolean;
data: PaginatedResponse<Consent>;
}>(`/health/patients/${patientId}/consents`, { params });
return data.data;
},
grant: async (req: CreateConsentReq) => {
const { data } = await client.post<{
success: boolean;
data: Consent;
}>('/health/consents', req);
return data.data;
},
revoke: async (consentId: string, req: RevokeConsentReq) => {
const { data } = await client.put<{
success: boolean;
data: Consent;
}>(`/health/consents/${consentId}/revoke`, req);
return data.data;
},
};

View File

@@ -0,0 +1,109 @@
import client from '../client';
// --- Types ---
export interface FamilyMember {
id: string;
patient_id: string;
name: string;
relationship: string;
phone?: string;
birth_date?: string;
notes?: string;
user_id?: string;
consent_status: string;
access_level: string;
consented_at?: string;
created_at: string;
updated_at: string;
version: number;
}
export interface FamilyPatientSummary {
family_member_id: string;
patient_id: string;
patient_name: string;
relationship: string;
consent_status: string;
access_level: string;
consented_at?: string;
}
export interface FamilyHealthSummary {
patient_id: string;
patient_name: string;
latest_vital_signs?: Record<string, unknown>;
active_care_plan?: Record<string, unknown>;
recent_alerts_count: number;
next_appointment?: Record<string, unknown>;
}
export interface GrantAccessReq {
access_level: string;
}
// --- Constants ---
export const CONSENT_STATUS_OPTIONS = [
{ label: '已同意', value: 'granted' },
{ label: '待确认', value: 'pending' },
{ label: '已撤销', value: 'revoked' },
{ label: '已过期', value: 'expired' },
];
export const ACCESS_LEVEL_OPTIONS = [
{ label: '完全访问', value: 'full' },
{ label: '只读', value: 'read_only' },
{ label: '摘要', value: 'summary' },
];
export const CONSENT_STATUS_COLOR: Record<string, string> = {
granted: 'green',
pending: 'orange',
revoked: 'red',
expired: 'default',
};
export const ACCESS_LEVEL_LABEL: Record<string, string> = Object.fromEntries(
ACCESS_LEVEL_OPTIONS.map((o) => [o.value, o.label]),
);
export const CONSENT_STATUS_LABEL: Record<string, string> = Object.fromEntries(
CONSENT_STATUS_OPTIONS.map((o) => [o.value, o.label]),
);
// --- API ---
export const familyProxyApi = {
grantAccess: async (patientId: string, familyMemberId: string, req: GrantAccessReq, version: number) => {
const { data } = await client.post<{
success: boolean;
data: FamilyMember;
}>(`/health/patients/${patientId}/family-members/${familyMemberId}/grant-access?version=${version}`, req);
return data.data;
},
revokeAccess: async (patientId: string, familyMemberId: string, version: number) => {
const { data } = await client.put<{
success: boolean;
data: FamilyMember;
}>(`/health/patients/${patientId}/family-members/${familyMemberId}/revoke-access?version=${version}`);
return data.data;
},
listMyPatients: async () => {
const { data } = await client.get<{
success: boolean;
data: FamilyPatientSummary[];
}>('/health/family/my-patients');
return data.data;
},
getHealthSummary: async (patientId: string) => {
const { data } = await client.get<{
success: boolean;
data: FamilyHealthSummary;
}>(`/health/family/patients/${patientId}/health-summary`);
return data.data;
},
};