hsy 2 months ago
parent
commit
2e094f0853

+ 4 - 2
src/views/open/error.vue

@@ -1,7 +1,9 @@
 <template>
   <div class="h-screen flex items-center justify-center flex-col">
     <img src="@/assets/icon-link-error.png" alt="" class="w-40">
-    <div class="text-xl mt-4 text-gray-600">{{ msg}}</div>
+    <div class="text-xl mt-4 text-gray-600 whitespace-pre-wrap text-center">
+      <div v-html="msg"></div>
+    </div>
   </div>
 </template>
 
@@ -14,7 +16,7 @@ import { request } from '@/utils';
 
 const [route, router] = [useRoute(), useRouter()];
 const msg = ref(route.query.msg || '未知错误');
-document.title = msg.value;
+document.title = '错误';
 
 </script>
 

+ 117 - 0
src/views/promotion/components/PaymentHistoryDialog.vue

@@ -0,0 +1,117 @@
+<template>
+  <van-popup
+    v-model:show="dialogVisible"
+    round
+    position="bottom"
+    :style="{ height: '80%' }"
+  >
+    <div class="p-4 flex flex-col h-full">
+      <!-- Header -->
+      <div class="flex justify-between items-center mb-4">
+        <div class="text-gray-400 cursor-pointer" @click="onClose">取消</div>
+        <div class="text-lg font-medium">购买记录</div>
+        <div class="w-8"></div>
+      </div>
+
+<!-- Loading State -->
+      <van-loading v-if="loading" class="self-center my-8" />
+
+      <!-- Empty State -->
+      <van-empty v-else-if="!records.length" description="暂无购买记录" />
+
+      <!-- Records List -->
+      <div v-else class="flex-1 overflow-y-auto">
+        <div  v-for="(record, index) in records" :key="index" class="bg-gray-50 rounded-lg p-4 mb-4">
+          <div class="flex justify-between items-center mb-2">
+            <span class="text-gray-600">购买手机号:</span>
+            <span>{{ record.mobile }}</span>
+          </div>
+          <div class="flex justify-between items-center mb-2">
+            <span class="text-gray-600">支付时间:</span>
+            <span>{{ record.createdAt }}</span>
+          </div>
+          <div class="flex justify-between items-center mb-2">
+            <span class="text-gray-600">支付金额:</span>
+            <span class="text-red-500">¥{{ (record.balance / 100 ).toFixed(2) }}</span>
+          </div>
+          <div class="flex justify-between items-center">
+            <span class="text-gray-600">商品名称:</span>
+            <span>{{ record.promotionGoods?.memberCardName }}</span>
+          </div>
+        </div>
+        <div v-if="goodsDetail && goodsDetail.paidSlogan" v-html="goodsDetail.paidSlogan" class="p-2"></div>
+      </div>
+
+    </div>
+  </van-popup>
+</template>
+<script setup>
+import { ref, computed, watch, inject } from "vue";
+import { showToast } from "vant";
+import { useRoute, useRouter } from "vue-router";
+import { request } from "@/utils";
+
+const [route, router] = [useRoute(), useRouter()];
+const props = defineProps({
+  show: Boolean,
+  onClose: Function,
+  onConfirm: Function,
+  openId: String
+});
+
+const goodsDetail = inject('goodsDetail')
+// 使用computed处理show
+const dialogVisible = computed({
+  get: () => props.show,
+  set: (value) => emit("update:show", value),
+});
+
+const emit = defineEmits(["update:show"]);
+
+// 数据相关
+const loading = ref(false);
+const records = ref([]);
+
+// 处理关闭
+const handleClose = () => {
+  emit('update:show', false);
+  props.onClose?.();
+};
+
+// 获取购买记录
+const fetchRecords = async () => {
+  try {
+    loading.value = true;
+    const { data } = await request.get(`/archivesService/member/promotionGoods/order/paginate`, {
+      params: {
+        openId: props.openId,
+        page: 1,
+        // size: 1,
+      }
+    });
+    records.value = data.list;
+  } finally {
+    loading.value = false;
+  }
+};
+
+watch(() => [dialogVisible.value, props.openId], () => {
+  if (dialogVisible.value && props.openId) {
+    fetchRecords()
+  }
+})
+</script>
+
+<style scoped>
+:deep(.van-field) {
+  background-color: #f5f5f5 !important;
+}
+
+:deep(.van-field__control) {
+  color: #333;
+}
+
+:deep(.van-popup) {
+  background-color: white;
+}
+</style>

