Browse Source

feat(app): 到店打卡

EvilDragon 4 months ago
parent
commit
b191dd507b

+ 14 - 0
packages/app/src/core/libs/enums.ts

@@ -12,3 +12,17 @@ export enum MessageType {
    */
   Interact = 3,
 }
+export enum QrCodeBusinessType {
+  /**
+   * 积分结账
+   */
+  PointsCheckout = 'PC',
+  /**
+   * 到店核销
+   */
+  InStoreWriteOff = 'ISWO',
+  /**
+   * 到店打卡
+   */
+  InStoreClockIn = 'ISCI',
+}

+ 0 - 10
packages/app/src/core/libs/models.ts

@@ -551,13 +551,3 @@ export enum BannerMode {
    */
   StudyTour = 5,
 }
-export enum QrCodeBusinessType {
-  /**
-   * 积分结账
-   */
-  PointsCheckout = 'PC',
-  /**
-   * 到店核销
-   */
-  InStoreWriteOff = 'ISWO',
-}

+ 11 - 1
packages/app/src/core/libs/requests.ts

@@ -1,4 +1,4 @@
-import { httpGet, httpPost, httpPut } from '../../utils/http'
+import { http, httpGet, httpPost, httpPut } from '../../utils/http'
 import { Schedule } from '../models/schedule'
 import {
   Category,
@@ -736,6 +736,16 @@ export const getAppMemberLevelConfigs = () =>
       }[]
     }[]
   >('/app-api/basicsetting/app-set-member-level-config/listAndRights')
+/**
+ * 到店打卡
+ */
+export const storeAndPunchIn = (data: { id: number }) =>
+  http<boolean>({
+    url: '/app-api/member/user-auth-info/storeAndPunchIn',
+    data,
+    hideErrorToast: true,
+    method: 'POST',
+  })
 export const refreshToken = (refreshToken: string) =>
   httpPost<any>('/app-api/member/auth/refresh-token', {}, { refreshToken })
 export const httpGetMock = <T>(data: T) =>

+ 27 - 6
packages/app/src/pages/mine/index.vue

@@ -8,14 +8,20 @@ import CardMenu from '@/components/card-menu.vue'
 import SectionHeading from '@/components/section-heading.vue'
 import { designer, settled, treaty, vipBg } from '../../core/libs/pngs'
 import { integral, coupon, order, agent, setting, vip, scan } from '../../core/libs/svgs'
-import { getDesignerInfo, getMemberUserInfo, getTasks } from '../../core/libs/requests'
+import {
+  getDesignerInfo,
+  getMemberUserInfo,
+  getTasks,
+  storeAndPunchIn,
+} from '../../core/libs/requests'
 import { useUserStore } from '../../store'
 import { storeToRefs } from 'pinia'
 import { isEmpty } from 'radash'
 import TasksCard from './components/tasks-card.vue'
 import { useRouter } from '../../core/utils/router'
 import { NetImages } from '../../core/libs/net-images'
-import { qrCodeString2Object, toQrCodeString } from '../../core/utils/common'
+import { qrCodeString2Object, requestToast, toQrCodeString } from '../../core/utils/common'
+import { QrCodeBusinessType } from '@/core/libs/enums'
 
 const router = useRouter()
 const userStore = useUserStore()
