Bladeren bron

feat: 半年付

ArvinQi 6 jaren geleden
bovenliggende
commit
f575d0ac97
4 gewijzigde bestanden met toevoegingen van 299 en 193 verwijderingen
  1. 169 0
      components/type/vip/buy-dialog.vue
  2. 76 66
      components/type/vip/mobile.vue
  3. 24 109
      components/type/vip/pc.vue
  4. 30 18
      pages/type/vip.vue

+ 169 - 0
components/type/vip/buy-dialog.vue

@@ -0,0 +1,169 @@
+<template>
+  <el-dialog class="wrapper-buy-dialog" :visible.sync="buyDialog" :before-close="handleClose">
+    <div class="buy-dialog">
+      <template v-if="type === 'dev'">
+        <img src="~@/assets/img/vip/vip_icon.png" alt="vip_icon" />
+        <h4>购买开发者会员</h4>
+      </template>
+      <template v-else>
+        <img src="~@/assets/img/vip/vip_icon_com.png" alt="vip_icon_com" />
+        <h4>购买企业会员</h4>
+      </template>
+      <div class="wrapper-number">
+        <div @click="clickNumber(3)" :class="{number: true, 'is-checked': number==3}">
+          <span>
+            <strong>3</strong>个月
+          </span>
+          <span>¥{{item['quarterly_real_price']}}</span>
+          <span class="del">¥{{item['quarterly_origin_price']}}</span>
+        </div>
+        <div @click="clickNumber(6)" :class="{number: true, 'is-checked': number==6}">
+          <span>
+            <strong>6</strong>个月
+          </span>
+          <span>¥{{item['half_year_real_price']}}</span>
+          <span class="del">¥{{item['half_year_origin_price']}}</span>
+        </div>
+        <div @click="clickNumber(12)" :class="{number: true, 'is-checked': number==12}">
+          <span>
+            <strong>12</strong>个月
+          </span>
+          <span>¥{{item['yearly_real_price']}}</span>
+          <span class="del">¥{{item['yearly_origin_price']}}</span>
+        </div>
+      </div>
+      <span slot="footer" class="dialog-footer">
+        <el-button
+          class="buy-btn"
+          type="primary"
+          @click="gotoPay(number)"
+        >{{vipDetail.is_vip ? "续费" : "开通"}}</el-button>
+      </span>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  props: ["handleClose", "buyDialog", "gotoPay", "type", "item", "vipDetail"],
+  data() {
+    return {
+      number: 3
+    };
+  },
+  computed: {},
+  mounted() {},
+  methods: {
+    clickNumber(number) {
+      this.number = number;
+    }
+  }
+};
+</script>
+
+<style lang="scss">
+.wrapper-buy-dialog .el-dialog {
+  width: 669px;
+}
+.buy-dialog {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  margin-top: -15px;
+  width: 650px;
+  img {
+    width: 44px;
+  }
+  h4 {
+    margin-top: 11px;
+    font-size: 23px;
+    font-family: PingFangSC-Semibold;
+    font-weight: 600;
+    color: rgba(34, 34, 34, 1);
+    line-height: 32px;
+  }
+  .wrapper-number {
+    display: flex;
+    justify-content: space-between;
+    margin: 35px 0;
+    padding: 0 25px;
+    width: 100%;
+    .number {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      padding-top: 20px;
+      width: 180px;
+      height: 120px;
+      border-radius: 2px;
+      border: 1px solid rgba(221, 221, 221, 1);
+      font-family: PingFangSC-Light;
+      font-weight: 300;
+      color: rgba(34, 34, 34, 1);
+      cursor: pointer;
+      strong {
+        font-size: 54px;
+        line-height: 50px;
+      }
+      span {
+        line-height: 20px;
+      }
+      .del {
+        color: #999;
+        text-decoration: line-through;
+      }
+    }
+    .is-checked {
+      border: 2px solid rgba(225, 168, 63, 1);
+    }
+  }
+  .buy-btn {
+    width: 236px;
+    height: 48px;
+    background: rgba(34, 34, 34, 1);
+    border-radius: 2px;
+    font-size: 16px;
+    font-family: PingFangSC-Semibold;
+    font-weight: 600;
+    color: rgba(232, 190, 79, 1);
+    line-height: 22px;
+  }
+}
+
+@media screen and (max-width: 960px) {
+  .wrapper-buy-dialog .el-dialog {
+    width: 309px;
+  }
+  .buy-dialog {
+    width: 255px;
+    .wrapper-number {
+      flex-direction: column;
+      padding: 0;
+      .number {
+        flex-direction: row;
+        justify-content: space-between;
+        margin-top: 12px;
+        padding: 7px 10px;
+        width: 255px;
+        height: 65px;
+        font-size: 12px;
+        strong {
+          line-height: 50px;
+          font-size: 36px;
+        }
+      }
+      span:nth-of-type(1) {
+        order: 0;
+      }
+      span:nth-of-type(2) {
+        order: 3;
+      }
+      span:nth-of-type(3) {
+        order: 2;
+        margin-left: 60px;
+      }
+    }
+  }
+}
+</style>

