diff --git a/pages/make/index.vue b/pages/make/index.vue index be19e4d..22c222d 100644 --- a/pages/make/index.vue +++ b/pages/make/index.vue @@ -203,6 +203,31 @@ + + + + + {{ + tpl.unlockType === "sing3" + ? "登录3天" + : tpl.unlockType === "sing1" + ? "登录1天" + : tpl.unlockType === "ad" + ? "广告" + : tpl.unlockType === "vip" + ? "VIP" + : "解锁" + }} + + + + + + + 跳过,直接制作 + + @@ -536,7 +563,12 @@ import { getCardTemplateTitleList, getCardMusicList, } from "@/api/make"; -import { abilityCheck, getShareReward, msgCheckApi } from "@/api/system"; +import { + abilityCheck, + getShareReward, + msgCheckApi, + watchAdReward, +} from "@/api/system"; import { onShareAppMessage, onShareTimeline, @@ -552,8 +584,11 @@ import LoginPopup from "@/components/LoginPopup/LoginPopup.vue"; import { saveRecordRequest, uploadImage, trackRecord } from "@/utils/common.js"; import NavBar from "@/components/NavBar/NavBar.vue"; +import RewardAd from "@/components/RewardAd/RewardAd.vue"; + const userStore = useUserStore(); const loginPopupRef = ref(null); +const rewardAdRef = ref(null); const isLoggedIn = computed(() => !!userStore.userInfo.nickName); const DEFAULT_AVATAR = @@ -1342,8 +1377,13 @@ const closePanel = () => { const templates = ref([]); const currentTemplate = ref(templates.value[0]); +const currentUnlockTpl = ref(null); const applyTemplate = (tpl) => { + if (tpl.isUnlock === false) { + handleUnlock(tpl); + return; + } trackRecord({ eventName: "card_tpl_choose", eventType: "click", @@ -1353,6 +1393,66 @@ const applyTemplate = (tpl) => { closePanel(); }; +const handleUnlock = (tpl) => { + switch (tpl.unlockType) { + case "vip": + uni.navigateTo({ + url: "/pages/mine/vip", + }); + break; + case "ad": + currentUnlockTpl.value = tpl; + rewardAdRef.value.showAd(); + break; + case "sing1": + uni.showToast({ + title: "需要连续登录1天解锁", + icon: "none", + }); + break; + case "sing3": + uni.showToast({ + title: "需要连续登录3天解锁", + icon: "none", + }); + break; + default: + uni.showToast({ + title: "未满足解锁条件", + icon: "none", + }); + } +}; + +const handleAdReward = async (token) => { + try { + const res = await watchAdReward(token); + if (res) { + uni.showToast({ + title: "解锁成功", + icon: "success", + }); + // 解锁成功后,更新本地状态,允许使用 + if (currentUnlockTpl.value) { + currentUnlockTpl.value.isUnlock = true; + // 同时更新列表中的状态 + const index = templates.value.findIndex( + (t) => t.id === currentUnlockTpl.value.id, + ); + if (index !== -1) { + templates.value[index].isUnlock = true; + } + + applyTemplate(currentUnlockTpl.value); + currentUnlockTpl.value = null; + } + } + } catch (e) { + console.error("Reward claim failed", e); + uni.showToast({ title: "奖励发放失败", icon: "none" }); + } +}; + const selectTitle = (title) => { trackRecord({ eventName: "card_title_choose", @@ -1932,6 +2032,56 @@ function drawRoundRect(ctx, x, y, w, h, r, color) { .user-desc { font-size: 20rpx; opacity: 0.6; + /* Lock Overlay - Modern Style */ + .lock-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-radius: 12rpx; + z-index: 5; + background: rgba(0, 0, 0, 0.05); /* very subtle dim */ + } + + .unlock-badge { + position: absolute; + top: 12rpx; + right: 12rpx; + padding: 4rpx 12rpx; + border-radius: 20rpx; + font-size: 18rpx; + color: #fff; + font-weight: bold; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2); + + &.vip { + background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%); + } + &.ad { + background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + } + &.sing1, + &.sing3 { + background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); + } + } + + .center-lock { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 56rpx; + height: 56rpx; + background: rgba(0, 0, 0, 0.4); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(4px); + border: 1px solid rgba(255, 255, 255, 0.2); + } } /* 顶部步骤条 */ @@ -2132,7 +2282,58 @@ function drawRoundRect(ctx, x, y, w, h, r, color) { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + position: relative; } +.tpl-card .lock-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border-radius: 12rpx; + z-index: 5; + background: rgba(0, 0, 0, 0.05); /* very subtle dim */ +} + +.tpl-card .unlock-badge { + position: absolute; + top: 12rpx; + right: 12rpx; + padding: 4rpx 12rpx; + border-radius: 20rpx; + font-size: 18rpx; + color: #fff; + font-weight: bold; + box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.2); + + &.vip { + background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%); + } + &.ad { + background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); + } + &.sing1, + &.sing3 { + background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%); + } +} + +.tpl-card .center-lock { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 56rpx; + height: 56rpx; + background: rgba(0, 0, 0, 0.4); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + backdrop-filter: blur(4px); + border: 1px solid rgba(255, 255, 255, 0.2); +} + .tpl-check { position: absolute; right: 6rpx;