Преглед изворни кода

登录时为弹出框的协议

Huanyi пре 2 месеци
родитељ
комит
5b87a80613
1 измењених фајлова са 201 додато и 8 уклоњено
  1. 201 8
      pages/login/login.vue

+ 201 - 8
pages/login/login.vue

@@ -77,6 +77,30 @@
         </button>
       </view>
     </view>
+    
+    <!-- 协议弹窗 -->
+    <view v-if="showAgreementModal" class="modal-overlay" @click="closeAgreementModal">
+      <view class="modal-content agreement-modal" @click.stop>
+        <view class="modal-header">
+          <text class="modal-title">{{ agreementTitle }}</text>
+          <view class="modal-close" @click="closeAgreementModal">
+            <text class="close-icon">×</text>
+          </view>
+        </view>
+        
+        <scroll-view scroll-y class="modal-body">
+          <view class="agreement-content">
+            <rich-text :nodes="agreementContent"></rich-text>
+          </view>
+        </scroll-view>
+        
+        <view class="modal-footer">
+          <view class="modal-btn confirm" @click="closeAgreementModal">
+            <text class="modal-btn-text">我知道了</text>
+          </view>
+        </view>
+      </view>
+    </view>
   </view>
 </template>
 
@@ -88,6 +112,7 @@ import { useUserStore } from '@/store/index'
 import { useLocaleStore } from '@/store/locale'
 import request from '@/utils/request.js'
 import { getAppName } from '@/config/app.js'
+import { getAgreementContent } from '@/apis/setting'
 
 const { t, locale } = useI18n()
 const userStore = useUserStore()
@@ -100,6 +125,12 @@ const isLanguageSwitching = ref(false)
 const agreedToTerms = ref(false)
 const statusBarHeight = ref(0)
 
+// 协议弹窗
+const showAgreementModal = ref(false)
+const agreementTitle = ref('')
+const agreementContent = ref('')
+const agreementLoading = ref(false)
+
 // 语言切换按钮的top位置
 const languageSwitcherTop = computed(() => {
   return statusBarHeight.value + 50 // 状态栏高度 + 50px间距,确保不被遮挡
@@ -186,17 +217,80 @@ const handleAgreementChange = (e) => {
 }
 
 // 查看用户协议
-const viewUserAgreement = () => {
-  uni.navigateTo({
-    url: '/pages/my/aggreement/detail?type=user'
-  })
+const viewUserAgreement = async () => {
+  agreementTitle.value = t('login.userAgreement')
+  showAgreementModal.value = true
+  await fetchAgreementContent('user')
 }
 
 // 查看隐私协议
-const viewPrivacyPolicy = () => {
-  uni.navigateTo({
-    url: '/pages/my/aggreement/detail?type=privacy'
-  })
+const viewPrivacyPolicy = async () => {
+  agreementTitle.value = t('login.privacyPolicy')
+  showAgreementModal.value = true
+  await fetchAgreementContent('privacy')
+}
+
+// 获取协议内容
+const fetchAgreementContent = async (type) => {
+  try {
+    agreementLoading.value = true
+    agreementContent.value = '<p style="text-align: center; color: #999;">加载中...</p>'
+    
+    // 调用API获取内容
+    const response = await getAgreementContent(type)
+    
+    if (response && response.code === 200 && response.data && response.data.content) {
+      // 解析JSON字符串
+      try {
+        const contentObj = JSON.parse(response.data.content)
+        
+        // 根据当前语言环境选择对应的内容
+        const currentLocale = locale.value // 'zh-CN' 或 'en-US'
+        const localeKey = currentLocale.replace('-', '_') // 转换为 'zh_CN' 或 'en_US'
+        
+        // 优先使用当前语言,如果不存在则使用中文,再不存在则使用任意可用语言
+        agreementContent.value = contentObj[localeKey] || 
+                                 contentObj['zh_CN'] || 
+                                 contentObj['en_US'] || 
+                                 Object.values(contentObj)[0] || 
+                                 ''
+      } catch (parseError) {
+        console.error('解析协议内容JSON失败:', parseError)
+        // 如果解析失败,尝试直接使用原始内容
+        agreementContent.value = response.data.content
+      }
+    } else {
+      throw new Error(response?.msg || '获取失败')
+    }
+  } catch (error) {
+    console.error('获取协议内容失败:', error)
+    agreementContent.value = getDefaultContent(type)
+  } finally {
+    agreementLoading.value = false
+  }
+}
+
+// 获取默认内容(API失败时的后备方案)
+const getDefaultContent = (type) => {
+  if (type === 'user') {
+    return `
+      <div style="padding: 10px; line-height: 1.8; color: #333;">
+        <p style="text-align: center; color: #999;">协议内容加载失败,请稍后重试。</p>
+      </div>
+    `
+  } else {
+    return `
+      <div style="padding: 10px; line-height: 1.8; color: #333;">
+        <p style="text-align: center; color: #999;">协议内容加载失败,请稍后重试。</p>
+      </div>
+    `
+  }
+}
+
+// 关闭协议弹窗
+const closeAgreementModal = () => {
+  showAgreementModal.value = false
+  agreementContent.value = ''
 }
 
 // 登录处理
@@ -488,4 +582,103 @@ const handleLogin = async () => {
     border: none;
   }
 }
+
+// 协议弹窗
+.modal-overlay {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  z-index: 1000;
+  
+  .modal-content {
+    width: 650rpx;
+    max-height: 80vh;
+    background: #ffffff;
+    border-radius: 24rpx;
+    overflow: hidden;
+    display: flex;
+    flex-direction: column;
+    
+    &.agreement-modal {
+      .modal-header {
+        padding: 32rpx;
+        border-bottom: 1rpx solid #f5f5f5;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        
+        .modal-title {
+          font-size: 34rpx;
+          font-weight: 600;
+          color: #333333;
+        }
+        
+        .modal-close {
+          width: 56rpx;
+          height: 56rpx;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          border-radius: 50%;
+          background: #f5f5f5;
+          
+          &:active {
+            background: #e0e0e0;
+          }
+          
+          .close-icon {
+            font-size: 40rpx;
+            color: #666666;
+            line-height: 1;
+          }
+        }
+      }
+      
+      .modal-body {
+        flex: 1;
+        padding: 32rpx;
+        max-height: 60vh;
+        
+        .agreement-content {
+          font-size: 28rpx;
+          color: #333333;
+          line-height: 1.8;
+        }
+      }
+      
+      .modal-footer {
+        padding: 24rpx 32rpx;
+        border-top: 1rpx solid #f5f5f5;
+        
+        .modal-btn {
+          height: 80rpx;
+          display: flex;
+          align-items: center;
+          justify-content: center;
+          border-radius: 40rpx;
+          
+          &.confirm {
+            background: linear-gradient(135deg, #1ec9c9 0%, #1eb8b8 100%);
+            
+            &:active {
+              opacity: 0.9;
+            }
+            
+            .modal-btn-text {
+              color: #ffffff;
+              font-size: 30rpx;
+              font-weight: 600;
+            }
+          }
+        }
+      }
+    }
+  }
+}
 </style>