drew пре 5 година
родитељ
комит
f8ef40eaae

+ 161 - 0
src/components/Coupon.vue

@@ -0,0 +1,161 @@
+<template>
+    <div class="coupon-component">
+        <div class="coupon-dialog-wrapper" v-if="visible">
+            <div class="coupon-dialog-mask" @click="dismiss"></div>
+            <button v-if="coupon.type === 'SHARE'" class="coupon-dialog" open-type="share">
+                <img :style="{ backgroundImage: `url(${coupon ? coupon.pic : ''})` }" class="coupon-dialog" />
+                <div class="share-num">已分享{{ shareNum }}/{{ totalShareNum }}</div>
+            </button>
+            <img
+                v-else
+                :style="{ backgroundImage: `url(${coupon ? coupon.pic : ''})` }"
+                class="coupon-dialog"
+                @click="reveiceCoupon"
+            />
+        </div>
+        <div class="msg-dialog success-dialog" v-if="showSuccess">
+            <div class="mask" @click="hideSuccess"></div>
+            <div class="dialog-wrapper">
+                <div class="dialog">
+                    <div class="head">
+                        领优惠券
+                    </div>
+                    <div class="content">
+                        <img src="../static/imgs/icon_success.png" class="icon" />
+                        <div class="h1">领取成功</div>
+                        <div class="h2">可到红包卡券查看使用</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <use-coupon :coupon="userCoupon" :visible.sync="showUseCoupon"></use-coupon>
+    </div>
+</template>
+<script>
+import { mapState } from 'vuex';
+import UseCoupon from './UseCoupon';
+export default {
+    components: { UseCoupon },
+    props: {
+        visible: {
+            default: false
+        },
+        coupon: {}
+    },
+    data() {
+        return {
+            totalShareNum: -1,
+            showSuccess: false,
+            successTimeout: null,
+            showUseCoupon: false,
+            userCoupon: null
+        };
+    },
+    computed: {
+        ...mapState(['shareNum'])
+    },
+    methods: {
+        dismiss() {
+            this.$emit('update:visible', false);
+        },
+        reveiceCoupon() {
+            wx.showLoading({
+                title: '领取中',
+                mask: true
+            });
+            this.$http
+                .get('/coupon/receive', { couponId: this.coupon.id })
+                .then(res => {
+                    this.dismiss();
+                    this.userCoupon = res;
+                    this.$store.commit('setAvailableCoupon', null);
+                    wx.hideLoading();
+                    this.showSuccess = true;
+                    setTimeout(() => {
+                        this.hideSuccess();
+                    }, 3000);
+                })
+                .catch(e => {
+                    wx.showToast({
+                        icon: 'none',
+                        title: e.error || '领取失败,请稍后再试'
+                    });
+                });
+        },
+        hideSuccess() {
+            if (this.successTimeout) {
+                clearTimeout(this.successTimeout);
+            }
+            this.showSuccess = false;
+            this.showUseCoupon = true;
+        }
+    },
+    watch: {
+        coupon() {
+            this.$store.commit('resetShareNum');
+            this.$http.get('/couponType/get/SHARE').then(res => {
+                this.totalShareNum = res.shareNum;
+            });
+        },
+        shareNum() {
+            if (this.visible && this.shareNum === this.totalShareNum && this.coupon) {
+                this.reveiceCoupon();
+            }
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.coupon-component {
+    .coupon-dialog-wrapper {
+        .coupon-dialog-mask {
+            position: absolute;
+            left: 0;
+            top: 0;
+            right: 0;
+            bottom: 0;
+            background: rgba(0, 0, 0, 0.3);
+        }
+        .coupon-dialog {
+            position: absolute;
+            left: 0;
+            top: 0;
+            right: 0;
+            bottom: 0;
+            width: 285px;
+            height: 228px;
+            margin: auto;
+            background-size: cover;
+            background-position: center;
+            background-repeat: no-repeat;
+            .share-num {
+                position: absolute;
+                left: 0;
+                right: 0;
+                top: 54px;
+                color: white;
+                font-size: 14px;
+            }
+        }
+    }
+}
+.success-dialog {
+    .content {
+        .icon {
+            width: 85px;
+            height: 85px;
+            margin-top: 18px;
+        }
+        .h1 {
+            color: black;
+            font-size: 24px;
+            margin-top: 13px;
+        }
+        .h2 {
+            color: black;
+            font-size: 15px;
+            margin-top: 11px;
+        }
+    }
+}
+</style>

+ 96 - 0
src/components/UseCoupon.vue

@@ -0,0 +1,96 @@
+<template>
+    <div>
+        <div class="msg-dialog choose-dialog" v-if="visible">
+            <div class="mask"></div>
+            <div class="dialog-wrapper">
+                <div class="dialog">
+                    <div class="head">
+                        使用优惠券
+                    </div>
+                    <div class="content">
+                        <div class="row" v-for="n in 10" :key="n">
+                            <div class="cb selected">
+                                <div></div>
+                            </div>
+                            <div class="name">套餐A 原价99</div>
+                            <div class="discount">4折</div>
+                            <div class="detail">详情 〉</div>
+                        </div>
+                    </div>
+                    <div class="tip">领取的优惠券可到红包卡券查看使用</div>
+                    <div class="btns">
+                        <div class="btn btn-confirm">去使用</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+export default {
+    props: {
+        visible: {
+            default: false
+        },
+        coupon: {}
+    },
+    data() {
+        return {
+            selectedTicket: null
+        };
+    }
+};
+</script>
+<style lang="less" scoped>
+.choose-dialog {
+    .tip {
+        color: red;
+        text-align: center;
+        font-size: 10px;
+    }
+    .content {
+        max-height: 240px;
+        overflow: auto;
+        padding: 0 20px;
+        .row {
+            .flex();
+            height: 60px;
+            font-size: 12px;
+            text-align: left;
+            border-bottom: 1px solid @border;
+            .cb {
+                width: 15px;
+                height: 15px;
+                background: rgba(255, 255, 255, 1);
+                border: 1px solid rgba(219, 219, 219, 1);
+                border-radius: 50%;
+                .flex();
+                justify-content: center;
+                &.selected > div {
+                    width: 9px;
+                    height: 9px;
+                    background: rgba(95, 195, 247, 1);
+                    border-radius: 50%;
+                }
+            }
+            .name {
+                margin-left: 20px;
+                width: 125px;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+            }
+            .discount {
+                color: red;
+                flex-grow: 1;
+            }
+            .detail {
+                color: #00b7ed;
+            }
+        }
+    }
+    .btns {
+        justify-content: space-around;
+    }
+}
+</style>

+ 9 - 40
src/pages/home.vue

@@ -120,15 +120,7 @@
             v-if="availableCoupon"
             @click="showCouponDialog = true"
         />
-        <div class="coupon-dialog-wrapper" v-if="showCouponDialog">
-            <div class="coupon-dialog-mask" @click="showCouponDialog = false"></div>
-            <button class="coupon-dialog" open-type="share">
-                <img
-                    :style="{ backgroundImage: `url(${availableCoupon ? availableCoupon.pic : ''})` }"
-                    class="coupon-dialog"
-                />
-            </button>
-        </div>
+        <coupon :coupon="availableCoupon" :visible.sync="showCouponDialog"></coupon>
         <land-mark-dialog
             :visible.sync="showLandMarkDialog"
             @confirm="checkOrder"
@@ -152,15 +144,16 @@
 </template>
 
 <script>
-import { mapGetters } from 'vuex';
+import { mapGetters, mapState } from 'vuex';
 import LandMarkDialog from '../components/LandMarkDialog';
 import MsgBox from '../components/MsgBox';
 import PurchaseDialog from '../components/PurchaseDialog';
 import LoginDialog from '../components/LoginDialog';
 import QQMapWX from '../qqmap-wx-jssdk';
+import Coupon from '../components/Coupon';
 export default {
     onShareAppMessage(res) {
-        this.shareNum++;
+        this.$store.commit('addShareNum');
         return {
             title: '来一米世界,购优惠门票!',
             path: 'pages/home',
@@ -180,7 +173,8 @@ export default {
         LandMarkDialog,
         MsgBox,
         PurchaseDialog,
-        LoginDialog
+        LoginDialog,
+        Coupon
     },
     data() {
         return {
@@ -202,14 +196,12 @@ export default {
             empty: false,
             showSharePopup: false,
             showLocationDialog: false,
-            availableCoupon: null,
-            showCouponDialog: false,
-            shareNum: 1,
-            currentShareNum: 0
+            showCouponDialog: false
         };
     },
     computed: {
         ...mapGetters(['screenWidth', 'statusBarHeight']),
+        ...mapState(['availableCoupon']),
         bannerWidth() {
             return (this.screenWidth - 48) / 2;
         },
@@ -340,7 +332,7 @@ export default {
                     scenicId: scenicId
                 })
                 .then(res => {
-                    this.availableCoupon = res;
+                    this.$store.commit('setAvailableCoupon', res);
                 });
         },
         checkOrder() {
@@ -668,27 +660,4 @@ export default {
     top: 300px;
     right: 0;
 }
-.coupon-dialog-wrapper {
-    .coupon-dialog-mask {
-        position: absolute;
-        left: 0;
-        top: 0;
-        right: 0;
-        bottom: 0;
-        background: rgba(0, 0, 0, 0.3);
-    }
-    .coupon-dialog {
-        position: absolute;
-        left: 0;
-        top: 0;
-        right: 0;
-        bottom: 0;
-        width: 285px;
-        height: 228px;
-        margin: auto;
-        background-size: cover;
-        background-position: center;
-        background-repeat: no-repeat;
-    }
-}
 </style>

BIN
src/static/.DS_Store


BIN
src/static/imgs/icon_success.png


+ 12 - 1
src/store/index.js

@@ -4,7 +4,9 @@ export default new Vuex.Store({
     state: {
         sysInfo: {},
         userInfo: {},
-        cityId: null
+        cityId: null,
+        availableCoupon: null,
+        shareNum: 0
     },
     mutations: {
         setSysInfo(state, sysInfo) {
@@ -12,6 +14,15 @@ export default new Vuex.Store({
         },
         setUserInfo(state, userInfo) {
             state.userInfo = userInfo;
+        },
+        setAvailableCoupon(state, coupon) {
+            state.availableCoupon = coupon;
+        },
+        addShareNum(state) {
+            state.shareNum++;
+        },
+        resetShareNum(state) {
+            state.shareNum = 0;
         }
     },
     getters: {