+ 76 - 66
components/type/vip/mobile.vue

@@ -3,42 +3,42 @@
     <section class="banners-box" @touchstart="touchStart" @touchend="touchEnd">
       <section class="banners" :class="{'banners-com': currentCom}">
         <section class="banner">
-          <img src="~@/assets/img/vip/vip.png" class="card">
+          <img src="~@/assets/img/vip/vip.png" class="card" />
           <section class="header">
             <section style="position: relative;">
-              <img :src="userInfo.icon_url" class="avator">
-              <img v-if="vipNow && !isCom" src="~@/assets/img/vip/vip_icon.png" class="diamond">
+              <img :src="userInfo.icon_url" class="avator" />
+              <img v-if="vipNow && !isCom" src="~@/assets/img/vip/vip_icon.png" class="diamond" />
             </section>
             <section>
               <span class="name">{{userInfo.nickname}}</span>
-              <br>
+              <br />
               <span v-if="isCom" class="date">暂未开通</span>
               <span v-else class="date">{{endTimeCalc}}</span>
             </section>
           </section>
           <section v-if="true || deviceType !== 'ios'">
-            <button v-if="!vipNow" class="renewal-fee" @click="clickPay(dev)">开通</button>
+            <button v-if="!vipNow" class="renewal-fee" @click="clickPay('dev')">开通</button>
             <button v-else-if="isCom" disabled class="renewal-fee disabled">开通</button>
-            <button v-else class="renewal-fee" @click="clickPay(dev)">{{vipNow ? '续费' : '开通'}}</button>
+            <button v-else class="renewal-fee" @click="clickPay('dev')">{{vipNow ? '续费' : '开通'}}</button>
           </section>
         </section>
         <section class="banner">
-          <img src="~@/assets/img/vip/vip_com.png" class="card">
+          <img src="~@/assets/img/vip/vip_com.png" class="card" />
           <section class="header">
             <section style="position: relative;">
-              <img :src="userInfo.icon_url" class="avator avator-com">
-              <img v-if="vipNow && isCom" src="~@/assets/img/vip/vip_icon_com.png" class="diamond">
+              <img :src="userInfo.icon_url" class="avator avator-com" />
+              <img v-if="vipNow && isCom" src="~@/assets/img/vip/vip_icon_com.png" class="diamond" />
             </section>
             <section>
               <span class="name">{{userInfo.nickname}}</span>
-              <br>
+              <br />
               <span v-if="isCom" class="date">{{endTimeCalc}}</span>
               <span v-else class="date">暂未开通</span>
             </section>
           </section>
           <section v-if="true || deviceType !== 'ios'">
