pull/8/head
kele 2023-01-10 18:24:52 +08:00
commit 43d23ed9b7
21 changed files with 38 additions and 1152 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ deploy.sh
**/.DS_Store **/.DS_Store
.env .env
yarn.lock yarn.lock
package-lock.json

View File

@ -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",

View File

@ -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"

View File

@ -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);

View File

@ -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;
} }

View File

@ -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);
}
});

View File

@ -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;

View File

@ -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默认60000H5(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
*/

View File

@ -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;
}

View File

@ -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;
},
};

View File

@ -1,3 +0,0 @@
import adapter from '../adapters/index';
export default (config) => adapter(config);

View File

@ -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;
};

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;
}>;
/** 要上传的文件对象仅H52.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;

View File

@ -1,3 +0,0 @@
import Request from './core/Request';
export default Request;

View File

@ -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';
}

View File

@ -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;

View File

@ -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';