首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在admin-bro中配置存储桶,用于上传文件的本地存储

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

Stack Overflow用户
提问于 2020-10-27 23:17:28
回答 1查看 817关注 0票数 0

我使用带有admin-broexpress和它的插件@admin-bro/upload在服务器上存储上传的图像文件。

使用以下AdminBroOptions初始化AdminBro对象

代码语言:javascript
复制
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"
        }
    })

文件夹结构:

folder structure

我遵循本教程主要是为了进行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'))

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

代码语言:javascript
复制
(node:153012) ExperimentalWarning: The fs.promises API is experimental
Error: EPERM: operation not permitted, mkdir 'F:'

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

代码语言:javascript
复制
provider: { local: { bucket: 'public' } }

弹出以下错误(请注意,'public‘文件夹位于F:/而不是F:/path-to-project- folder中:

代码语言:javascript
复制
(node:163580) ExperimentalWarning: The fs.promises API is experimental
Error: EXDEV: cross-device link not permitted, rename 'C:\Users\Lenovo\AppData\Local\Temp\upload_4ca3c78a0517022a555815196102aee6' -> 'F:\public\5f98496b31e9d37efe9a2584\1.jpg'

家具模型(如果需要):

代码语言:javascript
复制
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'
    }
})

所以在我看来,这个问题主要是由于存储桶选项的错误配置造成的。任何帮助都将不胜感激。

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

EN

回答 1

Stack Overflow用户

发布于 2021-01-09 06:13:51

我自己编写了一个自定义的基本提供程序,并手动对文件执行copying+removing操作,从而解决了这个问题:

代码语言:javascript
复制
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
    }
}

然后,像这样使用它:

代码语言:javascript
复制
// ...
const provider = new UploadProvider("assets", ASSET_PATH)

// ...
features: [
    uploadFileFeature({ provider, ... })
]
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64557467

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档