Commit 094a2bcf authored by 郭志伟's avatar 郭志伟

Merge branch 'master' into feat/v1.3

parents 8bf6e08c 9def40d4
......@@ -7,5 +7,14 @@ export default {
},
getShopCartCount() {
return http.get(`${config.kdspHost}/api/kdsp/shop-cart/count`);
},
getMpSchema(params) {
return http.post(`${config.kdspHost}/api/kdsp/ka/info/getShareMiniUrl`, params, { emulateJSON: true });
},
getWxConfig(url = window.location.href.split('#')[0]) {
return http.post(`${config.kdspHost}/api/kdsp/wx/mp/getJsapiSign`, {
url,
appId: 'wx2f44c7fe7b08458d'
});
}
};
\ No newline at end of file
......@@ -21,13 +21,14 @@ if (process.env.SENTRY_ENV !== 'test' && process.env.NODE_ENV === 'production')
.install();
}
// if (EASY_ENV_IS_BROWSER && process.env.SENTRY_ENV === 'test' || process.env.NODE_ENV !== 'production') {
// // ! 上线后务必取掉;
// const vConsole = require('vconsole');
// new vConsole();
// }
if (EASY_ENV_IS_BROWSER) {
// ! 上线后务必取掉;
// const vConsole = require('vconsole');
// new vConsole();
}
if (EASY_ENV_IS_BROWSER) {
// ios回退刷新,防止缓存
const isSafari = /^.*((iPhone)|(iPad)|(Safari))+.*$/;
const fromHost = getParameterByName('fromHost', window.location.href);
if (isSafari.test(navigator.userAgent) && fromHost?.indexOf('xc.bmall') === -1 && fromHost?.indexOf('tob') === -1) {
......@@ -40,6 +41,8 @@ if (EASY_ENV_IS_BROWSER) {
Vue.use(lazyload);
const saDirective = new SaDirective();
Vue.directive('track', saDirective.directive);
Vue.config.ignoredElements = ['wx-open-launch-weapp', 'wx-open-launch-app'];
// 全局app登录态监听
window.xyqbNativeEvent = function(res) {
const json = typeof res === 'string' ? JSON.parse(res) : res;
console.log('xyqbNativeEvent toggle');
......
......@@ -2,9 +2,10 @@ import apolloSsr from '../../../config/apollo.ssr.json';
const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'https';
const hostMap = {
apiHost: `${protocol}//quantum-blocks-vcc2.liangkebang.net`,
kdspHost: `${protocol}//talos-vcc2.liangkebang.net`,
apiHost: `${protocol}//quantum-blocks-test1.liangkebang.net`,
kdspHost: `${protocol}//talos-test1.liangkebang.net`,
shenceUrl: `${protocol}//bn.xyqb.com/sa?project=default`,
mallHost: `${protocol}://mall-test1.liangkebang.net`,
test: true
};
......
const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'https';
// const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'https';
export default {
apiHost: `https://quantum-blocks.q-gp.com`,
kdspHost: `${protocol}//talos.xyqb.com`,
shenceUrl: `${protocol}//bn.xyqb.com/sa?project=production`,
// opapiHost: `${protocol}//opapi.q-gp.com`,
kdspHost: `https://talos.q-gp.com`,
shenceUrl: `https://bn.xyqb.com/sa?project=production`,
mallHost: `https://mall.q-gp.com`,
test: false
};
......@@ -2,9 +2,10 @@ import apolloSsr from '../../../config/apollo.ssr.json';
const protocol = EASY_ENV_IS_BROWSER ? window.location.protocol : 'https';
const hostMap = {
apiHost: `${protocol}//quantum-blocks-vcc2.liangkebang.net`,
kdspHost: `${protocol}//talos-vcc2.liangkebang.net`,
apiHost: `${protocol}//quantum-blocks-test1.liangkebang.net`,
kdspHost: `${protocol}//talos-test1.liangkebang.net`,
shenceUrl: `${protocol}//bn.xyqb.com/sa?project=default`,
mallHost: `${protocol}://mall-test1.liangkebang.net`,
test: true
};
......
import Vue from 'vue';
import { sync } from 'vuex-router-sync';
import api from '@/api/editor.api';
import { isWechat } from '@/service/utils.service';
import initService from '@/service/init.service';
export default class App {
config: any;
......@@ -25,6 +27,7 @@ export default class App {
const { initSa } = require('@/service/sa.service');
initService.init(router);
initSa(router);
this.setWxConfig();
}
return {
router,
......@@ -35,6 +38,18 @@ export default class App {
};
}
async setWxConfig() {
if (!isWechat) { return; }
const wx = require('weixin-js-sdk');
const [res] = await api.getWxConfig();
wx.config({
debug: false,
jsApiList: ['onMenuShareTimeline', 'onMenuShareAppMessage'], // 必填,需要使用的JS接口列表
openTagList: ['wx-open-launch-weapp', 'wx-open-launch-app'],
...res
});
}
fetch(vm): Promise<any> {
const { store, router } = vm;
const matchedComponents = router.getMatchedComponents();
......
<template>
<wx-open-launch-app
class="launch-btn"
@launch="launch"
@error="launchError"
id="launch-btn"
appid="wx75d5a207551d0b4d"
:extinfo="extinfo"
>
<script type="text/wxtag-template">
<style>.btn {height: 100vh;width: 100vw;}</style>
<div class="btn">打开APP</div>
</script>
</wx-open-launch-app>
</template>
<script>
import { navToDlApp } from '@qg/citrus-ui/src/helper/service/utils';
export default {
name: "LaunchApp",
props: {
jumpUrl: String,
appSchema: String
},
computed: {
extinfo() {
return JSON.stringify({
url: this.jumpUrl,
data: {}
});
}
},
methods: {
launch() {
setTimeout(() => {
navToDlApp();
}, 2500);
window.location.href = this.appSchema;
},
launchError(e) {
if (e.detail.errMsg === "launch:fail") {
navToDlApp();
}
},
}
};
</script>
<style lang="less">
.launch-btn {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
opacity: 0;
z-index: 100;
left: 0;
}
</style>
<template>
<wx-open-launch-weapp
class="launch-btn"
username="gh_a976018bfb9e"
:path="jumpUrl"
@launch="launch"
@error="launchError"
>
<script type="text/wxtag-template">
<style>.btn {height: 100vh;width: 100vw;}</style>
<div class="btn">打开小程序</div>
</script>
</wx-open-launch-weapp>
</template>
<script>
export default {
name: "LaunchWeapp",
props: {
jumpUrl: String
},
data() {
return {};
},
methods: {
launch() {
console.log("launch");
},
launchError() {
console.log("launchError");
}
}
};
</script>
<style lang="less">
.launch-btn {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
opacity: 0;
z-index: 100;
left: 0;
}
</style>
<template>
<div>
<cr-back-top :show-back-top="showBackTop && pageData.props.showBackTop" :list="backTopList" @click="handleBackTopClick" ref="crBackTop" />
<cr-back-top :show-back-top="showTop" :list="backTopList" @click="handleBackTopClick" ref="crBackTop" @touchend.native="disTouch" />
<cr-popover
class="wxmp-tip"
:value="showMpTip"
......@@ -11,32 +11,37 @@
</div>
<template #reference>提示</template>
</cr-popover>
<div v-if="showShareOverlay" class="share-overlay" @click.self="onShareOverlayClick" />
</div>
</template>
<script>
import Bridge from '@qg/js-bridge';
import { mapGetters } from 'vuex';
import { isApp, isWxMp, debounce } from '@/service/utils.service';
import localStorage from '@/service/localStorage.service';
import { isApp, isWxMp, debounce, isWechat, isH5Normal } from '@/service/utils.service';
import { registeredEvents } from '@/service/sa.service';
import api from '@/api/editor.api';
import cfg from '@/config/index';
import localStorage from '@/service/localStorage.service';
import DisableTouchMixin from '../../../mixins/disableTouch.mixin';
import { navToDlApp } from '@qg/citrus-ui/src/helper/service/utils';
const SHARE_CONFIG = {
name: 'share',
txt: '',
icon: 'share',
url: '',
};
const WEAPP_PATH = 'pages/webview/webview';
const APP_PATH = 'xyqb://openHttp';
export default {
name: 'BackTop',
mixins: [DisableTouchMixin],
props: {
showBackTop: Boolean
},
computed: {
...mapGetters(['pageData']),
...mapGetters(['pageInfo']),
backTopList() {
const btAttachVal = this.pageData && this.pageData.props.btAttachVal ? this.pageData.props.btAttachVal : [];
if (this.cartIndex !== null && btAttachVal.length) {
btAttachVal[this.cartIndex - 1].info = this.cartCount;
}
return isApp ? btAttachVal : isWxMp ? btAttachVal.filter(item => item.persets !== '购物车') : [];
}
},
data() {
return {
showMpTip: false,
......@@ -45,28 +50,88 @@ export default {
wx: null,
cartIndex: null,
cartCount: 0,
getCartCountDebounce: debounce(this.getCartCount, 2000)
getCartCountDebounce: debounce(this.getCartCount, 2000),
mpSchema: '',
link: '',
shareInfo: {},
showShareOverlay: ((isWechat && !isWxMp) || isH5Normal) && !localStorage.get('vccChannel'),
isWechat
};
},
created() {
if (!EASY_ENV_IS_NODE) {
this.jsBridge = new Bridge();
this.wx = require('weixin-js-sdk');
computed: {
...mapGetters(['pageData', 'pageInfo']),
backTopList() {
const btAttachVal = this.pageData && this.pageData.props.btAttachVal ? this.pageData.props.btAttachVal : [];
if (this.cartIndex !== null && btAttachVal.length) {
btAttachVal[this.cartIndex - 1].info = this.cartCount;
}
return isApp ? btAttachVal : isWxMp ? btAttachVal.filter(item => item.persets !== '购物车') : [];
// if (this.pageData.props && this.pageData.props.btAttachVal) {
// const { btAttachVal, showShare } = this.pageData.props;
// const btAttachValDeep = JSON.parse(JSON.stringify(btAttachVal));
// showShare && (isApp || isWxMp) && btAttachValDeep.push(SHARE_CONFIG);
// return btAttachValDeep;
// }
// return [];
},
showTop() {
return this.showBackTop && this.pageData.props && this.pageData.props.showBackTop;
},
appSchema() {
return `${APP_PATH}?jumpUrl=${this.link}`;
},
shareOpenMethod() {
return this.pageInfo.shareOpenMethod;
}
},
watch: {
backTopList(val) {
this.cartIndex = (val || []).findIndex(item => item.persets === '购物车') + 1;
this.getCartCountDebounce();
}
},
created() {
if (!EASY_ENV_IS_NODE) {
this.jsBridge = new Bridge();
this.initShareInfo();
this.getMpSchema();
}
},
methods: {
async getMpSchema() {
if (isH5Normal && EASY_ENV_IS_BROWSER) {
try {
const [schema] = await api.getMpSchema({
miniUrl: WEAPP_PATH,
params: `url=${encodeURIComponent(JSON.stringify(this.link))}`
});
this.mpSchema = schema;
} catch (error) {
}
}
},
onShareOverlayClick() {
if (isH5Normal) {
window.location.href = this.shareOpenMethod === 1 ? this.mpSchema : this.appSchema;
setTimeout(() => {
this.shareOpenMethod === 2 && navToDlApp();
}, 2000);
} else if (isWechat && !isWxMp) {
const { shareOpenMethod, link: url } = this;
const jumpUrl = shareOpenMethod === 1 ? WEAPP_PATH : APP_PATH;
window.location.href = `${cfg.mallHost}/common/launch?jumpUrl=${jumpUrl}&terminal=${shareOpenMethod}&extraInfo=${encodeURIComponent(JSON.stringify({ url }))}`;
}
},
handleBackTopClick(e) {
// ! 此处以1.3为准,但需要对齐分享功能
registeredEvents('PD_WUXIEC_H5ActivityPageSuspendedBtnClick', {
activity_id: this.pageInfo.uuid,
jump_url: e.url,
navigation_name: e.name,
});
});
if (e && e.persets === '分享') {
if (this.tipTimer) {
clearTimeout(this.tipTimer);
......@@ -76,32 +141,45 @@ export default {
}, 600);
}
},
share() {
initShareInfo() {
if (EASY_ENV_IS_NODE) return;
const { coverImage, pageName, pageDescribe } = this.pageInfo;
const data = {
const { coverImage, pageName, pageDescribe, shareCoverImage } = this.pageInfo;
const link = `${window.location.origin}${window.location.pathname}`;
this.link = link;
this.shareInfo = {
event: "showShareView",
data: {
platform: ["weChat", "timeLine", "QQ", "QQZone", "CopyLink"], //依次分别是微信、朋友圈、QQ好友、QQ空间、复制链接
platform: ["weChat", "timeLine"],
shareDic: {
title: pageName || '羊小咩',
desc: pageDescribe || '羊小咩',
link: window.location.origin + window.location.pathname, // 页面地址
imgUrl: coverImage // 图片地址
desc: pageDescribe || '美好生活更从容',
link,
imgUrl: shareCoverImage || coverImage // 图片地址
}
}
};
if (isWxMp) {
this.postMpShareInfo();
}
},
share() {
if (EASY_ENV_IS_NODE) return;
if (isApp) {
this.appShare(data);
this.appShare();
} else if (isWxMp) {
this.mpShare(data);
this.mpShare();
}
},
appShare(data) {
this.jsBridge.showShareView(data);
appShare() {
this.jsBridge.showShareView(this.shareInfo);
},
mpShare(data) {
this.wx.miniProgram.postMessage(data);
postMpShareInfo() {
if (EASY_ENV_IS_NODE) return;
const wx = require('weixin-js-sdk');
const { shareInfo } = this;
wx.miniProgram.postMessage({ data: shareInfo });
},
mpShare() {
this.showMpTip = true;
setTimeout(() => {
this.showMpTip = false;
......@@ -121,28 +199,42 @@ export default {
</script>
<style lang="less" scoped>
@deep: ~'>>>';
.wxmp-tip {
position: fixed !important;
top: -32px;
right: 10%;
right: 60px;
z-index: 99;
@{deep} .cr-popover {
background-color: #fff;
color: #333;
box-shadow: 0 2px 12px 0 rgba(100, 101, 102, 28%);
&__reference {
font-size: 0;
}
&__angle::before {
border-color: transparent transparent rgb(255 255 255);
}
}
&__content {
width: 160px;
.cr-icon--weapp-nav {
vertical-align: sub;
margin: 0 5px;
}
}
}
.share-overlay {
position: fixed;
top: 0;
left: 0;
height: 100%;
width: 100%;
z-index: 8;
}
</style>
\ No newline at end of file
......@@ -26,4 +26,4 @@ export default class FreedomContainer extends Mixins(TransformStyleMixin, SaMixi
// }
}
}
\ No newline at end of file
}
......@@ -31,4 +31,4 @@
}
}
}
</style>
\ No newline at end of file
</style>
......@@ -9,11 +9,13 @@ import GridItem from '../../component/VueGridLayout/GridItem.vue';
import TransformStyleMixin from '@/page/mixins/transformStyle.mixin';
import SaMixin from '@/page/mixins/sa.mixin';
import { getStyle, debounce, isApp, isWxMp } from '@/service/utils.service';
import DisableTouchMixin from '@/page/mixins/disableTouch.mixin';
import { setAppTitleColor } from '@/service/color.service';
import { EventBus } from '@qg/citrus-ui/src/helper/service/eventBus';
import localStorage from '@/service/localStorage.service';
@Component({ components: { FreedomContainer, GridLayout, GridItem, PageBottomTip, BackTop, EmptyState }, name: 'Activity'})
export default class Activity extends Mixins(TransformStyleMixin, SaMixin) {
export default class Activity extends Mixins(TransformStyleMixin, SaMixin, DisableTouchMixin) {
@Getter('pageData') pageData;
@State(state => state.activity.pageInfo.pageName) pageName;
@State(state => state.activity.noPageData) noPageData;
......@@ -36,7 +38,6 @@ export default class Activity extends Mixins(TransformStyleMixin, SaMixin) {
targetEle: HTMLElement | null = null;
loading: boolean = true;
modfiTabsStyleDebounce = debounce(this.modfiTabsStyle, 300);
get layout() {
if (!isApp && !isWxMp && !EASY_ENV_IS_NODE) {
this.pageData.elements = this.pageData.elements.filter(v => v.name !== 'cs-search-bar');
......@@ -87,7 +88,7 @@ export default class Activity extends Mixins(TransformStyleMixin, SaMixin) {
}
mounted() {
this.targetEle = document.querySelector('body');
this.showBackTop = true;
if (EASY_ENV_IS_BROWSER) { this.showBackTop = true; }
this.pageVisibilityChange();
if (EASY_ENV_IS_BROWSER) {
EventBus.$on('NATIVE_EVENT_LOGIN', json => {
......@@ -133,7 +134,6 @@ export default class Activity extends Mixins(TransformStyleMixin, SaMixin) {
dot(title) {
console.log(title, '点击了');
}
layoutReadyEvent(newLayout) {
this.$nextTick(() => {
const loadingEle = document.querySelector('.mainload');
......
......@@ -24,7 +24,8 @@
:i="item.point.i"
:key="item.point.i"
:no-transforms="item.noTransforms"
@click.native="dot(item.title)"
@click.native="dot(item.title)"
@touchend.native="disTouch"
>
<component :data-index="index" :id="item.id" :containerIndex="index" :childItem="item" :is="item.name" :key="item.id" :sa-info="getSaInfo(item)" v-bind="item.props"></component>
</grid-item>
......@@ -48,6 +49,8 @@
</template>
<script lang="ts" src="./index.ts"></script>
<style lang="less" scoped>
@deep: ~'>>>';
.activity {
width: 100%;
min-height: 100%;
......@@ -81,4 +84,5 @@
overflow: visible !important;
transform: none !important;
}
</style>
import { Component, Vue } from 'vue-property-decorator';
let lastTouchEnd = 0;
@Component({ name: 'DisableTouchMixin' })
export default class DisableTouchMixin extends Vue {
disTouch(e) {
const now = (new Date()).getTime();
if (now - lastTouchEnd <= 300) {
e.preventDefault();
return false;
}
lastTouchEnd = now;
}
}
......@@ -45,6 +45,8 @@ export interface PageInfo {
enable?: number;
author?: string;
coverImage?: string;
shareCoverImage?: string; // 分享缩略图
shareOpenMethod?: string; // 分享后的打开方式
isTemplate?: number;
isPublish?: number | boolean;
appLoginState?: boolean;
......
......@@ -48,6 +48,8 @@ import Empty from '@qg/cherry-ui/src/empty';
Vue.use(Button);
Vue.use(Image);
Vue.use(Popover);
Vue.use(Icon);
// Vue.use(Cell);
// Vue.use(CellGroup);
// Vue.use(Row);
......
......@@ -8,6 +8,7 @@ export function initSa(router) {
const activityId = window.location.pathname.split('/')?.[2] || '';
const vccChannel = getParameterByName('vccChannel') || getParameterByName('registerFrom');
const sonVccChannel = getParameterByName('sonVccChannel');
const sa = require('sa-sdk-javascript');
sa.init({
server_url: config.shenceUrl,
heatmap: {
......
......@@ -139,6 +139,9 @@ export const isIOS = /iphone|ipad|ipod/.test(ua);
// 判读Android环境
export const isAndroid = /android/.test(ua);
// 判读非微信浏览器和appwebview和小程序webview
export const isH5Normal = !isWechat && !isWxMp && !isApp;
// 异常字段
export const errorQueryValues = ['{token}', '{vccToken}', '{registerFrom}', '{vccChannel}', '{sonVccChannel}', '{h}', '{uuid}', '{}'];
......
......@@ -6,6 +6,7 @@
"passportHost": "https://passportapi-test1.liangkebang.net",
"kdspHost": "https://talos-test1.liangkebang.net",
"loginUrl": "",
"mallHost": "https://mall-test1.liangkebang.net",
"h5ShopHost": "https://tenet-test1.liangkebang.net/#"
},
"mysql": {
......
......@@ -5,6 +5,7 @@
"passportHost": "https://passportapi-test1.liangkebang.net",
"kdspHost": "https://talos-test1.liangkebang.net",
"loginUrl": "",
"mallHost": "https://mall-test1.liangkebang.net",
"h5ShopHost": "https://tenet-test1.liangkebang.net/#",
"qiniuUpHost": "https://up-z0.qiniup.com",
"qiniuHost": "https://appsync.lkbang.net"
......
import { EggAppConfig } from 'egg';
import * as fs from 'fs';
import * as path from 'path';
import wxVertify from './wxVertify';
export default (appInfo: EggAppConfig) => {
const config: any = {};
config.siteFile = {
'/favicon.ico': fs.readFileSync(path.join(appInfo.baseDir, 'app/web/asset/images/favicon.ico')),
'/FZz8NUb3x0.txt': fs.readFileSync(path.join(appInfo.baseDir, 'app/web/asset/FZz8NUb3x0.txt')),
'/Ra6UCOeIhV.txt': fs.readFileSync(path.join(appInfo.baseDir, 'app/web/asset/Ra6UCOeIhV.txt'))
};
const siteFile = wxVertify;
siteFile['/favicon.ico'] = fs.readFileSync(path.join(appInfo.baseDir, 'app/web/asset/images/favicon.ico'));
config.siteFile = siteFile;
config.view = {
cache: false
......
import * as fs from 'fs';
import * as path from 'path';
export default {
'/FZz8NUb3x0.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/FZz8NUb3x0.txt')),
'/Ra6UCOeIhV.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/Ra6UCOeIhV.txt')),
'/2OqnbvHjoq.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/2OqnbvHjoq.txt')),
'/9HFuiOJ4BG.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/9HFuiOJ4BG.txt')),
'/bAgsGUG45y.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/bAgsGUG45y.txt')),
'/c8PA5Gybed.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/c8PA5Gybed.txt')),
'/J5QboPVm8N.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/J5QboPVm8N.txt')),
'/Jb5PMgT5lb.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/Jb5PMgT5lb.txt')),
'/NqUTl0J6Ed.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/NqUTl0J6Ed.txt')),
'/qsBZfgOk4y.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/qsBZfgOk4y.txt')),
'/tPICMyeJfv.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/tPICMyeJfv.txt')),
'/UBRJar2pST.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/UBRJar2pST.txt')),
'/yB3tnMTnRc.txt': fs.readFileSync(path.join(__dirname, '/wxVertify/yB3tnMTnRc.txt')),
};
90e68e2c196781968dba89bd5e6ac182
\ No newline at end of file
97efde44dc917901a8ca25a0feb54ad8
\ No newline at end of file
8fb57cfb856841b9d877e61df0729232
\ No newline at end of file
59297e3b609ad1c26e5b334fa56af181
\ No newline at end of file
cbc525fd71a2beb519d349084dece8da
\ No newline at end of file
3c6152f098bc4e3edad5b36f550cd268
\ No newline at end of file
25638138b18af91b2dd64db906b056a4
\ No newline at end of file
03f5c047a87a73854381c1d19c50fd68
\ No newline at end of file
8a154639c8af235d06e4b291463fb7a0
\ No newline at end of file
11f2efef0527b792380784ea1b4a4b65
\ No newline at end of file
5c9d1a08b3bda49beb0f950b1cdec27b
\ No newline at end of file
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