You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
300 lines
7.0 KiB
300 lines
7.0 KiB
3 years ago
|
# @fs/attachment 文件中心服务
|
||
|
|
||
|
## 一、Synopsis
|
||
|
文件中心提供文件的 `上传/下载/删除` 服务,支持云存储和本地存储。
|
||
|
|
||
|
|
||
|
|
||
|
### 存储形式
|
||
|
|
||
|
- 云存储:基于七牛云服务实现的文件服务
|
||
|
- 本地存储:本地磁盘
|
||
|
|
||
|
|
||
|
|
||
|
### 服务形式
|
||
|
|
||
|
- 原生 API 服务:应用侧直接引用 npm 包,调用 API 编程接口
|
||
|
- REST API 服务:使用 `fs-web-server-scaffold` 脚手架,该服务以中间件形式提供
|
||
|
|
||
|
|
||
|
|
||
|
## 二、Installation
|
||
|
|
||
|
### Node.js
|
||
|
@fs/attachment is available on npm. To install it, type:
|
||
|
|
||
|
`npm install @fs/attachment`
|
||
|
|
||
|
|
||
|
|
||
|
## 三、Usage
|
||
|
|
||
|
### Native API 服务
|
||
|
|
||
|
```js
|
||
|
const Attachment = require('@fs/attachment');
|
||
|
const opts = {
|
||
|
qiniu: { // 可选
|
||
|
accessKey: 'your access key',
|
||
|
secretKey: 'your secret key',
|
||
|
bucket: 'bucket',
|
||
|
domain: 'bucket domain'
|
||
|
},
|
||
|
local: { // 不指定七牛云配置,默认使用本地存储服务
|
||
|
origin: 'your local storage server origin', // 必填
|
||
|
rootPath: 'static',
|
||
|
childPath: 'upload'
|
||
|
},
|
||
|
uploadPath: 'your path',
|
||
|
maxSize: 10485760 // 10M
|
||
|
};
|
||
|
const attachment = new Attachment(opts);
|
||
|
let rslt = attachment.upload(file);
|
||
|
// let rslt = attachment.upload(file, {uploadPath: 'report'}); // 文件上传路径自定义为“report”,这里的 uploadPath 优先级高于 opts.uploadPath
|
||
|
attachment.download(rslt.key);
|
||
|
attachment.remove(rslt.key);
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
### REST API 服务
|
||
|
|
||
|
#### 1. REST API
|
||
|
|
||
|
##### 接口定义
|
||
|
|
||
|
```js
|
||
|
let prefix = opts.routePrefix ? `/${opts.routePrefix}` : '';
|
||
|
|
||
|
/**
|
||
|
* @api {POST} /attachments/:p 上传文件.
|
||
|
* @apiVersion 1.0.0
|
||
|
* @apiGroup Attachment
|
||
|
*/
|
||
|
router.post(`${prefix}/attachments/:p`, attachment.upload(mw));
|
||
|
|
||
|
/**
|
||
|
* @api {GET} /attachments 下载文件.
|
||
|
* @apiVersion 1.0.0
|
||
|
* @apiGroup Attachment
|
||
|
*/
|
||
|
router.get(`${prefix}/attachments`, attachment.download(mw));
|
||
|
|
||
|
/**
|
||
|
* @api {DELETE} /attachments 删除文件.
|
||
|
* @apiVersion 1.0.0
|
||
|
* @apiGroup Attachment
|
||
|
*/
|
||
|
router.del(`${prefix}/attachments`, attachment.deletee(mw));
|
||
|
|
||
|
/**
|
||
|
* @api {POST} /attachments 批量删除文件.
|
||
|
* @apiVersion 1.0.0
|
||
|
* @apiGroup Attachment
|
||
|
*/
|
||
|
router.post(`${prefix}/attachments`, attachment.bulkDelete(mw));
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
##### 接口说明
|
||
|
|
||
|
###### 上传指定文件
|
||
|
|
||
|
**HTTP Request**
|
||
|
|
||
|
```
|
||
|
POST /attachments/:p
|
||
|
```
|
||
|
|
||
|
**URL Parameters**
|
||
|
|
||
|
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|
||
|
| ---- | ------ | ------ | ---- | ---------------- |
|
||
|
| p | string | other | 是 | 文件存放的文件夹 |
|
||
|
|
||
|
**Body Parameters**
|
||
|
|
||
|
```
|
||
|
form-data
|
||
|
```
|
||
|
|
||
|
**Response 200**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"uploaded": "upload/report/WuSongQiao_daily_20181112_b46278f0-58cc-4dd7-9295-8021a57c86da.xls",
|
||
|
"key": "upload/report/WuSongQiao_daily_20181112_b46278f0-58cc-4dd7-9295-8021a57c86da.xls",
|
||
|
"url": "http://localhost:8081/upload/report/WuSongQiao_daily_20181112_b46278f0-58cc-4dd7-9295-8021a57c86da.xls"
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
###### 下载指定文件
|
||
|
|
||
|
**HTTP Request**
|
||
|
|
||
|
```
|
||
|
GET /attachments
|
||
|
```
|
||
|
|
||
|
**Query Parameters**
|
||
|
|
||
|
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|
||
|
| -------- | ------ | ------ | ---- | --------------------------------------- |
|
||
|
| src | string | -- | 是 | 文件 key 值,如:upload/data/report.xls |
|
||
|
| filename | string | -- | 是 | 保存的文件名,如:myreport.xls |
|
||
|
|
||
|
**Response 200**
|
||
|
|
||
|
```json
|
||
|
文件数据
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
###### 删除指定文件
|
||
|
|
||
|
**HTTP Request**
|
||
|
|
||
|
```
|
||
|
DELETE /attachments
|
||
|
```
|
||
|
|
||
|
**Query Parameters**
|
||
|
|
||
|
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|
||
|
| ---- | ------ | ------ | ---- | --------------------------------------- |
|
||
|
| src | string | -- | 是 | 文件 key 值,如:upload/data/report.xls |
|
||
|
|
||
|
**Response 204**
|
||
|
|
||
|
|
||
|
|
||
|
###### 批量删除文件
|
||
|
|
||
|
**HTTP Request**
|
||
|
|
||
|
```
|
||
|
POST /attachments
|
||
|
```
|
||
|
|
||
|
**Body Parameters**
|
||
|
|
||
|
| 参数 | 类型 | 默认值 | 必填 | 说明 |
|
||
|
| ---- | --------------- | ------ | ---- | ------------------------------------------------------------ |
|
||
|
| srcs | array of string | -- | 是 | 文件 key 值数组,如:["upload/data/吴淞桥_日报表_2018年11月12日_d2af9cf7-ea87-4d5f-a74a-1ebbaf37e307.xls", "upload/data/HongGu_daily_2021_a0292f7d-d97c-4a32-a148-10c70ea8e032.xls"] |
|
||
|
|
||
|
**Response 200**
|
||
|
|
||
|
```json
|
||
|
{
|
||
|
"keys": [
|
||
|
"upload/data/吴淞桥_日报表_2018年11月12日_d2af9cf7-ea87-4d5f-a74a-1ebbaf37e307.xls",
|
||
|
"upload/data/HongGu_daily_2021_a0292f7d-d97c-4a32-a148-10c70ea8e032.xls"
|
||
|
]
|
||
|
}
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
#### 2. fs-web-server-scaffold 配置示例
|
||
|
|
||
|
```js
|
||
|
/**
|
||
|
* Created by Julin on 2021/04/02.
|
||
|
*/
|
||
|
'use strict';
|
||
|
|
||
|
const path = require('path');
|
||
|
const os = require('os');
|
||
|
|
||
|
const dev = process.env.NODE_ENV == 'development';
|
||
|
|
||
|
const ANXINCLOUD_FC_CLOUD = process.env.ANXINCLOUD_FC_CLOUD;
|
||
|
const ANXINCLOUD_FC_LOCAL_SVR_ORIGIN = process.env.ANXINCLOUD_FC_LOCAL_SVR_ORIGIN;
|
||
|
const ANXINCLOUD_FC_LOCAL_ROOT_PATH = process.env.ANXINCLOUD_FC_LOCAL_ROOT_PATH;
|
||
|
|
||
|
const PORT = 4000;
|
||
|
|
||
|
const product = {
|
||
|
port: PORT,
|
||
|
staticDirs: [path.join(__dirname, ANXINCLOUD_FC_LOCAL_ROOT_PATH || 'static')],
|
||
|
mws: [{
|
||
|
entry: require('@fs/attachment').entry,
|
||
|
opts: Object.assign({
|
||
|
routePrefix: '_file-server',
|
||
|
uploadPath: 'other',
|
||
|
maxSize: 10485760 // 10M
|
||
|
}, ANXINCLOUD_FC_CLOUD == 'true' ? {
|
||
|
qiniu: {
|
||
|
domain: 'http://p7q1f8t1p.bkt.clouddn.com',
|
||
|
bucket: 'anxinyun-test',
|
||
|
accessKey: "5XrM4wEB9YU6RQwT64sPzzE6cYFKZgssdP5Kj3uu",
|
||
|
secretKey: "w6j2ixR_i-aelc6I7S3HotKIX-ukMzcKmDfH6-M5"
|
||
|
}
|
||
|
} : {
|
||
|
local: {
|
||
|
origin: ANXINCLOUD_FC_LOCAL_SVR_ORIGIN || `localhost:${PORT}`,
|
||
|
rootPath: 'static',
|
||
|
childPath: 'upload'
|
||
|
}
|
||
|
})
|
||
|
}],
|
||
|
dc: {
|
||
|
url: 'postgres://FashionAdmin:123456@10.8.30.39:5432/axy',
|
||
|
opts: {
|
||
|
pool: {
|
||
|
max: 20,
|
||
|
min: 10,
|
||
|
idle: 10000
|
||
|
},
|
||
|
define: {
|
||
|
freezeTableName: true, // 固定表名
|
||
|
timestamps: false // 不含列 "createAt"/"updateAt"/"DeleteAt"
|
||
|
},
|
||
|
timezone: '+08:00',
|
||
|
logging: false
|
||
|
},
|
||
|
models: []
|
||
|
},
|
||
|
logger: {
|
||
|
level: 'info',
|
||
|
json: false,
|
||
|
filename: path.join(__dirname, 'log', 'runtime.test.log'),
|
||
|
colorize: false,
|
||
|
maxsize: 1024 * 1024 * 5,
|
||
|
rotationFormat: false,
|
||
|
zippedArchive: true,
|
||
|
maxFiles: 10,
|
||
|
prettyPrint: true,
|
||
|
label: '',
|
||
|
timestamp: true,
|
||
|
eol: os.EOL,
|
||
|
tailable: true,
|
||
|
depth: null,
|
||
|
showLevel: true,
|
||
|
maxRetries: 1
|
||
|
}
|
||
|
};
|
||
|
|
||
|
const development = {
|
||
|
port: product.port,
|
||
|
mws: product.mws,
|
||
|
dc: product.dc,
|
||
|
logger: product.logger
|
||
|
};
|
||
|
|
||
|
if (dev) {
|
||
|
// logger
|
||
|
development.logger.filename = path.join(__dirname, 'log', 'development.test.log');
|
||
|
development.logger.level = 'debug';
|
||
|
development.dc.opts.logging = console.log;
|
||
|
}
|
||
|
|
||
|
module.exports = dev ? development : product;
|
||
|
|
||
|
```
|