如何在admin bro中配置bucket,用于上传文件的本地存储



我使用expressadmin-bro及其插件@admin-bro/upload将上传的图像文件存储在服务器中。

AdminBro对象使用以下AdminBroOptions 进行初始化

const adminBro = new AdminBro({
        resources: [
            {
                resource: Furniture,
                options: {
                    properties: {
                        '_id': {
                            isVisible: { list: false, filter: true, show: true, edit: false }
                        },
                        image: {
                            isVisible: false
                        }
                    }
                },
                features: [uploadFeature({
                    provider: { local: { bucket: path.join(__dirname, 'public', 'images', 'furniture') } },
                    properties: {
                        key: 'image.path',
                        bucket: 'image.folder',
                        mimeType: 'image.type',
                        size: 'image.size',
                        filename: 'image.filename',
                        file: 'uploadFile'
                    }
                })]
            }
        ],
        branding: {
            companyName: "Fran's Furniture"
        }
    })

文件夹结构:

文件夹结构

我遵循本教程主要针对admin-bro配置:https://itnext.io/the-easiest-and-fastest-way-to-upload-files-in-node-js-4b49e0123190

我还在server.js文件中添加了app.use('/public', express.static('public'))

但我在上传图像文件时遇到了这个错误:

(node:153012) ExperimentalWarning: The fs.promises API is experimental
Error: EPERM: operation not permitted, mkdir 'F:'

如果我将bucket属性更改为"public":

provider: { local: { bucket: 'public' } }

弹出以下错误(注意"public"文件夹位于F:/而非F:/项目文件夹的路径:

(node:163580) ExperimentalWarning: The fs.promises API is experimental
Error: EXDEV: cross-device link not permitted, rename 'C:UsersLenovoAppDataLocalTempupload_4ca3c78a0517022a555815196102aee6' -> 'F:public5f98496b31e9d37efe9a25841.jpg'

家具模型(如果需要(:

const Image  = new mongoose.Schema({
    path: String,
    type: String,
    size: Number,
    folder: String,
    filename: String
})

const FurnitureSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    },
    description: {
        type: String,
        required: true
    },
    price: {
        type: Number,
        required: true
    },
    status: {
        type: String,
        enum: ['show', 'hide'],
        default: 'show',
        required: true
    },
    condition: {
        type: String,
        enum: ['new', 'used'],
        required: true
    },
    image: Image,
    category: {
        type: mongoose.Schema.Types.ObjectId,
        required: true,
        ref: 'Category'
    }
})

所以在我看来,这个问题主要是因为bucket选项的配置不正确。如有任何帮助,我们将不胜感激。

项目路径(如果需要(:F:\Tutorials\Self Projects\frans node

我通过自己编写一个自定义的基本提供程序并手动复制+删除文件来解决这个问题:

import { BaseProvider } from '@admin-bro/upload'
import { ActionContext, UploadedFile } from 'admin-bro'
import { promises, existsSync } from "fs"
import { resolve, dirname } from "path"
export class UploadProvider extends BaseProvider {
    assetPath: string
    constructor(bucket: string, assetPath: string) {
        // it requires bucket as a parameter to properly pass it to other methods
        super(bucket)
        this.assetPath = assetPath
    }
    async upload(file: UploadedFile, key: string, context: ActionContext): Promise<any> {
        const fullPath = resolve(this.assetPath, key)
        const dirPath = dirname(fullPath)
        if (!existsSync(dirPath)) {
            await promises.mkdir(dirPath, { recursive: true })
        }
        await promises.copyFile(file.path, fullPath)
        await promises.unlink(file.path)
        return key
    }
    async delete(key: string, bucket: string, context: ActionContext): Promise<any> {
        const filePath = resolve(this.assetPath, key)
        if (existsSync(filePath)) {
            await promises.unlink(filePath)
            const dirPath = dirname(filePath)
            const otherFiles = await promises.readdir(dirPath)
            if (otherFiles && otherFiles.length == 0) {
                await promises.rmdir(dirPath)
            }
        }
    }
    path(key: string, bucket: string, context: ActionContext): Promise<string> | string {
        return "/" + bucket
    }
}

然后,像这样使用:

// ...
const provider = new UploadProvider("assets", ASSET_PATH)
// ...
features: [
    uploadFileFeature({ provider, ... })
]

相关内容

最新更新