diff --git a/pro_v3.5.1/view/uniapp_v2/api/user.js b/pro_v3.5.1/view/uniapp_v2/api/user.js index ff3a9936..d5029d3f 100644 --- a/pro_v3.5.1/view/uniapp_v2/api/user.js +++ b/pro_v3.5.1/view/uniapp_v2/api/user.js @@ -157,6 +157,14 @@ export function getSignCalendar(data) { return request.get('sign/calendar', data) } +/** + * 签到前置阅读:随机返回"签到广告"分类下一条文章 + * 后端无该分类或分类下没有可用文章时 data 为 null,前端可跳过门槛直接签到 + */ +export function getSignRequiredArticle() { + return request.get('sign/required_article') +} + /** * 活动状态 * diff --git a/pro_v3.5.1/view/uniapp_v2/pages/users/user_sgin/index.vue b/pro_v3.5.1/view/uniapp_v2/pages/users/user_sgin/index.vue index e71b9076..a01f2967 100644 --- a/pro_v3.5.1/view/uniapp_v2/pages/users/user_sgin/index.vue +++ b/pro_v3.5.1/view/uniapp_v2/pages/users/user_sgin/index.vue @@ -100,6 +100,29 @@ + + + + + + 签到广告 + + + + + {{ signAdArticle.title }} + + + 文章加载中… + + + + 浏览满 {{ signAdCountdown }} 秒后可签到 + + {{ signAdCountdown > 0 ? `阅读中… ${signAdCountdown}s` : '我已阅读,立即签到' }} + + + @@ -114,8 +137,10 @@ setSignIntegral, signRemind, getSignList, - getSignCalendar + getSignCalendar, + getSignRequiredArticle } from '@/api/user.js'; + import { getArticleDetails } from '@/api/api.js'; import BaseCalendar from '@/components/BaseCalendar.vue'; import emptyPage from '@/components/emptyPage.vue'; import { @@ -150,6 +175,11 @@ isScrolling: false, calendarVisible: false, pageScrollStatus:false, + // 签到前置阅读门槛 + signAdVisible: false, + signAdArticle: { id: 0, title: '', image: '', content: '' }, + signAdCountdown: 0, + signAdTimer: null, }; }, computed: mapGetters(['isLogin']), @@ -283,12 +313,71 @@ }); }, goSign: function(e) { - let that = this, - sum_sgin_day = that.userInfo.sum_sgin_day; - if (that.userInfo.is_day_sgin) + if (this.userInfo.is_day_sgin) return this.$util.Tips({ title: '您今日已签到!' }); + // 先取签到前置阅读文章;后端无文章/分类则跳过门槛 + getSignRequiredArticle().then(res => { + const article = res && res.data ? res.data : null; + if (article && article.id) { + this.signAdArticle = { + id: article.id, + title: article.title || '', + image: article.image || '', + content: '' + }; + this.signAdVisible = true; + this.startSignAdCountdown(Number(article.view_required_seconds) || 10); + this.fetchSignAdContent(article.id); + } else { + this.doSignIntegral(); + } + }).catch(() => { + // 拉文章失败兜底直接签到 + this.doSignIntegral(); + }); + }, + fetchSignAdContent(id) { + getArticleDetails(id).then(res => { + const data = res && res.data ? res.data : {}; + this.signAdArticle = { + ...this.signAdArticle, + title: data.title || this.signAdArticle.title, + content: data.content || '' + }; + }).catch(() => { + // 仅富文本拉取失败,模态保持显示,content 留空 + }); + }, + startSignAdCountdown(seconds) { + this.clearSignAdTimer(); + this.signAdCountdown = seconds; + this.signAdTimer = setInterval(() => { + this.signAdCountdown -= 1; + if (this.signAdCountdown <= 0) { + this.clearSignAdTimer(); + } + }, 1000); + }, + clearSignAdTimer() { + if (this.signAdTimer) { + clearInterval(this.signAdTimer); + this.signAdTimer = null; + } + }, + closeSignAd() { + this.clearSignAdTimer(); + this.signAdCountdown = 0; + this.signAdVisible = false; + }, + confirmSignAfterAd() { + if (this.signAdCountdown > 0) return; + this.closeSignAd(); + this.doSignIntegral(); + }, + doSignIntegral() { + const that = this; setSignIntegral() .then((res) => { this.$util.Tips({ @@ -724,4 +813,119 @@ transform: translateY(0); } } + + .sign-ad-overlay { + position: fixed; + left: 0; + top: 0; + right: 0; + bottom: 0; + z-index: 9999; + background: #fff; + display: flex; + flex-direction: column; + } + + .sign-ad-header { + flex: 0 0 auto; + display: flex; + align-items: center; + height: 88rpx; + padding: 0 24rpx; + border-bottom: 1rpx solid #eee; + } + + .sign-ad-close { + width: 56rpx; + height: 56rpx; + display: flex; + align-items: center; + justify-content: center; + font-size: 36rpx; + color: #333; + } + + .sign-ad-header-title { + flex: 1; + text-align: center; + font-size: 32rpx; + font-weight: 600; + color: #222; + } + + .sign-ad-header-spacer { + width: 56rpx; + height: 56rpx; + } + + .sign-ad-scroll { + flex: 1 1 auto; + min-height: 0; + } + + .sign-ad-body { + padding: 32rpx 32rpx 40rpx; + } + + .sign-ad-article-title { + font-size: 36rpx; + font-weight: 600; + color: #222; + line-height: 1.4; + margin-bottom: 24rpx; + } + + .sign-ad-image { + width: 100%; + max-height: 600rpx; + border-radius: 12rpx; + margin-bottom: 24rpx; + } + + .sign-ad-content { + font-size: 28rpx; + color: #333; + line-height: 1.7; + word-break: break-all; + } + + .sign-ad-loading { + text-align: center; + font-size: 26rpx; + color: #999; + padding: 40rpx 0; + } + + .sign-ad-footer { + flex: 0 0 auto; + padding: 16rpx 32rpx 32rpx; + background: #fff; + border-top: 1rpx solid #eee; + padding-bottom: calc(32rpx + constant(safe-area-inset-bottom)); + padding-bottom: calc(32rpx + env(safe-area-inset-bottom)); + } + + .sign-ad-tip { + text-align: center; + font-size: 26rpx; + color: #FAAD14; + margin-bottom: 16rpx; + } + + .sign-ad-btn { + height: 88rpx; + line-height: 88rpx; + text-align: center; + border-radius: 44rpx; + font-size: 30rpx; + } + + .sign-ad-btn.confirm { + background: linear-gradient(90deg, #FF7E30, #FAAD14); + color: #fff; + } + + .sign-ad-btn.confirm.disabled { + opacity: 0.55; + }