四好公路
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

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;
```