fix: lock resousers
This commit is contained in:
@@ -131,6 +131,18 @@
|
||||
>
|
||||
<image :src="item.imageUrl" class="grid-img" mode="aspectFill" />
|
||||
<view v-if="selectedFrame?.id === item.id" class="check">✓</view>
|
||||
<!-- Lock Overlay -->
|
||||
<view v-if="!item.isUnlock && item.unlockType" class="lock-overlay">
|
||||
<!-- Badge -->
|
||||
<view class="unlock-badge" :class="item.unlockType">
|
||||
{{ getUnlockLabel(item.unlockType) }}
|
||||
</view>
|
||||
|
||||
<!-- Center Lock -->
|
||||
<view class="center-lock">
|
||||
<uni-icons type="locked-filled" size="18" color="#fff" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="frameLoading" class="loading-more">加载中...</view>
|
||||
@@ -150,6 +162,18 @@
|
||||
>
|
||||
<image :src="item.imageUrl" class="grid-img" mode="aspectFill" />
|
||||
<view v-if="selectedDecor?.id === item.id" class="check">✓</view>
|
||||
<!-- Lock Overlay -->
|
||||
<view v-if="!item.isUnlock && item.unlockType" class="lock-overlay">
|
||||
<!-- Badge -->
|
||||
<view class="unlock-badge" :class="item.unlockType">
|
||||
{{ getUnlockLabel(item.unlockType) }}
|
||||
</view>
|
||||
|
||||
<!-- Center Lock -->
|
||||
<view class="center-lock">
|
||||
<uni-icons type="locked-filled" size="18" color="#fff" />
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="decorLoading" class="loading-more">加载中...</view>
|
||||
@@ -171,6 +195,7 @@
|
||||
@logind="handleLogind"
|
||||
:share-token="shareToken"
|
||||
/>
|
||||
<RewardAd ref="rewardAdRef" @onReward="handleAdReward" />
|
||||
|
||||
<!-- More Avatar Popup -->
|
||||
<!-- <uni-popup ref="morePopup" type="bottom" background-color="#fff">
|
||||
@@ -213,14 +238,14 @@ import {
|
||||
onReachBottom,
|
||||
} from "@dcloudio/uni-app";
|
||||
import { useUserStore } from "@/stores/user";
|
||||
import { checkAbilityAndHandle } from "@/utils/ability.js";
|
||||
import { checkAbilityAndHandle, getUnlockLabel } from "@/utils/ability.js";
|
||||
import {
|
||||
getAvatarSystemList,
|
||||
getAvatarFrameList,
|
||||
getAvatarDecorList,
|
||||
avatarCreateComplete,
|
||||
} from "@/api/avatar.js";
|
||||
import { getShareReward } from "@/api/system.js";
|
||||
import { getShareReward, watchAdReward } from "@/api/system.js";
|
||||
import {
|
||||
saveRecordRequest,
|
||||
getShareToken,
|
||||
@@ -231,9 +256,12 @@ import {
|
||||
import { trackRecord } from "@/utils/common.js";
|
||||
import NavBar from "@/components/NavBar/NavBar.vue";
|
||||
import LoginPopup from "@/components/LoginPopup/LoginPopup.vue";
|
||||
import RewardAd from "@/components/RewardAd/RewardAd.vue";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const loginPopupRef = ref(null);
|
||||
const rewardAdRef = ref(null);
|
||||
const currentUnlockItem = ref(null);
|
||||
|
||||
const isLoggedIn = computed(() => !!userStore.userInfo.nickName);
|
||||
const userPoints = computed(() => userStore.userInfo.points || 0);
|
||||
@@ -316,6 +344,7 @@ const loadFrames = async () => {
|
||||
if (list.length > 0) {
|
||||
frames.value.push(
|
||||
...list.map((item) => ({
|
||||
...item,
|
||||
id: item.id,
|
||||
imageUrl: item.imageUrl,
|
||||
})),
|
||||
@@ -343,6 +372,7 @@ const loadDecors = async () => {
|
||||
if (list.length > 0) {
|
||||
decors.value.push(
|
||||
...list.map((item) => ({
|
||||
...item,
|
||||
id: item.id,
|
||||
imageUrl: item.imageUrl,
|
||||
})),
|
||||
@@ -423,6 +453,10 @@ const toggleAvatar = (avatar) => {
|
||||
};
|
||||
|
||||
const toggleFrame = (frame) => {
|
||||
if (frame.unlockType && !frame.isUnlock) {
|
||||
handleUnlock(frame);
|
||||
return;
|
||||
}
|
||||
trackRecord({
|
||||
eventName: "avatar_frame_click",
|
||||
eventType: `select`,
|
||||
@@ -436,6 +470,10 @@ const toggleFrame = (frame) => {
|
||||
};
|
||||
|
||||
const toggleDecor = (decor) => {
|
||||
if (decor.unlockType && !decor.isUnlock) {
|
||||
handleUnlock(decor);
|
||||
return;
|
||||
}
|
||||
trackRecord({
|
||||
eventName: "avatar_decor_click",
|
||||
eventType: `select`,
|
||||
@@ -448,6 +486,93 @@ const toggleDecor = (decor) => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleUnlock = (item) => {
|
||||
switch (item.unlockType) {
|
||||
case "vip":
|
||||
uni.navigateTo({
|
||||
url: "/pages/mine/vip",
|
||||
});
|
||||
break;
|
||||
case "ad":
|
||||
currentUnlockItem.value = item;
|
||||
rewardAdRef.value.show();
|
||||
break;
|
||||
case "sing1":
|
||||
uni.showToast({
|
||||
title: "需要连续签到1天解锁",
|
||||
icon: "none",
|
||||
});
|
||||
break;
|
||||
case "sing3":
|
||||
uni.showToast({
|
||||
title: "需要连续签到3天解锁",
|
||||
icon: "none",
|
||||
});
|
||||
break;
|
||||
case "sing5":
|
||||
uni.showToast({
|
||||
title: "需要连续签到5天解锁",
|
||||
icon: "none",
|
||||
});
|
||||
break;
|
||||
case "sing7":
|
||||
uni.showToast({
|
||||
title: "需要连续签到7天解锁",
|
||||
icon: "none",
|
||||
});
|
||||
break;
|
||||
default:
|
||||
uni.showToast({
|
||||
title: "未满足解锁条件",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const handleAdReward = async (token) => {
|
||||
try {
|
||||
const res = await watchAdReward(
|
||||
token,
|
||||
"unlock",
|
||||
activeTool.value === "frame" ? "avatar_frame" : "avatar_decor",
|
||||
currentUnlockItem.value.id,
|
||||
);
|
||||
if (res) {
|
||||
uni.showToast({
|
||||
title: "解锁成功",
|
||||
icon: "success",
|
||||
});
|
||||
// 解锁成功后,更新本地状态,允许使用
|
||||
if (currentUnlockItem.value) {
|
||||
currentUnlockItem.value.isUnlock = true;
|
||||
|
||||
if (activeTool.value === "frame") {
|
||||
const index = frames.value.findIndex(
|
||||
(t) => t.id === currentUnlockItem.value.id,
|
||||
);
|
||||
if (index !== -1) {
|
||||
frames.value[index].isUnlock = true;
|
||||
}
|
||||
toggleFrame(currentUnlockItem.value);
|
||||
} else if (activeTool.value === "decor") {
|
||||
const index = decors.value.findIndex(
|
||||
(t) => t.id === currentUnlockItem.value.id,
|
||||
);
|
||||
if (index !== -1) {
|
||||
decors.value[index].isUnlock = true;
|
||||
}
|
||||
toggleDecor(currentUnlockItem.value);
|
||||
}
|
||||
|
||||
currentUnlockItem.value = null;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Reward claim failed", e);
|
||||
uni.showToast({ title: "奖励发放失败", icon: "none" });
|
||||
}
|
||||
};
|
||||
|
||||
// 挂饰状态
|
||||
const decorState = ref({
|
||||
x: 300, // 初始中心 X (rpx)
|
||||
@@ -775,7 +900,7 @@ onShareAppMessage(async (options) => {
|
||||
getShareReward({ scene: "avatar_download" });
|
||||
uni.hideLoading();
|
||||
return {
|
||||
title: "3 秒生成新春专属头像,真的好看😆",
|
||||
title: "3 秒生成专属头像,真的好看😆",
|
||||
path: `/pages/avatar/detail?shareToken=${shareToken}`,
|
||||
imageUrl:
|
||||
imageUrl +
|
||||
@@ -785,7 +910,7 @@ onShareAppMessage(async (options) => {
|
||||
const shareToken = await getShareToken("avatar_download_not_login", "");
|
||||
getShareReward({ scene: "avatar_index" });
|
||||
return {
|
||||
title: "3 秒生成新春专属头像,真的好看😆",
|
||||
title: "3 秒生成专属头像,真的好看😆",
|
||||
path: `/pages/avatar/index?shareToken=${shareToken}`,
|
||||
imageUrl:
|
||||
"https://file.lihailezzc.com/resource/8dd026d76ef7a63d123b7fd698fb989b.png",
|
||||
@@ -1148,6 +1273,69 @@ onShareTimeline(async () => {
|
||||
font-size: 20rpx;
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 0 0 0 16rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* 锁定遮罩样式 */
|
||||
.lock-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
pointer-events: none; /* 让点击事件穿透到 grid-item */
|
||||
}
|
||||
|
||||
.unlock-badge {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
background: linear-gradient(
|
||||
135deg,
|
||||
#ff9a9e 0%,
|
||||
#fecfef 99%,
|
||||
#fecfef 100%
|
||||
);
|
||||
color: #fff;
|
||||
font-size: 16rpx;
|
||||
padding: 4rpx 10rpx;
|
||||
border-radius: 0 0 0 12rpx;
|
||||
font-weight: bold;
|
||||
z-index: 20;
|
||||
|
||||
&.vip {
|
||||
background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
|
||||
}
|
||||
&.ad {
|
||||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||||
}
|
||||
&.sing1,
|
||||
&.sing3,
|
||||
&.sing5,
|
||||
&.sing7 {
|
||||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.center-lock {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
&.upload-card {
|
||||
|
||||
Reference in New Issue
Block a user