lex-wxl hace 13 horas
padre
commit
01c5df63f1

+ 39 - 0
src/components/VipPurchaseModal/index.module.less

@@ -203,4 +203,43 @@
     border-radius: 8px;
     border-radius: 8px;
     border: 1px solid rgba(0, 0, 0, 0.06);
     border: 1px solid rgba(0, 0, 0, 0.06);
   }
   }
+
+  .goodsName {
+    font-size: 16px;
+    color: #333;
+    margin-top: 12px;
+    padding: 10px 16px;
+    background: rgba(255, 255, 255, 0.8);
+    border-radius: 8px;
+    border: 1px solid rgba(0, 0, 0, 0.06);
+    font-weight: 500;
+  }
+
+  .failedTip {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    padding: 40px 0;
+  }
+
+  .failedIcon {
+    width: 80px;
+    height: 80px;
+    border-radius: 50%;
+    background: linear-gradient(135deg, #ffe8e8 0%, #ffcccc 100%);
+    color: #e6392b;
+    font-size: 40px;
+    font-weight: 700;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    margin-bottom: 20px;
+    box-shadow: 0 4px 16px rgba(230, 57, 43, 0.2);
+  }
+
+  .failedText {
+    font-size: 18px;
+    color: #e6392b;
+    font-weight: 600;
+  }
 }
 }

+ 64 - 15
src/components/VipPurchaseModal/index.tsx

@@ -58,6 +58,7 @@ export default defineComponent({
     const qrCodeUrl = ref('');
     const qrCodeUrl = ref('');
     const orderNo = ref('');
     const orderNo = ref('');
     const pollingTimer = ref<number | null>(null);
     const pollingTimer = ref<number | null>(null);
+    const paymentStatus = ref<'pending' | 'success' | 'failed'>('pending'); // 支付状态
 
 
     // 支付配置
     // 支付配置
     const paymentConfig = reactive({
     const paymentConfig = reactive({
@@ -166,13 +167,20 @@ export default defineComponent({
       pollingTimer.value = window.setInterval(async () => {
       pollingTimer.value = window.setInterval(async () => {
         try {
         try {
           const { data } = await getOrderDetail(orderNo.value);
           const { data } = await getOrderDetail(orderNo.value);
-          if (data && data.status === 'PAID') {
-            stopPolling();
-            window.$message.success('支付成功');
-            handleCancel();
-            await userStore.getInfo();
-            emit('success');
-            emit('close');
+          if (data) {
+            if (data.status === 'PAID') {
+              stopPolling();
+              paymentStatus.value = 'success';
+              window.$message.success('支付成功');
+              handleCancel();
+              await userStore.getInfo();
+              emit('success');
+              emit('close');
+            } else if (data.status === 'FAILED' || data.status === 'FAIL' || data.status === 'CLOSED') {
+              stopPolling();
+              paymentStatus.value = 'failed';
+              window.$message.error('支付失败');
+            }
           }
           }
         } catch (e) {
         } catch (e) {
           console.error('轮询订单状态失败', e);
           console.error('轮询订单状态失败', e);
@@ -195,6 +203,7 @@ export default defineComponent({
       qrCodeUrl.value = '';
       qrCodeUrl.value = '';
       orderNo.value = '';
       orderNo.value = '';
       hasClicked.value = false;
       hasClicked.value = false;
+      paymentStatus.value = 'pending';
     };
     };
 
 
     // 创建订单并生成二维码链接
     // 创建订单并生成二维码链接
@@ -202,6 +211,7 @@ export default defineComponent({
       if (hasClicked.value || loading.value) return;
       if (hasClicked.value || loading.value) return;
       hasClicked.value = true;
       hasClicked.value = true;
       loading.value = true;
       loading.value = true;
+      paymentStatus.value = 'pending';
       try {
       try {
         const pkg = currentPackage.value;
         const pkg = currentPackage.value;
         const goodsInfos = [
         const goodsInfos = [
@@ -245,7 +255,7 @@ export default defineComponent({
 
 
           // getHttpOrigin() +
           // getHttpOrigin() +
           qrCodeUrl.value =
           qrCodeUrl.value =
-            getHttpOrigin() + '/classroom-app/#/payDefine?' + params;
+            'https://test.kt.colexiu.com/classroom-app/#/payDefine?' + params;
           console.log(qrCodeUrl.value);
           console.log(qrCodeUrl.value);
           showQrCode.value = true;
           showQrCode.value = true;
           console.log(qrCodeUrl.value, 'value');
           console.log(qrCodeUrl.value, 'value');
@@ -259,6 +269,12 @@ export default defineComponent({
       }
       }
     };
     };
 
 
+    // 重新支付
+    const handleRetry = async () => {
+      hasClicked.value = false;
+      await handlePurchase();
+    };
+
     // 初始化获取支付配置
     // 初始化获取支付配置
     fetchPaymentConfig();
     fetchPaymentConfig();
 
 
@@ -324,19 +340,52 @@ export default defineComponent({
             </div>
             </div>
           ) : (
           ) : (
             <div class={styles.qrCodeSection}>
             <div class={styles.qrCodeSection}>
-              <div class={styles.qrCodeTitle}>扫码支付</div>
+              <div class={styles.qrCodeTitle}>
+                {paymentStatus.value === 'failed' ? '支付失败' : '扫码支付'}
+              </div>
               <div class={styles.qrCodeWrap}>
               <div class={styles.qrCodeWrap}>
-                {qrCodeUrl.value && (
-                  <TheQrCode text={qrCodeUrl.value} size={200} />
+                {paymentStatus.value === 'failed' ? (
+                  <div class={styles.failedTip}>
+                    <div class={styles.failedIcon}>✕</div>
+                    <div class={styles.failedText}>支付失败,请重新支付</div>
+                  </div>
+                ) : (
+                  [
+                    qrCodeUrl.value && (
+                      <TheQrCode text={qrCodeUrl.value} size={200} />
+                    ),
+                    <div class={styles.payTip}>
+                      请使用微信扫描二维码完成支付
+                    </div>
+                  ]
                 )}
                 )}
-                <div class={styles.payTip}>请使用微信扫描二维码完成支付</div>
+                <div class={styles.goodsName}>
+                  商品:{currentPackage.value?.name}
+                </div>
                 <div class={styles.orderInfo}>订单号:{orderNo.value}</div>
                 <div class={styles.orderInfo}>订单号:{orderNo.value}</div>
               </div>
               </div>
 
 
               <div class={styles.btnGroup}>
               <div class={styles.btnGroup}>
-                <NButton round size="large" onClick={handleCancel}>
-                  取消支付
-                </NButton>
+                {paymentStatus.value === 'failed' ? (
+                  [
+                    <NButton round size="large" onClick={handleCancel}>
+                      取消
+                    </NButton>,
+                    <NButton
+                      round
+                      size="large"
+                      type="primary"
+                      loading={loading.value}
+                      onClick={handleRetry}
+                    >
+                      重新支付
+                    </NButton>
+                  ]
+                ) : (
+                  <NButton round size="large" onClick={handleCancel}>
+                    取消支付
+                  </NButton>
+                )}
               </div>
               </div>
             </div>
             </div>
           )}
           )}