Commit ec1a581f authored by Xuguangxing's avatar Xuguangxing

Merge branch 'feat/group-buy' of git.quantgroup.cn:ui/group-buy-ui into feat/group-buy

parents d77e7142 6f909b8b
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<div id="app"> <div id="app">
<cr-nav-bar v-if="header" :title="title" left-text="" @click-left="backFun" /> <cr-nav-bar v-if="header" :title="title" left-text="" @click-left="backFun" />
<div class="app"> <div class="app">
<!-- <Weapp v-if="isWeixinBrowser" jump-url="/pages/user/login" /> --> <Weapp v-if="isWeixinBrowser" jump-url="/pages/groupbuy/webview" />
<keep-alive> <keep-alive>
<router-view v-if="$route.meta.keepLive" /> <router-view v-if="$route.meta.keepLive" />
</keep-alive> </keep-alive>
...@@ -20,14 +20,13 @@ import { mapState } from 'vuex'; ...@@ -20,14 +20,13 @@ import { mapState } from 'vuex';
import NetError from '@/components/NetError'; import NetError from '@/components/NetError';
import { isApp, isWxMp, isWechat } from '@/service/validation.service'; import { isApp, isWxMp, isWechat } from '@/service/validation.service';
import store from '@/store'; import store from '@/store';
// import Weapp from '@/components/weapp'; import Weapp from '@/components/weapp';
import goodsShare from '@/components/groupShare'; import goodsShare from '@/components/groupShare';
import qs from 'qs';
export default { export default {
name: 'App', name: 'App',
components: { components: {
NetError, NetError,
// Weapp, Weapp,
goodsShare goodsShare
}, },
data() { data() {
...@@ -59,19 +58,6 @@ export default { ...@@ -59,19 +58,6 @@ export default {
store.dispatch('change_is_weixin_browser', !isApp && !isWxMp && isWechat ? true : false); store.dispatch('change_is_weixin_browser', !isApp && !isWxMp && isWechat ? true : false);
} }
}, },
created() {
if (isWechat && !isWxMp) {
const params = {
jumpUrl: 'pages/groupbuy/webview',
terminal: 1,
extraInfo: JSON.stringify({
url: window.location.href
})
};
const url = qs.stringify(params);
window.location.href = `https://mall.q-gp.com/common/launch?${url}`;
}
},
methods: { methods: {
backFun() { backFun() {
this.$router.go(-1); this.$router.go(-1);
......
...@@ -31,11 +31,6 @@ export default { ...@@ -31,11 +31,6 @@ export default {
params params
}); });
}, },
getGroupAvator(data) {
return http.get(`http://yapi.quantgroups.com/mock/479/goods/getAvator`, data, {
hideLoading: true
});
},
getWxConfig(url = window.location.href.split('#')[0]) { getWxConfig(url = window.location.href.split('#')[0]) {
return http.post(`${talosHost}/api/kdsp/wx/mp/getJsapiSign`, { return http.post(`${talosHost}/api/kdsp/wx/mp/getJsapiSign`, {
url: url, url: url,
......
<template>
<div class="avator-swiper">
<swiper
ref="mySwiper"
:options="swiperOptions"
class="avator-swiper_container"
@slide-change="slideChange"
@set-translate="setTranslate"
>
<swiper-slide v-for="(item, index) in avatorData" :key="index" class="avator-swiper_item">
<div class="avator-swiper_item">
<img :src="item | Img2Thumb" />
</div>
</swiper-slide>
</swiper>
</div>
</template>
<script>
import { swiper, swiperSlide } from 'vue-awesome-swiper';
import 'swiper/dist/css/swiper.css';
import Img2Thumb from '@/filters/img2Thumb.filter';
export default {
name: 'AvatorSwiper',
components: {
swiper,
swiperSlide
},
filters: {
Img2Thumb
},
props: {
avatorData: {
type: Array,
default() {
return [];
}
}
},
data() {
return {
activeIndex: 0,
swiperOptions: {
loop: true,
initialSlide: 0,
slidesPerView: 9,
spaceBetween: 4,
speed: 900,
centeredSlides: true,
watchSlidesProgress: true,
allowTouchMove: false,
autoplay: {
delay: 900,
stopOnLastSlide: false,
disableOnInteraction: false
}
}
};
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper;
}
},
methods: {
slideChange() {
this.activeIndex = this.swiper.realIndex;
},
setTranslate() {
const slides = this.swiper.slides;
for (let i = 0; i < slides.length; i++) {
const slide = slides.eq(i);
const progress = slides[i].progress;
slide.css('opacity', 1 - Math.abs(progress) / 9);
slide.css('transform', `scale(${1 - Math.abs(progress) / 17}`);
}
}
}
};
</script>
<style lang="less">
.avator-swiper {
width: 100%;
margin: 0 auto !important;
&_item {
transition: transform 0.2s linear;
height: 32px;
padding-top: 2px;
img {
height: 25px;
width: 25px;
border-radius: 50%;
}
&.active {
transform: scale(1.2);
}
}
}
</style>
<template> <template>
<div class="avator-swiper"> <div class="avator-swiper">
<div ref="refLeft" :class="{ 'ani-left': isAddClass }" class="avator-swiper_left">
<cr-image class="avator-swiper_small" :src="leftImgPath" />
</div>
<swiper <swiper
ref="mySwiper" ref="mySwiper"
:options="swiperOptions" :options="swiperOptions"
class="avator-swiper_container" class="avator-swiper_container"
@set-translate="setTranslate" @set-translate="setTranslate"
> >
<swiper-slide v-for="(item, index) in avatorData" :key="index" class="avator-swiper_item"> <swiper-slide
v-for="(item, index) in avatorData"
:key="index"
:data-src="item"
:data-name="item"
class="avator-swiper_item"
>
<div class="avator-swiper_item"> <div class="avator-swiper_item">
<img :src="item | Img2Thumb" /> <img :src="item | Img2Thumb" />
</div> </div>
</swiper-slide> </swiper-slide>
</swiper> </swiper>
<div ref="refRight" :class="{ 'ani-right': isAddClass }" class="avator-swiper_right">
<cr-image class="avator-swiper_small" :src="rightImgPath" />
</div>
</div> </div>
</template> </template>
<script> <script>
...@@ -37,8 +49,12 @@ export default { ...@@ -37,8 +49,12 @@ export default {
}, },
data() { data() {
const vm = this; const vm = this;
return { return {
isAddClass: false,
activeIndex: 0, activeIndex: 0,
rightImgPath: '',
leftImgPath: '',
swiperOptions: { swiperOptions: {
loop: true, loop: true,
initialSlide: 0, initialSlide: 0,
...@@ -48,37 +64,28 @@ export default { ...@@ -48,37 +64,28 @@ export default {
centeredSlides: true, centeredSlides: true,
watchSlidesProgress: true, watchSlidesProgress: true,
allowTouchMove: false, allowTouchMove: false,
autoplay: false, autoplay: {
delay: 5000
on: {
init: function() {
const slideLeft = this.slides.eq(this.activeIndex);
console.log(slideLeft);
// slideLeft.addClass('ani-left');
}, },
on: {
transitionStart: function() { transitionStart: function() {
const activeIndex = this.activeIndex; const activeIndex = this.activeIndex;
// const slideLeft = this.slides.eq(activeIndex); const slideLeft = this.slides.eq(activeIndex - 5);
// const slideRight = this.slides.eq(activeIndex + 7); const slideRight = this.slides.eq(activeIndex + 4);
// vm.avatorItem = vm.getAvatorItem(slideLeft); vm.avatorItem = vm.getAvatorItem(slideRight);
// vm.rightImgPath = slideRight.data('src'); vm.leftImgPath = slideLeft.data('src');
// slideLeft.addClass('ani-left'); vm.rightImgPath = slideRight.data('src');
// slideRight.addClass('ani-right'); slideRight.addClass('ani-opt');
console.log(activeIndex); slideLeft.addClass('ani-opt');
vm.isAddClass = true;
vm.$store.dispatch('goods_avator_info', { showInfo: false });
}, },
transitionEnd: function() { transitionEnd: function() {
console.log('结束'); vm.$store.dispatch('goods_avator_info', { ...vm.avatorItem, showInfo: true });
vm.$emit('customers-end', vm.avatorItem); vm.isAddClass = false;
// // for (let i = 0; i < this.slides.length; i++) { for (let i = 0; i < this.slides.length; i++) {
// // let slide = this.slides.eq(i); let slide = this.slides.eq(i);
// // slide.removeClass('ani-left ani-right'); slide.removeClass('ani-opt');
// // }
const slides = this.slides;
for (let i = 0; i < slides.length; i++) {
const slide = slides.eq(i);
const progress = slides[i].progress;
slide.css('opacity', 1 - Math.abs(progress) / 9);
slide.css('transform', `scale(${1 - Math.abs(progress) / 17}`);
} }
} }
} }
...@@ -90,30 +97,15 @@ export default { ...@@ -90,30 +97,15 @@ export default {
return this.$refs.mySwiper.swiper; return this.$refs.mySwiper.swiper;
} }
}, },
mounted() {
this.onSlidePrevChange();
},
beforeDestroy() {
clearInterval(this.timer);
},
methods: { methods: {
setTranslate() { setTranslate() {
const slides = this.swiper.slides; const slides = this.swiper.slides;
for (let i = 0; i < slides.length; i++) { for (let i = 0; i < slides.length; i++) {
const slide = slides.eq(i); const slide = slides.eq(i);
const progress = slides[i].progress; const progress = slides[i].progress;
slide.css('opacity', 1 - Math.abs(progress) / 9);
slide.css('transform', `scale(${1 - Math.abs(progress) / 17}`); slide.css('transform', `scale(${1 - Math.abs(progress) / 17}`);
} }
}, },
onSlidePrevChange() {
this.timer && clearInterval(this.timer);
this.timer = setInterval(() => {
this.$emit('customers-start');
this.swiper.slideNext();
}, 5000);
},
getAvatorItem(ele) { getAvatorItem(ele) {
return { return {
src: ele.data('src'), src: ele.data('src'),
...@@ -121,18 +113,74 @@ export default { ...@@ -121,18 +113,74 @@ export default {
}; };
} }
} }
// methods: {
// slideChange() {
// this.activeIndex = this.swiper.realIndex;
// },
// }
}; };
</script> </script>
<style lang="less"> <style lang="less">
@keyframes bigToSamll {
from {
transform: scale(1);
}
to {
transform: scale(0);
}
}
@keyframes samllToBig {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
.ani-left {
transform-origin: center;
animation: bigToSamll 1s linear;
animation-fill-mode: forwards;
}
.ani-right {
transform-origin: center;
animation: samllToBig 1s linear;
animation-fill-mode: forwards;
}
.ani-opt {
opacity: 0;
}
@keyframes scaleTo {
to {
opacity: 1;
}
}
.avator-swiper_right {
img {
width: 100%;
height: 100%;
}
}
.avator-swiper { .avator-swiper {
position: relative;
&_left,
&_right {
position: absolute;
width: 18px;
height: 18px;
top: 50%;
margin-top: -9px;
border-radius: 50%;
overflow: hidden;
img {
width: 100%;
height: 100%;
}
}
&_left {
left: 3.5px;
}
&_right {
right: 3.5px;
}
width: 100%; width: 100%;
margin: 0 auto !important; margin: 0 auto !important;
&_item { &_item {
transition: transform 0.2s linear; transition: transform 0.2s linear;
height: 32px; height: 32px;
......
<template>
<div class="avator-swiper">
<swiper ref="mySwiper" :options="swiperOptions" class="avator-swiper_container">
<swiper-slide
v-for="(item, index) in avatorData"
:key="index"
:data-name="item.name"
:data-src="item.avatar"
class="avator-swiper_item"
>
<img :src="item.avatar" />
</swiper-slide>
</swiper>
<div class="avator-swiper_right">
<cr-image class="avator-swiper_item" :src="rightImgPath" />
</div>
</div>
</template>
<script>
import { swiper, swiperSlide } from 'vue-awesome-swiper';
import 'swiper/dist/css/swiper.css';
export default {
name: 'GroupSwiper',
components: {
swiper,
swiperSlide
},
props: {
avatorData: {
type: Array,
default() {
return [];
}
}
},
data() {
const vm = this;
return {
timer: null,
rightImgPath: '',
avatorItem: null,
swiperOptions: {
loop: true,
initialSlide: 0,
slidesPerView: 7,
spaceBetween: 4,
speed: 1600,
centeredSlides: true,
watchSlidesProgress: true,
allowTouchMove: false,
autoplay: false,
on: {
init: function() {
const slideLeft = this.slides.eq(this.activeIndex - 3);
slideLeft.addClass('ani-left');
},
transitionStart: function() {
const activeIndex = this.activeIndex;
const slideLeft = this.slides.eq(activeIndex - 3);
const slideRight = this.slides.eq(activeIndex + 4);
vm.avatorItem = vm.getAvatorItem(slideLeft);
vm.rightImgPath = slideRight.data('src');
slideLeft.addClass('ani-left');
slideRight.addClass('ani-right');
},
transitionEnd: function() {
vm.$emit('animation-event-end', vm.avatorItem);
for (let i = 0; i < this.slides.length; i++) {
let slide = this.slides.eq(i);
slide.removeClass('ani-left ani-right');
}
}
}
}
};
},
computed: {
swiper() {
return this.$refs.mySwiper.swiper;
}
},
mounted() {
this.onSlidePrevChange();
},
beforeDestroy() {
clearInterval(this.timer);
},
methods: {
onSlidePrevChange() {
this.timer && clearInterval(this.timer);
this.timer = setInterval(() => {
this.$emit('animation-event-start');
this.swiper.slidePrev();
}, 5000);
},
getAvatorItem(ele) {
return {
src: ele.data('src'),
name: ele.data('name')
};
}
}
};
</script>
<style lang="less">
@keyframes leftToRight {
from {
transform: scale(0.3, 0.3);
transform-origin: right right;
opacity: 0;
}
to {
transform: scale(1, 1);
transform-origin: left left;
opacity: 1;
}
}
.ani-left {
transform-origin: right;
animation: leftToRight 1.6s linear;
}
@keyframes scaleTo {
to {
opacity: 1;
}
}
.ani-right {
opacity: 0;
// animation: scaleTo 3s ease-out;
}
.avator-swiper {
width: 100%;
margin: 0 auto !important;
position: relative;
&_right {
height: 100%;
width: 25px;
position: absolute;
right: 3px;
top: 0px;
}
&_item {
// transition: transform 0.2s linear;
padding-top: 2px;
img {
height: 25px;
width: 25px;
border-radius: 50%;
border: solid @white 1px;
}
}
}
</style>
<template> <template>
<div class="avator-swiper"> <div class="avator-swiper">
<div class="avator-swiper_left" :class="{ anileft: isAnimate }">
<cr-image class="avator-swiper_item" :src="leftImgPath" />
</div>
<swiper ref="mySwiper" :options="swiperOptions" class="avator-swiper_container"> <swiper ref="mySwiper" :options="swiperOptions" class="avator-swiper_container">
<swiper-slide <swiper-slide
v-for="(item, index) in avatorData" v-for="(item, index) in avatorData"
...@@ -36,7 +39,9 @@ export default { ...@@ -36,7 +39,9 @@ export default {
data() { data() {
const vm = this; const vm = this;
return { return {
isAnimate: false,
timer: null, timer: null,
leftImgPath: '',
rightImgPath: '', rightImgPath: '',
avatorItem: null, avatorItem: null,
swiperOptions: { swiperOptions: {
...@@ -48,26 +53,29 @@ export default { ...@@ -48,26 +53,29 @@ export default {
centeredSlides: false, centeredSlides: false,
watchSlidesProgress: true, watchSlidesProgress: true,
allowTouchMove: false, allowTouchMove: false,
autoplay: false, autoplay: {
on: { delay: 5000,
init: function() { reverseDirection: true
const slideLeft = this.slides.eq(this.activeIndex);
slideLeft.addClass('ani-left');
}, },
on: {
transitionStart: function() { transitionStart: function() {
const activeIndex = this.activeIndex; const activeIndex = this.activeIndex,
const slideLeft = this.slides.eq(activeIndex); slideLeft = this.slides.eq(activeIndex),
const slideRight = this.slides.eq(activeIndex + 7); slideRight = this.slides.eq(activeIndex + 7);
vm.$emit('animation-event-start');
vm.avatorItem = vm.getAvatorItem(slideLeft); vm.avatorItem = vm.getAvatorItem(slideLeft);
vm.isAnimate = true;
vm.rightImgPath = slideRight.data('src'); vm.rightImgPath = slideRight.data('src');
slideLeft.addClass('ani-left'); vm.leftImgPath = slideLeft.data('src');
slideRight.addClass('ani-right'); slideLeft.addClass('ani-opt');
slideRight.addClass('ani-opt');
}, },
transitionEnd: function() { transitionEnd: function() {
vm.isAnimate = false;
vm.$emit('animation-event-end', vm.avatorItem); vm.$emit('animation-event-end', vm.avatorItem);
for (let i = 0; i < this.slides.length; i++) { for (let i = 0; i < this.slides.length; i++) {
let slide = this.slides.eq(i); let slide = this.slides.eq(i);
slide.removeClass('ani-left ani-right'); slide.removeClass('ani-opt');
} }
} }
} }
...@@ -79,21 +87,7 @@ export default { ...@@ -79,21 +87,7 @@ export default {
return this.$refs.mySwiper.swiper; return this.$refs.mySwiper.swiper;
} }
}, },
mounted() {
this.onSlidePrevChange();
},
beforeDestroy() {
clearInterval(this.timer);
// this.onSlidePrevChange();
},
methods: { methods: {
onSlidePrevChange() {
this.timer && clearInterval(this.timer);
this.timer = setInterval(() => {
this.$emit('animation-event-start');
this.swiper.slidePrev();
}, 5000);
},
getAvatorItem(ele) { getAvatorItem(ele) {
return { return {
src: ele.data('src'), src: ele.data('src'),
...@@ -116,18 +110,13 @@ export default { ...@@ -116,18 +110,13 @@ export default {
opacity: 1; opacity: 1;
} }
} }
.ani-left { .anileft {
transform-origin: right; transform-origin: right;
animation: leftToRight 1s linear; animation: leftToRight 1s linear;
} }
@keyframes scaleTo {
to { .ani-opt {
opacity: 1;
}
}
.ani-right {
opacity: 0; opacity: 0;
// animation: scaleTo 3s ease-out;
} }
.avator-swiper { .avator-swiper {
width: 100%; width: 100%;
...@@ -136,13 +125,19 @@ export default { ...@@ -136,13 +125,19 @@ export default {
&_container { &_container {
transition-timing-function: linear; transition-timing-function: linear;
} }
&_right { &_right,
&_left {
height: 100%; height: 100%;
width: 25px; width: 25px;
position: absolute; position: absolute;
right: 3px;
top: 0px; top: 0px;
} }
&_right {
right: 3px;
}
&_left {
left: 0px;
}
&_item { &_item {
transition: transform 0.2s linear; transition: transform 0.2s linear;
padding-top: 2px; padding-top: 2px;
......
<template> <template>
<!-- 狼大呜原始ID:gh_e1d790d67513
羊小咩原始ID:gh_a976018bfb9e -->
<wx-open-launch-weapp <wx-open-launch-weapp
class="launch-btn" class="launch-btn"
username="gh_a976018bfb9e" username="gh_e1d790d67513"
:path="jumpUrl" :path="jumpUrl"
@launch="launch" @launch="launch"
@error="launchError" @error="launchError"
......
import * as types from './type'; import * as types from './type';
import groupBuy from '@/api/groupBuy'; import groupBuy from '@/api/groupBuy';
import { isWxMp } from '@/service/validation.service';
import { paramsParentheses } from '@/service/utils.service'; import { paramsParentheses } from '@/service/utils.service';
const state = { const state = {
header: true, header: true,
...@@ -12,7 +11,7 @@ const state = { ...@@ -12,7 +11,7 @@ const state = {
isWeixinBrowser: false, // 是否是微信浏览器 isWeixinBrowser: false, // 是否是微信浏览器
showShare: false, // 是否打开底部分享showShare showShare: false, // 是否打开底部分享showShare
shareInfo: {}, // 分享信息 shareInfo: {}, // 分享信息
goodsShareInfo: null avatorInfo: {} // 详情页面头像滚动
}; };
// getters // getters
...@@ -41,14 +40,8 @@ const actions = { ...@@ -41,14 +40,8 @@ const actions = {
change_is_weixin_browser({ commit }, bool) { change_is_weixin_browser({ commit }, bool) {
commit(types.CHANGE_IS_WEIXIN_BROWSER, bool); commit(types.CHANGE_IS_WEIXIN_BROWSER, bool);
}, },
goods_share_open({ commit }, options) { goods_avator_info({ commit }, info) {
commit(types.GOODS_SHARE_OPEN, options); commit(types.GOODS_AVATOR_INFO, info);
},
goods_share_close({ commit }) {
commit(types.GOODS_SHARE_CLOSE);
},
goods_send_shareinfo({ commit }, options) {
commit(types.GOODS_SEND_SHAREINFO, options);
} }
}; };
...@@ -119,17 +112,8 @@ const mutations = { ...@@ -119,17 +112,8 @@ const mutations = {
}); });
} }
}, },
[types.GOODS_SHARE_OPEN](state, options) { [types.GOODS_AVATOR_INFO](state, info) {
if (isWxMp) { state.avatorInfo = info;
state.shareInfo = options;
state.showShare = true;
}
},
[types.GOODS_SHARE_CLOSE](state) {
state.showShare = false;
},
[types.GOODS_SEND_SHAREINFO](state, options) {
state.goodsShareInfo = options;
} }
}; };
......
...@@ -7,6 +7,4 @@ export const CHANGE_IS_WEIXIN_BROWSER = 'CHANGE_IS_WEIXIN_BROWSER'; ...@@ -7,6 +7,4 @@ export const CHANGE_IS_WEIXIN_BROWSER = 'CHANGE_IS_WEIXIN_BROWSER';
export const ADD_KEEP_ALIVE = 'ADD_KEEP_ALIVE'; export const ADD_KEEP_ALIVE = 'ADD_KEEP_ALIVE';
export const DEL_KEEP_ALIVE = 'DEL_KEEP_ALIVE'; export const DEL_KEEP_ALIVE = 'DEL_KEEP_ALIVE';
export const CLEAR_KEEP_ALIVE = 'CLEAR_KEEP_ALIVE'; export const CLEAR_KEEP_ALIVE = 'CLEAR_KEEP_ALIVE';
export const GOODS_SHARE_OPEN = 'GOODS_SHARE_OPEN'; export const GOODS_AVATOR_INFO = 'GOODS_AVATOR_INFO';
export const GOODS_SHARE_CLOSE = 'GOODS_SHARE_CLOSE';
export const GOODS_SEND_SHAREINFO = 'GOODS_SEND_SHAREINFO';
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
</template> </template>
</cr-swipe> </cr-swipe>
<div class="goods-swipe-avator"> <div class="goods-swipe-avator">
<swipe-customer-info v-model="showInfo" /> <swipe-customer-info v-model="avatorInfo.showInfo" :avatar="avatorInfo.src" />
</div> </div>
</div> </div>
<div class="goods-group-buy-info"> <div class="goods-group-buy-info">
...@@ -227,7 +227,6 @@ export default { ...@@ -227,7 +227,6 @@ export default {
return { return {
timestemp: '', // 大活动结束时间 timestemp: '', // 大活动结束时间
groupTimestemp: '', // 小团结束时间 groupTimestemp: '', // 小团结束时间
showInfo: false,
inProgress: false, // 活动是否已经开始 inProgress: false, // 活动是否已经开始
countDownText: '', countDownText: '',
showPage: false, // 是否显示页面,当查询完团与人的关系后进行处理,如果用户已经参与了此商品此活动的团,navigateto small else showpage = true showPage: false, // 是否显示页面,当查询完团与人的关系后进行处理,如果用户已经参与了此商品此活动的团,navigateto small else showpage = true
...@@ -265,7 +264,8 @@ export default { ...@@ -265,7 +264,8 @@ export default {
}, },
...mapState({ ...mapState({
isPrimordialBrowser: state => state.pay.showMiniappGuide, isPrimordialBrowser: state => state.pay.showMiniappGuide,
isWeixinBrowser: state => state.pay.isWeixinBrowser isWeixinBrowser: state => state.pay.isWeixinBrowser,
avatorInfo: state => state.pay.avatorInfo
}) })
}, },
created() { created() {
...@@ -284,15 +284,6 @@ export default { ...@@ -284,15 +284,6 @@ export default {
this.name = this.$route.params; this.name = this.$route.params;
this.init(this.detailParam); this.init(this.detailParam);
}, },
mounted() {
// todo 曝光埋点
setTimeout(() => {
this.showInfo = true;
}, 3000);
setTimeout(() => {
this.showInfo = false;
}, 5000);
},
methods: { methods: {
setShareData() { setShareData() {
const avatorList = []; const avatorList = [];
......
<template>
<div v-if="Object.keys(detailInfo).length > 0" class="goods" style="height: 100%">
<!-- 主体 -->
<div class="goods-container">
<div class="goods-red-bg" />
<div class="goods-group-buy-head-content">
<div class="goods-group-buy-head-content-desc">超值0元购,正在拼团中</div>
<div class="goods-group-buy-head-content-swipe">
<swipe-customer-info v-model="showInfo" direction="right" />
</div>
</div>
<div class="goods-product-info">
<div class="goods-product-info-img">
<span
v-if="detailInfo.groupBuyInfo && detailInfo.groupBuyInfo.groupBuyLimitUserCount"
class="goods-product-info-tag"
>{{ detailInfo.groupBuyInfo.groupBuyLimitUserCount }}人团</span
>
<cr-image
class="goods-product-info-img-img-box"
width=""
height=""
:src="detailInfo.thumbImageUrl"
/>
</div>
<div class="goods-product-info-desc">
<div class="goods-product-info-desc-part1">
<div class="goods-product-info-desc-title">
{{ detailInfo.goodsName }}
</div>
<div class="goods-product-info-desc-progress">
<cr-progress
class="group-item-progress"
stroke-width="5"
color="#EC1500"
track-color="#F7F8F9"
:show-pivot="false"
:percentage="stockPercentage"
/>
</div>
<div class="goods-product-info-desc-num">
已拼{{ detailInfo.groupBuyInfo ? detailInfo.groupBuyInfo.groupBuySuccessCount : 0 }}
</div>
</div>
<div class="goods-product-info-desc-price">
<div class="goods-product-info-desc-price-group">
成团价 ¥<span class="actualPrice">0</span>
</div>
<div class="goods-product-info-desc-price-market">
售价¥{{ detailInfo.activityPrice }}
</div>
</div>
</div>
</div>
<div class="goods-group-info">
<div class="goods-group-info-status">
<cr-image
v-if="detailInfo.groupBuyInfo.groupBuyStatus == 2"
width="80"
src="../../assets/images/success.png"
/>
<cr-image
v-if="detailInfo.groupBuyInfo.groupBuyStatus == 3"
width="80"
src="../../assets/images/defeat.png"
/>
</div>
<avatorGroup :group-info="detailInfo.groupBuyInfo || {}" />
<group-desc-info
:group-info="detailInfo.groupBuyInfo || {}"
:timestemp="groupTimestemp"
:show-button-group="true"
@changeButtonVisible="changeButtonVisible"
@share="setShareData"
/>
<successInfo :group-info="detailInfo.groupBuyInfo || {}" />
<cr-divider
hairline
:style="{
borderColor: '#ECECEC'
}"
/>
<rules :group-info="detailInfo.groupBuyInfo || {}" />
</div>
<span v-if="detailImgList.length" id="goodDetail" class="goods-divider">宝贝详情</span>
<div class="goods-detail-imgs">
<cr-image
v-for="(item, index) in detailImgList"
:key="index"
lazy-load
width=""
height=""
style="width: 100%; height: auto; display: block"
:src="item"
/>
</div>
</div>
<bottom-nav v-if="showButtonNav" :status="2" :disabled="false" @share="setShareData" />
</div>
</template>
<script>
import goods from '@/api/groupBuy';
import bottomNav from './components/bottomNav';
import swipeCustomerInfo from '@/components/swipeCustomerInfo';
import avatorGroup from '@/components/avatorGroup';
import successInfo from '@/components/groupBuySuccessInfo';
import rules from '@/components/rules';
import groupDescInfo from './components/groupDescInfo';
import localStorage from '@/service/localStorage.service';
import { EventBus } from '@/service/utils.service';
// import sharePic from '@/components/sharePic';
import config from '@/config';
export default {
// eslint-disable-next-line vue/name-property-casing
name: 'goodDetail',
components: {
bottomNav,
swipeCustomerInfo,
avatorGroup,
successInfo,
rules,
groupDescInfo
// sharePic
},
data() {
return {
groupTimestemp: '', // 小团结束时间
showInfo: false,
countDownText: '',
stockPercentage: 0,
shareInfo: {}, // 调用分享需要的参数
picUrl: '', // 海报url
// 以下是原有的data
detailParam: {
skuNo: '',
receiverId: '',
count: 1
},
detailInfo: {},
imgList: [],
detailImgList: [], // 商品详情图像展示
name: {},
showButtonNav: false // 是否显示底部按钮
};
},
created() {
console.log(config.localHost);
this.detailParam = { ...this.$route.query };
localStorage.set('templateId', this.detailParam.templateId); // 设置活动模板id,用于下单
if (this.detailParam.groupBuyGroupId) {
localStorage.set('groupBuyGroupId', this.detailParam.groupBuyGroupId); // 设置groupBuyGroupId,用于下单
this.groupId = +this.detailParam.groupBuyGroupId;
} else {
localStorage.remove('groupBuyGroupId');
this.groupId = 0;
}
this.name = this.$route.params;
this.imgList = [this.name.goodsimg];
this.init(this.detailParam);
},
mounted() {
// todo 曝光埋点
setTimeout(() => {
this.showInfo = true;
}, 3000);
setTimeout(() => {
this.showInfo = false;
}, 5000);
},
methods: {
setShareData() {
const avatorList = [];
if (this.detailInfo.groupBuyInfo.groupBuyValidUserInfoList) {
this.detailInfo.groupBuyInfo.groupBuyValidUserInfoList.map(v => {
avatorList.push(v.avatar);
});
}
const sharePicData = {
groupBuySuccessGuys: this.detailInfo?.groupBuyInfo.groupBuySuccessPersonCount,
salePrice: this.detailInfo.price, // y
groupBuyGroupId: this.groupId,
goodsSpecialId: this.detailParam.goodsSpecialId,
openGroupCnt: this.detailInfo?.groupBuyInfo.groupBuyLimitUserCount,
templateId: this.detailParam.templateId,
templateDetailId: this.detailParam.templateDetailId,
needGuys: this.detailInfo?.groupBuyInfo.groupBuyNeedUserCount,
skuName: this.detailInfo.goodsName, // y
activityId: this.detailParam.activityId,
skuImg: this.detailInfo.thumbImageUrl, // y,
activityPrice: this.detailInfo.activityPrice, // y
skuNo: this.detailParam.skuNo,
peoplePhotoList: avatorList,
endTime: this.detailInfo?.groupBuyInfo.currentGroupEndTime || this.detailInfo?.endTime || ''
};
EventBus.$emit('goods_share_info', {
shareInfo: sharePicData,
type: 2
});
},
changeButtonVisible(res) {
this.showButtonNav = res;
},
async init(detailParam) {
const [res] = await goods.detailInfo(detailParam);
if (res.groupBuyInfo.groupId) {
localStorage.set('groupBuyGroupId', res.groupBuyInfo.groupId || ''); // 设置groupBuyGroupId,用于下单
this.groupId = +res.groupBuyInfo.groupId || '';
}
if (res.saleCount && res.activitySkuTotalCount) {
const percentage = +res.saleCount / +res.activitySkuTotalCount;
if (isNaN(percentage)) {
this.stockPercentage = 0;
} else {
this.stockPercentage = Math.floor(percentage) >= 1 ? 100 : Math.floor(percentage * 100);
}
console.log(this.stockPercentage);
}
this.imgList = res.imageUrl || [];
this.detailInfo = res;
this.setStartStatus(res);
try {
const detailImages = await goods.getDetailPic(this.detailInfo.contentDetailUrl);
// const imgReg = new RegExp('(?<=src=").[^"]*', 'g');
// this.detailImgList = (detailImages || '').match(imgReg);
let imgReg = /<img.*?(?:>|\/>)/gi;
// eslint-disable-next-line no-useless-escape
let srcReg = /src=[\'"]?([^\'"]*)[\'"]?/i;
let arr = (detailImages || '').match(imgReg);
let srcArr = [];
for (let i = 0; i < arr.length; i++) {
let src = arr[i].match(srcReg)[1].replace('http://', 'https://');
srcArr.push(src);
}
this.detailImgList = srcArr;
} catch (error) {
console.error(error);
}
},
setStartStatus(data) {
const currentTime = new Date(data.currentTime.replace(/\-/g, '/')).getTime();
const activityStartTime = new Date(data.startTime.replace(/\-/g, '/')).getTime();
const activityEndTime = new Date(data.endTime.replace(/\-/g, '/')).getTime();
this.groupTimestemp = data.groupBuyInfo.currentGroupEndTime
? new Date(data.groupBuyInfo.currentGroupEndTime.replace(/\-/g, '/')).getTime()
: -1;
if (currentTime <= activityStartTime) {
// 当前时间小于活动开始时间
this.countDownText = '距活动开始时间';
return;
}
if (currentTime >= activityEndTime) {
this.countDownText = '活动已结束';
return;
}
if (currentTime > activityStartTime && currentTime < activityEndTime) {
this.countDownText = '距活动结束';
return;
}
}
}
};
</script>
<style lang="less" src="./smallPic.less" scoped></style>
...@@ -6,7 +6,11 @@ ...@@ -6,7 +6,11 @@
<div class="goods-group-buy-head-content"> <div class="goods-group-buy-head-content">
<div class="goods-group-buy-head-content-desc">超值0元购,正在拼团中</div> <div class="goods-group-buy-head-content-desc">超值0元购,正在拼团中</div>
<div class="goods-group-buy-head-content-swipe"> <div class="goods-group-buy-head-content-swipe">
<swipe-customer-info v-model="showInfo" direction="right" /> <swipe-customer-info
v-model="avatorInfo.showInfo"
:avatar="avatorInfo.src"
direction="right"
/>
</div> </div>
</div> </div>
<div class="goods-product-info"> <div class="goods-product-info">
...@@ -110,6 +114,7 @@ import localStorage from '@/service/localStorage.service'; ...@@ -110,6 +114,7 @@ import localStorage from '@/service/localStorage.service';
import { EventBus } from '@/service/utils.service'; import { EventBus } from '@/service/utils.service';
// import sharePic from '@/components/sharePic'; // import sharePic from '@/components/sharePic';
import config from '@/config'; import config from '@/config';
import { mapState } from 'vuex';
export default { export default {
// eslint-disable-next-line vue/name-property-casing // eslint-disable-next-line vue/name-property-casing
name: 'goodDetail', name: 'goodDetail',
...@@ -125,7 +130,6 @@ export default { ...@@ -125,7 +130,6 @@ export default {
data() { data() {
return { return {
groupTimestemp: '', // 小团结束时间 groupTimestemp: '', // 小团结束时间
showInfo: false,
countDownText: '', countDownText: '',
stockPercentage: 0, stockPercentage: 0,
shareInfo: {}, // 调用分享需要的参数 shareInfo: {}, // 调用分享需要的参数
...@@ -144,6 +148,11 @@ export default { ...@@ -144,6 +148,11 @@ export default {
showButtonNav: false // 是否显示底部按钮 showButtonNav: false // 是否显示底部按钮
}; };
}, },
computed: {
...mapState({
avatorInfo: state => state.pay.avatorInfo
})
},
created() { created() {
console.log(config.localHost); console.log(config.localHost);
this.detailParam = { ...this.$route.query }; this.detailParam = { ...this.$route.query };
...@@ -159,19 +168,6 @@ export default { ...@@ -159,19 +168,6 @@ export default {
this.imgList = [this.name.goodsimg]; this.imgList = [this.name.goodsimg];
this.init(this.detailParam); this.init(this.detailParam);
}, },
mounted() {
EventBus.$on('customers-end', customers => {
console.log(customers);
});
// todo 曝光埋点
setTimeout(() => {
this.showInfo = true;
}, 3000);
setTimeout(() => {
this.showInfo = false;
}, 5000);
},
methods: { methods: {
setShareData() { setShareData() {
const avatorList = []; const avatorList = [];
......
...@@ -40,48 +40,13 @@ ...@@ -40,48 +40,13 @@
<div class="Ol__foot-text">{{ cardInfoMation[item.openGroupStatus].footTxt }}</div> <div class="Ol__foot-text">{{ cardInfoMation[item.openGroupStatus].footTxt }}</div>
<div class="Ol__foot-btns"> <div class="Ol__foot-btns">
<cr-button <cr-button
v-if="item.showInvite && item.payStatus === '1'"
size="small" size="small"
plain plain
type="primary" type="primary"
shape="circle" shape="circle"
@click.stop="openShareEvent(item.skuList[0])" @click.stop="bundleButtonClick(item)"
> >
邀请好友 {{ showButtonMethod[item.showButton].text }}
</cr-button>
<cr-button
v-if="item.showOrderDetail"
size="small"
plain
type="primary"
shape="circle"
@click.stop="goGroupDetails(item)"
>
查看订单
</cr-button>
<!-- 支付中按钮跳转支付页面 -->
<!-- v-if="item.openGroupStatus === 0 && item.payStatus === '0'" -->
<cr-button
v-if="
(item.openGroupStatus == 0 || item.openGroupStatus == 1) && item.payStatus == '0'
"
size="small"
plain
type="primary"
shape="circle"
@click.stop="goGroupPayPages(item)"
>
去支付
</cr-button>
<cr-button
v-if="item.openGroupStatus === 3"
size="small"
plain
type="primary"
shape="circle"
@click.stop="goGroupBuyList(item)"
>
重新拼团
</cr-button> </cr-button>
</div> </div>
</div> </div>
...@@ -102,10 +67,7 @@ const EVENT_LOADING = 'load'; ...@@ -102,10 +67,7 @@ const EVENT_LOADING = 'load';
const EVENT_CLICK = 'option-click'; const EVENT_CLICK = 'option-click';
import countDown from '@/components/countDown'; import countDown from '@/components/countDown';
import { isWxMp, isApp } from '@/service/validation.service'; import { isWxMp, isApp } from '@/service/validation.service';
import Bridge from '@qg/js-bridge';
import MpBridge from '@/service/mp';
import { saTrackEvent } from '@/service/sa.service'; import { saTrackEvent } from '@/service/sa.service';
import groupBuyApi from '@/api/groupBuy';
import localStorage from '@/service/localStorage.service'; import localStorage from '@/service/localStorage.service';
export default { export default {
name: 'OrderSkuList', name: 'OrderSkuList',
...@@ -150,6 +112,24 @@ export default { ...@@ -150,6 +112,24 @@ export default {
message: '拼团失败', message: '拼团失败',
footTxt: '如已支付,退款将原路返还,请注意帐户变动' footTxt: '如已支付,退款将原路返还,请注意帐户变动'
} }
},
showButtonMethod: {
0: {
text: '重新拼团',
click: 'goGroupBuyList'
},
1: {
text: '去支付',
click: 'goGroupPayPages'
},
2: {
text: '邀请好友',
click: 'openShareEvent'
},
3: {
text: '查看订单',
click: 'goGroupDetails'
}
} }
}; };
}, },
...@@ -162,11 +142,10 @@ export default { ...@@ -162,11 +142,10 @@ export default {
this.listFinished = val; this.listFinished = val;
} }
}, },
created() {
if (isApp) this.nativeBridge = new Bridge();
else if (isWxMp) this.nativeBridge = new MpBridge();
},
methods: { methods: {
bundleButtonClick(item) {
this[this.showButtonMethod[item.showButton].click](item);
},
finishTimeChange() { finishTimeChange() {
this.$emit('finish-time'); this.$emit('finish-time');
}, },
...@@ -211,16 +190,8 @@ export default { ...@@ -211,16 +190,8 @@ export default {
return; return;
} }
}, },
async getGroupShareInfo(order) { async openShareEvent(item) {
const res = await groupBuyApi.getGroupShareInfo(order); this.$emit('option-click', { ...item.skuList[0], eventType: 'share' });
console.log(res);
},
async openShareEvent(skuInfo) {
this.$emit('option-click', { ...skuInfo, eventType: 'share' });
// this.getGroupShareInfo('1440970158226214912');
// this.shareInfo = skuInfo;
// this.$store.dispatch('goods_share_open');
saTrackEvent('H5_MyPuzzlePageGroupOrderBtnClick', { saTrackEvent('H5_MyPuzzlePageGroupOrderBtnClick', {
sku_no: '', sku_no: '',
leader_user_id: '' leader_user_id: ''
......
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