feat(web): 家庭健康代理 + 知情同意 Web UI — Phase 2c
家庭代理:关联患者列表 + 健康摘要查看 + 授权/撤销访问 知情同意:患者范围 CRUD 列表页(类型/范围/签署/撤销)
This commit is contained in:
92
apps/web/src/api/health/consents.ts
Normal file
92
apps/web/src/api/health/consents.ts
Normal 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;
|
||||
},
|
||||
};
|
||||
109
apps/web/src/api/health/familyProxy.ts
Normal file
109
apps/web/src/api/health/familyProxy.ts
Normal 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;
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user