-            <button v-if="!vipNow" class="renewal-fee renewal-fee-com" @click="clickPay(com)">开通</button>
-            <button v-else-if="isCom" class="renewal-fee renewal-fee-com" @click="clickPay(com)">
+            <button v-if="!vipNow" class="renewal-fee renewal-fee-com" @click="clickPay('com')">开通</button>
+            <button v-else-if="isCom" class="renewal-fee renewal-fee-com" @click="clickPay('com')">
               {{vipNow ? '续费' :
               '开通'}}
             </button>
@@ -72,36 +72,36 @@
         <li>
           <span>· 整包项目-平台服务费(减免{{detail.project_reduction_rate}}%)</span>
           <div v-show="currentCom" class="right">
-            <img src="~@/assets/img/vip/tag_com.png" class="sale">
+            <img src="~@/assets/img/vip/tag_com.png" class="sale" />
             <span class="discount">{{detail.project_discount}}折</span>
           </div>
           <div v-show="!currentCom" class="right">
-            <img src="~@/assets/img/vip/tag.png" class="sale">
+            <img src="~@/assets/img/vip/tag.png" class="sale" />
             <span class="discount">{{detail.project_discount}}折</span>
           </div>
         </li>
         <li>
           <span>· 云端工作-平台服务费(减免{{detail.job_reduction_rate}}%)</span>
           <div v-show="currentCom" class="right">
-            <img src="~@/assets/img/vip/tag_com.png" class="sale">
+            <img src="~@/assets/img/vip/tag_com.png" class="sale" />
             <span class="discount">{{detail.job_discount}}折</span>
           </div>
           <div v-show="!currentCom" class="right">
-            <img src="~@/assets/img/vip/tag.png" class="sale">
+            <img src="~@/assets/img/vip/tag.png" class="sale" />
             <span class="discount">{{detail.job_discount}}折</span>
           </div>
         </li>
         <li>
           <span v-if="currentCom">· 每天50次程序员聊天次数</span>
           <span v-else>· 认证的自由开发者可同时接两单</span>
-          <img v-show="currentCom" src="~@/assets/img/vip/check_com.png" class="yes">
-          <img v-show="!currentCom" src="~@/assets/img/vip/check.png" class="yes">
+          <img v-show="currentCom" src="~@/assets/img/vip/check_com.png" class="yes" />
+          <img v-show="!currentCom" src="~@/assets/img/vip/check.png" class="yes" />
         </li>
         <li>
           <span v-if="currentCom">· 优先推荐对接优质的开发者</span>
           <span v-else>· Ping接单意愿权重更高</span>
-          <img v-show="currentCom" src="~@/assets/img/vip/check_com.png" class="yes">
-          <img v-show="!currentCom" src="~@/assets/img/vip/check.png" class="yes">
+          <img v-show="currentCom" src="~@/assets/img/vip/check_com.png" class="yes" />
+          <img v-show="!currentCom" src="~@/assets/img/vip/check.png" class="yes" />
         </li>
       </ul>
     </section>
@@ -113,94 +113,113 @@
         <li class="li">3.如有任何问题,欢迎咨询在线客服,或拨打热线:0571-28120931 转1。</li>
       </ul>
     </section>
+    <buy-dialog
+      :handleClose="handleClose"
+      :buyDialog="buyDialog"
+      :gotoPay="gotoPay"
+      :type="type"
+      :item="item"
+      :vipDetail="vipDetail"
+    ></buy-dialog>
   </section>
 </template>
 
 <script>
