Ver código fonte

微信支付分校验

skyline 2 meses atrás
pai
commit
39a8d6e62d

+ 57 - 0
haha-mp/src/api/payscore.ts

@@ -0,0 +1,57 @@
+/**
+ * 微信支付分相关 API
+ */
+
+import { get, post } from '../utils/request';
+
+/**
+ * 检查用户是否已开通微信支付分
+ */
+export interface CheckPayscoreResponse {
+  enabled: boolean;
+  userId: number;
+}
+
+/**
+ * 开通微信支付分
+ */
+export interface EnablePayscoreResponse {
+  // 空响应
+}
+
+/**
+ * 创建支付分服务订单
+ */
+export interface CreatePayscoreOrderRequest {
+  orderId: number;
+  openId: string;
+  riskFundAmount?: string;
+  riskFundName?: string;
+}
+
+export interface CreatePayscoreOrderResponse {
+  outOrderNo: string;
+  state: string;
+  package: string;
+}
+
+/**
+ * 检查用户是否已开通微信支付分
+ */
+export const checkPayscoreEnabled = (): Promise<CheckPayscoreResponse> => {
+  return get<CheckPayscoreResponse>('/payscore/check-enable');
+};
+
+/**
+ * 开通微信支付分(标记已开通)
+ */
+export const enablePayscore = (): Promise<EnablePayscoreResponse> => {
+  return post<EnablePayscoreResponse>('/payscore/enable', {});
+};
+
+/**
+ * 创建支付分服务订单
+ */
+export const createPayscoreOrder = (params: CreatePayscoreOrderRequest): Promise<CreatePayscoreOrderResponse> => {
+  return post<CreatePayscoreOrderResponse>('/payscore/create', params);
+};

+ 8 - 0
haha-mp/src/pages.json

@@ -49,6 +49,14 @@
 				"navigationBarTextStyle": "black"
 			}
 		},
