Browse Source

维修预约

冯诚 2 years ago
parent
commit
0680d78df4

+ 1 - 0
package.json

@@ -8,6 +8,7 @@
   },
   "dependencies": {
     "axios": "^0.25.0",
+    "dayjs": "^1.10.7",
     "lodash-es": "^4.17.21",
     "nprogress": "^0.2.0",
     "vue": "^3.2.25",

+ 6 - 1
src/pages/appointment/StepOne.vue

@@ -29,7 +29,7 @@
               v-for="(item, index) of list"
               :key="index"
               class="shop-item border-bottom"
-              @click="state.step++"
+              @click="!item.can_appointment && selectShop(item)"
             >
               <div class="shop-name">
                 <span>{{ item.name }}</span>
@@ -87,4 +87,9 @@ async function fetchData() {
 function autocomplete(e: any) {
   showSuggestions.value = e.target.value.length > 0
 }
+
+function selectShop(shop: any) {
+  state.shop = { ...shop }
+  state.step++
+}
 </script>

+ 22 - 7
src/pages/appointment/StepThree.vue

@@ -2,10 +2,9 @@
   <h3 class="ptc-title">Confirm appointment</h3>
   <div class="ptc-block">
     <div class="ptc-inner">
-      <div class="shop-name">PTC Browns Plains Kiosk</div>
+      <div class="shop-name">{{ state.shop.name }}</div>
       <div class="shop-address">
-        Browns Plains Grand Plaza Shopping Centre, Shop K007 27-49 Browns Plains
-        Road, Browns Plains, QLD, 4118 (07) 3059 1014
+        {{ state.shop.address }}
       </div>
       <div class="shop-action">
         <span class="modify" @click="state.step = 0">Modify ></span>
@@ -16,8 +15,8 @@
     <div class="ptc-inner">
       <p class="t2">Appointed time</p>
       <div class="flex-ac space-between">
-        <strong class="p1">Mon,10</strong>
-        <strong class="p2">9:00 - 9:30</strong>
+        <strong class="p1">{{ state.uiDate }}</strong>
+        <strong class="p2">{{ state.uiPeriod }}</strong>
         <span class="modify" @click="state.step--">Modify ></span>
       </div>
     </div>
@@ -29,7 +28,12 @@
         the details with you。
       </p>
       <p class="t2">Phone number</p>
-      <input type="text" class="ptc-input" placeholder="Please enter" />
+      <input
+        v-model="state.phoneNumber"
+        type="text"
+        class="ptc-input"
+        placeholder="Please enter"
+      />
     </div>
   </div>
   <div class="ptc-wrapper">
@@ -38,7 +42,10 @@
         <p class="t1">
           Is there anything to pay attention to, nothing to skip。
         </p>
-        <textarea placeholder="Please enter, up to 1000 characters"></textarea>
+        <textarea
+          v-model="state.remark"
+          placeholder="Please enter, up to 1000 characters"
+        ></textarea>
       </div>
     </div>
     <div class="ptc-button-group">
@@ -50,5 +57,13 @@
 </template>
 
 <script setup lang="ts">
+import { onMounted } from 'vue'
 import { state } from './store'
+import { getRepairPhone } from '@/service/repair'
+
+onMounted(async () => {
+  if (state.repairId) {
+    state.phoneNumber = (await getRepairPhone()).results
+  }
+})
 </script>

+ 64 - 17
src/pages/appointment/StepTwo.vue

@@ -20,15 +20,15 @@
           <PtcRadioGroup
             v-model="state.date"
             class="date-list"
-            @change="state.period = ''"
+            @change="onDateChange"
           >
-            <PtcRadio class="date" value="1">Mon,10</PtcRadio>
-            <PtcRadio class="date" value="2" :disabled="true">Mon,10</PtcRadio>
-            <PtcRadio class="date" value="3">Mon,10</PtcRadio>
-            <PtcRadio class="date" value="4">Mon,10</PtcRadio>
-            <PtcRadio class="date" value="5">Mon,10</PtcRadio>
-            <PtcRadio class="date" value="6">Mon,10</PtcRadio>
-            <PtcRadio class="date" value="7">Mon,10</PtcRadio>
+            <PtcRadio
+              v-for="(item, index) of nex7Days"
+              :key="index"
+              class="date"
+              :value="item.fullDate"
+              >{{ item.day }},{{ item.date }}</PtcRadio
+            >
           </PtcRadioGroup>
         </div>
       </div>
@@ -39,11 +39,19 @@
       <div class="ptc-cell">
         <p class="ptc-label">Selection period</p>
         <div class="ptc-value">
-          <PtcRadioGroup v-model="state.period" class="date-list">
-            <PtcRadio class="date" value="1">9:00 - 9:30</PtcRadio>
-            <PtcRadio class="date" value="2">9:30 - 10:00</PtcRadio>
-            <PtcRadio class="date" value="3">10:00 - 10:30</PtcRadio>
-            <PtcRadio class="date" value="4">10:30 - 11:00</PtcRadio>
+          <PtcRadioGroup
+            v-model="state.period"
+            class="date-list"
+            @change="onPeriodChange"
+          >
+            <PtcRadio
+              v-for="(item, index) of state.periods"
+              :key="index"
+              class="date"
+              :disabled="!!item.is_resreve"
+              :value="item.interface_time"
+              >{{ item.time }}</PtcRadio
+            >
           </PtcRadioGroup>
         </div>
       </div>
@@ -53,11 +61,50 @@
 
 <script setup lang="ts">
 import { watch } from 'vue'
+import dayjs from 'dayjs'
 import { PtcRadioGroup, PtcRadio } from '@/components/radio'
 import { state } from './store'
+import { getShopPeriods } from '@/service/repair'
+
+const nex7Days = (function getNext7Days() {
+  const days = ['Sun', 'Mon', 'Tues', 'Wed', 'Thurs', 'Fri', 'Sat']
+  const _ = dayjs()
+  const day = _.day()
+  return days
+    .slice(day)
+    .concat(days.slice(0, day))
+    .map((day, index) => {
+      const today = _.add(index, 'd')
+      return {
+        day,
+        date: String(today.date()).padStart(2, '0'),
+        fullDate: today.format('YYYY-MM-DD'),
+      }
+    })
+})()
+
+// watch(
+//   () => state.period,
+//   val => state.date && val && setTimeout(() => state.step++, 200)
+// )
+
+async function onDateChange(date: string) {
+  state.period = ''
+  state.periods = (
+    await getShopPeriods({
+      date,
+      area_code: '1',
+      igeektek_id: state.shop.igeektek_id,
+    })
+  ).results
+
+  const _ = nex7Days.find(item => item.fullDate === date)!
+  state.uiDate = `${_.day},${_.date}`
+}
 
-watch(
-  () => state.period,
-  val => state.date && val && setTimeout(() => state.step++, 200)
-)
+function onPeriodChange(val: string) {
+  state.period = val
+  state.uiPeriod = state.periods.find(item => item.interface_time === val)!.time
+  state.date && setTimeout(() => state.step++, 200)
+}
 </script>

+ 2 - 2
src/pages/appointment/index.scss

@@ -256,11 +256,11 @@
       background: #dae1ef;
       color: $primary-color;
     }
-    &.s2 {
+    &.s0 {
       background: #f2f5fb;
       color: #97A6C4;
     }
-    &.s3 {
+    &.s2 {
       background: #eaeaea;
       color: #999;
     }

+ 8 - 3
src/pages/appointment/index.vue

@@ -5,20 +5,23 @@
 </template>
 
 <script setup lang="ts">
-import { computed, watch } from 'vue'
-import { onBeforeRouteLeave, useRouter } from 'vue-router'
+import { computed, watch, onUnmounted } from 'vue'
+import { onBeforeRouteLeave, useRouter, useRoute } from 'vue-router'
 import StepOne from './StepOne.vue'
 import StepTwo from './StepTwo.vue'
 import StepThree from './StepThree.vue'
 import StepFour from './StepFour.vue'
 import StepFive from './StepFive.vue'
-import { state } from './store'
+import { state, resetState } from './store'
 import { state as rootState } from '@/store'
 
 const Component = computed(
   () => [StepOne, StepTwo, StepThree, StepFour, StepFive][state.step]
 )
 const fromPath = history.state.back
+const { query } = useRoute()
+
+if (query.id) state.repairId = query.id as string
 
 onBeforeRouteLeave((to, from) => {
   if (to.path === fromPath && to.path !== '/' && state.step > 0) {
@@ -29,6 +32,8 @@ onBeforeRouteLeave((to, from) => {
   }
 })
 
+onUnmounted(resetState)
+
 watch(
   () => state.step,
   () => {

+ 65 - 18
src/pages/appointment/records.vue

@@ -1,55 +1,102 @@
 <template>
   <div class="p-appointment">
     <h3 class="ptc-title">Confirm appointment</h3>
-    <div class="ptc-block wrapper">
+    <div v-for="item of list" :key="item.id" class="ptc-block wrapper">
       <div class="inner">
         <div class="block-title">
-          <span class="text"
-            >Monday, October 10 9:00-9:30 PTC Browns Plains Kiosk</span
-          >
-          <span class="ptc-tag" :class="{ s1: 1, s2: 0, s3: 0 }"
-            >Under review</span
-          >
+          <span class="text">{{ item.pickup_time }} {{ item.shop_name }}</span>
+          <span class="ptc-tag" :class="`s${item.audit_status}`">{{
+            item.audit_status === 0
+              ? 'Under review'
+              : item.audit_status === 1
+              ? 'Approved'
+              : 'Canceled'
+          }}</span>
         </div>
         <div class="cell-group mt48">
           <div class="cell">
             <span class="cell-label">Phone Brand:</span>
-            <span class="cell-value">Apple</span>
+            <span class="cell-value">{{ item.phone_brand }}</span>
           </div>
           <div class="cell">
             <span class="cell-label">Phone Model:</span>
-            <span class="cell-value">iPhone 12</span>
+            <span class="cell-value">{{ item.phone_model }}</span>
           </div>
           <div class="cell">
             <span class="cell-label">Phone Number:</span>
-            <span class="cell-value">6668888</span>
+            <span class="cell-value">{{ item.phone_number }}</span>
           </div>
           <div class="cell">
             <span class="cell-label">IMEI:</span>
-            <span class="cell-value">iPhonaskfjoaxxx</span>
+            <span class="cell-value">{{ item.phone_imei }}</span>
           </div>
           <div class="cell">
             <span class="cell-label">Service:</span>
-            <span class="cell-value">Batery Replacement</span>
+            <span class="cell-value">{{ item.fix_name }}</span>
           </div>
           <div class="cell">
             <span class="cell-label">Member Price:</span>
-            <span class="cell-value">$35</span>
+            <span class="cell-value">${{ item.price }}</span>
           </div>
           <div class="cell mt48">
             <span class="cell-label">Postcript:</span>
-            <span class="cell-value"
-              >This is my remark,This is my remarkThis is my remark</span
-            >
+            <span class="cell-value">{{ item.remark }}</span>
           </div>
         </div>
       </div>
       <div class="button-group">
-        <button class="ptc-button">Reschedule</button>
-        <button class="ptc-button ptc-button--stroke">Cancel</button>
+        <button
+          v-if="item.audit_status === 2"
+          class="ptc-button ptc-button--stroke"
+          @click="deleteRepair(item)"
+        >
+          Delete
+        </button>
+        <template v-else>
+          <button
+            class="ptc-button"
+            @click="$router.push('/appointment?id=' + item.id)"
+          >
+            Reschedule
+          </button>
+          <button
+            class="ptc-button ptc-button--stroke"
+            @click="cancelRepair(item)"
+          >
+            Cancel
+          </button>
+        </template>
       </div>
     </div>
   </div>
 </template>
 
+<script>
+import { defineComponent } from 'vue'
+import * as api from '@/service/repair'
+
+export default defineComponent({
+  async beforeRouteEnter(to, from, next) {
+    const { results } = await api.getRepairList()
+    next(vm => (vm.list = results))
+  },
+  data() {
+    return {
+      /** @type {any[]} */
+      list: [],
+    }
+  },
+  methods: {
+    async cancelRepair(item) {
+      await api.cancelRepair(item.id)
+      item.audit_status = 2
+    },
+    async deleteRepair(item) {
+      await api.deleteRepair(item.id)
+      this.list.splice(this.list.indexOf(item), 1)
+    },
+  },
+})
+</script>
+
 <style lang="scss" src="./index.scss"></style>

+ 14 - 2
src/pages/appointment/store.ts

@@ -1,7 +1,19 @@
 import { reactive } from 'vue'
 
-export const state = reactive({
+const initialState = {
   step: 0,
+  repairId: '',
+  shop: null as any,
+  periods: [] as any[],
+  uiDate: '',
+  uiPeriod: '',
   date: '',
   period: '',
-})
+  phoneNumber: '',
+  remark: '',
+}
+export const state = reactive({ ...initialState })
+
+export function resetState() {
+  Object.assign(state, initialState)
+}

+ 5 - 0
yarn.lock

@@ -573,6 +573,11 @@ csstype@^2.6.8:
   resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.19.tgz#feeb5aae89020bb389e1f63669a5ed490e391caa"
   integrity sha512-ZVxXaNy28/k3kJg0Fou5MiYpp88j7H9hLZp8PDC3jV0WFjfH5E9xHb56L0W59cPbKbcHXeP4qyT8PrHp8t6LcQ==
 
+dayjs@^1.10.7:
+  version "1.10.7"
+  resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.10.7.tgz#2cf5f91add28116748440866a0a1d26f3a6ce468"
+  integrity sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==
+
 debug@^4.0.1, debug@^4.1.1:
   version "4.3.3"
   resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664"