-let touchX = 0
-import getDeviceType from '@/mixins/getDeviceType'
-import qs from 'qs';
+let touchX = 0;
+import getDeviceType from "@/mixins/getDeviceType";
+import qs from "qs";
+import buyDialog from "./buy-dialog";
 
 export default {
-  props: ['com', 'dev'],
+  props: ["com", "dev", "vipDetail", "isCom"],
   data() {
     return {
       // 当前是企业页
       currentCom: false,
       // 会员详情
-      vipDetail: {}
-    }
+      // vipDetail: {},
+      buyDialog: false,
+      type: "com" // com: 企业会员, dev: 开发者会员
+    };
+  },
+  components: {
+    buyDialog
   },
   mixins: [getDeviceType],
   computed: {
+    item: function() {
+      return this[this.type] || {};
+    },
     endTimeCalc() {
-      return this.vipNow ? '有效期至' + this.userInfo.vip_end_date : '暂未开通'
+      return this.vipNow ? "有效期至" + this.userInfo.vip_end_date : "暂未开通";
     },
     detail() {
-      return (this.currentCom ? this.com : this.dev) || {}
+      return (this.currentCom ? this.com : this.dev) || {};
     },
     vipNow() {
-      return this.vipDetail.is_vip || false
+      return this.vipDetail.is_vip || false;
     },
     vipInfo() {
-      return this.vipDetail.vip_info || {}
+      return this.vipDetail.vip_info || {};
     },
     userInfo() {
-      console.log(this.vipDetail)
-      return this.vipDetail.user_info || {}
-    },
-    isCom() {
-      if (this.$route.query.isCom) return true
-      return this.vipDetail.vip_type_id !== '2'
-    },
+      console.log(this.vipDetail);
+      return this.vipDetail.user_info || {};
+    }
   },
   mounted() {
-    this.getVipDetail();
+    console.log("mobile", this.com, this.dev);
   },
   methods: {
-    /**
-     * 点击开通
-     */
-    async clickPay(item) {
+    clickPay(type) {
+      this.type = type;
+      this.buyDialog = true;
+      // location.href = `/vip/pay?product_id=${item.id}&number=3&next=/type/vip/`;
+    },
+    handleClose() {
+      this.buyDialog = false;
+    },
+    async gotoPay(number) {
+      const item = this[this.type];
       let query = {
         product_type: 11,
-        number: 3,
+        number: number,
         product_id: item.id
-      }
-      if (this.deviceType === 'ios') {
+      };
+      if (this.deviceType === "ios") {
         let cookie = this.getSign();
-        let res = await this.$axios.$post('/api/vip/pay', {
+        let res = await this.$axios.$post("/api/vip/pay", {
           product_type: 11,
-          number: 3,
+          number: number,
           product_id: item.id,
-          channel: 'apple',
+          channel: "apple",
           ...cookie
         });
         if (res && res.data) {
           query = Object.assign({}, query, res.data);
         }
       }
-      location.href = 'proginn://pay?' + qs.stringify(query);
+      location.href = "proginn://pay?" + qs.stringify(query);
     },
     /**
      * 手指右划
      */
     swipeRight() {
-      this.currentCom = false
+      this.currentCom = false;
     },
     /**
      * 手指左划
      */
     swipeLeft() {
-      this.currentCom = true
+      this.currentCom = true;
     },
     touchStart(e) {
-      touchX = e.touches[0].clientX
+      touchX = e.touches[0].clientX;
     },
     touchEnd(e) {
-      var offsetX = e.changedTouches[0].clientX - touchX
-      if (offsetX < -50) this.swipeLeft()
-      else if (offsetX > 50) this.swipeRight()
+      var offsetX = e.changedTouches[0].clientX - touchX;
+      if (offsetX < -50) this.swipeLeft();
+      else if (offsetX > 50) this.swipeRight();
     },
     /**
      * 点击会员计划
@@ -208,18 +227,9 @@ export default {
     clickProject(index) {
       const vip = this.vipDetail[index];
       window.open(recommend.seo_uri);
-    },
-    /**
-     * 获取会员详情
-     */
-    async getVipDetail() {
-      let res = await this.$axios.$post('/api/vip/getVipUserDetail')
-      // if (!res || !res.data) return
-      this.vipDetail = res && res.data ? res.data : {};
-      if (this.isCom) this.currentCom = true
     }
-  },
-}
+  }
+};
 </script>
 
 <style scoped>

