fix: getFileKey (#6523)

* fix: getFileKey

* fix: storage cannot be deleted
This commit is contained in:
chenos 2025-03-22 05:13:24 +08:00 committed by GitHub
parent 1470ed902a
commit 44ee058730
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 6 deletions

View File

@ -62,11 +62,21 @@ export class PluginFileManagerServer extends Plugin {
return;
}
if (!record.get('storageId')) {
return;
}
const storage = this.storagesCache.get(record.get('storageId'));
if (!storage) {
return;
}
if (storage?.paranoid) {
return;
}
const Type = this.storageTypes.get(storage.type);
if (!Type) {
return;
}
const storageConfig = new Type(storage);
const result = await storageConfig.delete([record as unknown as AttachmentModel]);
if (!result[0]) {
@ -245,6 +255,15 @@ export class PluginFileManagerServer extends Plugin {
);
});
Storage.afterDestroy((m, { transaction }) => {
for (const collection of this.db.collections.values()) {
if (collection?.options?.template === 'file' && collection?.options?.storage === m.name) {
throw new Error(
this.t(
`The storage "${m.name}" is in use in collection "${collection.name}" and cannot be deleted.`,
) as any,
);
}
}
this.storagesCache.delete(m.id);
this.sendSyncMessage(
{

View File

@ -10,7 +10,7 @@
import { isURL } from '@nocobase/utils';
import { StorageEngine } from 'multer';
import urlJoin from 'url-join';
import { encodeURL, ensureUrlEncoded } from '../utils';
import { encodeURL, ensureUrlEncoded, getFileKey } from '../utils';
export interface StorageModel {
id?: number;
@ -42,6 +42,10 @@ export abstract class StorageType {
abstract make(): StorageEngine;
abstract delete(records: AttachmentModel[]): [number, AttachmentModel[]] | Promise<[number, AttachmentModel[]]>;
getFileKey(record: AttachmentModel) {
return getFileKey(record);
}
getFileData?(file: { [key: string]: any }): { [key: string]: any };
getFileURL(file: AttachmentModel, preview?: boolean): string | Promise<string> {
// 兼容历史数据

View File

@ -7,11 +7,11 @@
* For more information, please refer to: https://www.nocobase.com/agreement.
*/
import { S3Client, DeleteObjectCommand } from '@aws-sdk/client-s3';
import { DeleteObjectCommand, S3Client } from '@aws-sdk/client-s3';
import crypto from 'crypto';
import { AttachmentModel, StorageType } from '.';
import { STORAGE_TYPE_S3 } from '../../constants';
import { cloudFilenameGetter, getFileKey } from '../utils';
import { cloudFilenameGetter } from '../utils';
export default class extends StorageType {
static defaults() {
@ -87,8 +87,8 @@ export default class extends StorageType {
async delete(records: AttachmentModel[]): Promise<[number, AttachmentModel[]]> {
const { Deleted } = await this.deleteS3Objects(
this.storage.options.bucket,
records.map((record) => getFileKey(record)),
records.map((record) => this.getFileKey(record)),
);
return [Deleted.length, records.filter((record) => !Deleted.find((item) => item.Key === getFileKey(record)))];
return [Deleted.length, records.filter((record) => !Deleted.find((item) => item.Key === this.getFileKey(record)))];
}
}

View File

@ -9,6 +9,7 @@
import { uid } from '@nocobase/utils';
import path from 'path';
import urlJoin from 'url-join';
export function getFilename(req, file, cb) {
const originalname = Buffer.from(file.originalname, 'binary').toString('utf8');
@ -27,7 +28,7 @@ export const cloudFilenameGetter = (storage) => (req, file, cb) => {
};
export function getFileKey(record) {
return [record.path.replace(/^\/|\/$/g, ''), record.filename].filter(Boolean).join('/');
return urlJoin(record.path, record.filename).replace(/^\//, '');
}
export function ensureUrlEncoded(value) {