fix(admin,server): 上传改用 file.buffer 并移除手写 multipart 头
This commit is contained in:
@@ -31,9 +31,7 @@ export async function createImportRun(
|
||||
if (options.mapping && Object.keys(options.mapping).length > 0) {
|
||||
form.append('mapping', JSON.stringify(options.mapping));
|
||||
}
|
||||
const res = await api.post<ApiEnvelope<ImportRunDetail>>('/imports/runs', form, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
});
|
||||
const res = await api.post<ApiEnvelope<ImportRunDetail>>('/imports/runs', form);
|
||||
return res.data;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ export const aiChatApi = {
|
||||
form.append('file', file);
|
||||
return (
|
||||
await api.post<AiApiResponse<AiAttachment>>('/ai/chat/attachments', form, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
timeout: 120_000,
|
||||
})
|
||||
).data;
|
||||
|
||||
@@ -29,9 +29,7 @@ export const AttachmentsTab: React.FC<TabProps & { data: AttachmentRecord[] }> =
|
||||
);
|
||||
const uploadAttachmentMutation = useApiMutation(
|
||||
async (formData: FormData) =>
|
||||
api.post(`/archive/${studentId}/attachments`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post(`/archive/${studentId}/attachments`, formData),
|
||||
{ invalidate: [['archive', studentId]] },
|
||||
);
|
||||
|
||||
|
||||
@@ -140,9 +140,7 @@ const ClassroomRentalsPage: React.FC = () => {
|
||||
);
|
||||
const uploadContractMutation = useApiMutation(
|
||||
async ({ id, formData }: { id: number; formData: FormData }) =>
|
||||
api.post(`/classroom-rentals/${id}/contract`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post(`/classroom-rentals/${id}/contract`, formData),
|
||||
{ invalidate: [['classroom-rentals']] },
|
||||
);
|
||||
|
||||
|
||||
@@ -110,9 +110,7 @@ const ClassroomsPage: React.FC = () => {
|
||||
);
|
||||
const importMutation = useApiMutation(
|
||||
async (formData: FormData) =>
|
||||
api.post('/classrooms/import', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post('/classrooms/import', formData),
|
||||
{ invalidate: [['classrooms']] },
|
||||
);
|
||||
|
||||
|
||||
@@ -137,16 +137,12 @@ const ExpensesPage: React.FC = () => {
|
||||
),
|
||||
importUtility: useApiMutation(
|
||||
async (formData: FormData) =>
|
||||
api.post('/expenses/utility/import', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post('/expenses/utility/import', formData),
|
||||
{ invalidate: [['expenses']] },
|
||||
),
|
||||
importPersonal: useApiMutation(
|
||||
async (formData: FormData) =>
|
||||
api.post('/expenses/personal/import', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post('/expenses/personal/import', formData),
|
||||
{ invalidate: [['expenses']] },
|
||||
),
|
||||
archiveRoom: useApiMutation(
|
||||
|
||||
@@ -44,9 +44,7 @@ export function useOccupancyMutations() {
|
||||
);
|
||||
const importMutation = useApiMutation(
|
||||
async ({ formData, params }: { formData: FormData; params: string }) =>
|
||||
api.post(`/occupancies/import?${params}`, formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post(`/occupancies/import?${params}`, formData),
|
||||
{ invalidate: invalidateOccupancies },
|
||||
);
|
||||
|
||||
|
||||
@@ -143,9 +143,7 @@ export function useRoomMutations(editing: any) {
|
||||
);
|
||||
const importMutation = useApiMutation(
|
||||
async (formData: FormData) =>
|
||||
api.post<{ message?: string }>('/rooms/import', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post<{ message?: string }>('/rooms/import', formData),
|
||||
{ invalidate: [['rooms']] },
|
||||
);
|
||||
|
||||
|
||||
@@ -228,16 +228,12 @@ const StudentsPage: React.FC = () => {
|
||||
);
|
||||
const importMutation = useApiMutation(
|
||||
async (formData: FormData) =>
|
||||
api.post('/students/import', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post('/students/import', formData),
|
||||
{ invalidate: invalidateStudents },
|
||||
);
|
||||
const importMatchMutation = useApiMutation(
|
||||
async (formData: FormData) =>
|
||||
api.post('/students/import-match', formData, {
|
||||
headers: { 'Content-Type': 'multipart/form-data' },
|
||||
}),
|
||||
api.post('/students/import-match', formData),
|
||||
{ invalidate: invalidateStudents },
|
||||
);
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ export class AiExcelReaderService {
|
||||
|
||||
private async loadWithExcelJs(buffer: Buffer): Promise<ExcelSheetRows[]> {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(buffer as unknown as ArrayBuffer);
|
||||
const sheets: ExcelSheetRows[] = [];
|
||||
workbook.eachSheet((sheet) => {
|
||||
const rows: string[][] = [];
|
||||
|
||||
@@ -158,7 +158,7 @@ export class ClassroomsController {
|
||||
async importExcel(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(file.buffer as unknown as ArrayBuffer);
|
||||
const ws = workbook.worksheets[0];
|
||||
const rows: any[] = [];
|
||||
ws.eachRow((row, idx) => {
|
||||
|
||||
@@ -316,7 +316,7 @@ export class ExpensesController {
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
async importUtilityExpenses(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(file.buffer as unknown as ArrayBuffer);
|
||||
const ws = workbook.worksheets[0];
|
||||
const rows: any[] = [];
|
||||
ws.eachRow((row, idx) => {
|
||||
@@ -381,7 +381,7 @@ export class ExpensesController {
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
async importPersonalExpenses(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(file.buffer as unknown as ArrayBuffer);
|
||||
const ws = workbook.worksheets[0];
|
||||
const rows: any[] = [];
|
||||
ws.eachRow((row, idx) => {
|
||||
|
||||
@@ -84,7 +84,7 @@ export async function parseSheets(
|
||||
if (kind === 'csv') {
|
||||
await workbook.csv.read(Readable.from(Buffer.from(buffer)));
|
||||
} else {
|
||||
await workbook.xlsx.load(buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(buffer as unknown as ArrayBuffer);
|
||||
}
|
||||
const sheets = extractSheets(workbook, headerRow);
|
||||
if (sheets.length === 0) {
|
||||
|
||||
@@ -264,7 +264,7 @@ export class OccupanciesController {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
if (!file?.buffer) throw new BadRequestException('请上传入住名单 Excel 文件');
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(file.buffer as unknown as ArrayBuffer);
|
||||
const ws = workbook.worksheets[0];
|
||||
const rows = parseOccupancyImportWorksheet(ws);
|
||||
const result = await this.service.batchImportCheckIn(rows, {
|
||||
|
||||
@@ -343,7 +343,7 @@ export class RoomsController {
|
||||
async importExcel(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const { ipAddress, userAgent } = extractRequestInfo(req);
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(file.buffer as unknown as ArrayBuffer);
|
||||
const ws = workbook.worksheets[0];
|
||||
const rows: {
|
||||
roomNumber: string;
|
||||
|
||||
@@ -255,7 +255,7 @@ export class StudentsController {
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
async importExcel(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(file.buffer as unknown as ArrayBuffer);
|
||||
const importData = parseStudentImportWorkbook(workbook);
|
||||
// Resolve organization names to IDs
|
||||
for (const row of importData.students) {
|
||||
@@ -280,7 +280,7 @@ export class StudentsController {
|
||||
@UseInterceptors(FileInterceptor('file'))
|
||||
async matchImport(@UploadedFile() file: Express.Multer.File, @Request() req: any) {
|
||||
const workbook = new ExcelJS.Workbook();
|
||||
await workbook.xlsx.load(file.buffer.buffer as ArrayBuffer);
|
||||
await workbook.xlsx.load(file.buffer as unknown as ArrayBuffer);
|
||||
const importData = parseStudentImportWorkbook(workbook);
|
||||
// Resolve organization names to IDs
|
||||
for (const row of importData.students) {
|
||||
|
||||
Reference in New Issue
Block a user