+ 24 - 109
components/type/vip/pc.vue

@@ -78,57 +78,35 @@
       <li class="remind">2.开通会员即代表您已同意《程序员客栈会员服务条款》;</li>
       <li class="remind">3.如有任何问题,欢迎咨询在线客服,或拨打热线:0571-28120931 转1。</li>
     </ul>
-    <el-dialog width="669px" :visible.sync="buyDialog" :before-close="handleClose">
-      <div class="buy-dialog">
-        <template v-if="type === 'dev'">
-          <img src="~@/assets/img/vip/vip_icon.png" alt="vip_icon" />
-          <h4>购买开发者会员</h4>
-        </template>
-        <template v-else>
-          <img src="~@/assets/img/vip/vip_icon_com.png" alt="vip_icon_com" />
-          <h4>购买企业会员</h4>
-        </template>
-        <div class="wrapper-number">
-          <div @click="clickNumber(3)" :class="{number: true, 'is-checked': number==3}">
-            <span>
-              <strong>3</strong>个月
-            </span>
-            <span>¥149</span>
-            <span class="del">¥299</span>
-          </div>
-          <div @click="clickNumber(6)" :class="{number: true, 'is-checked': number==6}">
-            <span>
-              <strong>6</strong>个月
-            </span>
-            <span>¥149</span>
-            <span class="del">¥299</span>
-          </div>
-          <div @click="clickNumber(12)" :class="{number: true, 'is-checked': number==12}">
-            <span>
-              <strong>12</strong>个月
-            </span>
-            <span>¥149</span>
-            <span class="del">¥299</span>
-          </div>
-        </div>
-        <span slot="footer" class="dialog-footer">
-          <el-button type="primary" @click="buyDialog = false">开通</el-button>
-        </span>
-      </div>
-    </el-dialog>
+    <buy-dialog
+      :handleClose="handleClose"
+      :buyDialog="buyDialog"
+      :gotoPay="gotoPay"
+      :type="type"
+      :item="item"
+      :vipDetail="vipDetail"
+    ></buy-dialog>
   </section>
 </template>
 
 <script>
