- - + + @@ -200,7 +201,6 @@ getPotionsDetail } from '../../config/api/order.js' import { - getNoticeTextData, getActiveActivity } from '../../config/api/system.js' // 导入地图工具函数 @@ -291,27 +291,112 @@ } const noticeText = ref('') + const bannerImages = ref([]) // 首页广告图片列表 + + // 将语言代码转换为后端接受的格式 + const convertLanguageCode = (lang) => { + // zh-CN -> zh_CN (转换下划线) + // en-US -> en_US (转换下划线) + return lang.replace(/-/g, '_') + } + + // 获取公告内容(支持多语言) const getNoticeText = async () => { - const parasm = { - 'title': '用户端公告' - } - const res = await getNoticeTextData(parasm); - noticeText.value = res.data.noticeContent; - - // 设置通知栏高度 - if (res.data.noticeContent) { - noticeHeight.value = 50 // 通知栏高度约50px - } - - // 将通知内容存储到本地缓存 try { - uni.setStorageSync('noticeContent', res.data.noticeContent); - console.log('通知内容已缓存:', res.data.noticeContent); - } catch (e) { - console.warn('缓存通知内容失败:', e); + // 获取当前语言设置 + const currentLang = uni.getStorageSync('language') || 'zh-CN' + const languageCode = convertLanguageCode(currentLang) + + console.log('加载公告,语言:', currentLang, '转换后:', languageCode) + + // 调用接口获取公告内容 + const res = await uni.request({ + url: `${URL}/device/announcementConfig/current`, + method: 'GET', + header: { + 'Content-Language': languageCode + }, + data: { + type: 'wx_user_type' // 微信小程序用户端 + } + }) + + console.log('公告响应:', res) + + if (res.statusCode === 200 && res.data.code === 200 && res.data.data) { + // 使用后端自动解析的 announcement 字段 + const announcement = res.data.data.announcement || '' + noticeText.value = announcement + + // 设置通知栏高度 + if (announcement) { + noticeHeight.value = 50 // 通知栏高度约50px + } + + // 将通知内容存储到本地缓存 + try { + uni.setStorageSync('noticeContent', announcement) + console.log('通知内容已缓存:', announcement) + } catch (e) { + console.warn('缓存通知内容失败:', e) + } + } else { + console.warn('获取公告失败:', res.data?.msg || '未知错误') + } + } catch (error) { + console.error('获取公告失败:', error) } } + // 获取首页广告图片(支持多语言) + const getBannerImages = async () => { + try { + // 获取当前语言设置 + const currentLang = uni.getStorageSync('language') || 'zh-CN' + const languageCode = convertLanguageCode(currentLang) + + console.log('加载首页广告,语言:', currentLang, '转换后:', languageCode) + + // 调用接口获取广告内容 + const res = await uni.request({ + url: `${URL}/device/advertisementConfig/current`, + method: 'GET', + header: { + 'Content-Language': languageCode + }, + data: { + appPlatform: 'wechat', // 微信平台 + appType: 'user' // 用户端 + } + }) + + console.log('首页广告响应:', res) + + if (res.statusCode === 200 && res.data.code === 200 && res.data.data) { + // 使用 files 字段(图片列表) + const files = res.data.data.files || [] + if (files.length > 0) { + bannerImages.value = files + console.log('首页广告加载成功,图片数量:', files.length) + } else { + console.warn('未获取到广告图片') + } + } else { + console.warn('获取首页广告失败:', res.data?.msg || '未知错误') + } + } catch (error) { + console.error('获取首页广告失败:', error) + } + } + + // 处理首页广告点击 + const handleBannerClick = (index) => { + console.log('点击首页广告:', index, bannerImages.value[index]) + // 可以根据需要添加跳转逻辑 + // 例如跳转到合作加盟页面 + uni.navigateTo({ url: '/pages/join/index' }) + } + // 查询最近的活动 const checkActiveActivity = async () => { try { @@ -438,20 +523,25 @@ console.warn('清理旧缓存失败:', e); } - // 开发环境测试距离计算 - if (process.env.NODE_ENV === 'development') { - testDistanceCalculation() - } - await getNoticeText(); + // 开发环境测试距离计算 + if (process.env.NODE_ENV === 'development') { + testDistanceCalculation() + } + + // 并行加载公告和广告(不依赖定位) + await Promise.all([ + getNoticeText(), + getBannerImages() + ]) - // 1. 先获取用户位置 - await getUserLocationAndAddress() + // 1. 先获取用户位置 + await getUserLocationAndAddress() - // 2. 加载场地列表(依赖定位) - await loadPositions() + // 2. 加载场地列表(依赖定位) + await loadPositions() - // 3. 查询活动并显示弹窗 - await checkActiveActivity() + // 3. 查询活动并显示弹窗 + await checkActiveActivity() } catch (error) { console.error('初始化失败:', error) diff --git a/pages/legal/agreement.vue b/pages/legal/agreement.vue index 9f5b849..5a3ffc5 100644 --- a/pages/legal/agreement.vue +++ b/pages/legal/agreement.vue @@ -1,40 +1,118 @@ @@ -67,10 +145,41 @@ 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } - - text { - font-size: 28rpx; - color: #666; + + .error-page { + min-height: 100vh; + background: #f8f8f8; + display: flex; + align-items: center; + justify-content: center; + padding: 40rpx; + } + + .error-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 24rpx; + + .error-icon { + font-size: 80rpx; + } + + .error-message { + font-size: 28rpx; + color: #666; + text-align: center; + } + + .retry-btn { + margin-top: 20rpx; + padding: 20rpx 60rpx; + background: #07c160; + color: #fff; + border-radius: 8rpx; + font-size: 28rpx; + border: none; + } } .legal-page { @@ -83,33 +192,31 @@ .header { margin-bottom: 16rpx; + .title { font-size: 40rpx; font-weight: 600; color: #222; margin-bottom: 8rpx; + display: block; } + .subtitle { font-size: 24rpx; color: #888; + display: block; } } .content { - // width: 100%; background: #fff; border-radius: 16rpx; - padding: 16rpx 20rpx; + padding: 20rpx; flex: 1; - min-height: 0; box-sizing: border-box; - box-shadow: 0 4rpx 12rpx rgba(0,0,0,0.04); + box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); } - .h1 { font-size: 30rpx; font-weight: 600; color: #222; margin: 18rpx 0 12rpx; } - .p { font-size: 26rpx; color: #444; line-height: 1.8; margin-bottom: 10rpx; } - .bold { font-weight: 600; color: #222; } - .footer { text-align: center; margin-top: 16rpx; diff --git a/pages/legal/privacy.vue b/pages/legal/privacy.vue index 18e4571..0f419b8 100644 --- a/pages/legal/privacy.vue +++ b/pages/legal/privacy.vue @@ -1,40 +1,118 @@ @@ -67,10 +145,41 @@ 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } - - text { - font-size: 28rpx; - color: #666; + + .error-page { + min-height: 100vh; + background: #f8f8f8; + display: flex; + align-items: center; + justify-content: center; + padding: 40rpx; + } + + .error-content { + display: flex; + flex-direction: column; + align-items: center; + gap: 24rpx; + + .error-icon { + font-size: 80rpx; + } + + .error-message { + font-size: 28rpx; + color: #666; + text-align: center; + } + + .retry-btn { + margin-top: 20rpx; + padding: 20rpx 60rpx; + background: #07c160; + color: #fff; + border-radius: 8rpx; + font-size: 28rpx; + border: none; + } } .legal-page { @@ -83,60 +192,31 @@ .header { margin-bottom: 16rpx; - } - .title { - font-size: 40rpx; - font-weight: 600; - color: #222; - margin-bottom: 8rpx; - } + .title { + font-size: 40rpx; + font-weight: 600; + color: #222; + margin-bottom: 8rpx; + display: block; + } - .subtitle { - font-size: 24rpx; - color: #888; - } - - .card { - background: #fff; - border-radius: 16rpx; - padding: 20rpx; - box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); - } - - .notice { - margin-bottom: 16rpx; + .subtitle { + font-size: 24rpx; + color: #888; + display: block; + } } .content { background: #fff; border-radius: 16rpx; - padding: 16rpx 20rpx; + padding: 20rpx; flex: 1; - min-height: 0; box-sizing: border-box; box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04); } - .h1 { - font-size: 30rpx; - font-weight: 600; - color: #222; - margin: 18rpx 0 12rpx; - } - - .p { - font-size: 26rpx; - color: #444; - line-height: 1.8; - margin-bottom: 10rpx; - } - - .bold { - font-weight: 600; - color: #222; - } - .footer { text-align: center; margin-top: 16rpx; diff --git a/pages/my/index.vue b/pages/my/index.vue index 028c768..30fc32a 100644 --- a/pages/my/index.vue +++ b/pages/my/index.vue @@ -23,10 +23,21 @@