chore: 补充自定义 fetcher 时可能漏了 attachmentAdpator 实现的说明文档

This commit is contained in:
wuduoyi 2023-10-24 12:23:55 +08:00
parent af806d553c
commit 9e81e6b15c
6 changed files with 124 additions and 61 deletions

View File

@ -871,6 +871,13 @@ Content-Disposition: attachment; filename="download.pdf"
Access-Control-Expose-Headers: Content-Disposition Access-Control-Expose-Headers: Content-Disposition
``` ```
如果自己覆盖了 `fetcher` 函数,需要有类似如下代码,具体可以参考 `embed.tsx` 里的实现
```javascript
let response = await axios(config);
response = await attachmentAdpator(response, __);
```
### 配置提示信息 ### 配置提示信息
可以通过`messages`自定义接口请求提示信息。 可以通过`messages`自定义接口请求提示信息。

View File

@ -5,7 +5,7 @@ import Portal from 'react-overlays/Portal';
import {normalizeLink} from 'amis-core'; import {normalizeLink} from 'amis-core';
import {withRouter} from 'react-router'; import {withRouter} from 'react-router';
import copy from 'copy-to-clipboard'; import copy from 'copy-to-clipboard';
import {qsparse, parseQuery} from 'amis-core'; import {qsparse, parseQuery, attachmentAdpator} from 'amis-core';
import isPlainObject from 'lodash/isPlainObject'; import isPlainObject from 'lodash/isPlainObject';
function loadEditor() { function loadEditor() {
@ -106,16 +106,29 @@ export default function (schema, schemaProps, showCode, envOverrides) {
return false; return false;
}, },
fetcher: ({url, method, data, config, headers}) => { fetcher: async ({
url,
method,
data,
responseType,
config,
headers
}) => {
config = config || {}; config = config || {};
config.headers = headers || {}; config.url = url;
responseType && (config.responseType = responseType);
if (config.cancelExecutor) { if (config.cancelExecutor) {
config.cancelToken = new axios.CancelToken(config.cancelExecutor); config.cancelToken = new axios.CancelToken(config.cancelExecutor);
} }
if (data && data instanceof FormData) { config.headers = headers || {};
// config.headers = config.headers || {}; config.method = method;
config.data = data;
if (method === 'get' && data) {
config.params = data;
} else if (data && data instanceof FormData) {
// config.headers['Content-Type'] = 'multipart/form-data'; // config.headers['Content-Type'] = 'multipart/form-data';
} else if ( } else if (
data && data &&
@ -127,19 +140,40 @@ export default function (schema, schemaProps, showCode, envOverrides) {
config.headers['Content-Type'] = 'application/json'; config.headers['Content-Type'] = 'application/json';
} }
if (method !== 'post' && method !== 'put' && method !== 'patch') { //
if (data) { config.validateStatus = function () {
if (method === 'delete') { return true;
config.data = data; };
} else {
config.params = data;
}
}
return axios[method](url, config); let response = await axios(config);
response = await attachmentAdpator(response, s => {
return s;
});
if (response.status >= 400) {
if (response.data) {
// raw:
if (
response.status === 401 &&
response.data.location &&
response.data.location.startsWith('http')
) {
location.href = response.data.location.replace(
'{{redirect}}',
encodeURIComponent(location.href)
);
return new Promise(() => {});
} else if (response.data.msg) {
throw new Error(response.data.msg);
} else {
throw new Error(JSON.stringify(response.data, null, 2));
}
} else {
throw new Error(`${response.status}`);
}
} }
return axios[method](url, data, config); return response;
}, },
isCancel: value => axios.isCancel(value), isCancel: value => axios.isCancel(value),
copy: (content, options) => { copy: (content, options) => {

View File

@ -49,6 +49,18 @@ function mockResponse(event, context, callback) {
json: false, json: false,
body: res body: res
}); });
},
download(file) {
callback(null, {
statusCode: 200,
headers: {
...createHeaders(event.headers),
'Content-Type': 'application/octet-stream',
'Content-Disposition': `attachment; filename="${file}"`
},
json: false,
download: file
});
} }
}; };
} }

BIN
mock/cfc/mock/download.zip Normal file

