Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vipshop GitHub upstream master config data path code path #171

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 54 additions & 58 deletions src/actions/api.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import ams from '../ams';
import { getQueryString, getType, isFn } from '../utils';
import { getQueryString, getType, isFn, responseHandler } from '../utils';
import { httpRequestTypeExcludeGet } from '../ams/request';

/**
Expand Down Expand Up @@ -115,19 +115,14 @@ export const read = ams.createApiAction({
};
},
success(res) {
const successCode = this.getConfig('resource.api.read.successCode') || this.getConfig('resource.api.successCode');
if (res.data.code === successCode) {
const config = this.resource.api.read;
if (typeof config === 'object' && typeof config.transform === 'function') {
this.setBlockData(config.transform(res.data.data));
} else if (typeof config === 'object' && typeof config.responseDataParse === 'function') {
this.setBlockData(config.responseDataParse(res.data));
} else {
this.setBlockData(res.data.data);
}
const { message, code, isSuccess, data } = responseHandler.call(this, res, 'read');
if (isSuccess) {
const { transform, responseDataParse } = this.resource.api.read || {};
const handler = transform || responseDataParse || (data => data);
this.setBlockData(handler(data));
} else {
this.$message.error(`${res.data.msg}(${res.data.code})`);
throw '@read:' + res.data.code;
this.$message.error(`${message}(${code})`);
throw '@read:' + code;
}
return res;
}
Expand Down Expand Up @@ -163,16 +158,14 @@ export const update = ams.createApiAction({
};
},
success(res) {
// 默认successCode
const successCode = this.getConfig('resource.api.update.successCode') || this.getConfig('resource.api.successCode');
if (res.data.code === successCode) {
const { isSuccess, message, code, data } = responseHandler.call(this, res, 'update');
if (isSuccess) {
this.$message.success('更新成功');
if (typeof this.on['update-success'] === 'function') {
this.on['update-success'](res.data);
}
const onSuccess = this.on['update-success'];
if (isFn(onSuccess)) onSuccess(data);
} else {
this.$message.error(`${res.data.msg}(${res.data.code})`);
throw '@update:' + res.data.code;
this.$message.error(`${message}(${code})`);
throw '@update:' + code;
}
return res;
}
Expand Down Expand Up @@ -209,16 +202,14 @@ export const deleteAction = ams.createApiAction({
};
},
success(res) {
// 默认successCode
const successCode = this.getConfig('resource.api.delete.successCode') || this.getConfig('resource.api.successCode');
if (res.data.code === successCode) {
const { isSuccess, message, code, data } = responseHandler.call(this, res, 'delete');
if (isSuccess) {
this.$message.success('删除成功');
if (typeof this.on['delete-success'] === 'function') {
this.on['delete-success'](res.data);
}
const onSuccess = this.on['delete-success'];
if (isFn(onSuccess)) onSuccess(data);
} else {
this.$message.error(`${res.data.msg}(${res.data.code})`);
throw '@delete:' + res.data.code;
this.$message.error(`${message}(${code})`);
throw '@delete:' + code;
}
return res;
}
Expand Down Expand Up @@ -248,21 +239,21 @@ export const create = ams.createApiAction({
};
},
success(res) {
// 默认successCode
const successCode = this.getConfig('resource.api.create.successCode') || this.getConfig('resource.api.successCode');
if (res.data.code === successCode) {
const { isSuccess, message, code, data } = responseHandler.call(this, res, 'create');
if (isSuccess) {
this.$message.success('创建成功');
if (typeof this.on['create-success'] === 'function') {
this.on['create-success'](res.data);
}
const onSuccess = this.on['create-success'];
if (isFn(onSuccess)) onSuccess(data);
} else {
this.$message.error(`${res.data.msg}(${res.data.code})`);
throw '@create code:' + res.data.code;
this.$message.error(`${message}(${code})`);
throw '@create code:' + code;
}
return res;
}
});

// https://github.com/vipshop/ams/blob/5c8e0112c3b8e42c4bed9ff658767bbdbcf9bbd4/src/ams/request.js#L162
// createApiAction -> src/ams/request.js
export const list = ams.createApiAction({
getOptions(params) {
// 使用传入页数,如搜索使用 @list:1 将页数重置为1
Expand Down Expand Up @@ -339,35 +330,40 @@ export const list = ams.createApiAction({
params: arg
};
},
/**
*
* @param {*} res { status: statusCode, data: JSON.parse(xhr.responseText) }
*/
success(res) {
// 默认successCode
const successCode = this.getConfig('resource.api.list.successCode') || this.getConfig('resource.api.successCode');
if (
res.data.code === successCode &&
res.data.data
) {
const config = this.resource.api.list;
this.data.total = res.data.data.total;
const { message, code, isSuccess, data, getter } = responseHandler.call(this, res, 'list');
if (isSuccess) {
const total = data[getter.totalPath];
const list = data[getter.listPath];
this.data.list = list;
this.data.total = total;

if (typeof config === 'object' && typeof config.transform === 'function') {
this.data.list = config.transform(res.data.data.list) || [];
} else if (typeof config === 'object' && typeof config.responseDataParse === 'function') {
const convertResponseDataParse = config.responseDataParse(res.data);
if (getType(convertResponseDataParse) !== 'object') {
const { transform, responseDataParse } = this.resource.api.list || {};
if (isFn(transform)) {
this.data.list = transform(list);
} else if (isFn(responseDataParse)) {
const parsedData = responseDataParse({
...res,
msg: message,
code,
data
});
if (getType(parsedData) !== 'object') {
console.error('responseDataParse中需要返回object类型,如{ list: [] }');
this.data.list = [];
} else {
Object.assign(this.data, convertResponseDataParse);
Object.assign(this.data, parsedData);
}
} else {
this.data.list = res.data.data.list || [];
}
if (typeof this.on['list-success'] === 'function') {
this.on['list-success'](res.data);
}
const onSuccess = this.on['list-success'];
if (isFn(onSuccess)) onSuccess(data);
} else {
this.$message.error(`${res.data.msg}(${res.data.code})`);
throw '@list:' + res.data.code;
this.$message.error(`${message}(${code})`);
throw '@list:' + code;
}

return res;
Expand Down
24 changes: 10 additions & 14 deletions src/ams/configs/alias/field.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { deepExtend, get } from '../../../utils';
/* eslint-disable complexity,no-new,max-depth */

import { deepExtend, responseHandler } from '../../../utils';
import * as fieldGetSet from '../field-get-set';
import { httpRequestTypeExcludeGet } from '../../request';

Expand Down Expand Up @@ -171,19 +173,13 @@ export const SELECT_REMOTE = {
$field.loading = true;
const res = await remoteConfig.request.call(this, $field, query, isBackfill);
$field.loading = false;

let data = get(res.data, remoteConfig.dataPath);
let successCode;

if (typeof remoteConfig.successCode !== 'undefined') {
successCode = remoteConfig.successCode;
} else {
successCode = this.getConfig('resource.api.successCode');
}
if (
res.data.code === successCode &&
data
) {
// eslint-disable-next-line no-unused-vars
const { isSuccess, data } = responseHandler.call(this, res, '', {
dataPath: remoteConfig.dataPath, // 'data.list',
successCode: remoteConfig.successCode || this.getConfig('resource.api.successCode'),
codePath: remoteConfig.codePath || this.getConfig('resource.api.code') || 'code'
});
if (isSuccess && data) {
const options = remoteConfig.transform.call(this, $field, data);
const optionsEntity = options.reduce((obj, cur) => Object.assign(obj, { [cur.label]: cur.value }), {});
if (remoteConfig.isCache) {
Expand Down
60 changes: 60 additions & 0 deletions src/utils/api.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { get as lodashGet } from 'lodash';

const defaultGetter = {
codePath: 'code',
successCode: 0,
dataPath: 'data',
totalPath: 'total',
listPath: 'list',
messagePath: 'msg',
};

/**
* 从 API Response 中获取相关字段,如是否成功、total、data 等
* https://github.com/vipshop/ams/pull/125
*
* @param {Object} response : api response data
* @param {String} action : read/update/list/delete 增删改查
* @param {Object} actionGetter : 适配更多接口的返回值
*
* ams 默认接口数据结构: https://vipshop.github.io/ams/api/api.html#%E9%80%9A%E7%94%A8%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84
*
* -------常规请求----------
* {
[codePath]: [successCode],
[dataPath]: String,
[messagePath]: String
* }
*
*
* ------- 列表请求----------
* {
[codePath]: [successCode],
[dataPath]: {
[dataPath.listPath]: [],
[dataPath.totalPath]: Number,
},
[messagePath]: String
* }
*
*
*/
export function responseHandler(response, action, actionGetter) {
const configGetter = this.getConfig(`resource.api.${action}.getter`);
const getter = {
...defaultGetter,
...actionGetter,
...configGetter
};

const code = lodashGet(response.data, getter.codePath); // api response(success/result)对应的值
// eslint-disable-next-line
const isSuccess = code == getter.successCode;
return {
code,
getter,
isSuccess,
data: lodashGet(response.data, getter.dataPath),
message: lodashGet(response.data, getter.messagePath),
};
}
1 change: 1 addition & 0 deletions src/utils/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export * from './dom';
export * from './function';
export * from './tools';
export * from './localstorage';
export * from './api';
export * from './type';
export * from './loader';
export * from './list';
Expand Down