浏览代码

购买页面逻辑完善

cuiyalong 5 年之前
父节点
当前提交
e57fc38f5b
共有 5 个文件被更改,包括 280 次插入65 次删除
  1. 2 1
      public/index.html
  2. 28 0
      src/api/home.ts
  3. 4 3
      src/components/common/CountDownButton.vue
  4. 41 8
      src/store/modules/home.ts
  5. 205 53
      src/views/buy/Buy.vue

+ 2 - 1
public/index.html

@@ -17,7 +17,8 @@
     <meta name="apple-mobile-web-app-status-bar-style" content="black">
     <meta name="apple-mobile-web-app-status-bar-style" content="black">
     <meta name="format-detection" content="telephone=no">
     <meta name="format-detection" content="telephone=no">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
     <link rel="icon" href="<%= BASE_URL %>favicon.ico">
-    <title><%= htmlWebpackPlugin.options.title %></title>
+    <!-- <title><%= htmlWebpackPlugin.options.title %></title> -->
+    <title>剑鱼标讯</title>
     <!-- 使用CDN的CSS文件 -->
     <!-- 使用CDN的CSS文件 -->
     <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
     <% for (var i in htmlWebpackPlugin.options.cdn && htmlWebpackPlugin.options.cdn.css) { %>
     <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />
     <link rel="stylesheet" href="<%= htmlWebpackPlugin.options.cdn.css[i] %>" />

+ 28 - 0
src/api/home.ts

@@ -27,3 +27,31 @@ export function orderSubmit (data: any) {
     data
     data
   })
   })
 }
 }
+
+// 查询用户是否已经填写过邮箱或者手机号
+export function userMsg () {
+  return request({
+    url: '/datareport/userMsg',
+    method: 'get'
+  })
+}
+
+// 发送邮箱验证码
+export function sEmailCode (data: any) {
+  data = qs.stringify(data)
+  return request({
+    url: '/datareport/sendEmailCode',
+    method: 'post',
+    data
+  })
+}
+
+// 校验邮箱验证码
+export function cEmailCode (data: any) {
+  data = qs.stringify(data)
+  return request({
+    url: '/datareport/checkEmailCode',
+    method: 'post',
+    data
+  })
+}

+ 4 - 3
src/components/common/CountDownButton.vue

@@ -32,7 +32,8 @@ export default class CountdownButton extends Vue {
   count: any = 0
   count: any = 0
 
 
   get buttonText () {
   get buttonText () {
-    const dText = `${this.timerId ? '重新' : ''}${this.defaultText}`
+    // const dText = `${this.timerId ? '重新' : ''}${this.defaultText}`
+    const dText = this.defaultText
     return this.count <= 0 ? dText : `${this.count}s`
     return this.count <= 0 ? dText : `${this.count}s`
   }
   }
 
 
@@ -49,8 +50,8 @@ export default class CountdownButton extends Vue {
     this.$emit('click', this.startTimer)
     this.$emit('click', this.startTimer)
   }
   }
 
 
