import checkTypes from "@/utils/checkTypes"; import {urlJoin} from "@/utils/url"; import {isEmpty} from "@/utils/tools"; import http from './axios' const isDev = process.env.NODE_ENV === 'development' const getUrlByCode = function (url, obj = {}) { const reg = /\{([a-zA-Z0-9]+)\}/g const match = url.match(reg) || [] let str = url match.forEach(field => { const _field = field.substr(1, field.length - 2) str = str.replace(field, obj[_field] || field) }) return str } /** * 获取请求地址 * @param prefix * @param url */ const getUrl = (prefix, url) => { if (url.startsWith('http') || !prefix) return url if (prefix.startsWith('http')) { return urlJoin(`${prefix}/${url}`) } return urlJoin(`/${prefix}/${url}`) } /** * 请求处理 * @param httpMethod { String } 请求类型 * @param fetchUrl { String } 请求地址 * @returns {function(...[*]=)} */ const decoratorHandler = function (httpMethod, fetchUrl) { return function (target, propertyKey, descriptor) { const method = descriptor.value descriptor.value = async function (params = {}, options = {}, $logName) { const res = await method.apply(this, [params, options]) let _params = params let _options = options if (!isEmpty(res) && checkTypes.isObject(res) && res.params) { _params = res.params _options = res.options } if (this._commonAxiosOptions) { _options = { ...this._commonAxiosOptions, ..._options } } // 生成请求参数 const httpOptions = { method: httpMethod, url: getUrl(this.prefix, getUrlByCode(fetchUrl || propertyKey, _params)), baseURL: '', ..._options } if (httpMethod === 'get') { httpOptions.params = _params } else { httpOptions.data = _params } try { const response = await http(httpOptions) if (this.log) return this.log($logName, httpOptions, response) return response } catch (error) { if (this.log) throw this.log($logName, httpOptions, null, error) throw error } } } } /** * 根据环境过滤地址 * @param devUrl { String } * @param prodUrl { String } * @returns {String} */ const filterUrl = function (devUrl, prodUrl) { return (isDev ? devUrl : prodUrl || devUrl) || undefined } /** * 初始化请求接口前缀 * @param devPrefix { String } 开发环境请求地址前缀 * @param prodPrefix { String } 生产环境请求地址前缀 * @returns {function(*): {new(): {prefix: *}, prototype: {prefix: *}}} * @constructor */ export const Request = (devPrefix, prodPrefix) => { return function (constructor) { return class extends constructor { prefix = isDev ? devPrefix : prodPrefix || devPrefix } } } /** * Post请求 * @param devUrl { String } * @param prodUrl { String } * @returns {function(...[*]=)} * @constructor */ export const Post = (devUrl, prodUrl) => { let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl return decoratorHandler.call(this, 'post', filterUrl(_devUrl, prodUrl)) } /** * Get请求 * @param devUrl { String } * @param prodUrl { String } * @returns {function(...[*]=)} * @constructor */ export const Get = (devUrl, prodUrl) => { let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl return decoratorHandler.call(this, 'get', filterUrl(_devUrl, prodUrl)) } /** * Put请求注解 * @param devUrl { String } * @param prodUrl { String } * @returns {function(...[*]=)} * @constructor */ export const Put = (devUrl, prodUrl) => { let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl return decoratorHandler.call(this, 'put', filterUrl(_devUrl, prodUrl)) } /** * Delete请求注解 * @param devUrl { String } * @param prodUrl { String } * @returns {function(...[*]=)} * @constructor */ export const Delete = (devUrl, prodUrl) => { let _devUrl = typeof devUrl === 'string' ? devUrl : prodUrl return decoratorHandler.call(this, 'delete', filterUrl(_devUrl, prodUrl)) } /** * 为当前方法添加其他内容 * @param _options * @return {function(...[*]=)} * @constructor */ export const AxiosOptions = function (_options = {}) { return function (target, propertyKey, descriptor) { // 类 if (target.prototype) { return class extends target { _commonAxiosOptions = _options || {} } } else { const method = descriptor.value descriptor.value = function (params = {}, options = {}, $logName) { return method.apply(this, [params, { ...options, ..._options }, $logName]) } } } }