Binary file not shown.

View File

@ -2,58 +2,66 @@ const path = require('path');
const fs = require('fs'); const fs = require('fs');
const DIRNAME = path.dirname(__filename); const DIRNAME = path.dirname(__filename);
module.exports = function(req, res) { module.exports = function (req, res) {
const subpath = (req.originalUrl || req.url).replace(/^\/(api\/mock2|api)\/|\?.*$/g, ''); const subpath = (req.originalUrl || req.url).replace(
const jsonFile = subpath + '.json'; /^\/(api\/mock2|api)\/|\?.*$/g,
const jsFile = subpath + '.js'; ''
);
const jsonFile = subpath + '.json';
const jsFile = subpath + '.js';
if (subpath == 'options/users') { if (subpath == 'options/users') {
let json = readJson(jsonFile); let json = readJson(jsonFile);
let term = req.query.term; let term = req.query.term;
if (term) { if (term) {
json.data = json.data.filter(item => item.label.substring(0, term.length) === term); json.data = json.data.filter(
} item => item.label.substring(0, term.length) === term
);
return res.json(json);
} else if (/^sample/.test(subpath)) {
let file = require.resolve(path.join(DIRNAME, 'sample.js'));
delete require.cache[file];
return require(file)(req, res);
} else if (exist(jsFile)) {
let file = require.resolve(path.join(DIRNAME, jsFile));
delete require.cache[file];
if (req.query.waitSeconds) {
return setTimeout(function() {
require(file)(req, res);
}, parseInt(req.query.waitSeconds, 10) * 1000);
}
return require(file)(req, res);
} if (exist(jsonFile)) {
if (req.query.waitSeconds) {
return setTimeout(function() {
res.json(readJson(jsonFile));
}, parseInt(req.query.waitSeconds, 10) * 1000);
}
return res.json(readJson(jsonFile));
} else if (/crud\/\d+$/.test(subpath) && req.method === 'DELETE') {
return res.json({
status: 0,
msg: '删除成功'
})
} }
res.json(readJson('notFound.json')); return res.json(json);
} } else if (/^sample/.test(subpath)) {
let file = require.resolve(path.join(DIRNAME, 'sample.js'));
delete require.cache[file];
return require(file)(req, res);
} else if (exist(jsFile)) {
let file = require.resolve(path.join(DIRNAME, jsFile));
delete require.cache[file];
if (req.query.waitSeconds) {
return setTimeout(function () {
require(file)(req, res);
}, parseInt(req.query.waitSeconds, 10) * 1000);
}
return require(file)(req, res);
}
if (exist(jsonFile)) {
if (req.query.waitSeconds) {
return setTimeout(function () {
res.json(readJson(jsonFile));
}, parseInt(req.query.waitSeconds, 10) * 1000);
}
return res.json(readJson(jsonFile));
} else if (/crud\/\d+$/.test(subpath) && req.method === 'DELETE') {
return res.json({
status: 0,
msg: '删除成功'
});
} else if (/download/.test(subpath)) {
return res.download(path.join(DIRNAME, 'download.zip'));
}
res.json(readJson('notFound.json'));
};
function exist(subpath) { function exist(subpath) {
return fs.existsSync(path.join(DIRNAME, subpath)); return fs.existsSync(path.join(DIRNAME, subpath));
} }
function readJson(subpath) { function readJson(subpath) {
const content = fs.readFileSync(path.join(DIRNAME, subpath), 'utf8'); const content = fs.readFileSync(path.join(DIRNAME, subpath), 'utf8');
return JSON.parse(content); return JSON.parse(content);
} }

View File

@ -26,7 +26,9 @@ module.exports = function (req, res) {
res.status(500).json({status: 500, msg: err}); res.status(500).json({status: 500, msg: err});
} else { } else {
res.set(result.headers); res.set(result.headers);
if (!result.json) { if (result.download) {
res.download(result.download);
} else if (!result.json) {
res.status(result.statusCode).send(result.body); res.status(result.statusCode).send(result.body);
} else { } else {
res.status(result.statusCode).json(JSON.parse(result.body)); res.status(result.statusCode).json(JSON.parse(result.body));