Explorar o código

购买下单完善

冯诚 %!s(int64=3) %!d(string=hai) anos
pai
achega
275052ab71

+ 1 - 1
src/pages/account/index.vue

@@ -5,7 +5,7 @@
       <div class="ptc-block">
         <div class="ptc-inner">
           <p class="ptc-label">QR code</p>
-          <img class="qrcode" />
+          <img class="qrcode" :src="info.qrcode" />
         </div>
       </div>
       <div v-if="info.from == 1" class="ptc-block">

+ 37 - 36
src/pages/fill-order/StepOne.vue

@@ -10,15 +10,22 @@
             class="version"
             :value="product.id"
           >
-            <i :class="`icon-${1 ? 'lite' : 'pro'}`"></i>
+            <i
+              class="version-icon"
+              :style="{ backgroundImage: `url(${product.image})` }"
+            ></i>
             <span class="mt18">{{ product.name }}</span>
           </PtcRadio>
         </PtcRadioGroup>
         <div
           class="version-desc"
-          :class="{ second: state.form.product_id === 'pro' }"
+          :class="{
+            second:
+              state.productList[1] &&
+              state.form.product_id === state.productList[1].id,
+          }"
         >
-          {{ selectedProduct.remark }}
+          {{ getters.selectedProduct.remark }}
         </div>
       </div>
     </div>
@@ -27,18 +34,20 @@
         <p class="ptc-label">Choose a subscription method</p>
         <PtcRadioGroup v-model="state.form.subscribe_type">
           <PtcRadio class="method" value="year">
-            <span class="cost">${{ selectedProduct.amount_year }}</span>
+            <span class="cost">${{ getters.selectedProduct.amount_year }}</span>
             <span class="name">Annual</span>
             <span class="ptc-tag"
-              >-{{ selectedProduct.better_than_monthly }}% OFF</span
+              >-{{ getters.selectedProduct.better_than_monthly }}% OFF</span
             >
           </PtcRadio>
           <PtcRadio class="method" value="month">
-            <span class="cost">${{ selectedProduct.amount_month }}</span>
+            <span class="cost"
+              >${{ getters.selectedProduct.amount_month }}</span
+            >
             <span class="name">
-              Monthly<template v-if="+selectedProduct.amount_month_open"
+              Monthly<template v-if="+getters.selectedProduct.amount_month_open"
                 >&nbsp; Activation fee ${{
-                  selectedProduct.amount_month_open
+                  getters.selectedProduct.amount_month_open
                 }}</template
               ></span
             >
@@ -49,7 +58,7 @@
     <div class="ptc-block">
       <div class="ptc-inner">
         <p class="ptc-label">Do you have a discount code?</p>
-        <div v-if="!showCoupon" class="input-wrap pr">
+        <div v-if="!state.discount" class="input-wrap pr">
           <input
             v-model="state.form.discount_code"
             class="ptc-input"
@@ -60,8 +69,8 @@
         <div v-else class="coupon-wrap">
           <div class="coupon">
             <p class="p1">PTC CARE PLUS</p>
-            <p class="p2">NEWCOMER DISCOUNT</p>
-            <p class="p3">- $10</p>
+            <p class="p2">{{ state.discount.name }}</p>
+            <p class="p3">- ${{ state.discount.discount_amount }}</p>
           </div>
           <div class="action">
             <span class="code">{{ state.form.discount_code }}</span>
@@ -72,11 +81,13 @@
     </div>
 
     <div class="total">
-      <div v-if="cost" class="ptc-inner">
+      <div v-if="getters.cost" class="ptc-inner">
         <p>
-          total<strong>${{ cost }}</strong>
+          total<strong>${{ getters.cost }}</strong>
+        </p>
+        <p v-if="state.discount" class="highlight">
+          (${{ state.discount.discount_amount }} discounted)
         </p>
-        <p class="highlight">($10 discounted)</p>
       </div>
     </div>
     <div class="ptc-button-group">
@@ -88,32 +99,15 @@
 </template>
 
 <script setup lang="ts">
-import { ref, computed } from 'vue'
 import { PtcRadioGroup, PtcRadio } from '@/components/radio'
-import { state, getBrandList } from './store'
+import { state, getters, getBrandList } from './store'
 import * as api from '@/service/order'
 import Toast from '@/components/toast'
 
 const emit = defineEmits<{
-  (e: 'next'): void
+  (e: 'go', delta?: number): void
 }>()
 
