Merge branch 'master' of https://gitee.com/sheepjs/shopro-uniapp
commit
43d23ed9b7
|
@ -7,3 +7,4 @@ deploy.sh
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
.env
|
.env
|
||||||
yarn.lock
|
yarn.lock
|
||||||
|
package-lock.json
|
|
@ -92,6 +92,7 @@
|
||||||
"@hyoga/uni-socket.io": "^1.0.1",
|
"@hyoga/uni-socket.io": "^1.0.1",
|
||||||
"dayjs": "^1.11.6",
|
"dayjs": "^1.11.6",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"luch-request": "^3.0.8",
|
||||||
"pinia": "^2.0.24",
|
"pinia": "^2.0.24",
|
||||||
"pinia-plugin-persist-uni": "^1.2.0",
|
"pinia-plugin-persist-uni": "^1.2.0",
|
||||||
"qs-canvas": "^1.0.11",
|
"qs-canvas": "^1.0.11",
|
||||||
|
|
|
@ -186,7 +186,7 @@
|
||||||
:show="state.showSelectSku"
|
:show="state.showSelectSku"
|
||||||
:goodsInfo="state.data.goods"
|
:goodsInfo="state.data.goods"
|
||||||
:grouponAction="state.grouponAction"
|
:grouponAction="state.grouponAction"
|
||||||
v-model:grouponNum="state.grouponNum"
|
:grouponNum="state.grouponNum"
|
||||||
@buy="onBuy"
|
@buy="onBuy"
|
||||||
@change="onSkuChange"
|
@change="onSkuChange"
|
||||||
@close="state.showSelectSku = false"
|
@close="state.showSelectSku = false"
|
||||||
|
|
|
@ -116,8 +116,9 @@
|
||||||
:show="state.showSelectSku"
|
:show="state.showSelectSku"
|
||||||
:goodsInfo="state.goodsInfo"
|
:goodsInfo="state.goodsInfo"
|
||||||
:grouponAction="state.grouponAction"
|
:grouponAction="state.grouponAction"
|
||||||
v-model:grouponNum="state.grouponNum"
|
:grouponNum="state.defaultGrouponNum"
|
||||||
@buy="onBuy"
|
@buy="onBuy"
|
||||||
|
@ladder="onLadder"
|
||||||
@change="onSkuChange"
|
@change="onSkuChange"
|
||||||
@close="onSkuClose"
|
@close="onSkuClose"
|
||||||
/>
|
/>
|
||||||
|
@ -190,16 +191,17 @@
|
||||||
|
|
||||||
onPageScroll(() => {});
|
onPageScroll(() => {});
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
skeletonLoading: true,
|
skeletonLoading: true, // 骨架屏
|
||||||
goodsId: 0,
|
goodsId: 0, // 商品ID
|
||||||
goodsInfo: {},
|
goodsInfo: {}, // 商品信息
|
||||||
goodsSwiper: [],
|
goodsSwiper: [], // 商品轮播图
|
||||||
showSelectSku: false,
|
showSelectSku: false, // 显示规格弹框
|
||||||
selectedSkuPrice: {},
|
selectedSkuPrice: {}, // 选中的规格价格
|
||||||
grouponId: 0,
|
grouponId: 0, // 团购ID
|
||||||
grouponType: '',
|
grouponType: '', // 团购类型
|
||||||
grouponNum: 0,
|
defaultGrouponNum: 0, // 默认团购人数
|
||||||
grouponAction: 'create',
|
grouponNum: 0, // 团购人数
|
||||||
|
grouponAction: 'create', // 团购操作
|
||||||
});
|
});
|
||||||
|
|
||||||
// 商品主价格
|
// 商品主价格
|
||||||
|
@ -226,6 +228,11 @@
|
||||||
state.selectedSkuPrice = e;
|
state.selectedSkuPrice = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 阶梯变更
|
||||||
|
function onLadder(e) {
|
||||||
|
state.grouponNum = e
|
||||||
|
}
|
||||||
|
|
||||||
function onSkuClose() {
|
function onSkuClose() {
|
||||||
state.showSelectSku = false;
|
state.showSelectSku = false;
|
||||||
}
|
}
|
||||||
|
@ -241,6 +248,7 @@
|
||||||
function onJoinGroupon(groupon) {
|
function onJoinGroupon(groupon) {
|
||||||
state.grouponAction = 'join';
|
state.grouponAction = 'join';
|
||||||
state.grouponId = groupon.id;
|
state.grouponId = groupon.id;
|
||||||
|
state.defaultGrouponNum = groupon.num;
|
||||||
state.grouponNum = groupon.num;
|
state.grouponNum = groupon.num;
|
||||||
state.showSelectSku = true;
|
state.showSelectSku = true;
|
||||||
}
|
}
|
||||||
|
@ -303,6 +311,7 @@
|
||||||
state.goodsInfo = data;
|
state.goodsInfo = data;
|
||||||
state.grouponType = state.goodsInfo.activity_type;
|
state.grouponType = state.goodsInfo.activity_type;
|
||||||
if (state.grouponType === 'groupon') {
|
if (state.grouponType === 'groupon') {
|
||||||
|
state.defaultGrouponNum = state.goodsInfo.activity.rules.team_num;
|
||||||
state.grouponNum = state.goodsInfo.activity.rules.team_num;
|
state.grouponNum = state.goodsInfo.activity.rules.team_num;
|
||||||
}
|
}
|
||||||
state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.images);
|
state.goodsSwiper = formatGoodsSwiper(state.goodsInfo.images);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<!-- 规格弹窗 -->
|
<!-- 拼团商品规格弹窗 -->
|
||||||
<su-popup :show="show" round="10" @close="emits('close')">
|
<su-popup :show="show" round="10" @close="emits('close')">
|
||||||
<view class="ss-modal-box bg-white ss-flex-col">
|
<view class="ss-modal-box bg-white ss-flex-col">
|
||||||
<view class="modal-header ss-flex ss-col-center">
|
<view class="modal-header ss-flex ss-col-center">
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
class="ss-reset-button spec-btn"
|
class="ss-reset-button spec-btn"
|
||||||
:class="[
|
:class="[
|
||||||
{
|
{
|
||||||
'checked-btn': grouponNum == ladder,
|
'checked-btn': state.grouponNum == ladder,
|
||||||
},
|
},
|
||||||
]"
|
]"
|
||||||
@tap="onSelectLadder(ladder)"
|
@tap="onSelectLadder(ladder)"
|
||||||
|
@ -91,7 +91,7 @@
|
||||||
<view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center">
|
<view class="buy-box ss-flex ss-col-center ss-flex ss-col-center ss-row-center">
|
||||||
<view class="ss-flex">
|
<view class="ss-flex">
|
||||||
<button class="ss-reset-button origin-price-btn ss-flex-col">
|
<button class="ss-reset-button origin-price-btn ss-flex-col">
|
||||||
<view class="btn-title">{{ grouponNum }}人团</view>
|
<view class="btn-title">{{ state.grouponNum === 0 ? '阶梯团' : state.grouponNum + '人团' }}</view>
|
||||||
</button>
|
</button>
|
||||||
<button class="ss-reset-button btn-tox ss-flex-col" @tap="onBuy">
|
<button class="ss-reset-button btn-tox ss-flex-col" @tap="onBuy">
|
||||||
<view class="btn-price">
|
<view class="btn-price">
|
||||||
|
@ -128,16 +128,16 @@
|
||||||
import { formatPrice } from '@/sheep/hooks/useGoods';
|
import { formatPrice } from '@/sheep/hooks/useGoods';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
const emits = defineEmits(['change', 'addCart', 'buy', 'close', 'update:grouponNum']);
|
const emits = defineEmits(['change', 'addCart', 'buy', 'close', 'ladder']);
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
goodsInfo: {
|
|
||||||
type: Object,
|
|
||||||
default() {},
|
|
||||||
},
|
|
||||||
show: {
|
show: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
goodsInfo: {
|
||||||
|
type: Object,
|
||||||
|
default() {},
|
||||||
|
},
|
||||||
grouponAction: {
|
grouponAction: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'create',
|
default: 'create',
|
||||||
|
@ -150,6 +150,7 @@
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
selectedSkuPrice: {},
|
selectedSkuPrice: {},
|
||||||
currentSkuArray: [],
|
currentSkuArray: [],
|
||||||
|
grouponNum: props.grouponNum,
|
||||||
});
|
});
|
||||||
|
|
||||||
// 默认单规格
|
// 默认单规格
|
||||||
|
@ -204,7 +205,7 @@
|
||||||
|
|
||||||
// 获取阶梯价
|
// 获取阶梯价
|
||||||
function getSkuPriceByLadder() {
|
function getSkuPriceByLadder() {
|
||||||
return state.selectedSkuPrice.ladders.find((item) => item.ladder == props.grouponNum);
|
return state.selectedSkuPrice.ladders.find((item) => item.ladder == state.grouponNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@ -340,13 +341,14 @@
|
||||||
|
|
||||||
// 选择阶梯拼团人数
|
// 选择阶梯拼团人数
|
||||||
function onSelectLadder(ladder) {
|
function onSelectLadder(ladder) {
|
||||||
emits('update:grouponNum', ladder);
|
state.grouponNum = ladder;
|
||||||
|
emits('ladder', ladder);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 选择规格
|
// 选择规格
|
||||||
function onSelectSku(pid, skuId) {
|
function onSelectSku(pid, skuId) {
|
||||||
// 清空已选择
|
// 清空已选择
|
||||||
if (activityType === 'groupon_ladder' && props.grouponNum == 0) {
|
if (activityType === 'groupon_ladder' && state.grouponNum == 0) {
|
||||||
sheep.$helper.toast('请选择拼团人数');
|
sheep.$helper.toast('请选择拼团人数');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,101 +0,0 @@
|
||||||
import buildURL from '../helpers/buildURL';
|
|
||||||
import buildFullPath from '../core/buildFullPath';
|
|
||||||
import settle from '../core/settle';
|
|
||||||
import { isUndefined } from '../utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 返回可选值存在的配置
|
|
||||||
* @param {Array} keys - 可选值数组
|
|
||||||
* @param {Object} config2 - 配置
|
|
||||||
* @return {{}} - 存在的配置项
|
|
||||||
*/
|
|
||||||
const mergeKeys = (keys, config2) => {
|
|
||||||
const config = {};
|
|
||||||
keys.forEach((prop) => {
|
|
||||||
if (!isUndefined(config2[prop])) {
|
|
||||||
config[prop] = config2[prop];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return config;
|
|
||||||
};
|
|
||||||
export default (config) =>
|
|
||||||
new Promise((resolve, reject) => {
|
|
||||||
const fullPath = buildURL(buildFullPath(config.baseURL, config.url), config.params);
|
|
||||||
const _config = {
|
|
||||||
url: fullPath,
|
|
||||||
header: config.header,
|
|
||||||
complete: (response) => {
|
|
||||||
config.fullPath = fullPath;
|
|
||||||
response.config = config;
|
|
||||||
try {
|
|
||||||
// 对可能字符串不是json 的情况容错
|
|
||||||
if (typeof response.data === 'string') {
|
|
||||||
response.data = JSON.parse(response.data);
|
|
||||||
}
|
|
||||||
// eslint-disable-next-line no-empty
|
|
||||||
} catch (e) {}
|
|
||||||
settle(resolve, reject, response);
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let requestTask;
|
|
||||||
if (config.method === 'UPLOAD') {
|
|
||||||
delete _config.header['content-type'];
|
|
||||||
delete _config.header['Content-Type'];
|
|
||||||
const otherConfig = {
|
|
||||||
// #ifdef MP-ALIPAY
|
|
||||||
fileType: config.fileType,
|
|
||||||
// #endif
|
|
||||||
filePath: config.filePath,
|
|
||||||
name: config.name,
|
|
||||||
};
|
|
||||||
const optionalKeys = [
|
|
||||||
// #ifdef APP-PLUS || H5
|
|
||||||
'files',
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
'file',
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5 || APP-PLUS
|
|
||||||
'timeout',
|
|
||||||
// #endif
|
|
||||||
'formData',
|
|
||||||
];
|
|
||||||
requestTask = uni.uploadFile({
|
|
||||||
..._config,
|
|
||||||
...otherConfig,
|
|
||||||
...mergeKeys(optionalKeys, config),
|
|
||||||
});
|
|
||||||
} else if (config.method === 'DOWNLOAD') {
|
|
||||||
// #ifdef H5 || APP-PLUS
|
|
||||||
if (!isUndefined(config.timeout)) {
|
|
||||||
_config.timeout = config.timeout;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
requestTask = uni.downloadFile(_config);
|
|
||||||
} else {
|
|
||||||
const optionalKeys = [
|
|
||||||
'data',
|
|
||||||
'method',
|
|
||||||
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
|
||||||
'timeout',
|
|
||||||
// #endif
|
|
||||||
'dataType',
|
|
||||||
// #ifndef MP-ALIPAY
|
|
||||||
'responseType',
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
'sslVerify',
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
'withCredentials',
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
'firstIpv4',
|
|
||||||
// #endif
|
|
||||||
];
|
|
||||||
requestTask = uni.request({ ..._config, ...mergeKeys(optionalKeys, config) });
|
|
||||||
}
|
|
||||||
if (config.getTask) {
|
|
||||||
config.getTask(requestTask, config);
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,50 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function InterceptorManager() {
|
|
||||||
this.handlers = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new interceptor to the stack
|
|
||||||
*
|
|
||||||
* @param {Function} fulfilled The function to handle `then` for a `Promise`
|
|
||||||
* @param {Function} rejected The function to handle `reject` for a `Promise`
|
|
||||||
*
|
|
||||||
* @return {Number} An ID used to remove interceptor later
|
|
||||||
*/
|
|
||||||
InterceptorManager.prototype.use = function use(fulfilled, rejected) {
|
|
||||||
this.handlers.push({
|
|
||||||
fulfilled,
|
|
||||||
rejected,
|
|
||||||
});
|
|
||||||
return this.handlers.length - 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove an interceptor from the stack
|
|
||||||
*
|
|
||||||
* @param {Number} id The ID that was returned by `use`
|
|
||||||
*/
|
|
||||||
InterceptorManager.prototype.eject = function eject(id) {
|
|
||||||
if (this.handlers[id]) {
|
|
||||||
this.handlers[id] = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over all the registered interceptors
|
|
||||||
*
|
|
||||||
* This method is particularly useful for skipping over any
|
|
||||||
* interceptors that may have become `null` calling `eject`.
|
|
||||||
*
|
|
||||||
* @param {Function} fn The function to call for each interceptor
|
|
||||||
*/
|
|
||||||
InterceptorManager.prototype.forEach = function forEach(fn) {
|
|
||||||
this.handlers.forEach((h) => {
|
|
||||||
if (h !== null) {
|
|
||||||
fn(h);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export default InterceptorManager;
|
|
|
@ -1,198 +0,0 @@
|
||||||
/**
|
|
||||||
* @Class Request
|
|
||||||
* @description luch-request http请求插件
|
|
||||||
* @version 3.0.7
|
|
||||||
* @Author lu-ch
|
|
||||||
* @Date 2021-09-04
|
|
||||||
* @Email webwork.s@qq.com
|
|
||||||
* 文档: https://www.quanzhan.co/luch-request/
|
|
||||||
* github: https://github.com/lei-mu/luch-request
|
|
||||||
* DCloud: http://ext.dcloud.net.cn/plugin?id=392
|
|
||||||
* HBuilderX: beat-3.0.4 alpha-3.0.4
|
|
||||||
*/
|
|
||||||
|
|
||||||
import dispatchRequest from './dispatchRequest';
|
|
||||||
import InterceptorManager from './InterceptorManager';
|
|
||||||
import mergeConfig from './mergeConfig';
|
|
||||||
import defaults from './defaults';
|
|
||||||
import { isPlainObject } from '../utils';
|
|
||||||
import clone from '../utils/clone';
|
|
||||||
|
|
||||||
export default class Request {
|
|
||||||
/**
|
|
||||||
* @param {Object} arg - 全局配置
|
|
||||||
* @param {String} arg.baseURL - 全局根路径
|
|
||||||
* @param {Object} arg.header - 全局header
|
|
||||||
* @param {String} arg.method = [GET|POST|PUT|DELETE|CONNECT|HEAD|OPTIONS|TRACE] - 全局默认请求方式
|
|
||||||
* @param {String} arg.dataType = [json] - 全局默认的dataType
|
|
||||||
* @param {String} arg.responseType = [text|arraybuffer] - 全局默认的responseType。支付宝小程序不支持
|
|
||||||
* @param {Object} arg.custom - 全局默认的自定义参数
|
|
||||||
* @param {Number} arg.timeout - 全局默认的超时时间,单位 ms。默认60000。H5(HBuilderX 2.9.9+)、APP(HBuilderX 2.9.9+)、微信小程序(2.10.0)、支付宝小程序
|
|
||||||
* @param {Boolean} arg.sslVerify - 全局默认的是否验证 ssl 证书。默认true.仅App安卓端支持(HBuilderX 2.3.3+)
|
|
||||||
* @param {Boolean} arg.withCredentials - 全局默认的跨域请求时是否携带凭证(cookies)。默认false。仅H5支持(HBuilderX 2.6.15+)
|
|
||||||
* @param {Boolean} arg.firstIpv4 - 全DNS解析时优先使用ipv4。默认false。仅 App-Android 支持 (HBuilderX 2.8.0+)
|
|
||||||
* @param {Function(statusCode):Boolean} arg.validateStatus - 全局默认的自定义验证器。默认statusCode >= 200 && statusCode < 300
|
|
||||||
*/
|
|
||||||
constructor(arg = {}) {
|
|
||||||
if (!isPlainObject(arg)) {
|
|
||||||
arg = {};
|
|
||||||
console.warn('设置全局参数必须接收一个Object');
|
|
||||||
}
|
|
||||||
this.config = clone({ ...defaults, ...arg });
|
|
||||||
this.interceptors = {
|
|
||||||
request: new InterceptorManager(),
|
|
||||||
response: new InterceptorManager(),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Function
|
|
||||||
* @param {Request~setConfigCallback} f - 设置全局默认配置
|
|
||||||
*/
|
|
||||||
setConfig(f) {
|
|
||||||
this.config = f(this.config);
|
|
||||||
}
|
|
||||||
|
|
||||||
middleware(config) {
|
|
||||||
config = mergeConfig(this.config, config);
|
|
||||||
const chain = [dispatchRequest, undefined];
|
|
||||||
let promise = Promise.resolve(config);
|
|
||||||
|
|
||||||
this.interceptors.request.forEach((interceptor) => {
|
|
||||||
chain.unshift(interceptor.fulfilled, interceptor.rejected);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.interceptors.response.forEach((interceptor) => {
|
|
||||||
chain.push(interceptor.fulfilled, interceptor.rejected);
|
|
||||||
});
|
|
||||||
|
|
||||||
while (chain.length) {
|
|
||||||
promise = promise.then(chain.shift(), chain.shift());
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @Function
|
|
||||||
* @param {Object} config - 请求配置项
|
|
||||||
* @prop {String} options.url - 请求路径
|
|
||||||
* @prop {Object} options.data - 请求参数
|
|
||||||
* @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
|
|
||||||
* @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
|
|
||||||
* @prop {Object} [options.header = config.header] - 请求header
|
|
||||||
* @prop {Object} [options.method = config.method] - 请求方法
|
|
||||||
* @returns {Promise<unknown>}
|
|
||||||
*/
|
|
||||||
request(config = {}) {
|
|
||||||
return this.middleware(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
get(url, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
method: 'GET',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
post(url, data, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
data,
|
|
||||||
method: 'POST',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #ifndef MP-ALIPAY
|
|
||||||
put(url, data, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
data,
|
|
||||||
method: 'PUT',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
|
||||||
delete(url, data, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
data,
|
|
||||||
method: 'DELETE',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef H5 || MP-WEIXIN
|
|
||||||
connect(url, data, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
data,
|
|
||||||
method: 'CONNECT',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef H5 || MP-WEIXIN || MP-BAIDU
|
|
||||||
head(url, data, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
data,
|
|
||||||
method: 'HEAD',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
|
|
||||||
options(url, data, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
data,
|
|
||||||
method: 'OPTIONS',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef H5 || MP-WEIXIN
|
|
||||||
trace(url, data, options = {}) {
|
|
||||||
return this.middleware({
|
|
||||||
url,
|
|
||||||
data,
|
|
||||||
method: 'TRACE',
|
|
||||||
...options,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
upload(url, config = {}) {
|
|
||||||
config.url = url;
|
|
||||||
config.method = 'UPLOAD';
|
|
||||||
return this.middleware(config);
|
|
||||||
}
|
|
||||||
|
|
||||||
download(url, config = {}) {
|
|
||||||
config.url = url;
|
|
||||||
config.method = 'DOWNLOAD';
|
|
||||||
return this.middleware(config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* setConfig回调
|
|
||||||
* @return {Object} - 返回操作后的config
|
|
||||||
* @callback Request~setConfigCallback
|
|
||||||
* @param {Object} config - 全局默认config
|
|
||||||
*/
|
|
|
@ -1,20 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import isAbsoluteURL from '../helpers/isAbsoluteURL';
|
|
||||||
import combineURLs from '../helpers/combineURLs';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new URL by combining the baseURL with the requestedURL,
|
|
||||||
* only when the requestedURL is not already an absolute URL.
|
|
||||||
* If the requestURL is absolute, this function returns the requestedURL untouched.
|
|
||||||
*
|
|
||||||
* @param {string} baseURL The base URL
|
|
||||||
* @param {string} requestedURL Absolute or relative URL to combine
|
|
||||||
* @returns {string} The combined full path
|
|
||||||
*/
|
|
||||||
export default function buildFullPath(baseURL, requestedURL) {
|
|
||||||
if (baseURL && !isAbsoluteURL(requestedURL)) {
|
|
||||||
return combineURLs(baseURL, requestedURL);
|
|
||||||
}
|
|
||||||
return requestedURL;
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
/**
|
|
||||||
* 默认的全局配置
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default {
|
|
||||||
baseURL: '',
|
|
||||||
header: {},
|
|
||||||
method: 'GET',
|
|
||||||
dataType: 'json',
|
|
||||||
// #ifndef MP-ALIPAY
|
|
||||||
responseType: 'text',
|
|
||||||
// #endif
|
|
||||||
custom: {},
|
|
||||||
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
|
||||||
timeout: 60000,
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
sslVerify: true,
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
withCredentials: false,
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
firstIpv4: false,
|
|
||||||
// #endif
|
|
||||||
validateStatus: function validateStatus(status) {
|
|
||||||
return status >= 200 && status < 300;
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1,3 +0,0 @@
|
||||||
import adapter from '../adapters/index';
|
|
||||||
|
|
||||||
export default (config) => adapter(config);
|
|
|
@ -1,103 +0,0 @@
|
||||||
import { deepMerge, isUndefined } from '../utils';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 合并局部配置优先的配置,如果局部有该配置项则用局部,如果全局有该配置项则用全局
|
|
||||||
* @param {Array} keys - 配置项
|
|
||||||
* @param {Object} globalsConfig - 当前的全局配置
|
|
||||||
* @param {Object} config2 - 局部配置
|
|
||||||
* @return {{}}
|
|
||||||
*/
|
|
||||||
const mergeKeys = (keys, globalsConfig, config2) => {
|
|
||||||
const config = {};
|
|
||||||
keys.forEach((prop) => {
|
|
||||||
if (!isUndefined(config2[prop])) {
|
|
||||||
config[prop] = config2[prop];
|
|
||||||
} else if (!isUndefined(globalsConfig[prop])) {
|
|
||||||
config[prop] = globalsConfig[prop];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return config;
|
|
||||||
};
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param globalsConfig - 当前实例的全局配置
|
|
||||||
* @param config2 - 当前的局部配置
|
|
||||||
* @return - 合并后的配置
|
|
||||||
*/
|
|
||||||
export default (globalsConfig, config2 = {}) => {
|
|
||||||
const method = config2.method || globalsConfig.method || 'GET';
|
|
||||||
let config = {
|
|
||||||
baseURL: globalsConfig.baseURL || '',
|
|
||||||
method,
|
|
||||||
url: config2.url || '',
|
|
||||||
params: config2.params || {},
|
|
||||||
custom: { ...(globalsConfig.custom || {}), ...(config2.custom || {}) },
|
|
||||||
header: deepMerge(globalsConfig.header || {}, config2.header || {}),
|
|
||||||
};
|
|
||||||
const defaultToConfig2Keys = ['getTask', 'validateStatus'];
|
|
||||||
config = { ...config, ...mergeKeys(defaultToConfig2Keys, globalsConfig, config2) };
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-empty
|
|
||||||
if (method === 'DOWNLOAD') {
|
|
||||||
// #ifdef H5 || APP-PLUS
|
|
||||||
if (!isUndefined(config2.timeout)) {
|
|
||||||
config.timeout = config2.timeout;
|
|
||||||
} else if (!isUndefined(globalsConfig.timeout)) {
|
|
||||||
config.timeout = globalsConfig.timeout;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
} else if (method === 'UPLOAD') {
|
|
||||||
delete config.header['content-type'];
|
|
||||||
delete config.header['Content-Type'];
|
|
||||||
const uploadKeys = [
|
|
||||||
// #ifdef APP-PLUS || H5
|
|
||||||
'files',
|
|
||||||
// #endif
|
|
||||||
// #ifdef MP-ALIPAY
|
|
||||||
'fileType',
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
'file',
|
|
||||||
// #endif
|
|
||||||
'filePath',
|
|
||||||
'name',
|
|
||||||
// #ifdef H5 || APP-PLUS
|
|
||||||
'timeout',
|
|
||||||
// #endif
|
|
||||||
'formData',
|
|
||||||
];
|
|
||||||
uploadKeys.forEach((prop) => {
|
|
||||||
if (!isUndefined(config2[prop])) {
|
|
||||||
config[prop] = config2[prop];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
// #ifdef H5 || APP-PLUS
|
|
||||||
if (isUndefined(config.timeout) && !isUndefined(globalsConfig.timeout)) {
|
|
||||||
config.timeout = globalsConfig.timeout;
|
|
||||||
}
|
|
||||||
// #endif
|
|
||||||
} else {
|
|
||||||
const defaultsKeys = [
|
|
||||||
'data',
|
|
||||||
// #ifdef H5 || APP-PLUS || MP-ALIPAY || MP-WEIXIN
|
|
||||||
'timeout',
|
|
||||||
// #endif
|
|
||||||
'dataType',
|
|
||||||
// #ifndef MP-ALIPAY
|
|
||||||
'responseType',
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
'sslVerify',
|
|
||||||
// #endif
|
|
||||||
// #ifdef H5
|
|
||||||
'withCredentials',
|
|
||||||
// #endif
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
'firstIpv4',
|
|
||||||
// #endif
|
|
||||||
];
|
|
||||||
config = { ...config, ...mergeKeys(defaultsKeys, globalsConfig, config2) };
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
|
||||||
};
|
|
|
@ -1,16 +0,0 @@
|
||||||
/**
|
|
||||||
* Resolve or reject a Promise based on response status.
|
|
||||||
*
|
|
||||||
* @param {Function} resolve A function that resolves the promise.
|
|
||||||
* @param {Function} reject A function that rejects the promise.
|
|
||||||
* @param {object} response The response.
|
|
||||||
*/
|
|
||||||
export default function settle(resolve, reject, response) {
|
|
||||||
const { validateStatus } = response.config;
|
|
||||||
const status = response.statusCode;
|
|
||||||
if (status && (!validateStatus || validateStatus(status))) {
|
|
||||||
resolve(response);
|
|
||||||
} else {
|
|
||||||
reject(response);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,69 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
import * as utils from '../utils';
|
|
||||||
|
|
||||||
function encode(val) {
|
|
||||||
return encodeURIComponent(val)
|
|
||||||
.replace(/%40/gi, '@')
|
|
||||||
.replace(/%3A/gi, ':')
|
|
||||||
.replace(/%24/g, '$')
|
|
||||||
.replace(/%2C/gi, ',')
|
|
||||||
.replace(/%20/g, '+')
|
|
||||||
.replace(/%5B/gi, '[')
|
|
||||||
.replace(/%5D/gi, ']');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a URL by appending params to the end
|
|
||||||
*
|
|
||||||
* @param {string} url The base of the url (e.g., http://www.google.com)
|
|
||||||
* @param {object} [params] The params to be appended
|
|
||||||
* @returns {string} The formatted url
|
|
||||||
*/
|
|
||||||
export default function buildURL(url, params) {
|
|
||||||
/* eslint no-param-reassign:0 */
|
|
||||||
if (!params) {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
let serializedParams;
|
|
||||||
if (utils.isURLSearchParams(params)) {
|
|
||||||
serializedParams = params.toString();
|
|
||||||
} else {
|
|
||||||
const parts = [];
|
|
||||||
|
|
||||||
utils.forEach(params, (val, key) => {
|
|
||||||
if (val === null || typeof val === 'undefined') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (utils.isArray(val)) {
|
|
||||||
key = `${key}[]`;
|
|
||||||
} else {
|
|
||||||
val = [val];
|
|
||||||
}
|
|
||||||
|
|
||||||
utils.forEach(val, (v) => {
|
|
||||||
if (utils.isDate(v)) {
|
|
||||||
v = v.toISOString();
|
|
||||||
} else if (utils.isObject(v)) {
|
|
||||||
v = JSON.stringify(v);
|
|
||||||
}
|
|
||||||
parts.push(`${encode(key)}=${encode(v)}`);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
serializedParams = parts.join('&');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serializedParams) {
|
|
||||||
const hashmarkIndex = url.indexOf('#');
|
|
||||||
if (hashmarkIndex !== -1) {
|
|
||||||
url = url.slice(0, hashmarkIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new URL by combining the specified URLs
|
|
||||||
*
|
|
||||||
* @param {string} baseURL The base URL
|
|
||||||
* @param {string} relativeURL The relative URL
|
|
||||||
* @returns {string} The combined URL
|
|
||||||
*/
|
|
||||||
export default function combineURLs(baseURL, relativeURL) {
|
|
||||||
return relativeURL
|
|
||||||
? `${baseURL.replace(/\/+$/, '')}/${relativeURL.replace(/^\/+/, '')}`
|
|
||||||
: baseURL;
|
|
||||||
}
|
|
|
@ -1,14 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines whether the specified URL is absolute
|
|
||||||
*
|
|
||||||
* @param {string} url The URL to test
|
|
||||||
* @returns {boolean} True if the specified URL is absolute, otherwise false
|
|
||||||
*/
|
|
||||||
export default function isAbsoluteURL(url) {
|
|
||||||
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
|
|
||||||
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
|
|
||||||
// by any combination of letters, digits, plus, period, or hyphen.
|
|
||||||
return /^([a-z][a-z\d+\-.]*:)?\/\//i.test(url);
|
|
||||||
}
|
|
|
@ -1,116 +0,0 @@
|
||||||
type AnyObject = Record<string | number | symbol, any>
|
|
||||||
type HttpPromise<T> = Promise<HttpResponse<T>>;
|
|
||||||
type Tasks = UniApp.RequestTask | UniApp.UploadTask | UniApp.DownloadTask
|
|
||||||
export interface RequestTask {
|
|
||||||
abort: () => void;
|
|
||||||
offHeadersReceived: () => void;
|
|
||||||
onHeadersReceived: () => void;
|
|
||||||
}
|
|
||||||
export interface HttpRequestConfig<T = Tasks> {
|
|
||||||
/** 请求基地址 */
|
|
||||||
baseURL?: string;
|
|
||||||
/** 请求服务器接口地址 */
|
|
||||||
url?: string;
|
|
||||||
|
|
||||||
/** 请求查询参数,自动拼接为查询字符串 */
|
|
||||||
params?: AnyObject;
|
|
||||||
/** 请求体参数 */
|
|
||||||
data?: AnyObject;
|
|
||||||
|
|
||||||
/** 文件对应的 key */
|
|
||||||
name?: string;
|
|
||||||
/** HTTP 请求中其他额外的 form data */
|
|
||||||
formData?: AnyObject;
|
|
||||||
/** 要上传文件资源的路径。 */
|
|
||||||
filePath?: string;
|
|
||||||
/** 需要上传的文件列表。使用 files 时,filePath 和 name 不生效,App、H5( 2.6.15+) */
|
|
||||||
files?: Array<{
|
|
||||||
name?: string;
|
|
||||||
file?: File;
|
|
||||||
uri: string;
|
|
||||||
}>;
|
|
||||||
/** 要上传的文件对象,仅H5(2.6.15+)支持 */
|
|
||||||
file?: File;
|
|
||||||
|
|
||||||
/** 请求头信息 */
|
|
||||||
header?: AnyObject;
|
|
||||||
/** 请求方式 */
|
|
||||||
method?: "GET" | "POST" | "PUT" | "DELETE" | "CONNECT" | "HEAD" | "OPTIONS" | "TRACE" | "UPLOAD" | "DOWNLOAD";
|
|
||||||
/** 如果设为 json,会尝试对返回的数据做一次 JSON.parse */
|
|
||||||
dataType?: string;
|
|
||||||
/** 设置响应的数据类型,支付宝小程序不支持 */
|
|
||||||
responseType?: "text" | "arraybuffer";
|
|
||||||
/** 自定义参数 */
|
|
||||||
custom?: AnyObject;
|
|
||||||
/** 超时时间,仅微信小程序(2.10.0)、支付宝小程序支持 */
|
|
||||||
timeout?: number;
|
|
||||||
/** DNS解析时优先使用ipv4,仅 App-Android 支持 (HBuilderX 2.8.0+) */
|
|
||||||
firstIpv4?: boolean;
|
|
||||||
/** 验证 ssl 证书 仅5+App安卓端支持(HBuilderX 2.3.3+) */
|
|
||||||
sslVerify?: boolean;
|
|
||||||
/** 跨域请求时是否携带凭证(cookies)仅H5支持(HBuilderX 2.6.15+) */
|
|
||||||
withCredentials?: boolean;
|
|
||||||
|
|
||||||
/** 返回当前请求的task, options。请勿在此处修改options。 */
|
|
||||||
getTask?: (task: T, options: HttpRequestConfig<T>) => void;
|
|
||||||
/** 全局自定义验证器 */
|
|
||||||
validateStatus?: (statusCode: number) => boolean | void;
|
|
||||||
}
|
|
||||||
export interface HttpResponse<T = any> {
|
|
||||||
config: HttpRequestConfig;
|
|
||||||
statusCode: number;
|
|
||||||
cookies: Array<string>;
|
|
||||||
data: T;
|
|
||||||
errMsg: string;
|
|
||||||
header: AnyObject;
|
|
||||||
}
|
|
||||||
export interface HttpUploadResponse<T = any> {
|
|
||||||
config: HttpRequestConfig;
|
|
||||||
statusCode: number;
|
|
||||||
data: T;
|
|
||||||
errMsg: string;
|
|
||||||
}
|
|
||||||
export interface HttpDownloadResponse extends HttpResponse {
|
|
||||||
tempFilePath: string;
|
|
||||||
}
|
|
||||||
export interface HttpError {
|
|
||||||
config: HttpRequestConfig;
|
|
||||||
statusCode?: number;
|
|
||||||
cookies?: Array<string>;
|
|
||||||
data?: any;
|
|
||||||
errMsg: string;
|
|
||||||
header?: AnyObject;
|
|
||||||
}
|
|
||||||
export interface HttpInterceptorManager<V, E = V> {
|
|
||||||
use(
|
|
||||||
onFulfilled?: (config: V) => Promise<V> | V,
|
|
||||||
onRejected?: (config: E) => Promise<E> | E
|
|
||||||
): void;
|
|
||||||
eject(id: number): void;
|
|
||||||
}
|
|
||||||
export abstract class HttpRequestAbstract {
|
|
||||||
constructor(config?: HttpRequestConfig);
|
|
||||||
config: HttpRequestConfig;
|
|
||||||
interceptors: {
|
|
||||||
request: HttpInterceptorManager<HttpRequestConfig, HttpRequestConfig>;
|
|
||||||
response: HttpInterceptorManager<HttpResponse, HttpError>;
|
|
||||||
}
|
|
||||||
middleware<T = any>(config: HttpRequestConfig): HttpPromise<T>;
|
|
||||||
request<T = any>(config: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
get<T = any>(url: string, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
upload<T = any>(url: string, config?: HttpRequestConfig<UniApp.UploadTask>): HttpPromise<T>;
|
|
||||||
delete<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
head<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
post<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
put<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
connect<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
options<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
trace<T = any>(url: string, data?: AnyObject, config?: HttpRequestConfig<UniApp.RequestTask>): HttpPromise<T>;
|
|
||||||
|
|
||||||
download(url: string, config?: HttpRequestConfig<UniApp.DownloadTask>): Promise<HttpDownloadResponse>;
|
|
||||||
|
|
||||||
setConfig(onSend: (config: HttpRequestConfig) => HttpRequestConfig): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare class HttpRequest extends HttpRequestAbstract { }
|
|
||||||
export default HttpRequest;
|
|
|
@ -1,3 +0,0 @@
|
||||||
import Request from './core/Request';
|
|
||||||
|
|
||||||
export default Request;
|
|
|
@ -1,131 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
// utils is a library of generic helper functions non-specific to axios
|
|
||||||
|
|
||||||
const { toString } = Object.prototype;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a value is an Array
|
|
||||||
*
|
|
||||||
* @param {Object} val The value to test
|
|
||||||
* @returns {boolean} True if value is an Array, otherwise false
|
|
||||||
*/
|
|
||||||
export function isArray(val) {
|
|
||||||
return toString.call(val) === '[object Array]';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a value is an Object
|
|
||||||
*
|
|
||||||
* @param {Object} val The value to test
|
|
||||||
* @returns {boolean} True if value is an Object, otherwise false
|
|
||||||
*/
|
|
||||||
export function isObject(val) {
|
|
||||||
return val !== null && typeof val === 'object';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a value is a Date
|
|
||||||
*
|
|
||||||
* @param {Object} val The value to test
|
|
||||||
* @returns {boolean} True if value is a Date, otherwise false
|
|
||||||
*/
|
|
||||||
export function isDate(val) {
|
|
||||||
return toString.call(val) === '[object Date]';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if a value is a URLSearchParams object
|
|
||||||
*
|
|
||||||
* @param {Object} val The value to test
|
|
||||||
* @returns {boolean} True if value is a URLSearchParams object, otherwise false
|
|
||||||
*/
|
|
||||||
export function isURLSearchParams(val) {
|
|
||||||
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Iterate over an Array or an Object invoking a function for each item.
|
|
||||||
*
|
|
||||||
* If `obj` is an Array callback will be called passing
|
|
||||||
* the value, index, and complete array for each item.
|
|
||||||
*
|
|
||||||
* If 'obj' is an Object callback will be called passing
|
|
||||||
* the value, key, and complete object for each property.
|
|
||||||
*
|
|
||||||
* @param {Object|Array} obj The object to iterate
|
|
||||||
* @param {Function} fn The callback to invoke for each item
|
|
||||||
*/
|
|
||||||
export function forEach(obj, fn) {
|
|
||||||
// Don't bother if no value provided
|
|
||||||
if (obj === null || typeof obj === 'undefined') {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force an array if not already something iterable
|
|
||||||
if (typeof obj !== 'object') {
|
|
||||||
/* eslint no-param-reassign:0 */
|
|
||||||
obj = [obj];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isArray(obj)) {
|
|
||||||
// Iterate over array values
|
|
||||||
for (let i = 0, l = obj.length; i < l; i++) {
|
|
||||||
fn.call(null, obj[i], i, obj);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Iterate over object keys
|
|
||||||
for (const key in obj) {
|
|
||||||
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
||||||
fn.call(null, obj[key], key, obj);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否为boolean 值
|
|
||||||
* @param val
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
export function isBoolean(val) {
|
|
||||||
return typeof val === 'boolean';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否为真正的对象{} new Object
|
|
||||||
* @param {any} obj - 检测的对象
|
|
||||||
* @returns {boolean}
|
|
||||||
*/
|
|
||||||
export function isPlainObject(obj) {
|
|
||||||
return Object.prototype.toString.call(obj) === '[object Object]';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Function equal to merge with the difference being that no reference
|
|
||||||
* to original objects is kept.
|
|
||||||
*
|
|
||||||
* @see merge
|
|
||||||
* @param {Object} obj1 Object to merge
|
|
||||||
* @returns {Object} Result of all merge properties
|
|
||||||
*/
|
|
||||||
export function deepMerge(/* obj1, obj2, obj3, ... */) {
|
|
||||||
const result = {};
|
|
||||||
function assignValue(val, key) {
|
|
||||||
if (typeof result[key] === 'object' && typeof val === 'object') {
|
|
||||||
result[key] = deepMerge(result[key], val);
|
|
||||||
} else if (typeof val === 'object') {
|
|
||||||
result[key] = deepMerge({}, val);
|
|
||||||
} else {
|
|
||||||
result[key] = val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (let i = 0, l = arguments.length; i < l; i++) {
|
|
||||||
forEach(arguments[i], assignValue);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isUndefined(val) {
|
|
||||||
return typeof val === 'undefined';
|
|
||||||
}
|
|
|
@ -1,260 +0,0 @@
|
||||||
/* eslint-disable */
|
|
||||||
var clone = (function () {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
function _instanceof(obj, type) {
|
|
||||||
return type != null && obj instanceof type;
|
|
||||||
}
|
|
||||||
|
|
||||||
var nativeMap;
|
|
||||||
try {
|
|
||||||
nativeMap = Map;
|
|
||||||
} catch (_) {
|
|
||||||
// maybe a reference error because no `Map`. Give it a dummy value that no
|
|
||||||
// value will ever be an instanceof.
|
|
||||||
nativeMap = function () {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var nativeSet;
|
|
||||||
try {
|
|
||||||
nativeSet = Set;
|
|
||||||
} catch (_) {
|
|
||||||
nativeSet = function () {};
|
|
||||||
}
|
|
||||||
|
|
||||||
var nativePromise;
|
|
||||||
try {
|
|
||||||
nativePromise = Promise;
|
|
||||||
} catch (_) {
|
|
||||||
nativePromise = function () {};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Clones (copies) an Object using deep copying.
|
|
||||||
*
|
|
||||||
* This function supports circular references by default, but if you are certain
|
|
||||||
* there are no circular references in your object, you can save some CPU time
|
|
||||||
* by calling clone(obj, false).
|
|
||||||
*
|
|
||||||
* Caution: if `circular` is false and `parent` contains circular references,
|
|
||||||
* your program may enter an infinite loop and crash.
|
|
||||||
*
|
|
||||||
* @param `parent` - the object to be cloned
|
|
||||||
* @param `circular` - set to true if the object to be cloned may contain
|
|
||||||
* circular references. (optional - true by default)
|
|
||||||
* @param `depth` - set to a number if the object is only to be cloned to
|
|
||||||
* a particular depth. (optional - defaults to Infinity)
|
|
||||||
* @param `prototype` - sets the prototype to be used when cloning an object.
|
|
||||||
* (optional - defaults to parent prototype).
|
|
||||||
* @param `includeNonEnumerable` - set to true if the non-enumerable properties
|
|
||||||
* should be cloned as well. Non-enumerable properties on the prototype
|
|
||||||
* chain will be ignored. (optional - false by default)
|
|
||||||
*/
|
|
||||||
function clone(parent, circular, depth, prototype, includeNonEnumerable) {
|
|
||||||
if (typeof circular === 'object') {
|
|
||||||
depth = circular.depth;
|
|
||||||
prototype = circular.prototype;
|
|
||||||
includeNonEnumerable = circular.includeNonEnumerable;
|
|
||||||
circular = circular.circular;
|
|
||||||
}
|
|
||||||
// maintain two arrays for circular references, where corresponding parents
|
|
||||||
// and children have the same index
|
|
||||||
var allParents = [];
|
|
||||||
var allChildren = [];
|
|
||||||
|
|
||||||
var useBuffer = typeof Buffer != 'undefined';
|
|
||||||
|
|
||||||
if (typeof circular == 'undefined') circular = true;
|
|
||||||
|
|
||||||
if (typeof depth == 'undefined') depth = Infinity;
|
|
||||||
|
|
||||||
// recurse this function so we don't reset allParents and allChildren
|
|
||||||
function _clone(parent, depth) {
|
|
||||||
// cloning null always returns null
|
|
||||||
if (parent === null) return null;
|
|
||||||
|
|
||||||
if (depth === 0) return parent;
|
|
||||||
|
|
||||||
var child;
|
|
||||||
var proto;
|
|
||||||
if (typeof parent != 'object') {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_instanceof(parent, nativeMap)) {
|
|
||||||
child = new nativeMap();
|
|
||||||
} else if (_instanceof(parent, nativeSet)) {
|
|
||||||
child = new nativeSet();
|
|
||||||
} else if (_instanceof(parent, nativePromise)) {
|
|
||||||
child = new nativePromise(function (resolve, reject) {
|
|
||||||
parent.then(
|
|
||||||
function (value) {
|
|
||||||
resolve(_clone(value, depth - 1));
|
|
||||||
},
|
|
||||||
function (err) {
|
|
||||||
reject(_clone(err, depth - 1));
|
|
||||||
},
|
|
||||||
);
|
|
||||||
});
|
|
||||||
} else if (clone.__isArray(parent)) {
|
|
||||||
child = [];
|
|
||||||
} else if (clone.__isRegExp(parent)) {
|
|
||||||
child = new RegExp(parent.source, __getRegExpFlags(parent));
|
|
||||||
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
|
|
||||||
} else if (clone.__isDate(parent)) {
|
|
||||||
child = new Date(parent.getTime());
|
|
||||||
} else if (useBuffer && Buffer.isBuffer(parent)) {
|
|
||||||
if (Buffer.from) {
|
|
||||||
// Node.js >= 5.10.0
|
|
||||||
child = Buffer.from(parent);
|
|
||||||
} else {
|
|
||||||
// Older Node.js versions
|
|
||||||
child = new Buffer(parent.length);
|
|
||||||
parent.copy(child);
|
|
||||||
}
|
|
||||||
return child;
|
|
||||||
} else if (_instanceof(parent, Error)) {
|
|
||||||
child = Object.create(parent);
|
|
||||||
} else {
|
|
||||||
if (typeof prototype == 'undefined') {
|
|
||||||
proto = Object.getPrototypeOf(parent);
|
|
||||||
child = Object.create(proto);
|
|
||||||
} else {
|
|
||||||
child = Object.create(prototype);
|
|
||||||
proto = prototype;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (circular) {
|
|
||||||
var index = allParents.indexOf(parent);
|
|
||||||
|
|
||||||
if (index != -1) {
|
|
||||||
return allChildren[index];
|
|
||||||
}
|
|
||||||
allParents.push(parent);
|
|
||||||
allChildren.push(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_instanceof(parent, nativeMap)) {
|
|
||||||
parent.forEach(function (value, key) {
|
|
||||||
var keyChild = _clone(key, depth - 1);
|
|
||||||
var valueChild = _clone(value, depth - 1);
|
|
||||||
child.set(keyChild, valueChild);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (_instanceof(parent, nativeSet)) {
|
|
||||||
parent.forEach(function (value) {
|
|
||||||
var entryChild = _clone(value, depth - 1);
|
|
||||||
child.add(entryChild);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i in parent) {
|
|
||||||
var attrs = Object.getOwnPropertyDescriptor(parent, i);
|
|
||||||
if (attrs) {
|
|
||||||
child[i] = _clone(parent[i], depth - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
var objProperty = Object.getOwnPropertyDescriptor(parent, i);
|
|
||||||
if (objProperty.set === 'undefined') {
|
|
||||||
// no setter defined. Skip cloning this property
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
child[i] = _clone(parent[i], depth - 1);
|
|
||||||
} catch (e) {
|
|
||||||
if (e instanceof TypeError) {
|
|
||||||
// when in strict mode, TypeError will be thrown if child[i] property only has a getter
|
|
||||||
// we can't do anything about this, other than inform the user that this property cannot be set.
|
|
||||||
continue;
|
|
||||||
} else if (e instanceof ReferenceError) {
|
|
||||||
//this may happen in non strict mode
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Object.getOwnPropertySymbols) {
|
|
||||||
var symbols = Object.getOwnPropertySymbols(parent);
|
|
||||||
for (var i = 0; i < symbols.length; i++) {
|
|
||||||
// Don't need to worry about cloning a symbol because it is a primitive,
|
|
||||||
// like a number or string.
|
|
||||||
var symbol = symbols[i];
|
|
||||||
var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);
|
|
||||||
if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
child[symbol] = _clone(parent[symbol], depth - 1);
|
|
||||||
Object.defineProperty(child, symbol, descriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (includeNonEnumerable) {
|
|
||||||
var allPropertyNames = Object.getOwnPropertyNames(parent);
|
|
||||||
for (var i = 0; i < allPropertyNames.length; i++) {
|
|
||||||
var propertyName = allPropertyNames[i];
|
|
||||||
var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);
|
|
||||||
if (descriptor && descriptor.enumerable) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
child[propertyName] = _clone(parent[propertyName], depth - 1);
|
|
||||||
Object.defineProperty(child, propertyName, descriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return child;
|
|
||||||
}
|
|
||||||
|
|
||||||
return _clone(parent, depth);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Simple flat clone using prototype, accepts only objects, usefull for property
|
|
||||||
* override on FLAT configuration object (no nested props).
|
|
||||||
*
|
|
||||||
* USE WITH CAUTION! This may not behave as you wish if you do not know how this
|
|
||||||
* works.
|
|
||||||
*/
|
|
||||||
clone.clonePrototype = function clonePrototype(parent) {
|
|
||||||
if (parent === null) return null;
|
|
||||||
|
|
||||||
var c = function () {};
|
|
||||||
c.prototype = parent;
|
|
||||||
return new c();
|
|
||||||
};
|
|
||||||
|
|
||||||
// private utility functions
|
|
||||||
|
|
||||||
function __objToStr(o) {
|
|
||||||
return Object.prototype.toString.call(o);
|
|
||||||
}
|
|
||||||
clone.__objToStr = __objToStr;
|
|
||||||
|
|
||||||
function __isDate(o) {
|
|
||||||
return typeof o === 'object' && __objToStr(o) === '[object Date]';
|
|
||||||
}
|
|
||||||
clone.__isDate = __isDate;
|
|
||||||
|
|
||||||
function __isArray(o) {
|
|
||||||
return typeof o === 'object' && __objToStr(o) === '[object Array]';
|
|
||||||
}
|
|
||||||
clone.__isArray = __isArray;
|
|
||||||
|
|
||||||
function __isRegExp(o) {
|
|
||||||
return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
|
|
||||||
}
|
|
||||||
clone.__isRegExp = __isRegExp;
|
|
||||||
|
|
||||||
function __getRegExpFlags(re) {
|
|
||||||
var flags = '';
|
|
||||||
if (re.global) flags += 'g';
|
|
||||||
if (re.ignoreCase) flags += 'i';
|
|
||||||
if (re.multiline) flags += 'm';
|
|
||||||
return flags;
|
|
||||||
}
|
|
||||||
clone.__getRegExpFlags = __getRegExpFlags;
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
})();
|
|
||||||
|
|
||||||
export default clone;
|
|
|
@ -3,7 +3,7 @@
|
||||||
* @description api模块管理,loading配置,请求拦截,错误处理
|
* @description api模块管理,loading配置,请求拦截,错误处理
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Request from '@/sheep/libs/luch-request/core/Request';
|
import Request from 'luch-request';
|
||||||
import { baseUrl, apiPath } from '@/sheep/config';
|
import { baseUrl, apiPath } from '@/sheep/config';
|
||||||
import $store from '@/sheep/store';
|
import $store from '@/sheep/store';
|
||||||
import $platform from '@/sheep/platform';
|
import $platform from '@/sheep/platform';
|
||||||
|
|
Loading…
Reference in New Issue