fix(archive): serve student attachments securely

Download attachments through authenticated API requests, support configurable upload paths, validate resolved file locations, and retain compatibility with legacy stored paths.
This commit is contained in:
2026-07-10 14:11:47 +08:00
parent 55881863c1
commit 1ca4a4d185
3 changed files with 68 additions and 9 deletions

View File

@@ -630,7 +630,7 @@ const AttachmentsTab: React.FC<TabProps & { data: AttachmentRecord[] }> = ({ dat
const handleDelete = async (attachmentId: number) => {
try {
await api.delete(`/archive/${studentId}/attachments/${attachmentId}`);
await api.delete(`/archive/attachments/${attachmentId}`);
message.success('已删除');
onRefresh();
} catch (e: unknown) {
@@ -654,9 +654,18 @@ const AttachmentsTab: React.FC<TabProps & { data: AttachmentRecord[] }> = ({ dat
<Button
size="small"
icon={<EyeOutlined />}
onClick={() => {
const token = localStorage.getItem('token');
window.open(`/api/archive/${studentId}/attachments/${record.id}?token=${token}`, '_blank');
onClick={async () => {
try {
const blob = await api.get<Blob>(`/archive/${studentId}/attachments/${record.id}`, {
responseType: 'blob',
});
const url = URL.createObjectURL(blob);
window.open(url, '_blank');
setTimeout(() => URL.revokeObjectURL(url), 60_000);
} catch (e: unknown) {
const err = e as { message?: string };
message.error(err?.message || '查看失败');
}
}}
>