import Taro from '@tarojs/taro'
|
import Hashes from 'jshashes'
|
// import crypto from 'crypto';
|
import hmacSHA256 from 'crypto-js/hmac-sha256';
|
import encHex from 'crypto-js/enc-hex';
|
import { _XP_SECRET } from '../constants/app';
|
import { jumpTo } from './jump';
|
|
// 由于加密库体积太大,会导致开发过程中无法预览,所以可注释掉上面两行而用下面这行
|
// const Hashes = {MD5: function(){this.hex = function(){}}, Base64: function(){return {encode: function(){}}}}
|
// const crypto = {createHmac: function(){return {update: function(){return {digest: function(){return ''}}}}}}
|
|
const MD5 = new Hashes.MD5;
|
const HashesBase64 = new Hashes.Base64;
|
|
const ENV = process.env.TARO_ENV;
|
|
export const HomePath = {
|
// weapp: '/pages/home/index',
|
weapp: '/pages/xpeng/index',
|
};
|
|
// 工具
|
|
// 校验手机号
|
export function checkPhone(phone) {
|
return /^1\d{10}$/.test(phone)
|
}
|
|
// 获取本地存储数据
|
export function getStorage(key, { retryNumIfEmpty = 0 } = {}) {
|
if (retryNumIfEmpty === 0) return Taro.getStorage({ key }).then(res => res.data).catch(() => '')
|
else {
|
return new Promise(resolve => {
|
let retryNum = 0;
|
const fn = function () {
|
retryNum++;
|
const timeout = setTimeout(() => {
|
Taro.getStorage({ key }).then(res => {
|
resolve(res.data);
|
}).catch(() => {
|
if (retryNum > retryNumIfEmpty) {
|
resolve('')
|
} else {
|
fn();
|
}
|
}).finally(() => clearTimeout(timeout))
|
}, 1000)
|
}
|
Taro.getStorage({ key }).then(res => {
|
resolve(res.data);
|
}).catch(() => {
|
fn();
|
})
|
})
|
}
|
}
|
|
// 生成随机的设备唯一码存本地
|
export function getOrCreateLocalId() {
|
return getStorage('di').then(di => {
|
if (di) {
|
return di;
|
} else {
|
const diviceId = `${(Math.random() * 1000000).toString(16)}_${new Date().getTime()}`;
|
Taro.setStorage({ key: 'di', data: diviceId });
|
return diviceId;
|
}
|
})
|
}
|
|
// 返回xp-client字符串
|
export function getXpClientString(obj) {
|
return `di=${obj.di};ve=${obj.ve};pn=${obj.pn};br=${obj.br};mo=${obj.mo};sv=${obj.sv};nt=${obj.nt};t=${obj.t};st=${obj.st};re=${obj.re}`
|
}
|
|
export const parseObjIntoQuery = (obj, spliter = '&') => {
|
const keys = Object.keys(obj)
|
if (keys.length <= 0) { return }
|
|
return keys.map((key) => {
|
return `${key}=${obj[key]}`
|
}).join(spliter);
|
}
|
|
|
/**
|
* 生成自增值
|
*/
|
export function getStamp() {
|
const date = new Date().getTime();
|
const r = ~~(Math.random() * 10000)
|
return `${date}_${r}`
|
}
|
|
// 对象排序并且排序后使用&连接
|
export function sortAndJoinObj(obj: Record<string, any> = {}): string {
|
if (!obj || typeof obj !== 'object' || Array.isArray(obj)) return '';
|
return Object.keys(obj)
|
.sort()
|
.map(key => `${key}=${obj[key]}`)
|
.join('&');
|
}
|
|
/**
|
* 定义对象排序方法
|
*/
|
export function objectSort(parames, { keyUpperCase = true } = {}) {
|
if (typeof parames !== 'object' || Array.isArray(parames)) return parames; // 非对象原样返回
|
const newkeys = Object.keys(parames).sort();
|
const newObj = {};
|
for (let i = 0; i < newkeys.length; i++) {
|
// key转大写
|
const key = keyUpperCase ? newkeys[i].toUpperCase() : newkeys[i];
|
newObj[key] = parames[newkeys[i]];
|
}
|
return newObj;
|
}
|
|
/**
|
* 计算签名方法
|
*/
|
export function makeSign(method, params, content, secret = _XP_SECRET) {
|
let sign = '';
|
let parm = '';
|
params = objectSort(params);
|
for (const i in params) {
|
const j = params[i];
|
parm += i + '=' + j + '&';
|
}
|
parm = parm.slice(0, -1);
|
parm.trim();
|
let content_MD5 = ''
|
if (content && String(content) !== '{}') {
|
content_MD5 = MD5.hex(JSON.stringify(objectSort(content, { keyUpperCase: false }))); // content 也要排序,避免中间平台的干扰,例如 小红书 iOS 端发送的请求顺序就和我们传入的不一致
|
}
|
let ass = ''
|
if (method == 'POST' || method == 'PUT') {
|
ass = `${method}&${parm}&${content_MD5}`;
|
}
|
if (method == 'GET') {
|
ass = `${method}&${parm}&${content && Object.keys(content).length > 0 ? sortAndJoinObj(content) + '&' : ''}`;
|
}
|
const afterUtf8 = utf8Encode(ass);
|
// const third = crypto.createHmac('sha256', secret).update(afterUtf8).digest('hex');
|
// console.log('crypto---------------------------');
|
// console.log(third);
|
|
const third = encHex.stringify(hmacSHA256(afterUtf8, secret));
|
// console.log('crypto-js---------------------------');
|
// console.log(ass);
|
|
sign = third.toLowerCase();
|
return sign;
|
}
|
|
// 转base64
|
export function toBase64(data: any) {
|
const str = HashesBase64.encode(JSON.stringify(data));
|
|
return str;
|
}
|
|
// 转utf8
|
export function utf8Encode(str) {
|
let x, y, output = '',
|
i = -1,
|
l;
|
|
if (str && str.length) {
|
l = str.length;
|
while ((i += 1) < l) {
|
/* Decode utf-16 surrogate pairs */
|
x = str.charCodeAt(i);
|
y = i + 1 < l ? str.charCodeAt(i + 1) : 0;
|
if (0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
|
x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
|
i += 1;
|
}
|
/* Encode output as utf-8 */
|
if (x <= 0x7F) {
|
output += String.fromCharCode(x);
|
} else if (x <= 0x7FF) {
|
output += String.fromCharCode(0xC0 | ((x >>> 6) & 0x1F),
|
0x80 | (x & 0x3F));
|
} else if (x <= 0xFFFF) {
|
output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
|
0x80 | ((x >>> 6) & 0x3F),
|
0x80 | (x & 0x3F));
|
} else if (x <= 0x1FFFFF) {
|
output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
|
0x80 | ((x >>> 12) & 0x3F),
|
0x80 | ((x >>> 6) & 0x3F),
|
0x80 | (x & 0x3F));
|
}
|
}
|
}
|
return output;
|
}
|
|
/**
|
* 函数防抖
|
* @param fn 需要进行防抖操作的事件函数
|
* @param interval 间隔时间
|
* @returns {Function}
|
*/
|
export function debounce(fn, interval) {
|
let timer;
|
const gapTime = interval || 1000; //间隔时间,如果interval不传,则默认1000ms
|
return function () {
|
clearTimeout(timer);
|
const context = this;
|
const args = arguments; //保存此处的arguments,因为setTimeout是全局的,arguments无法在回调函数中获取,此处为闭包。
|
timer = setTimeout(function () {
|
fn.apply(context, args); //args是事件处理函数默认事件参数event call绑定当前page对象
|
}, gapTime);
|
};
|
}
|
|
/**
|
* 将 hex (如 #ffffff) 变成 grbc (如 rgba(255,255,255,1))
|
*/
|
export function hexToRgbA(hex, alpha) {
|
let c;
|
if (/^#([A-Fa-f0-9]{3}){1,2}$/.test(hex)) {
|
c = hex.substring(1).split('');
|
if (c.length == 3) {
|
c = [c[0], c[0], c[1], c[1], c[2], c[2]];
|
}
|
c = '0x' + c.join('');
|
return 'rgba(' + [(c >> 16) & 255, (c >> 8) & 255, c & 255].join(',') + `,${alpha === undefined ? 1 : alpha})`;
|
}
|
return hex;
|
}
|
|
export function getPageOptions(page) {
|
const options = page.options || {};
|
if (ENV === 'alipay') {
|
// 目前支付宝 options 返回了 {}, 暂时用 page.$taroParams 兼容一下
|
const taroParams = { ...page.$taroParams };
|
delete taroParams.$taroTimestamp;
|
return { ...options, ...taroParams };
|
}
|
return options;
|
}
|
|
/**
|
* 获取当前url(带参数)
|
*/
|
export function getCurrentUrl() {
|
const pages = Taro.getCurrentPages()
|
if (pages.length <= 0) {
|
return ''
|
}
|
|
const page = pages[pages.length - 1] || {};
|
const options = getPageOptions(page);
|
const queryKeys = Object.keys(options).filter(key => {
|
return key !== '__key_';
|
}); // __key_ 为内部key,需要过滤掉
|
const url = page.route + (queryKeys.length > 0 ? '?' + queryKeys.map(key => `${key}=${options[key]}`).join('&') : '')
|
return url;
|
}
|
|
/**
|
* 获取当前query参数
|
*/
|
export function getCurrentQueryStr() {
|
const pages = Taro.getCurrentPages()
|
if (pages.length <= 0) {
|
return ''
|
}
|
|
const page = pages[pages.length - 1] || {};
|
const options = getPageOptions(page);
|
const queryKeys = Object.keys(options).filter(key => {
|
return key !== '__key_' && key !== 'uid' && key !== 'ls' && key !== 'code'
|
}); // __key_ 为内部key,其余为小程序向webview透传的字段,不适合向外传播,需要过滤掉
|
const query = queryKeys.length > 0 ? queryKeys.map(key => `${key}=${options[key]}`).join('&') : ''
|
return query;
|
}
|
|
/**
|
* 移除 url 中的查询参数
|
*/
|
export function removeQs(url: string): string {
|
if (typeof url !== 'string') return url;
|
return url.split('?')[0];
|
}
|
|
/**
|
* 更新或补充当前页面url上的参数
|
*/
|
export function updateURL(param) {
|
const pages = Taro.getCurrentPages();
|
if (pages.length <= 0) {
|
return ''
|
}
|
const page = pages[pages.length - 1];
|
const options = getPageOptions(page);
|
const url = '/' + page.route + '?' + parseObjIntoQuery({ ...options, ...param })
|
console.log(url)
|
return url;
|
}
|
|
/**
|
* 返回先打开首页, 再打开当前页的Url
|
*/
|
export function shareHomeUrl(qId = '1', param = {}) {
|
const pages = Taro.getCurrentPages();
|
if (pages.length <= 0) {
|
return ''
|
}
|
const page = pages[pages.length - 1];
|
const options = getPageOptions(page);
|
const queryStr = parseObjIntoQuery({ ...options, ...param });
|
const url = `${HomePath[ENV]}?qId=${qId}${queryStr ? '&qUrl=' + encodeURIComponent(queryStr) : ''}`;
|
console.log(url)
|
return url;
|
}
|
|
// 把 object 转成 key=value&key2=value2
|
export function stringifyQuery(obj: any) {
|
let search = '';
|
Object.keys(obj).forEach(key => {
|
// 过滤taro自带的参数
|
if (key === '$taroTimestamp') {
|
return
|
}
|
if (search) {
|
search += `&${key}=${obj[key]}`
|
} else {
|
search += `${key}=${obj[key]}`
|
}
|
|
});
|
return search;
|
}
|
|
// 将 key=value&key2=value2 这样的字符串处理成对象
|
export function parseQuery(query: string) {
|
return query.split('&').reduce((re, item) => {
|
const [key, value] = item.split('=');
|
re[key] = value;
|
return re;
|
}, {});
|
}
|
|
/**
|
* 获取url上面query参数,返回参数的对象
|
* @param urlStr url
|
* @returns 返回query参数的数组
|
*/
|
export function getQueryObject(urlStr: string = ''): { [propName: string]: any } {
|
if (!urlStr || !urlStr.includes('?')) return {};
|
|
const query = urlStr.split('?')[1].replace('?', '');
|
const obj = {};
|
const reg = /([^?&=]+)=([^?&=]*)/g;
|
query.replace(reg, (_rs, $1, $2): any => {
|
const val = String($2);
|
obj[$1] = val;
|
});
|
return obj;
|
}
|
|
/**
|
* appId和域名的对应关系
|
*/
|
export function matchAppId(url) {
|
if (url && url.indexOf('//pre-share.ypeng.com') > -1) {
|
return 'xp_events';
|
}
|
if (url && url.indexOf('//share.ypeng.com') > -1) {
|
return 'xp_events';
|
}
|
if (url && url.indexOf('//events.xiaopeng.com') > -1) {
|
return 'xp_events';
|
}
|
if (url && url.indexOf('//event.cs-pre.xiaopeng.com') > -1) {
|
return 'xp_events';
|
}
|
|
if (url && url.indexOf('//www.cs-pre.xiaopeng.com') > -1) {
|
return 'xp_home_cms';
|
}
|
if (url && url.indexOf('//www.xiaopeng.com') > -1) {
|
return 'xp_home_cms';
|
}
|
|
if (url && url.indexOf('//mall.cs-pre.xiaopeng.com') > -1) {
|
return 'xp_market_new';
|
}
|
if (url && url.indexOf('//store.xiaopeng.com') > -1) {
|
return 'xp_market_new';
|
}
|
//积分中心跟任务中心用的同个域名 优先判断积分中心
|
|
if (url && url.indexOf('//xper.deploy-test.xiaopeng.com/credit') > -1) {
|
return 'xp_credit';
|
}
|
if (url && url.indexOf('//xper.xiaopeng.com/credit') > -1) {
|
return 'xp_credit';
|
}
|
|
if (url && url.indexOf('//xper.deploy-test.xiaopeng.com') > -1) {
|
return 'xp_xper';
|
}
|
if (url && url.indexOf('//xper.xiaopeng.com') > -1) {
|
return 'xp_xper';
|
}
|
|
if (url && url.indexOf('//pmall.cs-pre.xiaopeng.com') > -1) {
|
return 'xp_ppstore';
|
}
|
if (url && url.indexOf('//mall.xiaopeng.com') > -1) {
|
return 'xp_ppstore';
|
}
|
|
|
|
|
return '';
|
}
|
|
|
export function filterProvinceDetailByAreas(list, areas) {
|
if (!areas || !areas.length) {
|
return list;
|
}
|
const province = areas.map(item => item.provinceCode);
|
const provinceArray = province && province.length ? list.filter(item => province.includes(item.cityCode)) : list;
|
// console.log(provinceArray);
|
|
|
const city = areas.map(item => item.cityCode);
|
provinceArray.forEach(item => {
|
item.citys = city && city.length ? item.citys.filter(b => city.includes(b.cityCode)) : item.citys;
|
});
|
|
return provinceArray;
|
}
|
|
|
export function toH5(url, isLogin = true, noCarPlan = 1) {
|
if (isLogin) {
|
jumpTo({
|
url: `/pages/webpage/index?pageUrl=${encodeURIComponent(url)}` + (matchAppId(url) ? '&appId=' + matchAppId(url) : '') + (noCarPlan ? '' : '&noCarPlan=0'),
|
});
|
|
} else {
|
jumpTo({
|
url: `/pages/webpage/index?pageUrl=${encodeURIComponent(url)}` + (noCarPlan ? '' : '&noCarPlan=0'),
|
});
|
}
|
|
}
|
|
export function linkTypeHandle(linkType, linkUrl) {
|
if (linkType === 0) {
|
jumpTo({
|
url: `/pages/webpage/index?pageUrl=${encodeURIComponent(linkUrl)}` + (matchAppId(linkUrl) ? '&appId=' + matchAppId(linkUrl) : ''),
|
type: 'nav'
|
})
|
} else if (linkType === 1) {
|
jumpTo({
|
url: linkUrl,
|
type: 'nav'
|
})
|
} else if (linkType === 2) {
|
if (ENV !== 'weapp') {
|
jumpTo({
|
url: '/subPackages/pages/driveCopy/index?eventInfoCode=64jz91&ch=02592&ps=ma&carType=P7i',
|
type: 'nav'
|
});
|
return;
|
}
|
|
// @ts-ignore
|
wx.openChannelsLive({
|
finderUserName: linkUrl,
|
success: (res) => { console.log(res, '跳转直播成功') },
|
fail: (res) => {
|
Taro.showToast({
|
title: '请前往小鹏汽车视频号观看',
|
icon: 'none'
|
})
|
console.log(res, '跳转直播失败')
|
}
|
})
|
} else if (linkType === 3) {
|
if (ENV !== 'weapp') {
|
jumpTo({
|
url: '/subPackages/pages/driveCopy/index?eventInfoCode=64jz91&ch=02592&ps=ma&carType=P7i',
|
type: 'nav'
|
});
|
return;
|
}
|
|
// @ts-ignore
|
wx.openCustomerServiceChat({
|
extInfo: { url: linkUrl },
|
corpId: 'wwe04e18cdd5eb5101',
|
success: (res) => { console.log(res, '打开微信客服成功') },
|
fail: (res) => { console.log(res, '打开微信客服失败') },
|
})
|
} else if (linkType === 4) {
|
if (ENV !== 'weapp') {
|
jumpTo({
|
url: '/subPackages/pages/driveCopy/index?eventInfoCode=64jz91&ch=02592&ps=ma&carType=P7i',
|
type: 'nav'
|
});
|
return;
|
}
|
|
// @ts-ignore
|
// 跳转视频号主页
|
wx.openChannelsUserProfile({
|
finderUserName: linkUrl,
|
success: (res) => { console.log(res, '跳转视频号成功') },
|
fail: (res) => {
|
Taro.showToast({
|
title: '请前往小鹏汽车视频号观看',
|
icon: 'none'
|
})
|
console.log(res, '跳转视频号失败')
|
}
|
})
|
}
|
}
|
|
// 数字千分
|
export function priceFormat(num) {
|
const reg = /\d{1,3}(?=(\d{3})+$)/g;
|
return (num + '').replace(reg, '$&,');
|
};
|
|
// 秒转成分秒
|
export function realFormatSecond(second) {
|
var secondType = typeof second;
|
if (secondType === "number" || secondType === "string") {
|
second = parseInt(second);
|
var mimute = Math.floor(second / 60);
|
second = second - mimute * 60;
|
return ("0" + mimute).slice(-2) + ":" + ("0" + second).slice(-2);
|
} else {
|
return "00:00";
|
}
|
}
|
|
// 过万保留一位数
|
export function numberFormat(num) {
|
if (num < 9999) {
|
return num
|
} else {
|
return (num / 10000).toFixed(1) + 'W'
|
}
|
}
|
|
// 查看本地是否已有otp
|
export function checkOtp(autoLogin?, hideBack?) {
|
return new Promise((resolve) => {
|
// resolve(true)
|
getStorage('otp')
|
.then(res => {
|
resolve(res);
|
// 无otp,发起登录请求
|
if (!res && autoLogin) {
|
if (hideBack) {
|
jumpTo({ url: '/pages/user/login?hideBack=1' });
|
} else {
|
jumpTo({ url: '/pages/user/login' });
|
}
|
}
|
})
|
.catch(() => {
|
resolve('');
|
});
|
});
|
}
|
|
// 查看本地是否已有otp,没有则走登录流程,有则继续
|
let cacheLoginTime;
|
export function autoForceLogin(showDialog = true) {
|
const pages = Taro.getCurrentPages();
|
const page = pages[pages.length - 1];
|
|
if (page.data && page.data.loginSuccess === false) { // 如果在登录页没有允许授权
|
page.setData({ loginSuccess: '' });
|
return Promise.resolve(false);
|
}
|
|
const cacheT = cacheLoginTime;
|
if (cacheT && +new Date - cacheT < 1000 * 60 * 60 * 24) {
|
return Promise.resolve(false);
|
}
|
cacheLoginTime = +new Date();
|
return checkOtp(!showDialog).then(otp => {
|
return !otp;
|
});
|
}
|
|
/**
|
* @desc 根据对象数组中的指定属性进行数组元素排序
|
* @param objArr 要进行排序操作的对象数组
|
* @param attribute 排序属性
|
* @param orderFlag 方式标识,true 为正序 false 为倒序 默认为 true
|
* @returns 完成排序后的数组
|
*/
|
export function objectArraySortByAtr(objArr, attribute, orderFlag = true) {
|
function compare(key, sortFlag) {
|
let sortFlagRes;
|
if (sortFlag) {
|
sortFlagRes = 1;
|
} else {
|
sortFlagRes = sortFlag ? 1 : -1;
|
}
|
return function (value1, value2) {
|
const val1 = value1[key];
|
const val2 = value2[key];
|
if (val1 < val2) {
|
return sortFlagRes * -1;
|
}
|
if (val1 > val2) {
|
return sortFlagRes * 1;
|
}
|
return 0;
|
};
|
}
|
return objArr.sort(compare(`${attribute}`, orderFlag));
|
}
|
|
/**
|
* 更新或补充传入链接上的参数
|
*/
|
export function updateURLParams(url, param) {
|
if (!url) {
|
return ''
|
}
|
const options = getQueryObject(url);
|
const urlNew = url.split('?')[0] + '?' + parseObjIntoQuery({ ...options, ...param })
|
return urlNew;
|
}
|
|
/**
|
* 枚举定义工具
|
* 示例:
|
* const STATUS = createEnum({
|
* AUDIT_WAIT: [1, '审核中'],
|
* AUDIT_PASS: [2, '审核通过']
|
* })
|
* 获取枚举值:STATUS.AUDIT_WAIT
|
* 获取枚举描述:STATUS.getDesc('AUDIT_WAIT')
|
* 通过枚举值获取描述:STATUS.getDescFromValue(STATUS.AUDIT_WAIT)
|
*/
|
export function createEnum(definition) {
|
const strToValueMap = {};
|
const numToDescMap = {};
|
|
for (const enumName of Object.keys(definition)) {
|
const [value, desc] = definition[enumName];
|
strToValueMap[enumName] = value;
|
numToDescMap[value] = desc;
|
}
|
|
return {
|
...strToValueMap,
|
getDesc(enumName) {
|
return (definition[enumName] && definition[enumName][1]) || '';
|
},
|
getDescFromValue(value) {
|
return numToDescMap[value] || '';
|
},
|
};
|
}
|
|
|
export function loopDecodeFun(startCode) {
|
if (ENV !== 'alipay') { return decodeURIComponent(startCode) }
|
let decodeTimes = 0;
|
const loopDecode = (code) => {
|
const decode = (c) => {
|
return {
|
new: decodeURIComponent(c),
|
old: c
|
}
|
}
|
if (decodeTimes > 3) {
|
return code
|
} else {
|
let afterDecode = decode(code)
|
console.log(afterDecode)
|
if (afterDecode.new === afterDecode.old) {
|
return afterDecode.new
|
} else {
|
decodeTimes++
|
return loopDecode(afterDecode.new)
|
}
|
}
|
}
|
return loopDecode(startCode)
|
}
|
|
// 处理换行符
|
export function handleLineBreak(str) {
|
if (!str) {
|
return str;
|
}
|
|
return str.replace(/\\n/g, '\n');
|
}
|
|
export function getPositionSetting() {
|
// 微信朋友圈场景
|
if (ENV === 'weapp' && Taro.getStorageSync('scene') === 1154) {
|
return;
|
}
|
|
if (ENV === 'xhs') {
|
return new Promise((resolve) => {
|
// @ts-ignore
|
xhs.getSetting({
|
success: (res) => {
|
const settingName = 'scope.userLocation';
|
resolve(res.authSetting[settingName]);
|
},
|
fail: () => {
|
resolve('');
|
}
|
});
|
});
|
}
|
|
return new Promise((resolve) => {
|
Taro.getSetting({
|
success: (res) => {
|
const settingName = (ENV === 'alipay') ? 'location' : 'scope.userLocation';
|
resolve(res.authSetting[settingName]);
|
},
|
fail: () => {
|
resolve('');
|
}
|
});
|
});
|
}
|
|
|
// 公用跳转充电独立小程序方法
|
export function goToChargeMini(path: string) {
|
const $app: any = Taro.getApp().$app;
|
Taro.navigateToMiniProgram({
|
appId: 'xxxxxxxxxx', // 充电小程序 appid
|
path: path,
|
envVersion: process.env.NODE_ENV === 'development' ? 'develop' : 'release',
|
success: function () {
|
$app.xpReportSend({ pageId: 'P10342', buttonId: 'B067', para: { result: 1 } });
|
},
|
fail: function (err) {
|
console.log('打开失败err==', err)
|
$app.xpReportSend({ pageId: 'P10342', buttonId: 'B067', para: { result: 0, errMsg: err.errMsg } });
|
}
|
})
|
}
|