+import buyDialog from "./buy-dialog";
 export default {
-  props: ["com", "dev"],
+  props: ["com", "dev", "vipDetail", "isCom"],
   data() {
     return {
-      buyDialog: true,
-      type: "com", // com: 企业会员, dev: 开发者会员
-      number: 3
+      buyDialog: false,
+      type: "com" // com: 企业会员, dev: 开发者会员
     };
   },
+  components: {
+    buyDialog
+  },
+  computed: {
+    item: function() {
+      return this[this.type] || {};
+    }
+  },
   mounted() {
     console.log(this.com, this.dev);
   },
@@ -137,17 +115,17 @@ export default {
      * 点击支付
      */
     clickPay(type) {
-      const item = this[type];
       this.type = type;
       this.buyDialog = true;
       // location.href = `/vip/pay?product_id=${item.id}&number=3&next=/type/vip/`;
     },
-    clickNumber(number) {
-      this.number = number;
-    },
     handleClose() {
       this.buyDialog = false;
     },
+    gotoPay(number) {
+      const item = this[this.type];
+      location.href = `/vip/pay?product_id=${item.id}&number=${number}&next=/type/vip/`;
+    },
     // 点击会员计划
     clickProject(index) {
       let vip = this.vipList[index];
@@ -295,67 +273,4 @@ h3 {
   color: #666;
   cursor: not-allowed;
 }
-.buy-dialog {
-  display: flex;
-  flex-direction: column;
-  align-items: center;
-  justify-content: center;
-  margin-top: -15px;
-  img {
-    width: 44px;
-  }
-  h4 {
-    margin-top: 11px;
-    font-size: 23px;
-    font-family: PingFangSC-Semibold;
-    font-weight: 600;
-    color: rgba(34, 34, 34, 1);
-    line-height: 32px;
-  }
-  .wrapper-number {
-    display: flex;
-    justify-content: space-between;
-    margin: 35px 0;
-    padding: 0 25px;
-    width: 100%;
-    .number {
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      width: 180px;
-      height: 120px;
-      border-radius: 2px;
-      border: 1px solid rgba(221, 221, 221, 1);
-      font-family: PingFangSC-Light;
-      font-weight: 300;
-      color: rgba(34, 34, 34, 1);
-      cursor: pointer;
-      strong {
-        font-size: 54px;
-        line-height: 65px;
-      }
-      span {
-        line-height: 20px;
-      }
-      .del {
-        color: #999;
-        text-decoration: line-through;
-      }
-    }
-    .is-checked {
-      border: 2px solid rgba(225, 168, 63, 1);
-    }
-    .buy-btn {
-      width: 236px;
-      height: 48px;
-      background: rgba(34, 34, 34, 1);
-      border-radius: 2px;
-      font-size: 16px;
-      font-family: PingFangSC-Semibold;
-      font-weight: 600;
-      color: rgba(232, 190, 79, 1);
-      line-height: 22px;
-    }
-  }
-}
 </style>

+ 30 - 18
pages/type/vip.vue

@@ -1,15 +1,15 @@
 <template>
-  <pc v-if="isPC" :com="com" :dev="dev"></pc>
-  <mobile v-else :com="com" :dev="dev"></mobile>
+  <pc v-if="isPC" :com="com" :dev="dev" :vipDetail="vipDetail" :isCom="isCom"></pc>
+  <mobile v-else :com="com" :dev="dev" :vipDetail="vipDetail" :isCom="isCom"></mobile>
 </template>
 
 <script>
-import { mapState } from 'vuex'
+import { mapState } from "vuex";
 // import http from '@/plugins/http'
-import pc from '@/components/type/vip/pc'
-import mobile from '@/components/type/vip/mobile'
-import getDeviceType from '@/mixins/getDeviceType'
-import qs from 'qs';
+import pc from "@/components/type/vip/pc";
+import mobile from "@/components/type/vip/mobile";
+import getDeviceType from "@/mixins/getDeviceType";
+import qs from "qs";
 
 export default {
   // async asyncData({ $axios, params }) {
@@ -17,43 +17,55 @@ export default {
   //   console.log('init', res)
   // },
   head: {
-    title: '会员中心页 - 程序员客栈',
+    title: "会员中心页 - 程序员客栈"
   },
   components: {
     pc,
-    mobile,
+    mobile
   },
   mixins: [getDeviceType],
   data() {
     return {
-      vipList: []
-    }
+      vipList: [],
+      vipDetail: {}
+    };
   },
   computed: {
-    ...mapState(['isPC']),
+    ...mapState(["isPC"]),
     com() {
       return this.vipList[0];
     },
     dev() {
       return this.vipList[1];
+    },
+    isCom() {
+      if (this.$route.query.isCom) return true;
+      return this.vipDetail.vip_type_id !== "2";
     }
   },
-  mounted() {
-    this.getList()
+  async mounted() {
+    await this.getList();
+    this.getVipDetail();
   },
   methods: {
     async getList() {
       let extraHeaders = {};
-      if (this.deviceType === 'ios') {
+      if (this.deviceType === "ios") {
         extraHeaders = this.getSign();
       }
-      let res = await this.$axios.$post(`/api/vip/getList`, extraHeaders)
+      let res = await this.$axios.$post(`/api/vip/getList`, extraHeaders);
       if (res) {
-        this.vipList = res.data
+        this.vipList = res.data;
       }
+    },
+    async getVipDetail() {
+      let res = await this.$axios.$post("/api/vip/getVipUserDetail");
+      // if (!res || !res.data) return
+      this.vipDetail = res && res.data ? res.data : {};
+      if (this.isCom) this.currentCom = true;
     }
   }
-}
+};
 </script>
 
 <style>