@@ -130,10 +136,25 @@ const handleMenuClick = (path) => {
 const handleClickScan = async () => {
   const { result } = await uni.scanCode({})
   console.log(result)
-  const a = qrCodeString2Object('WIFI:S:KM;T:WPA;P:km666888;H:false;;')
-  console.log(a)
-  console.log(toQrCodeString('到店', { a: 1, orderId: 2222 }))
-  console.log(qrCodeString2Object(toQrCodeString('到店', { a: 1, orderId: 2222 })))
+  // const a = qrCodeString2Object('WIFI:S:KM;T:WPA;P:km666888;H:false;;')
+  // console.log(a)
+  // console.log(toQrCodeString('到店', { a: 1, orderId: 2222 }))
+  // console.log(qrCodeString2Object(toQrCodeString('到店', { a: 1, orderId: 2222 })))
+  const { type, options } = qrCodeString2Object(result)
+  if (type === QrCodeBusinessType.InStoreClockIn) {
+    try {
+      await storeAndPunchIn({ id: options.id })
+      router.push(`/pages/mine/scan/result/index?result=${result}`)
+    } catch (e) {
+      console.log(e)
+      if (e.code === 10000) {
+        router.push(
+          `/pages/mine/scan/result/index?result=${toQrCodeString(type, { name: options.name, desc: e.msg })}`,
+        )
+      }
+    }
+    return
+  }
   router.push(`/pages/mine/scan/result/index?result=${result}`)
 }
 const handle2Video = () => {

+ 1 - 1
packages/app/src/pages/mine/orders/code/index.vue

@@ -6,7 +6,7 @@ import dayjs from 'dayjs'
 import UQRCode from 'uqrcodejs'
 import { getPointsOrder } from '../../../../core/libs/requests'
 import { toQrCodeString } from '../../../../core/utils/common'
-import { QrCodeBusinessType } from '../../../../core/libs/models'
+import { QrCodeBusinessType } from '../../../../core/libs/enums'
 
 const id = ref()
 const { data, run: setData } = useRequest(() => getPointsOrder(id.value), { initialData: {} })

+ 47 - 3
packages/app/src/pages/mine/scan/result/index.vue

@@ -2,12 +2,15 @@
 { "style": { "navigationBarTitleText": "扫码结果", "navigationBarBackgroundColor": "#fff" } }
 </route>
 <script setup lang="ts">
-import { pointsPay } from '../../../../core/libs/requests'
-import { QrCodeBusinessType } from '../../../../core/libs/models'
+import { pointsPay, storeAndPunchIn } from '../../../../core/libs/requests'
+import {} from '../../../../core/libs/models'
 import { qrCodeString2Object, requestToast } from '../../../../core/utils/common'
-import { useUserStore } from '@/store'
+import { useUserStore } from '../../../../store'
 import { storeToRefs } from 'pinia'
 import { useRouter } from '../../../../core/utils/router'
+import { QrCodeBusinessType } from '../../../../core/libs/enums'
+import { success } from '../../../../core/libs/svgs'
+import SectionHeading from '@/components/section-heading.vue'
 
 const router = useRouter()
 const userStore = useUserStore()
@@ -20,8 +23,10 @@ const data = ref<{
   points?: string
   avatar?: string
   name?: string
+  desc?: string
 }>()
 const isPointsCheckout = computed(() => scanType.value === QrCodeBusinessType.PointsCheckout)
+const isInStoreClockIn = computed(() => scanType.value === QrCodeBusinessType.InStoreClockIn)
 const handleSubmit = async () => {
   if (isPointsCheckout.value) {
     const { code } = await requestToast(() =>
@@ -44,7 +49,22 @@ onLoad(async (query: { result: string }) => {
     console.log(scanType.value)
     console.log(data.value)
 
+    console.log(isInStoreClockIn.value)
+
     if (isPointsCheckout.value) uni.setNavigationBarTitle({ title: '付款' })
+    // if (isInStoreClockIn.value) {
+    //   console.log(11111)
+    //   nextTick(async () => {
+    //     const { code, data } = await requestToast(() =>
+    //       storeAndPunchIn({ id: Number(data.value?.id) }),
+    //     )
+    //     console.log(data, code)
+    //   })
+
+    //   // if (code === 0) {
+    //   //   data.value
+    //   // }
+    // }
   } catch (error) {
     msg.value = error.message
   }
@@ -78,6 +98,30 @@ onLoad(async (query: { result: string }) => {
       </div>
       <div><wd-button @click="handleSubmit">确认付款</wd-button></div>
     </template>
+    <template v-else-if="isInStoreClockIn">
+      <div class="w-full box-border px-8.25 flex flex-col items-center gap-7">
+        <wd-img width="60" height="60" :src="success" custom-class="mb--4"></wd-img>
+        <div class="text-black/90 text-xl font-normal font-['PingFang SC'] leading-none">
+          扫描成功
+        </div>
+        <div
+          class="w-[162px] h-[18px] text-center text-black/40 text-base font-normal font-['PingFang SC'] leading-relaxed"
+        >
+          {{ data?.desc ? data.desc : '恭喜您!到店打卡成功' }}
+        </div>
+        <div class="w-full mt-19.75" v-if="data?.name">
+          <SectionHeading
+            size="base"
+            title="到店材料商"
+            dark
+            :end-text="data?.name"
+          ></SectionHeading>
+        </div>
+        <div class="w-full" v-if="data?.points">
+          <SectionHeading size="base" title="获得积分" :end-text="data?.points"></SectionHeading>
+        </div>
+      </div>
+    </template>
     <template v-else>
       <div class="text-black/60 text-base font-normal font-['PingFang_SC'] leading-none">
         不支持此二维码/条码

+ 1 - 1
packages/app/src/utils/http.ts

@@ -61,7 +61,7 @@ export const http = async <T>(options: CustomRequestOptions) => {
                 title: (res.data as IResData<T>).msg || '请求错误',
               })
             sentry.captureException(res)
-            reject(res)
+            reject(res.data)
           }
         } else if (res.statusCode === 401) {
           // 401错误  -> 清理用户信息,跳转到登录页