|
@@ -77,6 +77,30 @@
|
|
|
</button>
|
|
</button>
|
|
|
</view>
|
|
</view>
|
|
|
</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>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
@@ -88,6 +112,7 @@ import { useUserStore } from '@/store/index'
|
|
|
import { useLocaleStore } from '@/store/locale'
|
|
import { useLocaleStore } from '@/store/locale'
|
|
|
import request from '@/utils/request.js'
|
|
import request from '@/utils/request.js'
|
|
|
import { getAppName } from '@/config/app.js'
|
|
import { getAppName } from '@/config/app.js'
|
|
|
|
|
+import { getAgreementContent } from '@/apis/setting'
|
|
|
|
|
|
|
|
const { t, locale } = useI18n()
|
|
const { t, locale } = useI18n()
|
|
|
const userStore = useUserStore()
|
|
const userStore = useUserStore()
|
|
@@ -100,6 +125,12 @@ const isLanguageSwitching = ref(false)
|
|
|
const agreedToTerms = ref(false)
|
|
const agreedToTerms = ref(false)
|
|
|
const statusBarHeight = ref(0)
|
|
const statusBarHeight = ref(0)
|
|
|
|
|
|
|
|
|
|
+// 协议弹窗
|
|
|
|
|
+const showAgreementModal = ref(false)
|
|
|
|
|
+const agreementTitle = ref('')
|
|
|
|
|
+const agreementContent = ref('')
|
|
|
|
|
+const agreementLoading = ref(false)
|
|
|
|
|
+
|
|
|
// 语言切换按钮的top位置
|
|
// 语言切换按钮的top位置
|
|
|
const languageSwitcherTop = computed(() => {
|
|
const languageSwitcherTop = computed(() => {
|
|
|
return statusBarHeight.value + 50 // 状态栏高度 + 50px间距,确保不被遮挡
|
|
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;
|
|
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>
|
|
</style>
|