From 886a4a863821f69cebc27860db97a0b59bc10d9c Mon Sep 17 00:00:00 2001 From: FairyEver <1711467488@qq.com> Date: Tue, 17 Nov 2020 14:33:07 +0800 Subject: [PATCH] =?UTF-8?q?feat(api):=20:sparkles:=20=E5=AE=8C=E5=96=84=20?= =?UTF-8?q?service=20=E4=BB=A3=E7=A0=81=EF=BC=8Crequest=20=E7=8E=B0?= =?UTF-8?q?=E5=9C=A8=E4=BC=9A=E6=A0=B9=E6=8D=AE=E9=9C=80=E8=A6=81=E8=87=AA?= =?UTF-8?q?=E5=8A=A8=E5=BA=8F=E5=88=97=E5=8C=96=E5=8F=82=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 15 ++++-- package.json | 1 + src/api/service.js | 120 +++++++++++++++++++++++++++++++++------------ src/api/tools.js | 40 --------------- 4 files changed, 101 insertions(+), 75 deletions(-) diff --git a/package-lock.json b/package-lock.json index 65fdaa7c..9d30cbdc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12971,10 +12971,9 @@ "dev": true }, "qs": { - "version": "6.5.2", - "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz", - "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", - "dev": true + "version": "6.9.4", + "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.9.4.tgz", + "integrity": "sha1-kJCykNH5FyjTwi5UhDykSupatoc=" }, "query-string": { "version": "4.3.4", @@ -13357,6 +13356,14 @@ "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "dependencies": { + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npm.taobao.org/qs/download/qs-6.5.2.tgz", + "integrity": "sha1-yzroBuh0BERYTvFUzo7pjUA/PjY=", + "dev": true + } } }, "request-promise-core": { diff --git a/package.json b/package.json index f62d8614..dfb4fe90 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "lowdb": "^1.0.0", "marked": "^1.0.0", "nprogress": "^0.2.0", + "qs": "^6.9.4", "quill": "^1.3.7", "screenfull": "^5.0.2", "simplemde": "^1.11.2", diff --git a/src/api/service.js b/src/api/service.js index 38b6a591..bdd70d59 100644 --- a/src/api/service.js +++ b/src/api/service.js @@ -1,8 +1,36 @@ +import { Message } from 'element-ui' import axios from 'axios' import Adapter from 'axios-mock-adapter' -import { get } from 'lodash-es' +import { get, isEmpty } from 'lodash-es' +import qs from 'qs' import util from '@/libs/util' -import { errorLog, errorCreate } from './tools' +import store from '@/store' + +/** + * @description 记录和显示错误 + * @param {Error} error 错误对象 + */ +function handleError (error) { + // 添加到日志 + store.dispatch('d2admin/log/push', { + message: '数据请求异常', + type: 'danger', + meta: { + error + } + }) + // 打印到控制台 + if (process.env.NODE_ENV === 'development') { + util.log.danger('>>>>>> Error >>>>>>') + console.log(error) + } + // 显示提示 + Message({ + message: error.message, + type: 'error', + duration: 5 * 1000 + }) +} /** * @description 创建请求实例 @@ -22,29 +50,43 @@ function createService () { // 响应拦截 service.interceptors.response.use( response => { - // dataAxios 是 axios 返回数据中的 data - const dataAxios = response.data - // 这个状态码是和后端约定的 - const { code } = dataAxios - // 根据 code 进行判断 - if (code === undefined) { - // 如果没有 code 代表这不是项目后端开发的接口 比如可能是 D2Admin 请求最新版本 - return dataAxios - } else { - // 有 code 代表这是一个后端接口 可以进行进一步的判断 - switch (code) { - case 0: - // [ 示例 ] code === 0 代表没有错误 - return dataAxios.data - case 'xxx': - // [ 示例 ] 其它和后台约定的 code - errorCreate(`[ code: xxx ] ${dataAxios.msg}: ${response.config.url}`) - break - default: - // 不是正确的 code - errorCreate(`${dataAxios.msg}: ${response.config.url}`) - break - } + // http 状态码 200 情况 + // 根据 前后端约定的 response.data.code 判断接口是否请求成功 + // 例如 接口返回数据为 + // { + // code: 0, + // msg: 'success', + // data: { + // list: [], + // count: 0 + // } + // } + // 此时 + // response.data.code : + // 0 + // response.data.msg : + // 'success' + // response.data.data : (在调用接口) + // { + // list: [], + // count: 0 + // } + // 默认约定 code 为 0 时代表成功 + // 你也可以不使用这种方法,改为在下面的 http 错误拦截器里做处理 + + // 没有 code 视为非项目接口不作处理 + if (response.data.code === undefined) { + return response.data + } + + // 有 code 判断为项目接口请求 + switch (response.data.code) { + // 返回响应内容 + case 0: return response.data.data + // 例如在 code 401 情况下退回到登录页面 + case 401: throw new Error('请重新登录') + // 根据需要添加其它判断 + default: throw new Error(`${response.data.msg}: ${response.config.url}`) } }, error => { @@ -63,18 +105,22 @@ function createService () { case 505: error.message = 'HTTP版本不受支持'; break default: break } - errorLog(error) - return Promise.reject(error) + handleError(error) + throw error } ) return service } +function stringify (data) { + return qs.stringify(data, { allowDots: true, encode: false }) +} + /** * @description 创建请求方法 * @param {Object} service axios 实例 */ -function createRequestFunction (service) { +function createRequest (service) { return function (config) { const token = util.cookies.get('token') const configDefault = { @@ -86,17 +132,29 @@ function createRequestFunction (service) { baseURL: process.env.VUE_APP_API, data: {} } - return service(Object.assign(configDefault, config)) + const option = Object.assign(configDefault, config) + // 处理 get 请求的参数 + // 请根据实际需要修改 + if (!isEmpty(option.params)) { + option.params = {} + option.url = option.url + '?' + stringify(option.params) + } + // 当需要以 form 形式发送时 处理发送的数据 + // 请根据实际需要修改 + if (!isEmpty(option.data) && option.headers['Content-Type'] === 'application/x-www-form-urlencoded') { + option.data = stringify(option.data) + } + return service(option) } } // 用于真实网络请求的实例和请求方法 export const service = createService() -export const request = createRequestFunction(service) +export const request = createRequest(service) // 用于模拟网络请求的实例和请求方法 export const serviceForMock = createService() -export const requestForMock = createRequestFunction(serviceForMock) +export const requestForMock = createRequest(serviceForMock) // 网络请求数据模拟工具 export const mock = new Adapter(serviceForMock) diff --git a/src/api/tools.js b/src/api/tools.js index 990e8405..720a13a1 100644 --- a/src/api/tools.js +++ b/src/api/tools.js @@ -1,7 +1,3 @@ -import { Message } from 'element-ui' -import store from '@/store' -import util from '@/libs/util' - /** * @description 安全地解析 json 字符串 * @param {String} jsonString 需要解析的 json 字符串 @@ -48,39 +44,3 @@ export function responseSuccess (data = {}, msg = '成功') { export function responseError (data = {}, msg = '请求失败', code = 500) { return response(data, msg, code) } - -/** - * @description 记录和显示错误 - * @param {Error} error 错误对象 - */ -export function errorLog (error) { - // 添加到日志 - store.dispatch('d2admin/log/push', { - message: '数据请求异常', - type: 'danger', - meta: { - error - } - }) - // 打印到控制台 - if (process.env.NODE_ENV === 'development') { - util.log.danger('>>>>>> Error >>>>>>') - console.log(error) - } - // 显示提示 - Message({ - message: error.message, - type: 'error', - duration: 5 * 1000 - }) -} - -/** - * @description 创建一个错误 - * @param {String} msg 错误信息 - */ -export function errorCreate (msg) { - const error = new Error(msg) - errorLog(error) - throw error -}