-  startTimer () {
-    this.count = this.countdown
+  startTimer (start = 0) {
+    this.count = start || this.countdown
     this.timerId = setInterval(() => {
     this.timerId = setInterval(() => {
       this.count--
       this.count--
       if (this.count <= 0) {
       if (this.count <= 0) {

+ 41 - 8
src/store/modules/home.ts

@@ -1,23 +1,28 @@
 import {
 import {
   getReportList,
   getReportList,
-  getReportDetail
+  getReportDetail,
+  userMsg,
+  orderSubmit,
+  sEmailCode,
+  cEmailCode
 } from '@/api/home'
 } from '@/api/home'
 
 
 export default {
 export default {
   namespaced: true,
   namespaced: true,
   state: {
   state: {
-    dataList: sessionStorage.getItem('activity-x-dataList') ? JSON.parse(sessionStorage.getItem('activity-x-dataList') || '') : {}
+    // 购买页面数据保存
+    buyState: sessionStorage.getItem('activity-x-buyState') ? JSON.parse(sessionStorage.getItem('activity-x-buyState') || '') : {}
   },
   },
   mutations: {
   mutations: {
-    saveDataListState (state, data) {
+    saveBuyState (state, data) {
       for (const key in data) {
       for (const key in data) {
-        state.dataList[key] = data[key]
+        state.buyState[key] = data[key]
       }
       }
-      sessionStorage.setItem('activity-x-dataList', JSON.stringify(data))
+      sessionStorage.setItem('activity-x-buyState', JSON.stringify(data))
     },
     },
-    clearDataListState (state) {
-      state.dataList = {}
-      sessionStorage.setItem('activity-x-dataList', JSON.stringify({}))
+    clearBuyState (state) {
+      state.buyState = {}
+      sessionStorage.setItem('activity-x-buyState', JSON.stringify({}))
     }
     }
   },
   },
   actions: {
   actions: {
@@ -34,6 +39,34 @@ export default {
         const res = await getReportDetail(data)
         const res = await getReportDetail(data)
         return res.data
         return res.data
       } catch (error) {}
       } catch (error) {}
+    },
+    // 获取信息
+    async orderSubmit (state, data: any) {
+      try {
+        const res = await orderSubmit(data)
+        return res.data
+      } catch (error) {}
+    },
+    // 获取信息
+    async getUserMsg (state) {
+      try {
+        const res = await userMsg()
+        return res.data
+      } catch (error) {}
+    },
+    // 获取信息
+    async sendEmailCode (state, data: any) {
+      try {
+        const res = await sEmailCode(data)
+        return res.data
+      } catch (error) {}
+    },
+    // 获取信息
+    async checkEmailCode (state, data: any) {
+      try {
+        const res = await cEmailCode(data)
+        return res.data
+      } catch (error) {}
     }
     }
   },
   },
   getters: {}
   getters: {}

+ 205 - 53
src/views/buy/Buy.vue

@@ -2,16 +2,60 @@
   <div class="report-buy">
   <div class="report-buy">
     <div class="j-main">
     <div class="j-main">
       <van-cell-group title="请填写订单信息">
       <van-cell-group title="请填写订单信息">
-        <van-field v-model="userInfo.email" class="field" center placeholder="输入邮箱地址" @blur="checkPass('email')" :error-message="errorMsg.email" />
+        <van-field
+          v-model="userInfo.email"
+          :formatter="formatter"
+          class="field"
+          center
+          placeholder="输入邮箱地址"
+          :disabled="sendedEmail && emailCodePass"
+          :error-message="errorMsg.email"
+          @blur="checkPass('email')"
+        />
         <transition name="van-slide-right">
         <transition name="van-slide-right">
-          <van-field v-show="true" class="field" center v-model="userInfo.code" maxlength="6" @blur="checkPass('code')" placeholder="输入邮箱验证码" :error-message="errorMsg.code">
+          <van-field
+            v-show="showSendEmailCode"
+            v-model="userInfo.code"
+            :formatter="formatter"
+            :disabled="sendedEmail && emailCodePass"
+            :error-message="errorMsg.code"
+            class="field"
+            center
+            maxlength="6"
+            placeholder="输入邮箱验证码"
+            @blur="checkPass('code')"
+          >
             <template #button>
             <template #button>
-              <countdown-button @click="sendCode" :countdown="120" :disabled="sendButtonDisabled"></countdown-button>
+              <countdown-button
+                ref="countdownButton"
+                :countdown="120"
+                :disabled="sendButtonDisabled"
+                @click="sendCode"
+              ></countdown-button>
             </template>
             </template>
           </van-field>
           </van-field>
         </transition>
         </transition>
-        <van-field v-model="userInfo.phone" class="field" center type="tel" placeholder="输入手机号" @blur="checkPass('phone')" :error-message="errorMsg.phone" />
-        <van-field v-model="userInfo.company" class="field" center autosize @blur="checkPass('company')" type="textarea" rows="1"  maxlength="50" placeholder="输入公司名称" :error-message="errorMsg.company" />
+        <van-field
+          v-model="userInfo.phone"
+          class="field"
+          :formatter="formatter"
+          center type="tel"
+          placeholder="输入手机号"
+          @blur="checkPass('phone')"
+          :error-message="errorMsg.phone"
+        />
+        <van-field
+          v-model="userInfo.company"
+          class="field"
+          :formatter="formatter"
+          center
+          autosize
+          @blur="checkPass('company')"
+          type="textarea" rows="1"
+          maxlength="50"
+          placeholder="输入公司名称"
+          :error-message="errorMsg.company"
+        />
       </van-cell-group>
       </van-cell-group>
       <div class="tips">
       <div class="tips">
         <p v-for="(item, index) in tipText" :key="index">*&nbsp;&nbsp;{{item}}</p>
         <p v-for="(item, index) in tipText" :key="index">*&nbsp;&nbsp;{{item}}</p>
@@ -36,7 +80,7 @@
       </div>
       </div>
       <van-cell class="statement" clickable @click="toggleStatementState" center :border="false">
       <van-cell class="statement" clickable @click="toggleStatementState" center :border="false">
         <template #icon>
         <template #icon>
-          <van-checkbox v-model="iAgreee" icon-size="17" checked-color="#2ABED1" ref="iAgreeeCheckbox" />
+          <van-checkbox v-model="iAgree" icon-size="17" checked-color="#2ABED1" ref="iAgreeCheckbox" />
         </template>
         </template>
         <template #title>
         <template #title>
           <p class="state">
           <p class="state">
@@ -55,7 +99,7 @@
 <script lang="ts">
 <script lang="ts">
 import { Component, Vue } from 'vue-property-decorator'
 import { Component, Vue } from 'vue-property-decorator'
 import { Field, Cell, CellGroup, Checkbox, CheckboxGroup } from 'vant'
 import { Field, Cell, CellGroup, Checkbox, CheckboxGroup } from 'vant'
-import { mapActions } from 'vuex'
+import { mapState, mapMutations, mapActions } from 'vuex'
 import countdownButton from '@/components/common/CountDownButton.vue'
 import countdownButton from '@/components/common/CountDownButton.vue'
 import { inputFocusHideFooter } from '@/utils/globalFunctions'
 import { inputFocusHideFooter } from '@/utils/globalFunctions'
 
 
@@ -70,14 +114,32 @@ import { inputFocusHideFooter } from '@/utils/globalFunctions'
     countdownButton
     countdownButton
   },
   },
   methods: {
   methods: {
+    ...mapState('home', {
+      buyState: (state: any) => state.buyState
+    }),
+    ...mapMutations({
+      saveBuyState: 'home/saveBuyState',
+      clearBuyState: 'home/clearBuyState'
+    }),
     ...mapActions({
     ...mapActions({
-      // getServiceTerms: 'home/getServiceTerms'
+      getUserMsg: 'home/getUserMsg',
+      orderSubmit: 'home/orderSubmit',
+      sendEmailCode: 'home/sendEmailCode',
+      checkEmailCode: 'home/checkEmailCode'
     })
     })
   }
   }
 })
 })
 
 
 export default class BuyReport extends Vue {
 export default class BuyReport extends Vue {
-  // protected getServiceTerms!: any
+  protected getUserMsg!: any
+  protected orderSubmit!: any
+  protected sendEmailCode!: any
+  protected checkEmailCode!: any
+
+  // 保存恢复状态
+  protected buyState!: any
+  protected saveBuyState!: any
+  protected clearBuyState!: any
 
 
   tipText = [
   tipText = [
     '数据报告将以邮件形式发至您的邮箱',
     '数据报告将以邮件形式发至您的邮箱',
@@ -87,10 +149,17 @@ export default class BuyReport extends Vue {
 
 
   // 订单金额等数据
   // 订单金额等数据
   orderInfo = {
   orderInfo = {
+    reportId: '',
     price: 123,
     price: 123,
     before_price: 2990
     before_price: 2990
   }
   }
 
 
+  originInfo = {
+    email: '',
+    phone: '',
+    company: ''
+  }
+
   // 用户信息(需要提交)
   // 用户信息(需要提交)
   userInfo = {
   userInfo = {
     email: '',
     email: '',
@@ -99,8 +168,9 @@ export default class BuyReport extends Vue {
     company: ''
     company: ''
   }
   }
 
 
-  allRegPass = false
-  iAgreee = false
+  iAgree = false
+  sendedEmail = false
+  emailCodePass = false
 
 
   // 错误提示信息
   // 错误提示信息
   errorMsg = {
   errorMsg = {
@@ -130,8 +200,40 @@ export default class BuyReport extends Vue {
     }
     }
   }
   }
 
 
+  get allRegPass () {
+    const info = this.userInfo
+    const regArr: any = []
+    for (const key in info) {
+      const r = this.errorMsgMap[key]
+      let pass = true
+      if (r.reg) {
+        // 有正则的就根据正则替换
+        pass = r.reg.test(info[key])
+      } else {
+        // 判断是不是company
+        if (key === 'code') {
+          pass = this.sendedEmail && this.emailCodePass
+        } else if (key === 'company') {
+          pass = !!info[key]
+        }
+      }
+      // console.log(r, key, pass)
+      regArr.push(pass)
+    }
+    return regArr.indexOf(false) === -1
+  }
+
   get confirmDisabled () {
   get confirmDisabled () {
-    return !this.iAgreee || !this.allRegPass
+    return !this.iAgree || (!this.allRegPass && this.showSendEmailCode)
+  }
+
+  get showSendEmailCode () {
+    const oe = this.originInfo.email
+    const ue = this.userInfo.email
+    if (oe === '' || oe !== ue) {
+      return true
+    }
+    return false
   }
   }
 
 
   get sendButtonDisabled () {
   get sendButtonDisabled () {
@@ -141,20 +243,59 @@ export default class BuyReport extends Vue {
     return !reg.test(email)
     return !reg.test(email)
   }
   }
 
 
-  toggleStatementState () {
-    this.iAgreee = !this.iAgreee
-  }
-
   mounted () {
   mounted () {
+    const recover = this.recoverState()
+    if (!recover) {
+      this.getInfo()
+    }
     const inputs: any = document.querySelectorAll('.field .van-field__control')
     const inputs: any = document.querySelectorAll('.field .van-field__control')
     inputFocusHideFooter(inputs, this.$refs.footer)
     inputFocusHideFooter(inputs, this.$refs.footer)
   }
   }
 
 
-  checkPass (type) {
+  getInfo () {
+    const toast = this.$toast.loading({
+      message: '加载中...',
+      forbidClick: true,
+      duration: 0
+    })
+    // test
+    const res = {
+      data: {
+        email: 'a@qq.com',
+        phone: '13200088125',
+        company: '金额急急急'
+      }
+    }
+    setTimeout(() => {
+      toast.clear()
+      this.originInfo = res.data
+      for (const key in res.data) {
+        this.userInfo[key] = res.data[key]
+      }
+    }, 1000)
+    // this.getUserMsg().then(res => {
+    //   toast.clear()
+    //   if (res.error_code === 0) {
+    //     this.originInfo = res.data
+    //     for (const key in res.data) {
+    //       this.userInfo[key] = res.data[key]
+    //     }
+    //   }
+    // })
+  }
+
+  formatter (value) {
+    return value.replace(/\s+/, '')
+  }
+
+  toggleStatementState () {
+    this.iAgree = !this.iAgree
+  }
+
+  async checkPass (type) {
     const r = this.errorMsgMap[type]
     const r = this.errorMsgMap[type]
     const info = this.userInfo[type]
     const info = this.userInfo[type]
     // 数据为空不显示校验失败提示,直接认定校验失败
     // 数据为空不显示校验失败提示,直接认定校验失败
-    this.checkAllPass()
     if (!info) return false
     if (!info) return false
 
 
     let pass = true
     let pass = true
@@ -164,7 +305,7 @@ export default class BuyReport extends Vue {
     } else {
     } else {
       // 判断是不是company
       // 判断是不是company
       if (type === 'code') {
       if (type === 'code') {
-        pass = !!info
+        pass = await this.verifyCode()
       } else if (type === 'company') {
       } else if (type === 'company') {
         // 判断是不是company
         // 判断是不是company
         pass = !!info
         pass = !!info
@@ -179,33 +320,8 @@ export default class BuyReport extends Vue {
     return pass
     return pass
   }
   }
 
 
-  checkAllPass () {
-    const info = this.userInfo
-    const regArr: any = []
-    for (const key in info) {
-      const r = this.errorMsgMap[key]
-      let pass = true
-      if (r.reg) {
-        // 有正则的就根据正则替换
-        pass = r.reg.test(info[key])
-      } else {
-        // 判断是不是company
-        if (key === 'code') {
-          pass = !!info[key]
-        } else if (key === 'company') {
-          pass = !!info[key]
-        }
-      }
-      // console.log(r, key, pass)
-      regArr.push(pass)
-    }
-    const f = regArr.indexOf(false) === -1
-    this.allRegPass = f
-    return f
-  }
-
-  toServiceTerms (e) {
-    this.saveBuyState()
+  toServiceTerms () {
+    this.saveState()
     // location.href = e.target.href
     // location.href = e.target.href
   }
   }
 
 
@@ -214,26 +330,62 @@ export default class BuyReport extends Vue {
     const email = this.userInfo.email
     const email = this.userInfo.email
     const emailPass = reg.test(email)
     const emailPass = reg.test(email)
     if (!emailPass) return
     if (!emailPass) return
+    this.sendedEmail = true
     cb && cb()
     cb && cb()
-    console.log('sendCode')
+    this.sendEmailCode({ email: this.userInfo.email })
   }
   }
 
 
   verifyCode () {
   verifyCode () {
-    console.log('verifyCode')
+    return this.checkEmailCode({ email: this.userInfo.email, emailCode: this.userInfo.code }).then(res => {
+      if (res.error_code === 0) {
+        if (res.status === 1) {
+          // 将错误提示清空
+          this.errorMsg.code = ''
+          this.emailCodePass = true
+          return true
+        } else {
+          // 给出错误提示
+          this.errorMsg.code = this.errorMsgMap.code.text
+          return false
+        }
+      } else {
+        return false
+      }
+    })
   }
   }
 
 
   onSubmit () {
   onSubmit () {
-    console.log(JSON.stringify(this.userInfo))
+    const data = {
+      email: this.userInfo.email,
+      phone: this.userInfo.phone,
+      company: this.userInfo.company,
+      reportId: this.orderInfo.reportId
+    }
+    console.log(JSON.stringify(data))
+    this.orderSubmit(data)
+  }
+
+  recoverState () {
+    const buyState = this.buyState()
+    if (Object.keys(buyState).length === 0) return false
+    for (const key in buyState) {
+      this[key] = buyState[key]
+    }
+    return true
   }
   }
 
 
-  saveBuyState () {
-    const JSON = {
+  saveState () {
+    const pageState = {
       orderInfo: this.orderInfo,
       orderInfo: this.orderInfo,
+      originInfo: this.originInfo,
       userInfo: this.userInfo,
       userInfo: this.userInfo,
-      allRegPass: this.allRegPass,
-      iAgreee: this.iAgreee,
+      iAgree: this.iAgree,
+      sendedEmail: this.sendedEmail,
+      emailCodePass: this.emailCodePass,
       errorMsg: this.errorMsg
       errorMsg: this.errorMsg
     }
     }
+    console.log(JSON.stringify(pageState))
+    this.saveBuyState(pageState)
   }
   }
 }
 }
 </script>
 </script>