Commit c6a3dc05 authored by Xuguangxing's avatar Xuguangxing

feat: 增加收银台页面,通过验证,正常展示

parent 4a2a9fc5
This diff is collapsed.
import config from '@/config';
import { saDeviceId } from '@/service/sa.service';
import http from '@/service/httpDecorator';
const { talosHost } = config;
export default {
// 猜你喜欢-(商品详情页)
recommendLike: async function() {
// return http.get(talosHost + '/vcc/xyqb/recommend/like');
return http.get(`${talosHost}/vcc/xyqb/recommend/goods-list`, {
customHeader: {
scDeviceId: await saDeviceId()
}
});
}
};
import request from '@/service/httpDecorator';
import config from '@/config';
import { saDeviceId } from '@/service/sa.service';
const { talosHost } = config;
const queryPayInfo = function(data) {
return request.post(`${talosHost}/open/checkout`, data);
};
const prepay = async function(data) {
const scDeviceId = await saDeviceId();
return request.post(`${talosHost}/open/checkout/prepay`, data, {
customHeader: {
scDeviceId
},
hideToast: true
});
};
const pay = async function(data) {
const scDeviceId = await saDeviceId();
return request.post(`${talosHost}/open/checkout/pay`, data, {
customHeader: {
scDeviceId
},
hideToast: true
});
};
const queryPayStatus = function(data) {
return request.post(`${talosHost}/open/checkout/pay_status/query`, data);
};
const sendSms = function(data) {
return request.post(`${talosHost}/open/checkout/send_sms`, data);
};
const desSalt = function() {
return request.get(`${talosHost}/vcc/account/salt`);
};
const h5AppyUrl = function() {
return request.get(`${talosHost}/vcc/xyqb_mall/app_url`);
};
const getCoupon = async function(params) {
const scDeviceId = await saDeviceId();
return request.post(`${talosHost}/open/checkout/pay_coupon_list`, params, {
customHeader: {
scDeviceId
}
});
};
const ocrFaceId = function(params) {
return request.post(`${talosHost}/open/checkout/ocr_faceId`, params);
};
const getGoodsList = async function(data) {
const scDeviceId = await saDeviceId();
return request.get(`${talosHost}/vcc/xyqb/recommend/goods-list`, {
params: data,
hideLoading: true,
customHeader: {
scDeviceId
}
});
};
// KA流程节点
const kaGetNextUrl = function() {
return request.get(`${talosHost}/api/kdsp/ka/process/get-next-url`);
};
const reissueContract = function(params) {
return request.post(`${talosHost}/open/checkout/payReissueContract`, params);
};
export default {
// 商品详情页面
desSalt() {
return request.get(`${talosHost}/vcc/account/salt`);
}
};
const getCouponList = function(params) {
return request.get(`${talosHost}/api/kdsp/appconfig/pay-succ-page/guide-stream`, { params });
};
// 获取用户手机号
const getPhoneNumber = function() {
return request.get(`${talosHost}/api/kdsp/user/phone`);
};
export {
pay,
prepay,
sendSms,
desSalt,
h5AppyUrl,
getCoupon,
ocrFaceId,
queryPayInfo,
getGoodsList,
kaGetNextUrl,
getCouponList,
queryPayStatus,
reissueContract,
getPhoneNumber
};
import http from '@/service/httpDecorator';
import config from '@/config';
const { talosHost, faceHost } = config;
export default {
// 获取信用钱包用户信息
getXhkInfo() {
return http.get(`${talosHost}/api/kdsp/profile/vcc/user-account`);
},
getUserInfo() {
return http.get(`${talosHost}/api/kdsp/user/about`);
}
};
// 发送短信
export const smsCode = param => {
const data = { ...param, smsMerchant: 'XIN_YONG_QIAN_BAO' };
return http.post(`${talosHost}/vcc/usercenter/send_vcc_sms_code`, data);
};
// KA流程节点
export const kaGetNextUrl = params => {
let options = {
sonVccChannel: true
};
return http.get(`${talosHost}/api/kdsp/ka/process/get-next-url`, { params }, options);
};
// 验证短信并登录
export const friendLogin = data => {
return http.post(`${talosHost}/vcc/usercenter/fast_login_by_sms_code`, data);
};
// 验证短信类型
export const captchaType = data => {
return http.post(`${talosHost}/vcc/usercenter/captcha_type`, data);
};
// 获取图形验证
export const captcha = () => {
return http.get(`${talosHost}/vcc/usercenter/qg_captcha`);
};
export const getFaceUrl = params => {
return http.get(`${faceHost}/auth-center/ex/face/h5/auth_url.json`, { params });
};
export default {
MP_URL_MAP: {
home: '/pages/index/index',
webview: '/pages/webview/webview',
// webview: '/pages/groupbuy/webview',
middleWay: '/pages/webview/middleWay',
goodDetail: '/pages/product/goodDetail',
landPage: '/pages/landing/goods',
searchPage: '/pages/search/index'
}
};
export const APP_ID = '102';
export const PUBLIC_KEY = `
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCGf4wnNJXHXM54wsmxTwhpiPaAp27zM
3QsrWu1+GOMoCDmAEOb2jYjyNhwBIeV9eY0fwoK+MfWBywbonypyXs1j5l/mTmFRQ8IZY
+xZF0t01cornoMpKJncoNiwqc9OnsiwGPqzIs/iLalBonppqhWSn0g99vFS2qgr0WnOWl
qLQIDAQAB
-----END PUBLIC KEY-----
`;
export const PRIVATE_KEY = `
-----BEGIN RSA PRIVATE KEY-----
MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAIC46noXi7VhxDMCQNK3x
k7uVQICaIwhQ6Ye5c5XYaM9IgUhFUioQZ3llelM3oAnYqLuAZMU0POcNqm8qmr7I3fc8A
SZZKm5XUm6i/PI++xT+5c9zhHHsHumoSoTJ/bpS8xNhDFz/X2JQTIn6izFtBBnsMJRx5K
aJWXYebk1RyCVAgMBAAECgYA27bGxE+ccKXINykJbKOzItc80ok52raMuejTaTlNt0yJ3
SdzJOnN1q4jDG3g++4+Nsz6cwt8/dUOmPsoCCNTjMDUg40Cl8NopPMXvo/INwd2vJSEFr
JyC629pl3N7E18Iqjdt8jMy/zEMSDMPh7+NDtSDQqfQpeT0w31/Q1qdwQJBALtk/xIIPN
/zyCZcAIKtXvp0FrHslEL55q01kV6bwhyfAnyz+GcGJwxPWOKJ1FRCnzjOZRc3ygekMZU
WGLjszDkCQQCv2Qo/q97pjw4QwxsTwuuQKlLhAuBr2W0eTsnou9tk3i7PJX/xQXlccp0C
FRWAe3xdpYtapUiMJ8zpKkw+PC89AkBdn9UMRk9buKmL+LVMlJ/6U5uvIzrjx4UnjrblZ
L5znEIa2bPGjT1fGhmXfTM3Md3o/L1m/zmR3cfj65lIcw6JAkB0uf6qmz0CDnrIt6pOqN
HTRbT0NgOgs5hSSPyQJ7sPrsilqn/ONqcHrfD5A+PdAJtiUlQ5nIOWvYiwseogWbUFAkB
y6/cB1HblHJzuyJwaAW9vLNmbqeKW5DhU2QG7Jp1uUgk4GcopDAgFWlAjbQcBCGDyStHH
YxINn+qpKviRkeFf
-----END RSA PRIVATE KEY-----
`;
/*
* @Description:
* @Date: 2021-03-31 19:59:17
* @LastEditors: gzw
* @LastEditTime: 2021-03-31 19:59:17
*/
/*
* @Description:
* @Date: 2021-03-31 19:59:12
* @LastEditors: gzw
* @LastEditTime: 2021-03-31 19:59:13
*/
let protocol = window.location.protocol;
let payHost = protocol + '//mapi-qa.liangkebang.net/pay';
let shenceHost = 'https://bn.xyqb.com/sa?project=default'; // 测试地址
let talosHost = 'https://talos-vcc2.liangkebang.net'; // 电商分期测试环境服务地址
let talosHost = 'https://talos-test1.liangkebang.net'; // 电商分期测试环境服务地址
let operatorHost = 'https://operator.liangkebang.com';
export default {
talosHost,
operatorHost,
payHost,
test: true,
shenceHost
};
const protocol = window.location.protocol;
const talosHost = protocol + '//talos.xyqb.com';
const operatorHost = protocol + '//auth.quantgroup.cn';
// const payHost = protocol + '//mapi.q-gp.com/pay';
const payHost = protocol + '//payapi.xyqb.com';
const shenceHost = 'https://bn.xyqb.com/sa?project=production';
export default {
// apiHost,
test: false,
shenceHost,
talosHost,
payHost,
operatorHost
};
......@@ -20,7 +20,7 @@ if (process.env.SENTRY_ENV !== 'test' && process.env.NODE_ENV === 'production')
.install();
}
Vue.prototype.util = new Bridge();
Vue.prototype.$track = saService;
saService.init(router);
Vue.config.productionTip = false;
......
......@@ -4,18 +4,12 @@ export default [
redirect: '/error'
},
{
path: '/demo',
alias: ['/demo-page'],
name: 'demo-page',
back: false,
path: '/pay',
name: 'pay',
meta: {
title: 'DEMO',
has: {
header: true,
footer: true
}
title: '收银台'
},
component: () => import('../views/demo')
component: () => import('../views/pay')
},
{
path: '/error',
......
......@@ -7,6 +7,8 @@ import {
Icon,
Cell,
CellGroup,
Radio,
RadioGroup,
Row,
Col,
Dialog,
......@@ -24,7 +26,36 @@ import {
Form,
Sticky,
Tab,
Tabs
Tabs,
Empty,
Swipe,
SwipeItem,
Tabbar,
TabbarItem,
BackTop,
Stepper,
AddressEdit,
SubmitBar,
CouponList,
Switch,
AddressList,
Collapse,
CollapseItem,
Uploader,
IndexList,
IndexListItem,
Tag,
ActionSheet,
Steps,
Step,
Notify,
CountDown,
PwdField,
AuthcodeField,
Skeleton,
Card,
Progress,
GoodsAction
} from '@qg/cherry-ui';
import DialogFn from '@qg/cherry-ui/src/dialog/func';
// import "@qg/cherry-ui/dist/cherry.css";
......@@ -33,6 +64,8 @@ Vue.use(Button);
Vue.use(Image);
Vue.use(Cell);
Vue.use(CellGroup);
Vue.use(Radio);
Vue.use(RadioGroup);
Vue.use(Row);
Vue.use(Col);
Vue.use(Popup);
......@@ -46,12 +79,40 @@ Vue.use(Form);
Vue.use(Icon);
Vue.use(Sticky);
Vue.use(Overlay);
Vue.use(Form);
Vue.use(CardList);
Vue.use(Loading);
Vue.use(List);
Vue.use(Tab);
Vue.use(Tabs);
Vue.use(Empty);
Vue.use(Swipe);
Vue.use(SwipeItem);
Vue.use(Tabbar);
Vue.use(TabbarItem);
Vue.use(Stepper);
Vue.use(BackTop);
Vue.use(AddressEdit);
Vue.use(SubmitBar);
Vue.use(CouponList);
Vue.use(Switch);
Vue.use(AddressList);
Vue.use(Collapse);
Vue.use(CollapseItem);
Vue.use(Uploader);
Vue.use(IndexList);
Vue.use(IndexListItem);
Vue.use(Tag);
Vue.use(ActionSheet);
Vue.use(Steps);
Vue.use(Step);
Vue.use(Notify);
Vue.use(CountDown);
Vue.use(PwdField);
Vue.use(AuthcodeField);
Vue.use(Skeleton);
Vue.use(Card);
Vue.use(Progress);
Vue.use(GoodsAction);
// const _proto = Vue.prototype;
// const proto = Object.create(_proto);
......
import cookies from 'js-cookie';
const option = {
domain: window.location.host.indexOf('.q-gp.com') >= 0 ? '.q-gp.com' : '',
expires: 365
expires: 1
};
const Cookies = {
get(key) {
......
/*
* @Description: 数据加密,aes加密数据主体,rsa加密aes密钥,aes密钥前端自己存储
* @Date: 2020-12-08 11:08:28
* @LastEditors: gzw
* @LastEditTime: 2021-07-07 17:44:22
*/
import { cipher as AES, util as UTIL, pki as PKI, md as SHA1 } from 'node-forge';
import uuidv1 from 'uuid/v1';
import { parseTime } from './utils.service';
import { APP_ID, PUBLIC_KEY, PRIVATE_KEY } from '@/config/encrypt.config';
import CryptoJS from 'crypto-js';
import pay from '@/api/pay.api';
/**
* @description: 数据加密
* @param {String} data 数据源
* @return {String} 加密后的数据base64
*/
export function encryption(data = '') {
if (!data) return null;
const key = generateRandomStr(16);
const iv = key; // 后台约定iv与key一致
const plaintext = typeof data === 'object' ? JSON.stringify(data) : data;
const body = encryptDataByAes(plaintext, key, iv); // AES加密数据
const encryptKey = encryptDataByPb(key); // RSA公钥加密AES密钥
const signData = generateSign(plaintext);
return {
appId: APP_ID,
body,
encryptKey,
...signData
};
}
/**
* @description: 数据加密
* @message {String} message 数据源
* @return {String} 加密后的数据16进制
*/
export async function encryptByDESModeEBC(message) {
console.log(message);
const [{ payPwdSalt }] = await pay.desSalt();
var keyHex = CryptoJS.enc.Utf8.parse(payPwdSalt);
var encrypted = CryptoJS.DES.encrypt(message, keyHex, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.ciphertext.toString().toLocaleUpperCase();
}
/**
* @description: AES加密数据,默认CBC, Pki#cs7
* @param {String} txt 数据源
* @param {String} key 密钥,16位字符串
* @param {String} iv 初始化向量
* @return {String} 加密后的数据base64
*/
function encryptDataByAes(txt, key, iv) {
const cipher = AES.createCipher('AES-CBC', key);
cipher.start({ iv });
cipher.update(UTIL.createBuffer(txt, 'utf8'));
cipher.finish();
const ciphertext = cipher.output.getBytes();
return buffer2Base64(ciphertext);
}
/**
* @description: 使用RSA公钥加密数据
* @param {String} txt 数据源
* @return {String} 加密后的数据base64
*/
function encryptDataByPb(txt) {
const publicKey = PKI.publicKeyFromPem(PUBLIC_KEY);
const pbData = publicKey.encrypt(txt);
return buffer2Base64(pbData);
}
/**
* @description: RSA私钥+SHA1生成签名
* 签名组成结构nonce+appid+timestamp+body
* @param {String} txt 数据源
* @return {Object} 生成的sign数据,时间戳、Nonce
*/
function generateSign(txt) {
const timestamp = parseTime('');
const nonce = generateNonce();
const privateKey = PKI.privateKeyFromPem(PRIVATE_KEY);
const md = SHA1.sha1.create();
md.update(nonce + APP_ID + timestamp + txt, 'utf8');
let sign = privateKey.sign(md);
sign = buffer2Base64(sign);
return {
timestamp,
nonce,
sign
};
}
/**
* @description: buffer转base64
* @param {Buffer} buf buffer源数据
* @return {String} base64 字符串
*/
function buffer2Base64(buf) {
return UTIL.encode64(buf);
}
/**
* @description: 生成nonce(uuid)
* 规则:以当前时间的uuid作为name,以随机生成的uuid作为namespace,生成最终的uuid
* @return {String} 生成的uuid
*/
function generateNonce() {
return uuidv1();
}
/**
* @description: 生成随机字符串
* @param {Number} n 位数
* @return {String} 生成的字符串
*/
function generateRandomStr(n) {
const len = n || 32;
const chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz0123456789';
const maxPos = chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
import HttpRequest from '@qg/ui-request';
import { Toast } from '@qg/cherry-ui';
import store from '@/store';
import { appVersion, isApp, isWxMp } from '@/service/validation.service';
import { getVccChannel } from './userInfo.service';
import localStorage from '@/service/localStorage.service';
import sessionStorage from '@/service/sessionStorage.service';
import MpBridge from '@/service/mp';
import Bridge from '@qg/js-bridge';
function getURLSearchParams(json) {
if (!json) return '';
const dataArray = Object.keys(json).map(key => {
if (json[key] === undefined) return '';
return encodeURIComponent(key) + '=' + encodeURIComponent(json[key]);
});
return dataArray.filter(item => item !== undefined && item !== null).join('&');
}
const http = new HttpRequest(
{},
{},
{
payCenter: {
response(res) {
const { data, config } = res;
const returnRawData = config.rawData;
if (returnRawData) return [data, null];
// if (data.businessCode === '401' || data.businessCode === '0401') {
// // router.push({ name: 'login' });
// window.localStorage.removeItem('vccToken');
// window.sessionStorage.removeItem('vccToken');
// }
const success =
(data.code === '0000' && data.businessCode === '0000') || data.business_code === 0;
if (success) {
return [data.data, null];
}
const msg = data.msg || '服务异常';
if (!config.hideToast || !data.noAlert) {
Toast(msg);
}
let error = new Error(msg);
error.response = data;
if (
error?.response?.businessCode === '6049' ||
error?.response?.businessCode === '401' ||
error?.response?.businessCode === '0401'
) {
localStorage.remove('vccToken');
sessionStorage.remove('vccToken');
if (isApp) {
const nativeBridge = new Bridge();
window.xyqbNativeEvent = function(res) {
const json = typeof res === 'string' ? JSON.parse(res) : res;
if (json.event === 'getTokenSuccess') {
const appData = json.data || {};
if (appData && appData.token) {
localStorage.set('vccToken', appData.token);
sessionStorage.set('vccToken', appData.token);
setTimeout(() => {
window.location.reload();
}, 500);
}
}
};
nativeBridge.getToken();
}
if (isWxMp) {
const nativeBridge = new MpBridge();
nativeBridge.getToken({
clear: 1
});
}
}
console.error(error);
return [null, error];
},
request(cfg) {
const { method } = cfg;
cfg.headers['X-Auth-Token'] = localStorage.get('vccToken') || '';
if (cfg.customHeader) {
Object.assign(cfg.headers, cfg.customHeader);
}
cfg.headers['x-user-terminal'] = isWxMp ? 'MINI-APP' : 'H5';
cfg.headers['vccChannel'] = getVccChannel();
cfg.headers['sonVccChannel'] = getVccChannel('sonVccChannel');
if (method === 'post' && cfg.emulateJSON) {
cfg.headers['Content-Type'] = 'application/x-www-form-urlencoded';
cfg.data = getURLSearchParams(cfg.data);
}
return cfg;
}
}
},
{
strategy: 'payCenter',
headers: {
'x-user-terminal': isWxMp ? 'MINI-APP' : 'H5',
version: appVersion || '7900'
}
},
function(msg) {
Toast(msg);
},
function(loadingState) {
store.dispatch('change_loading', loadingState);
}
);
).getInstance();
export default http;
......@@ -2,27 +2,41 @@
* Created by jialiu on 17/1/11.
*/
import store from '../store';
import { isWechat, isApp } from './validation.service';
import { isWechat, isApp, isAndroid, isIOS } from './validation.service';
import Cookies from './cookieStorage.service';
import localStorage from './localStorage.service';
//formXcxPage:标识是从小程序跳转过来的;
const localStorageParams = ['creditToken', 'vccToken', 'vccChannel', 'formXcxPage'];
const cookiesParams = ['h'];
import sessionStorage from './sessionStorage.service';
// import { Toast } from '@qg/cherry-ui';
export default {
// token校验,整个流程都是登陆后的
init: router => {
router.beforeEach((to, from, next) => {
Cookies.set('h', 0);
const query = JSON.parse(JSON.stringify(to.query));
if (Object.keys(query).indexOf('vccToken') == -1) {
to.query.vccToken = sessionStorage.get('vccToken') || '';
}
// console.log(to.query, 1);
// 所有自定义路由字段在此处理
const { meta } = to;
isWechat && localStorage.set('vccChannel', '159913');
isIOS && localStorage.set('vccChannel', '214');
isAndroid && localStorage.set('vccChannel', '217');
meta?.has?.header && store.commit('CHANGE_HEADER', meta.has.header); // 改变header
localStorageParams.forEach(item => {
to.query[item] && localStorage.set(item, to.query[item]);
});
cookiesParams.forEach(item => {
to.query[item] && Cookies.set(item, to.query[item]);
const localParams = ['redirectUrl', 'h', 'vccToken', 'vccChannel', 'sonVccChannel'];
// TODO: 类似逻辑可以整合
localParams.forEach(item => {
const value = to.query[item];
if (item === 'vccToken' && value === '') {
localStorage.remove('vccToken');
sessionStorage.remove(item);
}
if (value && value !== '{token}' && value !== '{vccToken}') {
localStorage.set(item, value);
sessionStorage.set(item, value);
}
});
(isWechat || isApp || Cookies.get('h') === '0') && store.commit('CHANGE_HEADER', false); // 改变header
document.body.className = store.state.pay.header ? 'has-header' : '';
store.commit('CHANGE_TITLE', meta?.title); // 改变title
......
/*
* @Description: h5 与 mp 交互
* @Date: 2021-04-29 15:19:37
* @LastEditors: gzw
* @LastEditTime: 2021-06-07 19:30:02
*/
import qs from 'qs';
import commonCfg from '../config/common.setting';
const { MP_URL_MAP } = commonCfg;
class Mp {
constructor() {
this.callbackQueue = {};
this.wx = require('weixin-js-sdk');
}
// 小程序中postMessage在特定时机(小程序后退、组件销毁、分享)触发; 如果需要立即触发,需要navigateTo跳转
run(data, callback, immediate = false) {
const { wx } = this;
console.log(data.event);
if (immediate) {
const url = `${MP_URL_MAP.middleWay}${qs.stringify(data, {
encode: true,
addQueryPrefix: true
})}`;
if (callback) this.callbackQueue[data.event] = callback;
wx.miniProgram.navigateTo({
url,
success: () => {
this.bindListener();
}
});
} else {
wx.miniProgram.postMessage({ data });
}
}
getToken(data, callback = () => {}) {
this.run({ event: 'getToken', ...data }, callback, true);
}
closeBrowser() {
const { wx } = this;
wx.miniProgram.navigateBack();
}
openNewUrl(data = {}) {
const { wx } = this;
const { newUrl } = data;
console.log(newUrl);
if (/(https|http):\/\//gi.test(newUrl)) {
// window.location.href = newUrl;
wx.miniProgram.navigateTo({
url: `${MP_URL_MAP['webview']}?url=${encodeURIComponent(JSON.stringify(newUrl))}`
});
} else if (/xyqb:\/\//gi.test(newUrl)) {
let urlTag = '';
if (/goodsdetail|goodsDetail/gi.test(newUrl)) {
urlTag = 'goodDetail';
} else if (/goodsList/gi.test(newUrl)) {
urlTag = 'landPage';
} else if (/discover|homepage/gi.test(newUrl)) {
urlTag = 'home';
} else {
urlTag = 'home';
}
if (urlTag) {
const url = `${MP_URL_MAP[urlTag]}?${newUrl.split('?')[1]}`;
wx.miniProgram[urlTag === 'home' ? 'reLaunch' : 'navigateTo']({ url });
}
} else {
wx.miniProgram[data.type || 'navigateTo']({
url: newUrl
});
}
}
getHashData(that, currentHref) {
const hashArr = decodeURIComponent(currentHref).split('#/');
const lastHashStr = hashArr[hashArr.length - 1];
const hashData = qs.parse(lastHashStr);
this.callbackQueue[hashData.event](hashData.data);
this.unBindListener();
}
// TODO hashchange使用非匿名函数,获取location是异步的
bindListener() {
window.addEventListener(
'hashchange',
() => {
this.getHashData(this, window.location.href);
},
false
);
}
// TODO
unBindListener() {
window.removeEventListener(
'hashchange',
() => {
this.getHashData(this, window.location.href);
},
false
);
}
}
export default Mp;
/* eslint-disable space-before-function-paren */
/* eslint-disable prettier/prettier */
/*
* @Description: 支付微信h5, jsapi, 第三方收银台,跳转)
* @Date: 2020-07-28 15:03:52
* @LastEditors: gzw
* @LastEditTime: 2021-08-11 10:33:50
*/
import qs from 'qs';
import cookies from '@/service/cookieStorage.service';
import localStorage from '@/service/localStorage.service';
/**
* payByWeixinJsapi
* @description: 微信通过jsapi支付
* 可以在微信浏览器调起支付
* @param {type}
* @return:
*/
function payByWeixinJsapi(info = {}, callback) {
function onBridgeReady() {
// eslint-disable-next-line no-undef
WeixinJSBridge.invoke('getBrandWCPayRequest', info, function (res) {
if (res.err_msg == 'get_brand_wcpay_request:ok') {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
callback('ok');
} else if (res.err_msg == 'get_brand_wcpay_request:cancel') {
// 支付取消
callback('cancel');
} else {
// 支付失败
callback('fail');
}
});
}
if (typeof WeixinJSBridge == 'undefined') {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
}
} else {
onBridgeReady();
}
}
/**
* payByWeixinH5
* @description: 微信通过H5支付
* 可以在浏览器调起微信支付
* 在羊小咩(信用钱包)app中调起微信支付,会先唤起微信,原来的页面会自动跳转到redirect_url设定的地址
* @param {type}
* @return:
*/
function payByWeixinH5(info) {
if (!info.url) return;
if (!info.params) {
info.params = {};
}
const vccToken = localStorage.get('vccToken');
const orderNo = cookies.get('orderNo');
info.params.isWxH5 = 1;
info.params.vccToken = vccToken;
info.params.orderNo = orderNo;
info.params.isWx = true;
const currentPath = encodeURIComponent(
window.location.origin +
// eslint-disable-next-line prettier/prettier
'/payWaiting' +
qs.stringify(info.params, { encode: true, addQueryPrefix: true })
);
try {
const nextPage = document.createElement('a');
nextPage.setAttribute('href',);
nextPage.click();
} catch (error) {
window.location.href = `${info.url}&redirect_url=${currentPath}`;
}
}
/**
* payByALIH5
* @description: 支付宝支付
* @param {type}
* @return:
*/
function payByALIH5(info) {
if (!info.url) return;
const aliWrap = document.createElement('div');
aliWrap.id = 'ALIWEB_WRAP';
aliWrap.setAttribute('id', 'ALIWEB_WRAP');
aliWrap.innerHTML = info.url;
document.body.appendChild(aliWrap);
document.forms[0].submit();
setTimeout(() => {
const ALIWEB_WRAP = document.getElementById('ALIWEB_WRAP');
if (ALIWEB_WRAP != null) ALIWEB_WRAP.parentNode.removeChild(ALIWEB_WRAP);
}, 500);
}
/**
* payByThirdPartyCashier
* @description: 第三方收银台
* @param {type}
* @return:
*/
function payByThirdPartyCashier(info) {
if (!info.url) return;
const orderNo = cookies.get('orderNo');
info.params.third = 1;
info.params.orderNo = orderNo;
const currentPath = encodeURIComponent(
window.location.origin +
'/payWaiting' +
qs.stringify(info.params, { encode: true, addQueryPrefix: true })
);
const nextPage = document.createElement('a');
nextPage.setAttribute('href', `${info.url}&redirect_uri=${currentPath}`);
nextPage.click();
window.location.href = `${info.url}&redirect_uri=${currentPath}`;
}
/**
* @description: 支付方式判断, 返回promise
* NATIVE=原生扫码支付.,APP=ap支付,,JSAPI=公众号支付/小程序支付,,MWEB=H5支付.,MICROPAY=刷卡支付,默认JSAPI
* @param {String} type 支付方式,THIRD -> 第三方,MWEB -> H5支付, JSAPI -> jsapi支付,默认支付方式,THIRD
* @param {Object/String} payInfo 支付信息
* @return {Promise} 回调
*/
export function payByWay(type = 'THIRD', payInfo) {
return new Promise((resolve, reject) => {
if (type === 'JSAPI' && !payInfo.url) {
payByWeixinJsapi(payInfo, function (e) {
if (e === 'ok') {
resolve();
} else {
reject();
}
});
} else {
if (payInfo.url.indexOf('tenpay') > -1) {
payByWeixinH5(payInfo);
reject();
} else if (type === 'ALIWEB') {
payByALIH5(payInfo);
resolve();
} else {
payByThirdPartyCashier(payInfo);
reject();
}
// resolve();
}
});
}
import Vue from 'vue';
import sa from 'sa-sdk-javascript';
import config from '@/config';
console.log(config);
export default {
init: function(router) {
sa.init({
server_url: config.shenceHost,
heatmap: {
//是否开启点击图,默认 default 表示开启,自动采集 $WebClick 事件,可以设置 'not_collect' 表示关闭
// 是否开启点击图,默认 default 表示开启,自动采集 $WebClick 事件,可以设置 'not_collect' 表示关闭
clickmap: 'default',
//是否开启触达注意力图,默认 default 表示开启,自动采集 $WebStay 事件,可以设置 'not_collect' 表示关闭
scroll_notice_map: 'default'
// 关闭触达注意力
scroll_notice_map: 'not_collect'
},
//判断外层是否有 App 的 SDK ,如果有的话,会往 App 的 SDK 发数据。如果没有,就正常发送数据。
use_app_track: true,
show_log: config.test,
app_js_bridge: true
// TODO: app是如何判断的
// 判断外层是否有 App 的 SDK ,如果有的话,会往 App 的 SDK 发数据。如果没有,就正常发送数据。
use_app_track: false,
show_log: config.env === 'test'
});
// 添加公共属性
sa.registerPage({
platformType: 'H5',
uuid: '',
qg_device_id: '',
channel_code: '',
splitStream: ''
});
sa.registerPage({ platformType: 'H5' });
router.afterEach(() => {
Vue.nextTick(() => {
sa.quick('autoTrackSinglePage');
......@@ -31,16 +27,9 @@ export default {
});
}
};
export function registeredEvents(eventName, eventData, callback = () => {}) {
sa.track(eventName, eventData, callback);
}
// 用户登录神策埋点
export function loginSa(uuid = localStorage.get('uuid')) {
if (!uuid) return;
localStorage.set('uuid', uuid);
sa.login(uuid);
export function saTrackEvent(name, data) {
sa.track(name, data);
}
export function saDeviceId() {
return new Promise(resolve => {
sa.quick('isReady', function() {
......@@ -48,3 +37,7 @@ export function saDeviceId() {
});
});
}
// 设置公共属性
export function setRegisterPage(registerPageObj) {
sa.registerPage(registerPageObj);
}
export default {
get(key) {
let result = window.sessionStorage.getItem(key);
try {
return JSON.parse(result);
} catch (e) {
return result;
}
},
set(key, value) {
let toString = Object.prototype.toString;
if (toString.call(value) === '[object Array]' || toString.call(value) === '[object Object]') {
value = JSON.stringify(value);
}
return window.sessionStorage.setItem(key, value);
},
remove(key) {
return window.sessionStorage.removeItem(key);
},
clear() {
return window.sessionStorage.clear();
}
};
import user from '@/api/user.api';
import store from '@/store';
import { getQueryString, parseSearch } from './utils.service';
import localStorage from './localStorage.service';
// eslint-disable-next-line space-before-function-paren
export const getUserInfo = async () => {
const [data] = await user.getUserInfo();
const { userInfo } = data || {};
store.commit('CHANGE_LOGIN', userInfo);
return userInfo;
};
export const getToKen = () => {
const vccToken = getQueryString('vccToken');
const oldToken = localStorage.get('vccToken') || '';
if (!oldToken) {
store.commit('CHANGE_TOKEN', vccToken);
}
};
export function getVccChannel(channelKey = 'vccChannel') {
if (channelKey === 'sonVccChannel') {
return localStorage.get(channelKey) || parseSearch(window.location.href)[channelKey] || '';
}
return localStorage.get(channelKey) || parseSearch(window.location.href)[channelKey] || '';
}
import { isAndroid, isIOS } from './validation.service';
import { isAndroid, isIOS, isXyqb, isWxMp } from './validation.service';
import Bridge from '@qg/js-bridge';
import MpBridge from '@/service/mp';
const jsBridge = new Bridge();
import Vue from 'vue';
import config from '@/config';
export const EventBus = new Vue();
import qs from 'qs';
/**
* 替换邮箱字符
* @param {String} email 输入字符串
......@@ -264,6 +270,19 @@ export function onKeyboardStateChange(callback = () => {}, off = false) {
}
}
export function throttle(fn, wait) {
let flag = true;
return function() {
if (flag) {
fn.apply(this, arguments);
flag = false;
setTimeout(() => {
flag = true;
}, wait);
}
};
}
export function changeTitleOfIOS() {
if (isIOS) {
const hackIframe = document.createElement('iframe');
......@@ -313,3 +332,103 @@ export function idNoFormat(value) {
export function dateFormat(value) {
return value.replace(/(\d{4})(\d{2})(\d{2})/, '$1.$2.$3');
}
export function getQueryString(name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)');
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
// HEX转RGB
export function hexToRgb(hex) {
var rgb = [];
for (let i = 1; i < 7; i += 2) {
rgb.push(parseInt('0x' + hex.slice(i, i + 2)));
}
return rgb;
}
export function setAppTitleColor(bgcolor = '#fff') {
if (!isXyqb) return;
const isGradient = Array.isArray(bgcolor);
let rgbColor = isGradient ? bgcolor[0] : bgcolor;
if (rgbColor.toLocaleLowerCase().indexOf('#') > -1) rgbColor = hexToRgb(rgbColor);
const isDarkContent = 0.213 * rgbColor[0] + 0.715 * rgbColor[1] + 0.072 * rgbColor[2] <= 255 / 2;
const colors = isGradient
? [bgcolor[0].substr(1), bgcolor[1].substr(1)]
: [bgcolor.substr(1), bgcolor.substr(1)];
jsBridge.run({
event: 'resetNavigationBarColor',
data: {
isDarkContent,
colors
}
});
}
export function paramsParentheses(pointer) {
let params = pointer.$route.query;
const path = pointer.$route.path;
Object.keys(params).indexOf('vccToken') > -1 && delete params.vccToken;
const paramsString = qs.stringify(params);
return `${config.localHost}${path}?` + paramsString;
}
export function firstGroupShare(shareInfo, type) {
if (!isWxMp) return;
const nativeBridge = new MpBridge();
if (!shareInfo) {
nativeBridge.run({
event: 'showShareView',
data: {
shareDic: {
title: `[0元购] 羊小咩Plus`,
link: '/pages/index/index', // 页面地址
imgUrl:
'https://img.lkbang.net/activity/share/default/shareDefault.png?imageMogr2/thumbnail/500x500/quality/75/interlace/1' // 图片地
}
}
});
return;
}
// eslint-disable-next-line no-unused-vars
const vccTokenString = `vccToken=${encodeURIComponent('{token}')}`;
let linkPath = '';
let detailData = {
skuNo: shareInfo.skuNo,
goodsSpecialId: shareInfo.goodsSpecialId,
activityId: shareInfo.activityId,
templateId: shareInfo.templateId,
templateDetailId: shareInfo.templateDetailId,
vccToken: encodeURIComponent('{token}')
};
switch (type) {
case 0:
linkPath = `${config.localHost}/groupBuy/list?activityId=${shareInfo.activityId}&${vccTokenString}`;
break;
case 1:
linkPath = `${config.localHost}/orderList/0?${vccTokenString}`;
break;
case 2:
case 3:
shareInfo.groupBuyGroupId && (detailData.groupBuyGroupId = shareInfo.groupBuyGroupId);
linkPath = qs.stringify(detailData);
linkPath = `${config.localHost}/groupBuy/skuInfo?${linkPath}`;
break;
}
shareInfo.linkPath = `/pages/groupbuy/webview?url=${encodeURIComponent(
JSON.stringify(linkPath)
)}`;
const tagName = type ? '[0元购] ' : '';
nativeBridge.run({
event: 'showShareView',
data: {
shareDic: {
title: `${tagName}${shareInfo.skuName}`,
link: shareInfo.linkPath, // 页面地址
imgUrl: shareInfo.skuImg // 图片地
}
}
});
}
......@@ -285,11 +285,14 @@ const ua = window.navigator.userAgent.toLowerCase();
// 判断微信环境
export const isWechat = ua.match(/MicroMessenger/i) == "micromessenger";
// 判断小程序
export const isWxMp = ua.match(/miniProgram/i) == 'miniprogram';
// 判断羊小咩(信用钱包)环境
export const isApp= ua.match(/xyqb/i) == "xyqb";
export const isApp = ua.match(/xyqb/i) == "xyqb";
// 判断真享生活
export const isVcc= ua.match(/VCC/i) == "vcc";
export const isVcc = ua.match(/VCC/i) == "vcc";
// 判断IOS环境
export const isIOS = /iphone|ipad|ipod/.test(ua);
......@@ -298,7 +301,10 @@ export const isIOS = /iphone|ipad|ipod/.test(ua);
export const isAndroid = /android/.test(ua);
// 判断
export const appVersion = ua.match(/xyqb\/([\d|.]+)/);
export const appVersion = ua.match(/xyqb\/([\d|.]+)/) ? ua.match(/xyqb\/([\d|.]+)/)[1] : "7.7.00";
// 判断羊小咩环境
export const isXyqb = ua.match(/xyqb/i) == "xyqb";
export const isQQ = ua.match(/QQ/i) == 'qq';
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
@import 'var.less';
@import 'mixins.less';
@import 'iconfont.less';
@import 'icon.less';
html,
body,
#app {
......@@ -18,6 +18,13 @@ body {
font-family: @font-family;
background-color: @background-color;
}
button{
border:0;
}
.tel {
color: #5371E0;
font-size: 12px;
}
.page {
background-size: contain;
background-color: @background-color;
......@@ -88,6 +95,12 @@ strong {
min-height: calc(100% - @nav-bar-height);
}
}
.has-tab-bar {
.app {
height: calc(100% - @tab-bar-height);
min-height: calc(100% - @tab-bar-height);
}
}
.cr-dialog--confirm, .cr-dialog--confirm:active {
color: @red;
}
......@@ -102,3 +115,15 @@ strong {
border-bottom: 0.026667rem solid #f2f3f5;
transform: scaleY(0.5);
}
.ellipsis{
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap
}
.cr-dialog--header {
padding: @padding-xl;
&--isolated {
padding-bottom: 0;
}
}
\ No newline at end of file
......@@ -7,3 +7,44 @@
margin-bottom: constant(safe-area-inset-bottom);
margin-bottom: env(safe-area-inset-bottom);
}
.countdown-mixin(@txtColor, @bgColor, @colonColor, @txtSize, @txtWeight) {
.cr-count-down {
font-size: 10px;
span {
box-sizing: border-box;
display: inline-block;
text-align: center;
height: @txtSize;
line-height: @txtSize+1;
font-weight: @txtWeight;
}
}
.block {
background-color: @bgColor;
color: @txtColor;
border-radius: 3.2px;
width: @txtSize;
}
.colon {
color: @colonColor;
width: 12px;
margin: 0 2px;
}
}
.through-line-mixin(@color) {
position: relative;
&:after {
content: ' ';
display: block;
position: absolute;
top: 0;
bottom: 0;
left: -5%;
margin: auto;
width: 110%;
height: 1px;
background-color: @color;
}
}
\ No newline at end of file
// 覆盖cherry-ui样式
@import "./var.less";
@button-border-width: 0;
@button-border-width: 1px;
@button-default-height: 37px;
@button-default-line-height: 37px;
@button-default-font-size: 16px;
@button-default-color: @gray-4;
@button-default-border-color: @gray-4;
@button-primary-color: @white;
@button-primary-background-color: @gradient-red;
@button-danger-background-color: @red;
@button-danger-border-color: @red;
@button-large-height: 48px;
@button-large-line-height: 48px;
@image-placeholder-text-color: @gray-4;
@field-error-message-color: @red-dark;
@field-error-message-font-size: 12px;
@field-error-placeholder-color: @red-dark;
@index-list-bar-font-size: 11px;
@checkbox-icon-border: @border-width-base solid @gray-2;
@checkbox-label-color: @text-color;
@checkbox-checked-color: @white;
......@@ -30,16 +32,19 @@
@cell-icon-size: 16px;
@field-label-width: 75px;
@dialog-width: 290px;
@dialog-font-size: 14px;
@dialog-border-radius: @border-radius-lg;
@dialog-message-font-size: 16px;
@dialog-has-title-message-text-color: @text-color;
@dialog-confirm-button-text-color: @red;
@dialog-has-title-message-text-color: @text-grey;
@navbar-default-height: @nav-bar-height;
@picker-toolbar-padding: @padding-unit - 2 @padding-md;
@picker-font-size: 14px;
@loading-color: @white;
@loading-text-color: @white;
\ No newline at end of file
@empty-description-color: @gray-4;
@tabs-nav-background-color: @background-color;
@list-text-color: @gray-4;
@index-list-title-color: @gray-5;
@back-top-txt-color: @gray-5;
\ No newline at end of file
// page Colors
@page-color-base: #f7f8fa;
// Color Palette
@black: #333333;
@white: #fff;
......@@ -6,16 +9,28 @@
@gray-3: #c8c9cc;
@gray-4: #999999;
@gray-5: #666666;
@gray-6: #f8f8f8;
@gray-7: #d8d8d8;
@red: #ec1500;
@red-light: #ec3333;
@red-dark: #ee0a24;
@orange: #faab0c;
@red-btn: #ff5d00;
@green: #07C160;
@grey-border: #f2f3f5;
// Gradient Colors
@gradient-red: linear-gradient(269deg, #ff5d00 12%, #ff1900 86%);
@gradient-pink: linear-gradient(180deg, #fff7f0 0%, #ffe4dc 100%);
@primary-bg: {
background-image: linear-gradient(269deg, #ff4b00 12%, #ff7705 86%);
background-image: linear-gradient(269deg, #ff5d00 12%, #ff1900 86%);
};
@cherry-color-error: #dd524d;
@text-color-red: #e81800;
@text-color-light: #ff5a4b;
// Component Colors
@text-color: @black;
@text-grey: @gray-4;
......@@ -37,16 +52,23 @@
// Padding
@padding-unit: 4px;
@padding-x: @padding-unit + 2;
@padding-xs: @padding-unit * 2;
@padding-sm: @padding-unit * 3;
@padding-md: @padding-unit * 4;
@padding-lg: @padding-unit * 5;
@padding-xl: @padding-unit * 8;
@padding-sd: @padding-xs + 4;
@font-color-disabled: #c0c4cc;
@font-color-dark: #333333;
@font-color-light: #909399;
@font-color-red: #f23e33;
// Font
@font-size-list: 10,11, 12, 13, 14, 16, 17, 18, 20, 26, 28, 30, 52;
@font-size-list: 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28, 30, 52, 40;
.generate-text(12);
.generate-text(15);
.generate-text(@n, @i: 1) when (@i =< @n) {
@font: extract(@font-size-list, @i);
.text-@{font} {
......@@ -56,9 +78,9 @@
.generate-text(@n, @i + 1);
}
@font-weight-bold: 600;
@font-family: -apple-system, BlinkMacSystemFont, 'Helvetica Neue', Helvetica, Segoe UI, Arial, Roboto, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
@font-family: 'Helvetica Neue', Helvetica, Segoe UI, Arial,
Roboto, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft Yahei', sans-serif;
@font-din: 'din';
@deep: ~'>>>';
......@@ -71,3 +93,51 @@
// 页面顶部header高度
@nav-bar-height: 48px;
@tab-bar-height: 50px;
/* 页面左右间距 */
@page-row-spacing: 15px;
/* 行为相关颜色 */
@color-primary: #fa436a;
// 灰色
// 主要操作按钮背景色
@background-primary: linear-gradient(269deg, #ff5d00 12%, #ff1900 86%);
@background-coupon: linear-gradient(270deg, #f76b1c 0%, #ffc049 100%);
/*文字颜色*/
@font-color-dark: #333333;
@font-color-base: #606266;
@font-color-light: #909399;
@font-color-disabled: #c0c4cc;
@font-color-spec: #4399fc;
@font-color-search: #ec1500;
@font-color-red: #f23e33;
// @font-color-red: #EC3333;
@font-color-red: #f23e33;
// Font
@font-size-11: 11px;
@font-size-12: 12px;
@font-size-13: 14px;
@font-size-14: 14px;
@font-size-16: 16px;
@font-size-18: 18px;
@font-size-20: 20px;
@font-size-26: 26px;
@font-size-28: 28px;
@font-size-30: 30px;
@font-size-32: 32px;
@font-size-36: 36px;
// 边框
@border-sm: 2rpx;
@border-md: 4rpx;
@border-gray: #999;
@border-red: #ec1500;
/* 边框颜色 */
@border-color-dark: #dcdfe6;
@border-color-base: #e4e7ed;
@border-color-light: #ebeef5;
@border-color-search: #ec1500;
@import '../../style/var.less';
.page {
padding: @page-padding-lg @page-padding-lg 0;
height: calc(100% - @page-padding-lg);
}
.banner {
position: relative;
display: flex;
justify-content: center;
background-image: @gradient-red;
background-repeat: no-repeat;
margin: -1 * @page-padding-lg -1 * @page-padding-lg 48px -1 * @page-padding-lg;
padding: @padding-md @padding-lg 0;
}
.card {
&__icon {
height: 200px;
width: 200px;
margin: 0 auto;
display: block;
}
&__info {
padding: 20px 0;
color: #fff;
font-size: 28px;
text-align: center;
}
}
<template>
<div class="page">
<div class="banner">
<div class="card">
<p class="card__info">{{ list.length }}</p>
</div>
</div>
<svg-icon icon-class="ufo" class="card__icon" />
</div>
</template>
<script>
import demoApi from '@/api/demo.auth';
export default {
data() {
return {
list: []
};
},
mounted() {
this.getList();
},
methods: {
async getList() {
const res = await demoApi.recommendLike();
this.list = res;
}
}
};
</script>
<style lang="less" src="./index.less" scoped></style>
const creditPayStatusType = {
1: 'pwd',
2: 'sms'
};
const payTypeText = ['享花卡支付', '微信支付'];
const status = ['未申请', '审核中', '审核失败', '已有额度未激活', '开户成功'];
const payTypeE = [
'PD_YXMMAEC_UserClickCashierSelectXiangHuaCardPay',
'PD_YXMMAEC_UserClickCashierSelectWechatPay'
];
const codeArr = ['4034', '4035', '4036', '3005'];
// (4034, "密码错误"),
// (4035, "密码重试超限,无法验证"),
// (4036, "验证码错误");
// (3005, "组合支付方式被锁定")
// (6049, "token过期")
const payStatus = [3, 5]; // 展示支付文案
const creditStatus = [1, 2]; //展示开通文案
// (1, "VCC未申请"),
// (2, "VCC审核中"),
// (3, "VCC审核失败"),
// (4, "VCC审核成功未开户(包含开户失败)"),
// (5, "已开户"),;
const ACCOUNT_NO_APPLY = 1;
const ACCOUNT_APPLY_AUDITING = 2;
const ACCOUNT_APPLY_AUDIT_FAIL = 3;
const ACCOUNT_APPLY_FAIL = 4;
const ACCOUNT_APPLY_SUCCESS = 5;
// 1信用支付 2微信支付 3支付宝支付 4信用支付_微信支付 5信用支付_支付宝支付 6虚拟支付0元
const CREDIT_PAY = 1;
const WECHAT_PAY = 2;
const ALIPAY_PAY = 3;
const CREDIT_AND_WECHAT_PAY = 4;
const CREDIT_AND_ALIPAY_PAY = 5;
// 三方支付
const IS_THIRD_PAY = method => [WECHAT_PAY, ALIPAY_PAY].indexOf(method) > -1;
//组合支付
const IS_GROUP_PAY = method => [CREDIT_AND_WECHAT_PAY, CREDIT_AND_ALIPAY_PAY].indexOf(method) > -1;
//信用支付
const IS_CREDIT_PAY = method =>
[CREDIT_AND_WECHAT_PAY, CREDIT_AND_ALIPAY_PAY, CREDIT_PAY].indexOf(method) > -1;
const PAYMENT_CODE_PAY = 1; // 支付密码
const SMS_VERIFICATION_CODE_PAY = 2; //短信验证码
const FACE_VERIFICATION_CODE_PAY = 4; //人脸验证
const PAY_SUCCESS = 3; // 支付成功
const PAY_PAYING = 2; //支付中
function isDetentionFn() {
// 推荐开通享花卡
if (this.creditPayInfo.accountStatus !== ACCOUNT_APPLY_SUCCESS) {
this.$dialog({
message: '您有一笔免费额度可以使用,40天免息等你拿',
confirmButtonText: '立即开通',
cancelButtonText: '继续支付',
confirmButtonColor: '#EC1500',
onCancel: () => {
this.pay();
},
onConfirm: () => {
this.goApply();
}
});
} else if (
// 推荐享花卡支付
this.creditPayInfo.accountStatus === ACCOUNT_APPLY_SUCCESS &&
this.creditPayList.isGroupPay
) {
this.$dialog({
message: '使用组合支付部分金额可免息使用40天哦!',
confirmButtonText: '组合支付',
cancelButtonText: '继续支付',
confirmButtonColor: '#EC1500',
onCancel: () => {
this.pay();
},
onConfirm: () => {
// 推荐组合支付
for (let key in this.creditPayList.payList) {
if (this.creditPayList.payList[key].isRecommend) {
const type = this.creditPayList.payList[key].payType;
this.changePayType(type, this.creditPayList.payList[key].mergePayPretreatmentInfo);
this.isCheckAgreement = true;
this.pay();
return;
}
}
}
});
} else if (
this.creditPayInfo.accountStatus === ACCOUNT_APPLY_SUCCESS &&
!this.creditPayList.isGroupPay
) {
this.$dialog({
message: '使用享花卡支付可免息使用40天哦',
confirmButtonText: '享花卡支付',
cancelButtonText: '继续支付',
confirmButtonColor: '#EC1500',
onCancel: () => {
this.pay();
},
onConfirm: () => {
// 切换享花卡支付
this.changePayType(CREDIT_PAY);
this.isCheckAgreement = true;
this.pay();
}
});
}
}
function havePayingOrder() {
/* 有享花卡未支付的订单 */
this.$dialog({
message: '您的享花卡额度被其他订单占用,暂时不可使用享花卡支付哦!',
confirmButtonText: '重新选择',
closeOnClickOverlay: true,
showCancelButton: false,
confirmButtonColor: '#EC1500'
});
}
function filterAllPayList(type, data) {
for (let item in data.payList) {
if (data.payList[item].payType === type) {
data.payList[item].isCheck = true;
continue;
}
data.payList[item].isCheck = false;
}
return data;
}
const payTypeMap = {
'1': '信用支付',
'2': '微信支付',
'3': '支付宝支付',
'4': '信用支付_微信支付',
'5': '信用支付_支付宝支付',
'6': '虚拟支付0元付'
};
export {
status,
codeArr,
payTypeE,
payStatus,
PAY_PAYING,
CREDIT_PAY,
WECHAT_PAY,
ALIPAY_PAY,
PAY_SUCCESS,
payTypeText,
creditStatus,
IS_THIRD_PAY,
IS_GROUP_PAY,
IS_CREDIT_PAY,
isDetentionFn,
havePayingOrder,
filterAllPayList,
ACCOUNT_NO_APPLY,
PAYMENT_CODE_PAY,
ACCOUNT_APPLY_FAIL,
creditPayStatusType,
CREDIT_AND_WECHAT_PAY,
CREDIT_AND_ALIPAY_PAY,
ACCOUNT_APPLY_SUCCESS,
ACCOUNT_APPLY_AUDITING,
ACCOUNT_APPLY_AUDIT_FAIL,
SMS_VERIFICATION_CODE_PAY,
FACE_VERIFICATION_CODE_PAY,
payTypeMap
};
<template>
<div class="contract">
<cr-checkbox
v-model="isCheck"
shape="round"
class="contract-checkbox"
btn-size="mini"
@change="change"
/>
<p class="contract-list">
勾选同意
<span
v-for="contract in contractList"
:key="contract.contractName"
@click="goview(contract.contractVisitUrl)"
>
{{ contract.contractName }}</span
>
</p>
</div>
</template>
<script>
export default {
name: 'Contract',
props: {
contractList: Array,
value: Boolean
},
data() {
return {
isCheck: this.value
};
},
methods: {
goview(url) {
window.location.href = url;
},
change(e) {
this.$emit('input', e);
}
}
};
</script>
<style lang="less">
.contract {
width: 100%;
position: relative;
display: flex;
align-items: flex-start;
color: @gray-5;
.text-10;
&-list {
color: @gray-5;
span {
color: @red;
}
}
}
</style>
<template>
<div class="pay-type-list">
<p class="type-title">{{ value.title }}</p>
<payGroupItem
v-if="value.isGroupPay"
v-model="payList"
:pay-type="payType"
:disabled="disabled"
:coupon-info="couponInfo"
:show-coupon="showCoupon"
:coupon-disabled="showCoupon && !payCouponCouldBeUsed"
/>
<template v-else>
<template v-for="(item, key) of payList">
<payCardItem
v-if="item.show"
:key="key"
:pay-type="payType"
:value="item"
:disabled="disabled"
:coupon-info="couponInfo"
:show-coupon="showCoupon"
:coupon-disabled="showCoupon && !payCouponCouldBeUsed"
/>
</template>
</template>
</div>
</template>
<script>
import payCardItem from './PayCardItem';
import payGroupItem from './PayGroupCard.vue';
export default {
name: 'PayCard',
components: {
payCardItem,
payGroupItem
},
provide() {
return {
payCard: this
};
},
props: {
value: Object,
payType: Number,
payText: String,
disabled: Boolean,
couponInfo: Object,
riskLimit: Boolean,
showCoupon: Boolean,
payCouponCouldBeUsed: Boolean,
single: { type: Boolean, default: false },
creditPay: { type: Boolean, default: false }
},
data() {
return {
payList: this?.value?.payList || {}
};
},
mounted() {},
methods: {}
};
</script>
<style lang="less">
.pay-type-list {
background-color: #fff;
border-radius: @border-radius-sm;
margin-top: @padding-sm;
.type-title {
height: 48px;
.text-16;
font-weight: bold;
padding-left: @padding-md;
position: relative;
line-height: 48px;
}
}
</style>
<template>
<div class="pay-type-list">
<p class="type-title">{{ value.title }}</p>
<payGroupItem
v-if="value.isGroupPay"
v-model="payList"
:pay-type="payType"
:disabled="disabled"
:coupon-info="couponInfo"
:show-coupon="showCoupon"
:coupon-disabled="showCoupon && !payCouponCouldBeUsed"
/>
<template v-else>
<template v-for="(item, key) of payList">
<payCardItem
v-if="item.show"
:key="key"
:pay-type="payType"
:value="item"
:disabled="disabled"
:coupon-info="couponInfo"
:show-coupon="showCoupon"
:coupon-disabled="showCoupon && !payCouponCouldBeUsed"
/>
</template>
</template>
</div>
</template>
<script>
import payCardItem from './PayCardItem';
import payGroupItem from './PayGroupCard.vue';
export default {
name: 'PayCard',
components: {
payCardItem,
payGroupItem
},
provide() {
return {
payCard: this
};
},
props: {
value: Object,
payType: Number,
payText: String,
disabled: Boolean,
couponInfo: Object,
riskLimit: Boolean,
showCoupon: Boolean,
payCouponCouldBeUsed: Boolean,
single: { type: Boolean, default: false },
creditPay: { type: Boolean, default: false }
},
data() {
return {
payList: this?.value?.payList || {}
};
},
mounted() {},
methods: {}
};
</script>
<style lang="less">
.pay-type-list {
background-color: #fff;
border-radius: @border-radius-sm;
margin-top: @padding-sm;
.type-title {
height: 48px;
.text-16;
font-weight: bold;
padding-left: @padding-md;
position: relative;
line-height: 48px;
}
}
</style>
<template>
<div class="payCardItem">
<div
:class="['type-item', { 'b-t': !isGroupPay || value.payType === 1 }]"
@click="changePayType(value)"
>
<div class="type-item-content">
<div class="type-item-content-info">
<cr-image :src="value.icon" class="icon" mode="aspectFit" width="39" height="39" />
<div class="content-info-con">
<div class="content-info-tit">
<div class="content-info-tit-wrap">
<p class="content-info-tit">{{ value.name }}</p>
<p v-if="value.tagName" class="content-info-tit_tag">{{ value.tagName }}</p>
</div>
<p v-if="isGroupPay && value.payAmt" class="content-info-amount">
{{ value.payAmt }}
</p>
</div>
<p>{{ value.accountStatusDesc }}</p>
</div>
</div>
<div v-if="showCoupon && value.payType === 1" class="coupon">
<p class="couponDes" :class="{ disable: couponDisabled }" @click.stop="openCouponModal">
<span v-if="couponInfo.pickupId">
{{ `满${couponInfo.limitAmountNew}减${couponInfo.faceValueNew}元` }}
</span>
<span v-else>
未选择优惠券
</span>
<cr-icon type="arrow" class="selectArrow" size="15px" />
</p>
</div>
<p v-if="value.riskLimitDesc" class="limitDes">
{{ value.riskLimitDesc }}
</p>
</div>
<cr-checkbox
v-if="!isGroupPay"
v-model="value.isCheck"
shape="round"
class="type-item-checkbox"
checked-color="#EC1500"
:disabled="disabled || value.disabled"
@click.native="changePayType(value)"
/>
</div>
</div>
</template>
<script>
export default {
name: 'PayCardItem',
inject: ['payCard', 'pay'],
props: {
value: Object,
payType: Number,
disabled: Boolean,
couponInfo: Object,
riskLimit: Boolean,
showCoupon: Boolean,
isGroupPay: Boolean,
couponDisabled: Boolean
},
methods: {
changePayType({ payType, mergePayPretreatmentInfo }) {
if (this.disabled || this.value.disabled || this.isGroupPay) {
return;
}
this.$emit('click');
this.pay.changePayType(payType, mergePayPretreatmentInfo);
},
openCouponModal() {
if (this.couponDisabled) {
this.$toast('优惠券不可更改');
return;
}
this.pay.openCouponModal(this.pay.orderNo);
}
}
};
</script>
<style lang="less" scoped>
.payCardItem {
width: 100%;
padding-bottom: 2px;
}
.coupon {
margin-top: 4px;
height: 20px;
padding-left: 51px;
display: flex;
}
.couponDes {
display: inline-block;
color: @text-color-red;
.text-12;
border: @border-width-base solid @text-color-light;
border-radius: 3px;
padding: 0 0 0 3px;
&.disable {
color: @font-color-disabled;
border-color: @font-color-disabled;
}
text {
color: @text-color-red;
.text-12;
&.disable {
color: @font-color-disabled;
}
}
}
.limitDes {
color: #ed6a0c;
background: #fffbe8;
.text-11;
padding: 4px 8px;
margin: 8px 8px 8px 4px;
border-radius: 3px;
}
.type-item {
width: 100%;
padding: 12px 8px 12px 12px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
&-content {
width: 100%;
}
&-content-info {
width: 100%;
display: flex;
align-items: center;
}
&-checkbox {
width: 18px;
}
}
.icon {
width: 39px;
height: 39px;
margin-right: @padding-sm;
}
.content-info-tit {
font-size: 15px;
color: @font-color-dark;
margin-bottom: 2px;
display: flex;
align-items: center;
justify-content: space-between;
&-wrap {
display: flex;
}
&_tag {
display: inline-flex;
align-items: center;
height: 16px;
border: @border-width-base solid @text-color-light;
border-radius: 3px;
font-size: 11px;
color: @text-color-light;
margin-left: @padding-unit;
padding: 0 2px;
}
}
.content-info-con {
flex: 1;
display: flex;
flex-direction: column;
.text-12;
color: @font-color-light;
}
.content-info-amount {
width: 100px;
text-align: left;
word-break: break-all;
&::before {
content: '¥';
}
.text-15;
color: @black;
}
.selectArrow {
vertical-align: text-top;
margin-left: -2px;
}
</style>
<template>
<div>
<div @click="changePayType(thirdPayInfo)">
<div class="groupCard">
<PayCardItem
:is-group-pay="true"
:value="creditPayInfo"
:coupon-info="couponInfo"
:show-coupon="showCoupon"
:risk-limit="riskLimit"
:coupon-disabled="couponDisabled"
/>
</div>
<div class="dashed">
<p class="dashed-line" />
<cr-image
src="@/assets/images/pay/addicon.png"
width="24px"
height="24px"
class="dashed-icon"
/>
<cr-checkbox
v-model="thirdPayInfo.isCheck"
shape="round"
checked-color="#EC1500"
:disabled="disabled || thirdPayInfo.disabled"
class="dashed-checkbox"
@click.native="changePayType(thirdPayInfo)"
/>
</div>
<div class="groupCard">
<PayCardItem :is-group-pay="true" :value="thirdPayInfo" />
</div>
</div>
<p class="group-more b-t" @click="openMore">更多支付组合<cr-icon type="arrow" size="15px" /></p>
<cr-popup v-model="morePopup" round position="bottom" :style="{ height: '30%' }" closeable>
<p class="more-title">更换支付组合</p>
<PayCardItem
v-for="item in thirdPayList"
:key="item.payType"
:value="item"
:coupon-info="couponInfo"
:show-coupon="showCoupon"
:risk-limit="riskLimit"
@click="morePopup = false"
/>
</cr-popup>
</div>
</template>
<script>
import PayCardItem from './PayCardItem.vue';
export default {
name: 'PayGroupCard',
inject: ['payCard', 'pay'],
components: {
PayCardItem
},
props: {
value: Object,
payType: Number,
disabled: Boolean,
couponInfo: Object,
showCoupon: Boolean,
riskLimit: Boolean,
couponDisabled: Boolean
},
data() {
return {
morePopup: false,
thirdPayList: [],
creditPayInfo: this.value.creditPayInfo || {}
};
},
computed: {
thirdPayInfo: function() {
let temp = {};
for (const key in this.value) {
if (this.value[key].isRecommend || this.value[key].isCheck) {
const mergePayPretreatmentInfo = this.value[key]?.mergePayPretreatmentInfo || {};
temp = {
...this.value[key],
payAmt: mergePayPretreatmentInfo?.otherPayAmt
};
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.creditPayInfo.payAmt = mergePayPretreatmentInfo.creditPayAmt;
}
}
return temp;
}
},
mounted() {
for (const key in this.value) {
if (this.value[key].isGroupPay) {
this.thirdPayList.push(this.value[key]);
}
}
},
methods: {
changePayType({ payType, mergePayPretreatmentInfo }) {
if (this.disabled || this.creditPayInfo.disabled) {
return;
}
this.pay.changePayType(payType, mergePayPretreatmentInfo);
},
openMore() {
this.morePopup = true;
}
}
};
</script>
<style lang="less">
.groupCard {
width: 100%;
}
.group-more {
.text-13;
width: 335px;
height: 36px;
margin: auto;
display: flex;
color: #ec1500;
position: relative;
align-items: center;
justify-content: center;
}
.cr-popup--close-top-right {
z-index: 2;
}
.dashed {
width: 100%;
padding: 0 12px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
position: relative;
&-line {
width: 310px;
border-bottom: 1px dashed #dcdcdc;
}
&-checkbox {
width: 18px;
}
&-icon {
position: absolute;
left: 50%;
transform: translateX(-50%);
}
}
.more-title {
.text-16;
display: flex;
justify-content: center;
align-items: center;
height: 48px;
color: @black;
position: relative;
}
</style>
<template>
<cr-overlay :show="value">
<div class="sms-modal">
<div class="sms">
<p class="sms-icon"><cr-icon type="cross" color="#999999" @click="closeModal" /></p>
<p class="sms-title">请输入短信验证码</p>
<p class="sms-des">为保证您账户安全,此笔交易需要短信验证</p>
<p class="phone">已发送至 {{ phoneNumber }}</p>
<cr-authcode-field
span-size="24px"
type="number"
border-type="bottom"
:number="6"
height="40px"
span-color="#666"
input-color="#666"
input-size="20px"
class="sms-input"
:success="success"
/>
</div>
<div slot="footer" class="sms-action">
<p v-if="errorInfo" class="sms-error">{{ errorInfo }}</p>
<p v-if="!send" class="sms-set" @click="sendSms()">获取验证码</p>
<p v-else class="sms-set grey">{{ time }}s后重新获取验证码</p>
</div>
</div>
</cr-overlay>
</template>
<script>
import { sendSms as sendSmsApi, getPhoneNumber } from '@/api/pay.api';
export default {
props: {
value: {
type: Boolean,
default: true
},
orderNo: String,
flowOrderNo: String,
errorInfo: String
},
data() {
return {
send: false,
time: 60,
timer: null,
phoneNumber: ''
};
},
computed: {},
watch: {
value: function(val) {
if (val) {
this.sendSms(1);
}
},
errorInfo: function() {}
},
created() {
this.getPhone();
},
methods: {
closeModal() {
this.clearTimer();
this.$emit('close');
},
success(smsCode) {
this.$emit('submit', smsCode);
},
async sendSms() {
// 页面摧毁清掉定时器
if (this.send) return;
const [, error] = await sendSmsApi({ orderNo: this.orderNo, flowOrderNo: this.flowOrderNo });
if (!error) {
this.send = true;
this.timer = setInterval(() => {
--this.time;
if (!this.time) {
this.clearTimer();
}
}, 1000);
}
},
async getPhone() {
const [phoneNumber] = await getPhoneNumber();
this.phoneNumber = phoneNumber;
},
clearTimer() {
clearInterval(this.timer);
this.send = false;
this.time = 60;
}
}
};
</script>
<style lang="less">
.sms-modal {
box-sizing: border-box;
position: absolute;
left: 50%;
top: 26%;
margin-left: -150px;
padding: 12px 18px 24px;
width: 300px;
border-radius: 16px;
background: #fff;
}
.sms {
&-icon {
width: 100%;
height: 20px;
line-height: 20px;
text-align: right;
}
&-title {
text-align: center;
width: 100%;
font-size: 16px;
font-weight: bold;
}
&-des {
padding: 18px 0 0 8px;
display: flex;
justify-content: flex-start;
font-size: 12px;
color: #999999;
}
&-input {
margin: auto;
}
.phone {
padding-left: 8px;
margin-top: 8px;
color: #323233;
font-size: 14px;
}
&-sms {
margin-top: 4px;
font-size: 30px;
color: #333333;
&:before {
content: '¥';
.text-12;
}
}
&-input {
margin: 20px 0;
}
}
.sms-action {
width: 100%;
display: flex;
justify-content: space-between;
p {
font-size: 14px;
color: #666666;
}
.sms-error {
flex: 1;
color: #ee0a24;
}
.sms-set {
flex: 1;
text-align: right;
}
.grey {
color: #999999;
}
}
</style>
import cookies from '@/service/cookieStorage.service';
export const goUrlExtends = {
methods: {
goHome() {
// 商城地址
setTimeout(() => {
this.$router.replace({ name: 'home' });
}, 500);
},
goOrderList() {
setTimeout(() => {
this.$router.replace({ name: 'orderList', params: { status: 0 } });
}, 500);
},
goOrderDetail() {
const orderNo = cookies.get('orderNo')?.orderNo;
this.$router.push({
name: 'orderDetail',
query: { orderNo }
});
}
}
};
@import url('../../style/mixins');
.pay {
padding: @padding-xs;
}
.price-box {
background-color: @white;
height: 120px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.text-13;
color: @black;
border-radius: @border-radius-sm;
.price{
.text-30;
color: @font-color-red;
font-weight: bold;
margin-top: @padding-xs;
&:before{
content: '¥';
.text-14;
font-weight: bold;
}
}
.time{
display: flex;
align-items: center;
margin-top: @padding-unit;
}
}
.payBtn{
width: 100%;
position: fixed;
padding-left: @padding-lg;
padding-right: @padding-lg;
padding-top: 10px;
box-sizing: border-box;
z-index: 99;
bottom: 0;
left:0;
background-color:@white;
padding-bottom: calc(10px + constant(safe-area-inset-bottom));
padding-bottom: calc(10px + env(safe-area-inset-bottom));
button{
.text-16;
width: 100%;
color: @white;
font-size: @line-height-sm;
border-radius: @border-radius-lx;
span{
font-weight: bold;
}
}
button[disabled] {
color: rgba(255,255,255,.6);
}
&-primary {
@primary-bg();
}
}
.btn{
width: 100%;
position: fixed;
padding-left: @padding-lg;
padding-right: @padding-lg;
padding-top: 10px;
padding-bottom: calc(10px + constant(safe-area-inset-bottom));
padding-bottom: calc(10px + env(safe-area-inset-bottom));
box-sizing: border-box;
bottom: 0;
left:0;
background-color:@white;
display: flex;
align-items: center;
justify-content: center;
button{
flex:1;
color: @white;
font-size: @line-height-sm;
border-radius: @border-radius-lx;
}
button[disabled] {
color: rgba(255,255,255,.6);
}
&-primary {
@primary-bg();
}
&-default{
border: 1px solid @cherry-color-error;
color: @cherry-color-error !important;
margin-right: @padding-xs;
background-color: @white !important;
}
}
.placeholder{
width: 100%;
height: 100px;
}
\ No newline at end of file
This diff is collapsed.
......@@ -918,22 +918,30 @@
"resolved" "http://npmprivate.quantgroups.com/@popperjs%2fcore/-/core-2.9.1.tgz"
"version" "2.9.1"
"@qg/cherry-ui@^2.16.65":
"integrity" "sha512-1Q8rDvjglSC9rzapCvlSlXVxaPEwJD6y20yo1M4Lxq6Ndf+x4eR6C8e1S7iIQU9WJeya+KhG1Il2aAoX7roYZg=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fcherry-ui/-/cherry-ui-2.20.6.tgz"
"version" "2.20.6"
"@qg/cherry-ui@^2.23.6":
"integrity" "sha512-czpyl06OfKKnfUls4o5vX8chpeddc87l06E6lDiPks+mM47PJdhobGgvwDWZBIeYETBnlI+VqvUhAXeQ/ISTKg=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fcherry-ui/-/cherry-ui-2.23.9.tgz"
"version" "2.23.9"
dependencies:
"@popperjs/core" "^2.5.4"
"vue-lazyload" "^1.3.3"
"vue-video-player" "^5.0.2"
"@qg/js-bridge@^1.1.9":
"@qg/js-bridge@^1.1.11", "@qg/js-bridge@^1.1.9":
"integrity" "sha512-WVvkSUg2zcc2nblzYGxM/bVo+VDcANy/dw7vcbxLoW1Jega9Jm2d5FGSb7uS6m4746waghUUqcAWNJZ0Q5yeqA=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fjs-bridge/-/js-bridge-1.1.11.tgz"
"version" "1.1.11"
dependencies:
"rollup" "^2.41.3"
"@qg/js-bridge@^1.2.0-beta2":
"integrity" "sha512-iGWg5cUZnkI7xD8m8ra7mxqdLVc3DEtUpS5zAafAcINMqG7vtzXJyJACRQtxb8T2WZMSblSuGmdAiiqCeY8+4g=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fjs-bridge/-/js-bridge-1.2.0-beta2.tgz"
"version" "1.2.0-beta2"
dependencies:
"qs" "^6.10.1"
"weixin-js-sdk" "^1.6.0"
"@qg/qg-scroll@^1.4.2":
"integrity" "sha512-GosH+vgafMs/piEpcBNJZlBiYA25XOQnpvDkJiSEfl+l6oU7U/gXkr6vLLemoAzt6TAntBcTk2bOi0V5aOuWkw=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fqg-scroll/-/qg-scroll-1.4.2.tgz"
......@@ -941,13 +949,23 @@
dependencies:
"babel-runtime" "^6.0.0"
"@qg/ui-request@^0.0.5":
"integrity" "sha512-6RAAMxEzud18N0WQk5CR5vnrQ+FvBdejK+Ig5HAEyBMbFJ6sE1EfuccfYqx7qQ3CizHL58VpIa9pM+zhhdztFw=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fui-request/-/ui-request-0.0.5.tgz"
"version" "0.0.5"
"@qg/ui-request@^0.0.20":
"integrity" "sha512-8UDA86s5JZsJZ61Ho4tIWtjT7z/R9DeSPChIjsoRv/elLZTXSHd1DerdQ5XGXDMbQYNSAyBsni8Eo/iA22mL6A=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fui-request/-/ui-request-0.0.20.tgz"
"version" "0.0.20"
dependencies:
"@qg/js-bridge" "^1.2.0-beta2"
"axios" "^0.19.2"
"@qg/ui-track-web@0.0.3":
"integrity" "sha512-eVo3fXcp3eRGG5YznmfZQa8ih03nJtmNJYCS9VCt3Q8x/mpK3iaqk7Be6+ntUUeCfVSre7uq7fXGwUEfj1ieUw=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fui-track-web/-/ui-track-web-0.0.3.tgz"
"version" "0.0.3"
dependencies:
"@qg/js-bridge" "^1.1.11"
"sa-sdk-javascript" "^1.18.2"
"vue" "^2.6.14"
"@qg/webpack-cos-cdn-upload-plugin@0.0.4":
"integrity" "sha512-ekReJxjD+/R+Rgsatb6qRsJHYyQmS525NfTYjRQTZM/4IEdhfG+068xI9837jpCo8DvjllaaypB6m4Qol5s0gw=="
"resolved" "http://npmprivate.quantgroups.com/@qg%2fwebpack-cos-cdn-upload-plugin/-/webpack-cos-cdn-upload-plugin-0.0.4.tgz"
......@@ -2171,6 +2189,14 @@
"neo-async" "^2.6.1"
"schema-utils" "^2.0.0"
"call-bind@^1.0.0":
"integrity" "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA=="
"resolved" "http://npmprivate.quantgroups.com/call-bind/-/call-bind-1.0.2.tgz"
"version" "1.0.2"
dependencies:
"function-bind" "^1.1.1"
"get-intrinsic" "^1.0.2"
"call-me-maybe@^1.0.1":
"integrity" "sha1-JtII6onje1y95gJQoV8DHBak1ms="
"resolved" "http://npmprivate.quantgroups.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz"
......@@ -2848,6 +2874,11 @@
"randombytes" "^2.0.0"
"randomfill" "^1.0.3"
"crypto-js@^3.1.9-1":
"integrity" "sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q=="
"resolved" "http://npmprivate.quantgroups.com/crypto-js/-/crypto-js-3.3.0.tgz"
"version" "3.3.0"
"css-color-names@^0.0.4", "css-color-names@0.0.4":
"integrity" "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA="
"resolved" "http://npmprivate.quantgroups.com/css-color-names/-/css-color-names-0.0.4.tgz"
......@@ -4226,6 +4257,15 @@
"resolved" "http://npmprivate.quantgroups.com/get-caller-file/-/get-caller-file-2.0.5.tgz"
"version" "2.0.5"
"get-intrinsic@^1.0.2":
"integrity" "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q=="
"resolved" "http://npmprivate.quantgroups.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz"
"version" "1.1.1"
dependencies:
"function-bind" "^1.1.1"
"has" "^1.0.3"
"has-symbols" "^1.0.1"
"get-own-enumerable-property-symbols@^3.0.0":
"integrity" "sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g=="
"resolved" "http://npmprivate.quantgroups.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz"
......@@ -6235,10 +6275,10 @@
"resolved" "http://npmprivate.quantgroups.com/object-hash/-/object-hash-1.3.1.tgz"
"version" "1.3.1"
"object-inspect@^1.7.0":
"integrity" "sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA=="
"resolved" "http://npmprivate.quantgroups.com/object-inspect/-/object-inspect-1.8.0.tgz"
"version" "1.8.0"
"object-inspect@^1.7.0", "object-inspect@^1.9.0":
"integrity" "sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg=="
"resolved" "http://npmprivate.quantgroups.com/object-inspect/-/object-inspect-1.11.0.tgz"
"version" "1.11.0"
"object-is@^1.0.1":
"integrity" "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ=="
......@@ -7298,6 +7338,13 @@
dependencies:
"request" "^2.88.0"
"qs@^6.10.1":
"integrity" "sha512-M528Hph6wsSVOBiYUnGf+K/7w0hNshs/duGsNXPUCLH5XAqjEtiPGwNONLV0tBH8NoGb0mvD5JubnUTrujKDTg=="
"resolved" "http://npmprivate.quantgroups.com/qs/-/qs-6.10.1.tgz"
"version" "6.10.1"
dependencies:
"side-channel" "^1.0.4"
"qs@~6.5.2":
"integrity" "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
"resolved" "http://npmprivate.quantgroups.com/qs/-/qs-6.5.2.tgz"
......@@ -7720,10 +7767,10 @@
dependencies:
"tslib" "^1.9.0"
"sa-sdk-javascript@^1.15.16":
"integrity" "sha512-UIFJBYk8EEcMAg6kSeUdjYAnl3IEXA8DDk/7xqS1aU4bZV3+iUXo2hT1rzGPsSWanVvcDZ/uSGUNZqojsfZaGA=="
"resolved" "http://npmprivate.quantgroups.com/sa-sdk-javascript/-/sa-sdk-javascript-1.15.16.tgz"
"version" "1.15.16"
"sa-sdk-javascript@^1.15.16", "sa-sdk-javascript@^1.18.2":
"integrity" "sha1-9XUy7rqlRBee5Jc9joq43QDMlr4="
"resolved" "http://npmprivate.quantgroups.com/sa-sdk-javascript/-/sa-sdk-javascript-1.19.3.tgz"
"version" "1.19.3"
"safe-buffer@^5.0.1", "safe-buffer@^5.1.0", "safe-buffer@^5.1.1", "safe-buffer@^5.1.2", "safe-buffer@~5.1.0", "safe-buffer@~5.1.1", "safe-buffer@5.1.2":
"integrity" "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
......@@ -7957,6 +8004,15 @@
"resolved" "http://npmprivate.quantgroups.com/shell-quote/-/shell-quote-1.7.2.tgz"
"version" "1.7.2"
"side-channel@^1.0.4":
"integrity" "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw=="
"resolved" "http://npmprivate.quantgroups.com/side-channel/-/side-channel-1.0.4.tgz"
"version" "1.0.4"
dependencies:
"call-bind" "^1.0.0"
"get-intrinsic" "^1.0.2"
"object-inspect" "^1.9.0"
"signal-exit@^3.0.0", "signal-exit@^3.0.2":
"integrity" "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA=="
"resolved" "http://npmprivate.quantgroups.com/signal-exit/-/signal-exit-3.0.3.tgz"
......@@ -9186,7 +9242,12 @@
"videojs-flash" "^2.1.0"
"videojs-hotkeys" "^0.2.20"
"vue@2.6.11":
"vue@^2.6.14":
"integrity" "sha512-x2284lgYvjOMj3Za7kqzRcUSxBboHqtgRE2zlos1qWaOye5yUmHn42LB1250NJBLRwEcdrB0JRwyPTEPhfQjiQ=="
"resolved" "http://npmprivate.quantgroups.com/vue/-/vue-2.6.14.tgz"
"version" "2.6.14"
"vue@>= 2.6.11", "vue@2.6.11":
"integrity" "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ=="
"resolved" "http://npmprivate.quantgroups.com/vue/-/vue-2.6.11.tgz"
"version" "2.6.11"
......@@ -9385,6 +9446,11 @@
"resolved" "http://npmprivate.quantgroups.com/webwackify/-/webwackify-0.1.6.tgz"
"version" "0.1.6"
"weixin-js-sdk@^1.6.0":
"integrity" "sha512-3IYQH7aalJGFJrwdT3epvTdR1MboMiH7vIZ5BRL2eYOJ12BNah7csoMkmSZzkq1+l92sSq29XdTCVjCJoK2sBQ=="
"resolved" "http://npmprivate.quantgroups.com/weixin-js-sdk/-/weixin-js-sdk-1.6.0.tgz"
"version" "1.6.0"
"which-module@^2.0.0":
"integrity" "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho="
"resolved" "http://npmprivate.quantgroups.com/which-module/-/which-module-2.0.0.tgz"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment