feat(file-manager): add aliyun oss storage

This commit is contained in:
chenos 2020-12-31 12:11:38 +08:00
parent 52a1ce012c
commit 4fc2843a05
9 changed files with 80 additions and 13 deletions

View File

@ -18,5 +18,11 @@ HTTP_PORT=23000
VERDACCIO_PORT=4873 VERDACCIO_PORT=4873
LOCAL_STORAGE_BASE_URL=http://localhost:23000/uploads
USE_STATIC_SERVER=true USE_STATIC_SERVER=true
LOCAL_STORAGE_BASE_URL=http://localhost:23000/uploads
STORAGE_BASE_URL=http://localhost:23000/uploads
ALIYUN_OSS_REGION=oss-cn-beijing
ALIYUN_OSS_ACCESS_KEY_ID=
ALIYUN_OSS_ACCESS_KEY_SECRET=
ALIYUN_OSS_BUCKET=

View File

@ -28,7 +28,7 @@ const api = Api.create({
charset: 'utf8mb4', charset: 'utf8mb4',
collate: 'utf8mb4_unicode_ci', collate: 'utf8mb4_unicode_ci',
}, },
// logging: false, logging: false,
define: {}, define: {},
sync, sync,
}, },

View File

@ -188,11 +188,23 @@ api.registerPlugin('plugin-file-manager', [path.resolve(__dirname, '../../../plu
}); });
} }
const Storage = database.getModel('storages'); const Storage = database.getModel('storages');
// await Storage.create({
// title: '本地存储',
// name: `local`,
// type: 'local',
// baseUrl: process.env.LOCAL_STORAGE_BASE_URL,
// default: true
// });
await Storage.create({ await Storage.create({
title: '本地存储', name: `ali-oss`,
name: `local`, type: 'ali-oss',
type: 'local', baseUrl: process.env.STORAGE_BASE_URL,
baseUrl: process.env.LOCAL_STORAGE_BASE_URL, options: {
region: process.env.ALIYUN_OSS_REGION,// 'oss-cn-beijing',
accessKeyId: process.env.ALIYUN_OSS_ACCESS_KEY_ID,// 'LTAI4GEGDJsdGantisvSaz47',
accessKeySecret: process.env.ALIYUN_OSS_ACCESS_KEY_SECRET,//'cDFaOUwigps7ohRmsfBFXGDxNm8uIq',
bucket: process.env.ALIYUN_OSS_BUCKET, //'nocobase'
},
default: true default: true
}); });
await database.getModel('collections').import(require('./collections/example').default); await database.getModel('collections').import(require('./collections/example').default);

View File

@ -258,7 +258,7 @@ export function AttachmentFieldItem(props: any) {
e.preventDefault(); e.preventDefault();
} }
}} className={'attachment-field-item'} target={'_blank'} href={url}> }} className={'attachment-field-item'} target={'_blank'} href={url}>
<img style={{marginRight: 5}} height={20} alt={title} title={title} src={img}/> <img style={{marginRight: 5}} height={20} alt={title} title={title} src={`${img}?x-oss-process=style/thumbnail`}/>
</a> </a>
<Modal <Modal
className={'attachment-modal'} className={'attachment-modal'}

View File

@ -8,6 +8,7 @@
"@nocobase/database": "^0.3.0-alpha.0", "@nocobase/database": "^0.3.0-alpha.0",
"@nocobase/resourcer": "^0.3.0-alpha.0", "@nocobase/resourcer": "^0.3.0-alpha.0",
"@types/multer": "^1.4.5", "@types/multer": "^1.4.5",
"ali-oss": "^6.12.0",
"koa-mount": "^4.0.0", "koa-mount": "^4.0.0",
"koa-static": "^5.0.0", "koa-static": "^5.0.0",
"mime-match": "^1.0.2", "mime-match": "^1.0.2",

View File

@ -0,0 +1,42 @@
import AliOss from 'ali-oss';
import { getFilename } from '../utils';
export class AliOssStorage {
private client: AliOss;
private getFilename: Function;
constructor(opts) {
this.client = new AliOss(opts.config);
this.getFilename = opts.filename || getFilename;
}
_handleFile(req, file, cb) {
if (!this.client) {
console.error('oss client undefined');
return cb({message: 'oss client undefined'});
}
this.getFilename(req, file, (err, filename) => {
if (err) return cb(err)
this.client.putStream(filename, file.stream).then(
result => cb(null, {
filename: result.name,
url : result.url
})
).catch(cb);
});
}
_removeFile(req, file, cb) {
if (!this.client) {
console.error('oss client undefined');
return cb({message: 'oss client undefined'});
}
this.client.delete(file.filename).then(
result => cb(null, result)
).catch(cb);
}
}
export default (storage) => new AliOssStorage({config: storage.options});

View File

@ -1,9 +1,11 @@
import local from './local'; import local from './local';
import oss from './ali-oss';
import { STORAGE_TYPE_LOCAL, STORAGE_TYPE_ALI_OSS } from '../constants'; import { STORAGE_TYPE_LOCAL, STORAGE_TYPE_ALI_OSS } from '../constants';
const map = new Map<string, Function>(); const map = new Map<string, Function>();
map.set(STORAGE_TYPE_LOCAL, local); map.set(STORAGE_TYPE_LOCAL, local);
map.set(STORAGE_TYPE_ALI_OSS, oss);
export default map; export default map;

View File

@ -1,4 +1,3 @@
import crypto from 'crypto';
import path from 'path'; import path from 'path';
import { URL } from 'url'; import { URL } from 'url';
import mkdirp from 'mkdirp'; import mkdirp from 'mkdirp';
@ -6,6 +5,7 @@ import multer from 'multer';
import serve from 'koa-static'; import serve from 'koa-static';
import mount from 'koa-mount'; import mount from 'koa-mount';
import { STORAGE_TYPE_LOCAL } from '../constants'; import { STORAGE_TYPE_LOCAL } from '../constants';
import { getFilename } from '../utils';
export function getDocumentRoot(storage): string { export function getDocumentRoot(storage): string {
const { documentRoot = 'uploads' } = storage.options || {}; const { documentRoot = 'uploads' } = storage.options || {};
@ -71,9 +71,5 @@ export default (storage) => multer.diskStorage({
cb(null, destPath); cb(null, destPath);
}).catch(cb); }).catch(cb);
}, },
filename: function (req, file, cb) { filename: getFilename
crypto.randomBytes(16, (err, raw) => {
cb(err, err ? undefined : `${raw.toString('hex')}${path.extname(file.originalname)}`)
});
}
}); });

View File

@ -0,0 +1,8 @@
import crypto from 'crypto';
import path from 'path';
export function getFilename (req, file, cb) {
crypto.pseudoRandomBytes(16, function (err, raw) {
cb(err, err ? undefined : `${raw.toString('hex')}${path.extname(file.originalname)}`)
})
}