+ 23 - 11
src/views/promotion/goods.vue

@@ -28,9 +28,7 @@
               <div :class="goodsDetail?.originPrice ? 'pb-3' : 'py-3'">
                 <span>¥</span>
                 <span class="text-2xl">
-                  {{
-                    parseFloat((goodsDetail?.price / 100).toFixed(2))
-                  }}
+                  {{ parseFloat((goodsDetail?.price / 100).toFixed(2)) }}
                 </span>
                 <span>/{{ goodsDetail.memberCard?.lifespan }}天</span>
               </div>
@@ -53,6 +51,13 @@
       <div
         class="flex w-10/12 items-center justify-center overflow-hidden rounded-xl bg-[#2c2c2c]"
       >
+        <button
+          class="flex-1 whitespace-nowrap border-0 bg-[#2c2c2c] p-4 text-sm text-[#e59223] after:hidden"
+          @click="buyHistory"
+        >
+          <span class="text-base">购买记录</span>
+        </button>
+        <div class="h-5 w-px bg-[#e59223]"></div>
         <button
           class="flex-1 whitespace-nowrap border-0 bg-[#2c2c2c] p-4 text-sm text-[#e59223] after:hidden"
           @click="buy"
@@ -66,19 +71,22 @@
       :onClose="handleClose"
       :onConfirm="handleConfirm"
     />
+    <PaymentHistoryDialog :show="showHistory" :openId="openId" />
   </div>
 </template>
 
 <script setup>
-import { ref, reactive, onMounted, computed, watch } from "vue";
+import { ref, reactive, onMounted, computed, watch, provide } from "vue";
 
 import PaymentDialog from "./components/PaymentDialog.vue";
+import PaymentHistoryDialog from "./components/PaymentHistoryDialog.vue";
 import { useRoute, useRouter } from "vue-router";
 
 import { request } from "@/utils";
 
 const [route, router] = [useRoute(), useRouter()];
 const goodsDetail = ref({});
+provide("goodsDetail", goodsDetail);
 const getGoodsDetail = async () => {
   const { data } = await request.get(
     `archivesService/member/promotionGoods/detail`,
@@ -114,12 +122,12 @@ function onBridgeReady(paySign) {
         //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠,商户需进一步调用后端查单确认支付结果。
         console.log("支付成功");
         router.push({
-          name: 'promotionPayResult',
+          name: "promotionPayResult",
           query: {
             promotionGoodsId: route.query.promotionGoodsId,
             promotionSiteId: route.query.promotionSiteId,
-          }
-        })
+          },
+        });
       } else {
         showToast("支付失败" + res.err_msg);
       }
@@ -142,6 +150,10 @@ const handleConfirm = async (mobile, captcha) => {
   console.log(data.paymentParams);
   data.paymentParams?.paySign && onBridgeReady(data.paymentParams.paySign);
 };
+const showHistory = ref(false);
+const buyHistory = () => {
+  showHistory.value = true;
+};
 const buy = () => {
   showDialog.value = true;
 };
@@ -152,7 +164,7 @@ const preCheck = async () => {
     {
       params: {
         promotionGoodsId: route.query.promotionGoodsId,
-      promotionSiteId: route.query.promotionSiteId,
+        promotionSiteId: route.query.promotionSiteId,
       },
     }
   );
@@ -176,7 +188,7 @@ const preCheck = async () => {
 //   });
 // };
 const appId = ref(sessionStorage.getItem("appId"));
-const openId = ref("ozZpI7OTqj9cNlHfzAxcJ9MH41V8");
+const openId = ref("KfZnJNKFaFXWWCagSlX0dT4tNkwsLEwQVlrzpHvo");
 const getWeChatAuth = async () => {
   const { appId, errMsg, paymentSettingId } = await preCheck();
   if (errMsg) {
@@ -234,9 +246,9 @@ const init = async () => {
   }
   const paymentSettingId = sessionStorage.getItem("paymentSettingId");
   if (!code || !paymentSettingId) {
-    return getWeChatAuth();
+    // return getWeChatAuth();
   }
-  getOpenId()
+  // getOpenId()
   // wxConfig();
 };
 onMounted(() => init());