-const showCoupon = ref(false)
-const selectedProduct = computed(() =>
-  state.productList.find(item => item.id === state.form.product_id)
-)
-const cost = computed(() => {
-  const { amount_year, amount_month, amount_month_open } = selectedProduct.value
-  switch (state.form.subscribe_type) {
-    case 'year':
-      return amount_year
-    case 'month':
-      return (+amount_month + +amount_month_open).toFixed(2)
-    default:
-      return ''
-  }
-})
-
 async function checkDiscount() {
   if (!state.form.discount_code) return Toast('Please enter promotional code')
   try {
@@ -121,20 +115,21 @@ async function checkDiscount() {
       state.form.discount_code
     )
     Toast(message)
-    showCoupon.value = true
+    state.discount = results
   } catch {
     state.form.discount_code = ''
   }
 }
 
 function reviseDiscount() {
-  showCoupon.value = false
+  state.discount = null
   state.form.discount_code = ''
 }
 
 async function next() {
   if (!state.brandList.length) await getBrandList()
-  emit('next')
+  emit('go')
+  if (!state.discount) state.form.discount_code = ''
 }
 </script>
 
@@ -150,6 +145,12 @@ async function next() {
   font-size: 56px;
   font-weight: bold;
 
+  &-icon {
+    width: 36px;
+    height: 36px;
+    background-size: contain;
+  }
+
   .mt18 {
     margin-top: 18px;
   }

+ 10 - 6
src/pages/fill-order/StepThree.vue

@@ -4,14 +4,14 @@
       <div class="ptc-inner">
         <p class="ptc-label">Version & Price</p>
         <div class="detail">
-          <strong class="s1">Lite</strong>
+          <strong class="s1">{{ getters.selectedProduct.name }}</strong>
           <span style="font-size: 0"
-            ><strong class="s2">$99</strong
+            ><strong class="s2">${{ getters.cost }}</strong
             ><span class="s3">{{
               state.form.subscribe_type === 'year' ? 'Annual' : 'Monthly'
             }}</span></span
           >
-          <strong class="s4" @click="$router.go(-2)">Modify ></strong>
+          <strong class="s4" @click="$emit('go', -2)">Modify ></strong>
         </div>
       </div>
     </div>
@@ -19,8 +19,8 @@
       <div class="ptc-inner">
         <p class="ptc-label">Phone model</p>
         <div class="detail">
-          <strong class="s1">iPhone 13 Pro</strong>
-          <strong class="s4" @click="$router.back()">Modify ></strong>
+          <strong class="s1">{{ getters.modelName }}</strong>
+          <strong class="s4" @click="$emit('go', -1)">Modify ></strong>
         </div>
       </div>
     </div>
@@ -49,10 +49,14 @@
 
 <script setup lang="ts">
 import { string } from 'yup'
-import { state } from './store'
+import { state, getters } from './store'
 import { checkoutOrder } from '@/service/order'
 import Toast from '@/components/toast'
 
+defineEmits<{
+  (e: 'go', delta?: number): void
+}>()
+
 async function submit() {
   try {
     await string()

+ 12 - 9
src/pages/fill-order/StepTwo.vue

@@ -4,14 +4,14 @@
       <div class="ptc-inner">
         <p class="ptc-label">Version & Price</p>
         <div class="detail">
-          <strong class="s1">Lite</strong>
+          <strong class="s1">{{ getters.selectedProduct.name }}</strong>
           <span style="font-size: 0"
-            ><strong class="s2">$99</strong
+            ><strong class="s2">${{ getters.cost }}</strong
             ><span class="s3">{{
               state.form.subscribe_type === 'year' ? 'Annual' : 'Monthly'
             }}</span></span
           >
-          <strong class="s4" @click="$router.back()">Modify ></strong>
+          <strong class="s4" @click="$emit('go', -1)">Modify ></strong>
         </div>
       </div>
     </div>
@@ -29,7 +29,7 @@
             class="device-item"
             :value="brand.id"
           >
-            <img class="device-img" />
+            <i :class="['device-img', `device-img-${brand.id}`]" />
             <p class="device-name">{{ brand.name }}</p>
           </PtcRadio>
         </PtcRadioGroup>
@@ -50,7 +50,7 @@
               class="device-item"
               :value="model.id"
             >
-              <img class="device-img" />
+              <img class="device-img" :src="model.image" />
               <p class="device-name">{{ model.name }}</p>
             </PtcRadio>
           </PtcRadioGroup>
@@ -62,10 +62,10 @@
 
 <script setup lang="ts">
 import { PtcRadioGroup, PtcRadio } from '@/components/radio'
-import { state, getModelList } from './store'
+import { state, getters, getModelList } from './store'
 
 const emit = defineEmits<{
-  (e: 'next'): void
+  (e: 'go', delta?: number): void
 }>()
 
 function onSelectBrand() {
@@ -74,7 +74,7 @@ function onSelectBrand() {
 }
 
 function onSelectModel() {
-  setTimeout(() => emit('next'), 200)
+  setTimeout(() => emit('go'), 200)
 }
 </script>
 
@@ -103,10 +103,13 @@ function onSelectModel() {
   }
 
   &-img {
+    display: inline-block;
+    vertical-align: top;
     margin-bottom: 18px;
     width: 200px;
     height: 200px;
-    background: teal;
+    background-color: #eee;
+    background-size: contain;
   }
 }
 </style>

+ 21 - 14
src/pages/fill-order/index.vue

@@ -1,13 +1,13 @@
 <template>
   <div class="p-fill-order">
     <h3 class="ptc-title">Fill Order</h3>
-    <component :is="Component" @next="next" />
+    <component :is="Component" @go="go" />
   </div>
 </template>
 
 <script lang="ts">
-import { defineComponent } from 'vue'
-import { state, initProducts } from './store'
+import { defineComponent, onUnmounted } from 'vue'
+import { initProducts } from './store'
 
 export default defineComponent({
   name: 'FillOrder',
@@ -18,22 +18,29 @@ export default defineComponent({
 </script>
 
 <script setup lang="ts">
-import { useRoute, useRouter } from 'vue-router'
+import { ref, computed, watch } from 'vue'
+import { useRoute } from 'vue-router'
 import StepOne from './StepOne.vue'
 import StepTwo from './StepTwo.vue'
 import StepThree from './StepThree.vue'
+import { state } from './store'
 
-const router = useRouter()
-const step = +((useRoute().query.step || '0') as string)
-const Component = [StepOne, StepTwo, StepThree][step]
+const step = ref(0)
+const Component = computed(() => [StepOne, StepTwo, StepThree][step.value])
+const { from, invitee } = useRoute().query as any
 
-function next() {
-  router.push({
-    path: '',
-    query: {
-      step: step + 1,
-    },
-  })
+state.form.from = from
+state.form.invitor = invitee
+
+onUnmounted(() => {
+  state.form = {} as any
+  state.modelList = []
+})
+
+watch(step, () => window.scrollTo(0, 0))
+
+function go(delta = 1) {
+  step.value += delta
 }
 </script>
 

+ 31 - 1
src/pages/fill-order/store.ts

@@ -1,4 +1,4 @@
-import { reactive } from 'vue'
+import { reactive, computed } from 'vue'
 import * as api from '@/service/order'
 
 export const state = reactive({
@@ -15,6 +15,36 @@ export const state = reactive({
     from: '',
     invitor: '',
   },
+  discount: null as any,
+})
+
+const selectedProduct = computed(() =>
+  state.productList.find(item => item.id === state.form.product_id)
+)
+
+const cost = computed(() => {
+  if (!selectedProduct.value) return ''
+  const { amount_year, amount_month, amount_month_open } = selectedProduct.value
+  const { discount_amount = 0 } = state.discount || {}
+  switch (state.form.subscribe_type) {
+    case 'year':
+      return (+amount_year - discount_amount).toFixed(2)
+    case 'month':
+      return (+amount_month + +amount_month_open - discount_amount).toFixed(2)
+    default:
+      return ''
+  }
+})
+
+const modelName = computed(
+  () =>
+    state.modelList.find(item => item.id === state.form.phone_id)?.name || ''
+)
+
+export const getters = reactive({
+  selectedProduct,
+  cost,
+  modelName,
 })
 
 export async function initProducts() {

+ 7 - 5
src/pages/invite/index.vue

@@ -27,12 +27,9 @@
                 type="text"
                 class="ptc-input"
                 readonly
-                value="http://www.ptcplis.com/2333453"
+                :value="inviteUrl"
               />
-              <button
-                class="ptc-button"
-                @click="copy('http://www.ptcplis.com/2333453')"
-              >
+              <button class="ptc-button" @click="copy(inviteUrl)">
                 Copy Link
               </button>
             </p>
@@ -91,6 +88,7 @@ import { string } from 'yup'
 import { inviteFriends, getInviteRewards } from '@/service/user'
 import Toast from '@/components/toast'
 import copy from '@/utils/clipboard'
+import { state } from '@/store'
 
 export default defineComponent({
   name: 'InviteFriends',
@@ -102,6 +100,10 @@ export default defineComponent({
     return {
       emails: '',
       awards: [] as any[],
+      inviteUrl:
+        location.origin +
+        '/fill-order?from=member&invitee=' +
+        state.userInfo!.id,
     }
   },
   computed: {

+ 1 - 0
src/service/types/user.d.ts

@@ -54,6 +54,7 @@ declare namespace ApiUser {
       num_gift_card: number
       num_order: number
       num_repair: number
+      qrcode: string
       orders: {
         id: number
         phone_info: string