Files
platforms/frontend/gas_admin/src/api/contract-attachment.ts
2026-08-18 21:52:00 +08:00

75 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 功能:配送合同 PDF 附件的上传、失败清理与鉴权预览客户端。
* 版本v1.0.0
*/
import { getToken } from '@/utils/auth';
const gasApiBaseURL =
import.meta.env.VITE_API_BASE_URL ||
'http://localhost:12426/heqi/gas/v1';
export type ContractAttachmentMetadata = {
has_file: boolean;
available: boolean;
requires_reupload: boolean;
display_name: string;
version: string;
};
export type ContractAttachmentUploadReply = {
receipt: string;
cleanup_token: string;
display_name: string;
size: number;
};
type ApiEnvelope<T> = { code?: number; message?: string; details?: T };
/** 返回当前登录凭证请求头。 */
function authorizationHeaders(): Record<string, string> {
const token = getToken();
return token ? { Authorization: token } : {};
}
/** 上传经过前端预检的单个 PDF服务端仍会验证真实内容。 */
async function upload(file: File): Promise<ContractAttachmentUploadReply> {
const form = new FormData();
form.append('file', file);
const response = await fetch(
`${gasApiBaseURL}/gasorder_contract/attachment/upload`,
{ method: 'POST', headers: authorizationHeaders(), body: form },
);
const payload = (await response.json()) as ApiEnvelope<ContractAttachmentUploadReply>;
if (!response.ok || payload.code !== 0 || !payload.details) {
throw new Error(payload.message || '合同附件上传失败');
}
return payload.details;
}
/** 使用受签名保护的清理凭证删除尚未绑定的临时文件。 */
async function cleanup(cleanupToken: string): Promise<void> {
const response = await fetch(
`${gasApiBaseURL}/gasorder_contract/attachment/cleanup`,
{
method: 'POST',
headers: { 'Content-Type': 'application/json', ...authorizationHeaders() },
body: JSON.stringify({ cleanup_token: cleanupToken }),
},
);
if (!response.ok) throw new Error('临时合同附件清理失败');
const payload = (await response.json()) as ApiEnvelope<{ deleted: boolean }>;
if (payload.code !== 0) throw new Error(payload.message || '临时合同附件清理失败');
}
/** 获取鉴权 PDF Blob内部存储 URI 始终不会暴露给浏览器。 */
async function load(identity: string): Promise<Blob> {
const response = await fetch(
`${gasApiBaseURL}/gasorder_contract/${encodeURIComponent(identity)}/attachment`,
{ headers: authorizationHeaders() },
);
if (!response.ok) throw new Error('合同附件不可用,请重新上传');
return response.blob();
}
export const contractAttachmentApi = { upload, cleanup, load };