+		{
+			"path": "pages/payscore/enable",
+			"style": {
+				"navigationBarTitleText": "开通微信支付分",
+				"navigationBarBackgroundColor": "#FFFFFF",
+				"navigationBarTextStyle": "black"
+			}
+		},
 		{
 			"path": "pages/orderDetail/orderDetail",
 			"style": {

+ 37 - 3
haha-mp/src/pages/index/index.vue

@@ -40,15 +40,30 @@
 import { ref, onMounted } from 'vue'
 import { onShow } from '@dcloudio/uni-app'
 import { scanDoor } from '../../api/device'
+import { checkPayscoreEnabled } from '../../api/payscore'
 import { isLoggedIn, getToken } from '../../utils/auth'
 
-// 页面显示时检查token
+// 页面显示时检查 token
 onShow(() => {
   const token = getToken()
-  console.log('[首页 onShow] token状态:', token ? '存在' : '不存在')
+  console.log('[首页 onShow] token 状态:', token ? '存在' : '不存在')
 })
 
-const scanCode = () => {
+// 处理支付分开通成功
+const onPayscoreEnabled = () => {
+  console.log('[首页] 用户已开通支付分')
+  // 可以自动触发扫码
+  setTimeout(() => {
+    scanCode()
+  }, 500)
+}
+
+// 定义暴露给其他页面的方法
+defineExpose({
+  onPayscoreEnabled
+})
+
+const scanCode = async () => {
   // 检查登录状态
   if (!isLoggedIn()) {
     uni.showModal({
@@ -64,6 +79,25 @@ const scanCode = () => {
     return;
   }
   
+  // 检查微信支付分开通状态
+  try {
+    const payscoreResult = await checkPayscoreEnabled()
+    if (!payscoreResult.enabled) {
+      // 未开通,跳转到开通页面
+      uni.navigateTo({
+        url: '/pages/payscore/enable'
+      })
+      return
+    }
+  } catch (error: any) {
+    console.error('检查支付分状态失败:', error)
+    // 如果检查失败,也跳转到开通页面
+    uni.navigateTo({
+      url: '/pages/payscore/enable'
+    })
+    return
+  }
+  
   // 调用摄像头扫码
   uni.scanCode({
     success: async function (res) {

+ 516 - 0
haha-mp/src/pages/payscore/enable.vue

@@ -0,0 +1,516 @@
+<template>
+  <view class="container">
+    <!-- 顶部导航栏 -->
+    <view class="header">
+      <view class="back-btn" @click="goBack">
+        <text class="back-icon">‹</text>
+      </view>
+      <text class="header-title">开通微信支付分</text>
+    </view>
+
+    <!-- 主要内容区 -->
+    <view class="content">
+      <!-- 说明卡片 -->
+      <view class="info-card">
+        <view class="card-header">
+          <image class="payscore-icon" src="/static/icons/payscore.svg" mode="aspectFit"></image>
+          <text class="card-title">微信支付分</text>
+        </view>
+        
+        <view class="card-content">
+          <text class="desc-text">微信支付分是微信支付基于历史行为作出的综合评分,用于评估用户的信用水平。</text>
+          
+          <view class="benefits-section">
+            <text class="benefits-title">开通后可享受:</text>
+            <view class="benefit-item">
+              <text class="benefit-icon">✓</text>
+              <text class="benefit-text">先享后付,开门购物更便捷</text>
+            </view>
+            <view class="benefit-item">
+              <text class="benefit-icon">✓</text>
+              <text class="benefit-text">免押金租借物品</text>
+            </view>
+            <view class="benefit-item">
+              <text class="benefit-icon">✓</text>
+              <text class="benefit-text">更多信用服务特权</text>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <!-- 分数要求提示 -->
+      <view class="score-requirement">
+        <view class="score-info">
+          <text class="score-label">当前要求</text>
+          <text class="score-value">550 分及以上</text>
+        </view>
+        <view class="score-tip">
+          <text class="tip-icon">ℹ</text>
+          <text class="tip-text">分数越高,可享受的信用服务越多</text>
+        </view>
+      </view>
+
+      <!-- 开通流程 -->
+      <view class="steps-section">
+        <text class="section-title">开通流程</text>
+        
+        <view class="step-item">
+          <view class="step-number">1</view>
+          <view class="step-content">
+            <text class="step-title">点击开通按钮</text>
+            <text class="step-desc">授权开启微信支付分服务</text>
+          </view>
+        </view>
+        
+        <view class="step-item">
+          <view class="step-number">2</view>
+          <view class="step-content">
+            <text class="step-title">完成身份验证</text>
+            <text class="step-desc">根据提示完成身份信息验证</text>
+          </view>
+        </view>
+        
+        <view class="step-item">
+          <view class="step-number">3</view>
+          <view class="step-content">
+            <text class="step-title">等待评分结果</text>
+            <text class="step-desc">系统将自动评估您的信用分数</text>
+          </view>
+        </view>
+        
+        <view class="step-item">
+          <view class="step-number">4</view>
+          <view class="step-content">
+            <text class="step-title">开通成功</text>
+            <text class="step-desc">成功后即可使用先享后付服务</text>
+          </view>
+        </view>
+      </view>
+
+      <!-- 温馨提示 -->
+      <view class="tips-section">
+        <text class="tips-title">温馨提示</text>
+        <view class="tip-item">
+          <text class="tip-dot">•</text>
+          <text class="tip-content">微信支付分评估过程不收取任何费用</text>
+        </view>
+        <view class="tip-item">
+          <text class="tip-dot">•</text>
+          <text class="tip-content">请确保已实名认证并绑定银行卡</text>
+        </view>
+        <view class="tip-item">
+          <text class="tip-dot">•</text>
+          <text class="tip-content">良好的信用记录有助于提升分数</text>
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部操作区 -->
+    <view class="footer">
+      <button class="enable-button" @click="handleEnablePayscore" :loading="isEnabling">
+        <text class="button-text">立即开通</text>
+      </button>
+      
+      <view class="help-section">
+        <text class="help-text">遇到问题?</text>
+        <text class="help-link" @click="contactService">联系客服</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+import { enablePayscore, checkPayscoreEnabled } from '@/api/payscore'
+import { scanDoor } from '@/api/device'
+
+const isEnabling = ref(false)
+
+// 返回上一页
+const goBack = () => {
+  uni.navigateBack()
+}
+
+// 处理开通支付分
+const handleEnablePayscore = async () => {
+  if (isEnabling.value) return
+  
+  try {
+    isEnabling.value = true
+    
+    // 调用开通接口
+    await enablePayscore()
+    
+    // 显示成功提示
+    uni.showModal({
+      title: '开通成功',
+      content: '您已成功开通微信支付分,现在可以扫码开门了!',
+      showCancel: false,
+      success: () => {
+        // 跳转到首页或直接返回
+        const pages = getCurrentPages()
+        if (pages.length > 1) {
+          // 如果有上一页,返回时携带开通成功的标记
+          const prevPage = pages[pages.length - 2]
+          if (prevPage && (prevPage as any).onPayscoreEnabled) {
+            ;(prevPage as any).onPayscoreEnabled()
+          }
+          uni.navigateBack()
+        } else {
+          // 否则跳转到首页
+          uni.reLaunch({
+            url: '/pages/index/index'
+          })
+        }
+      }
+    })
+  } catch (error: any) {
+    console.error('开通支付分失败:', error)
+    uni.showModal({
+      title: '开通失败',
+      content: error.message || '开通过程中出现错误,请稍后重试',
+      confirmText: '再试一次'
+    })
+  } finally {
+    isEnabling.value = false
+  }
+}
+
+// 联系客服
+const contactService = () => {
+  uni.makePhoneCall({
+    phoneNumber: '400-123-4567'
+  })
+}
+
+// 检查支付分状态(页面加载时)
+const checkPayscoreStatus = async () => {
+  try {
+    const result = await checkPayscoreEnabled()
+    if (result.enabled) {
+      // 如果已开通,提示用户
+      uni.showModal({
+        title: '提示',
+        content: '您已开通微信支付分,无需重复开通',
+        showCancel: false,
+        success: () => {
+          goBack()
+        }
+      })
+    }
+  } catch (error) {
+    console.error('检查支付分状态失败:', error)
+  }
+}
+
+// 页面加载时检查状态
+checkPayscoreStatus()
+</script>
+
+<style>
+.container {
+  min-height: 100vh;
+  background-color: #f5f5f5;
+  padding-bottom: 200rpx;
+}
+
+/* 顶部导航栏 */
+.header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20rpx 30rpx;
+  background-color: #fff;
+  border-bottom: 1rpx solid #eee;
+}
+
+.back-btn {
+  width: 60rpx;
+  height: 60rpx;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.back-icon {
+  font-size: 60rpx;
+  color: #333;
+  line-height: 1;
+}
+
+.header-title {
+  font-size: 36rpx;
+  font-weight: bold;
+  color: #333;
+}
+
+/* 内容区 */
+.content {
+  padding: 30rpx;
+}
+
+/* 信息卡片 */
+.info-card {
+  background-color: #fff;
+  border-radius: 20rpx;
+  padding: 40rpx;
+  margin-bottom: 30rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+}
+
+.card-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 30rpx;
+}
+
+.payscore-icon {
+  width: 80rpx;
+  height: 80rpx;
+  margin-right: 20rpx;
+}
+
+.card-title {
+  font-size: 40rpx;
+  font-weight: bold;
+  color: #FFD700;
+}
+
+.card-content {
+  display: flex;
+  flex-direction: column;
+}
+
+.desc-text {
+  font-size: 28rpx;
+  color: #666;
+  line-height: 1.6;
+  margin-bottom: 30rpx;
+}
+
+.benefits-section {
+  background-color: #f9f9f9;
+  border-radius: 15rpx;
+  padding: 30rpx;
+}
+
+.benefits-title {
+  font-size: 28rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 20rpx;
+}
+
+.benefit-item {
+  display: flex;
+  align-items: center;
+  margin-bottom: 15rpx;
+}
+
+.benefit-icon {
+  width: 30rpx;
+  height: 30rpx;
+  background-color: #52c41a;
+  color: #fff;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 20rpx;
+  margin-right: 15rpx;
+  flex-shrink: 0;
+}
+
+.benefit-text {
+  font-size: 28rpx;
+  color: #333;
+}
+
+/* 分数要求 */
+.score-requirement {
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  border-radius: 20rpx;
+  padding: 40rpx;
+  margin-bottom: 30rpx;
+  color: #fff;
+}
+
+.score-info {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20rpx;
+}
+
+.score-label {
+  font-size: 28rpx;
+  opacity: 0.9;
+}
+
+.score-value {
+  font-size: 48rpx;
+  font-weight: bold;
+}
+
+.score-tip {
+  display: flex;
+  align-items: center;
+  background-color: rgba(255, 255, 255, 0.2);
+  border-radius: 10rpx;
+  padding: 15rpx 20rpx;
+}
+
+.tip-icon {
+  font-size: 32rpx;
+  margin-right: 10rpx;
+}
+
+.tip-text {
+  font-size: 24rpx;
+  opacity: 0.9;
+}
+
+/* 开通流程 */
+.steps-section {
+  background-color: #fff;
+  border-radius: 20rpx;
+  padding: 40rpx;
+  margin-bottom: 30rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+}
+
+.section-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 30rpx;
+}
+
+.step-item {
+  display: flex;
+  align-items: flex-start;
+  margin-bottom: 30rpx;
+}
+
+.step-item:last-child {
+  margin-bottom: 0;
+}
+
+.step-number {
+  width: 50rpx;
+  height: 50rpx;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  color: #fff;
+  border-radius: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  font-size: 24rpx;
+  font-weight: bold;
+  flex-shrink: 0;
+  margin-right: 20rpx;
+}
+
+.step-content {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+}
+
+.step-title {
+  font-size: 30rpx;
+  font-weight: bold;
+  color: #333;
+  margin-bottom: 8rpx;
+}
+
+.step-desc {
+  font-size: 26rpx;
+  color: #999;
+}
+
+/* 温馨提示 */
+.tips-section {
+  background-color: #fff;
+  border-radius: 20rpx;
+  padding: 40rpx;
+  margin-bottom: 30rpx;
+  box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
+}
+
+.tips-title {
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #ff9800;
+  margin-bottom: 20rpx;
+}
+
+.tip-item {
+  display: flex;
+  align-items: flex-start;
+  margin-bottom: 15rpx;
+}
+
+.tip-dot {
+  color: #ff9800;
+  font-size: 28rpx;
+  margin-right: 10rpx;
+  flex-shrink: 0;
+}
+
+.tip-content {
+  font-size: 26rpx;
+  color: #666;
+  line-height: 1.6;
+}
+
+/* 底部操作区 */
+.footer {
+  position: fixed;
+  bottom: 0;
+  left: 0;
+  right: 0;
+  background-color: #fff;
+  padding: 30rpx;
+  padding-bottom: calc(30rpx + env(safe-area-inset-bottom));
+  border-top: 1rpx solid #eee;
+  box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.05);
+}
+
+.enable-button {
+  width: 100%;
+  height: 100rpx;
+  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+  border-radius: 50rpx;
+  border: none;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  margin-bottom: 20rpx;
+  font-size: 32rpx;
+  font-weight: bold;
+  color: #fff;
+}
+
+.button-text {
+  color: #fff;
+}
+
+.help-section {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.help-text {
+  font-size: 26rpx;
+  color: #999;
+}
+
+.help-link {
+  font-size: 26rpx;
+  color: #667eea;
+  margin-left: 10rpx;
+  text-decoration: underline;
+}
+</style>

+ 4 - 0
haha-mp/src/static/icons/payscore.svg

@@ -0,0 +1,4 @@
+<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
+  <path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z" fill="#FFD700"/>
+  <path d="M696.8 369.6L469.2 597.2c-12.5 12.5-32.8 12.5-45.3 0L307.2 480.4c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l94.1 94.1 205-205c12.5-12.5 32.8-12.5 45.3 0s12.5 32.9-.1 45.4z" fill="#FFD700"/>
+</svg>