optimize: avatar page share reward

This commit is contained in:
zzc
2026-01-28 10:35:31 +08:00
parent 4a1cbf1f5a
commit 29498e4994
2 changed files with 79 additions and 59 deletions

View File

@@ -47,7 +47,6 @@
<text>加载中...</text>
</view>
<!-- Decorative Elements -->
<view class="decor-tag">🐰</view>
<view class="card-footer-text">
<text class="icon">🌸</text> 2026 丙午马年限定
</view>
@@ -59,9 +58,6 @@
<button class="btn primary-btn" @tap="goToMake">
<text class="icon">🎨</text> 我也要领同款制作
</button>
<button class="btn secondary-btn" @tap="saveImage">
<text class="icon">📥</text> 保存到相册
</button>
</view>
<!-- Recommended Frames -->
@@ -94,7 +90,27 @@
<text>🖼</text>
</view>
<view class="banner-content">
<text class="banner-title">去挑选更多壁纸</text>
<text class="banner-title">去挑选新年壁纸</text>
<text class="banner-desc">新年新气象全套皮肤限时领</text>
</view>
<text class="banner-arrow"></text>
</view>
<view class="wallpaper-banner" @tap="goToWallpaper">
<view class="banner-icon">
<text>🖼</text>
</view>
<view class="banner-content">
<text class="banner-title">去挑选新年壁纸</text>
<text class="banner-desc">新年新气象全套皮肤限时领</text>
</view>
<text class="banner-arrow"></text>
</view>
<view class="wallpaper-banner" @tap="goToWallpaper">
<view class="banner-icon">
<text>🖼</text>
</view>
<view class="banner-content">
<text class="banner-title">去挑选新年壁纸</text>
<text class="banner-desc">新年新气象全套皮肤限时领</text>
</view>
<text class="banner-arrow"></text>
@@ -188,37 +204,6 @@ const previewImage = () => {
}
};
const saveImage = () => {
if (!detailData.value?.imageUrl) return;
uni.showLoading({ title: "保存中..." });
uni.downloadFile({
url: detailData.value.imageUrl,
success: (res) => {
if (res.statusCode === 200) {
uni.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: () => {
// uni.hideLoading();
uni.showToast({ title: "保存成功", icon: "success" });
},
fail: () => {
// uni.hideLoading();
uni.showToast({ title: "保存失败", icon: "none" });
},
});
} else {
// uni.hideLoading();
uni.showToast({ title: "下载失败", icon: "none" });
}
},
fail: () => {
// uni.hideLoading();
uni.showToast({ title: "下载失败", icon: "none" });
},
});
};
const goToMake = () => {
uni.navigateTo({
url: "/pages/avatar/index",

View File

@@ -6,17 +6,21 @@
</view>
<view class="preview-card">
<view class="preview-square">
<image class="avatar-img" :src="currentAvatar" mode="aspectFill" />
<image
class="avatar-img"
:src="currentAvatar?.imageUrl"
mode="aspectFill"
/>
<image
v-if="selectedFrame"
class="frame-img"
:src="selectedFrame"
:src="selectedFrame?.imageUrl"
mode="aspectFill"
/>
<image
v-if="selectedDecor"
class="decor-img"
:src="selectedDecor"
:src="selectedDecor?.imageUrl"
mode="aspectFit"
:style="decorStyle"
@touchstart.stop="onTouchStart"
@@ -58,7 +62,11 @@
:class="{ active: currentAvatar === item }"
@tap="currentAvatar = item"
>
<image :src="item" class="avatar-thumb" mode="aspectFill" />
<image
:src="item.imageUrl"
class="avatar-thumb"
mode="aspectFill"
/>
<view v-if="currentAvatar === item" class="check"></view>
</view>
</view>
@@ -88,7 +96,7 @@
:class="{ active: selectedFrame === frame }"
@tap="toggleFrame(frame)"
>
<image :src="frame" class="grid-img" mode="aspectFill" />
<image :src="frame.imageUrl" class="grid-img" mode="aspectFill" />
<view v-if="selectedFrame === frame" class="check"></view>
</view>
</view>
@@ -101,7 +109,7 @@
:class="{ active: selectedDecor === decor }"
@tap="selectedDecor = decor"
>
<image :src="decor" class="grid-img" mode="aspectFit" />
<image :src="decor.imageUrl" class="grid-img" mode="aspectFit" />
<view v-if="selectedDecor === decor" class="check"></view>
</view>
</view>
@@ -136,7 +144,7 @@
class="popup-item"
@tap="selectMoreAvatar(item)"
>
<image :src="item" class="popup-img" mode="aspectFill" />
<image :src="item.imageUrl" class="popup-img" mode="aspectFill" />
</view>
</view>
<view v-if="loading" class="loading-text">加载中...</view>
@@ -191,9 +199,9 @@ const decorPage = ref(1);
const decorHasNext = ref(true);
const decorLoading = ref(false);
const currentAvatar = ref("");
const selectedFrame = ref("");
const selectedDecor = ref("");
const currentAvatar = ref(null);
const selectedFrame = ref(null);
const selectedDecor = ref(null);
const activeTab = ref("frame");
// More Popup logic
@@ -210,7 +218,12 @@ const loadFrames = async () => {
const res = await getAvatarFrameList(framePage.value);
const list = res?.list || [];
if (list.length > 0) {
frames.value.push(...list.map((item) => item.imageUrl));
frames.value.push(
...list.map((item) => ({
id: item.id,
imageUrl: item.imageUrl,
})),
);
framePage.value++;
}
if (typeof res.hasNext !== "undefined") {
@@ -232,7 +245,12 @@ const loadDecors = async () => {
const res = await getAvatarDecorList(decorPage.value);
const list = res?.list || [];
if (list.length > 0) {
decors.value.push(...list.map((item) => item.imageUrl));
decors.value.push(
...list.map((item) => ({
id: item.id,
imageUrl: item.imageUrl,
})),
);
decorPage.value++;
}
if (typeof res.hasNext !== "undefined") {
@@ -253,7 +271,9 @@ const initSystemAvatars = async () => {
const list = res?.list || [];
if (list.length > 0) {
// 取前3个展示在首页
systemAvatars.value = list.slice(0, 3).map((item) => item.imageUrl);
systemAvatars.value = list
.slice(0, 3)
.map((item) => ({ id: item.id, imageUrl: item.imageUrl }));
// 默认选中第一个
if (systemAvatars.value.length > 0) {
currentAvatar.value = systemAvatars.value[0];
@@ -301,7 +321,10 @@ const loadMoreAvatars = async () => {
const list = res?.list || [];
if (list.length > 0) {
const newAvatars = list.map((item) => item.imageUrl);
const newAvatars = list.map((item) => ({
id: item.id,
imageUrl: item.imageUrl,
}));
moreAvatars.value.push(...newAvatars);
page.value++;
}
@@ -328,14 +351,14 @@ const createAvatarId = () => {
return id;
};
const selectMoreAvatar = (url) => {
currentAvatar.value = url;
const selectMoreAvatar = (item) => {
currentAvatar.value = item;
closeMorePopup();
};
const toggleFrame = (frame) => {
if (selectedFrame.value === frame) {
selectedFrame.value = "";
selectedFrame.value = null;
} else {
selectedFrame.value = frame;
}
@@ -424,7 +447,10 @@ const useWeChatAvatar = () => {
if (!isLoggedIn.value) {
loginPopupRef.value.open();
} else {
currentAvatar.value = userStore.userInfo.avatarUrl;
currentAvatar.value = {
id: "wechat_" + Date.now(),
imageUrl: userStore.userInfo.avatarUrl,
};
}
};
@@ -460,15 +486,15 @@ const saveByCanvas = async (save = true) => {
const size = 600;
canvas.width = size;
canvas.height = size;
const avatarPath = await loadCanvasImage(currentAvatar.value);
const avatarPath = await loadCanvasImage(currentAvatar.value.imageUrl);
ctx.clearRect(0, 0, size, size);
ctx.drawImage(avatarPath, 0, 0, size, size);
if (selectedFrame.value) {
const framePath = await loadCanvasImage(selectedFrame.value);
const framePath = await loadCanvasImage(selectedFrame.value.imageUrl);
ctx.drawImage(framePath, 0, 0, size, size);
}
if (selectedDecor.value) {
const decorPath = await loadCanvasImage(selectedDecor.value);
const decorPath = await loadCanvasImage(selectedDecor.value.imageUrl);
ctx.save();
// 映射 rpx 坐标到 Canvas 坐标 (假设 1rpx = 1 unit for 600x600 canvas logic)
// Canvas size is 600, Preview is 600rpx. Ratio is 1:1 in logical space.
@@ -553,7 +579,10 @@ const saveAndUse = async () => {
return;
}
saveByCanvas();
const tempPath = saveByCanvas(true);
const id = createAvatarId();
saveRecordRequest(tempPath, id, "avatar_download");
completeCardInfo(id);
return;
// 调用avatarDownloadRecord API记录下载次数
// await avatarDownloadRecord({
@@ -605,7 +634,13 @@ const saveAndUse = async () => {
const completeCardInfo = async (id) => {
const tempPath = await saveByCanvas(false);
const imageUrl = await uploadImage(tempPath);
avatarCreateComplete({ id, imageUrl, avatarId: id });
avatarCreateComplete({
id,
imageUrl,
avatarId: currentAvatar?.value?.id,
decorId: selectedDecor?.value?.id,
frameId: selectedFrame?.value?.id,
});
};
onShareAppMessage(async () => {