optimize: avatar page share reward
This commit is contained in:
@@ -47,7 +47,6 @@
|
|||||||
<text>加载中...</text>
|
<text>加载中...</text>
|
||||||
</view>
|
</view>
|
||||||
<!-- Decorative Elements -->
|
<!-- Decorative Elements -->
|
||||||
<view class="decor-tag">🐰</view>
|
|
||||||
<view class="card-footer-text">
|
<view class="card-footer-text">
|
||||||
<text class="icon">🌸</text> 2026 丙午马年限定
|
<text class="icon">🌸</text> 2026 丙午马年限定
|
||||||
</view>
|
</view>
|
||||||
@@ -59,9 +58,6 @@
|
|||||||
<button class="btn primary-btn" @tap="goToMake">
|
<button class="btn primary-btn" @tap="goToMake">
|
||||||
<text class="icon">🎨</text> 我也要领同款制作
|
<text class="icon">🎨</text> 我也要领同款制作
|
||||||
</button>
|
</button>
|
||||||
<button class="btn secondary-btn" @tap="saveImage">
|
|
||||||
<text class="icon">📥</text> 保存到相册
|
|
||||||
</button>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- Recommended Frames -->
|
<!-- Recommended Frames -->
|
||||||
@@ -94,7 +90,27 @@
|
|||||||
<text>🖼</text>
|
<text>🖼</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="banner-content">
|
<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>
|
<text class="banner-desc">新年新气象,全套皮肤限时领</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="banner-arrow">›</text>
|
<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 = () => {
|
const goToMake = () => {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: "/pages/avatar/index",
|
url: "/pages/avatar/index",
|
||||||
|
|||||||
@@ -6,17 +6,21 @@
|
|||||||
</view>
|
</view>
|
||||||
<view class="preview-card">
|
<view class="preview-card">
|
||||||
<view class="preview-square">
|
<view class="preview-square">
|
||||||
<image class="avatar-img" :src="currentAvatar" mode="aspectFill" />
|
<image
|
||||||
|
class="avatar-img"
|
||||||
|
:src="currentAvatar?.imageUrl"
|
||||||
|
mode="aspectFill"
|
||||||
|
/>
|
||||||
<image
|
<image
|
||||||
v-if="selectedFrame"
|
v-if="selectedFrame"
|
||||||
class="frame-img"
|
class="frame-img"
|
||||||
:src="selectedFrame"
|
:src="selectedFrame?.imageUrl"
|
||||||
mode="aspectFill"
|
mode="aspectFill"
|
||||||
/>
|
/>
|
||||||
<image
|
<image
|
||||||
v-if="selectedDecor"
|
v-if="selectedDecor"
|
||||||
class="decor-img"
|
class="decor-img"
|
||||||
:src="selectedDecor"
|
:src="selectedDecor?.imageUrl"
|
||||||
mode="aspectFit"
|
mode="aspectFit"
|
||||||
:style="decorStyle"
|
:style="decorStyle"
|
||||||
@touchstart.stop="onTouchStart"
|
@touchstart.stop="onTouchStart"
|
||||||
@@ -58,7 +62,11 @@
|
|||||||
:class="{ active: currentAvatar === item }"
|
:class="{ active: currentAvatar === item }"
|
||||||
@tap="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 v-if="currentAvatar === item" class="check">✔</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -88,7 +96,7 @@
|
|||||||
:class="{ active: selectedFrame === frame }"
|
:class="{ active: selectedFrame === frame }"
|
||||||
@tap="toggleFrame(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 v-if="selectedFrame === frame" class="check">✔</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -101,7 +109,7 @@
|
|||||||
:class="{ active: selectedDecor === decor }"
|
:class="{ active: selectedDecor === decor }"
|
||||||
@tap="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 v-if="selectedDecor === decor" class="check">✔</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -136,7 +144,7 @@
|
|||||||
class="popup-item"
|
class="popup-item"
|
||||||
@tap="selectMoreAvatar(item)"
|
@tap="selectMoreAvatar(item)"
|
||||||
>
|
>
|
||||||
<image :src="item" class="popup-img" mode="aspectFill" />
|
<image :src="item.imageUrl" class="popup-img" mode="aspectFill" />
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view v-if="loading" class="loading-text">加载中...</view>
|
<view v-if="loading" class="loading-text">加载中...</view>
|
||||||
@@ -191,9 +199,9 @@ const decorPage = ref(1);
|
|||||||
const decorHasNext = ref(true);
|
const decorHasNext = ref(true);
|
||||||
const decorLoading = ref(false);
|
const decorLoading = ref(false);
|
||||||
|
|
||||||
const currentAvatar = ref("");
|
const currentAvatar = ref(null);
|
||||||
const selectedFrame = ref("");
|
const selectedFrame = ref(null);
|
||||||
const selectedDecor = ref("");
|
const selectedDecor = ref(null);
|
||||||
const activeTab = ref("frame");
|
const activeTab = ref("frame");
|
||||||
|
|
||||||
// More Popup logic
|
// More Popup logic
|
||||||
@@ -210,7 +218,12 @@ const loadFrames = async () => {
|
|||||||
const res = await getAvatarFrameList(framePage.value);
|
const res = await getAvatarFrameList(framePage.value);
|
||||||
const list = res?.list || [];
|
const list = res?.list || [];
|
||||||
if (list.length > 0) {
|
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++;
|
framePage.value++;
|
||||||
}
|
}
|
||||||
if (typeof res.hasNext !== "undefined") {
|
if (typeof res.hasNext !== "undefined") {
|
||||||
@@ -232,7 +245,12 @@ const loadDecors = async () => {
|
|||||||
const res = await getAvatarDecorList(decorPage.value);
|
const res = await getAvatarDecorList(decorPage.value);
|
||||||
const list = res?.list || [];
|
const list = res?.list || [];
|
||||||
if (list.length > 0) {
|
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++;
|
decorPage.value++;
|
||||||
}
|
}
|
||||||
if (typeof res.hasNext !== "undefined") {
|
if (typeof res.hasNext !== "undefined") {
|
||||||
@@ -253,7 +271,9 @@ const initSystemAvatars = async () => {
|
|||||||
const list = res?.list || [];
|
const list = res?.list || [];
|
||||||
if (list.length > 0) {
|
if (list.length > 0) {
|
||||||
// 取前3个展示在首页
|
// 取前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) {
|
if (systemAvatars.value.length > 0) {
|
||||||
currentAvatar.value = systemAvatars.value[0];
|
currentAvatar.value = systemAvatars.value[0];
|
||||||
@@ -301,7 +321,10 @@ const loadMoreAvatars = async () => {
|
|||||||
const list = res?.list || [];
|
const list = res?.list || [];
|
||||||
|
|
||||||
if (list.length > 0) {
|
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);
|
moreAvatars.value.push(...newAvatars);
|
||||||
page.value++;
|
page.value++;
|
||||||
}
|
}
|
||||||
@@ -328,14 +351,14 @@ const createAvatarId = () => {
|
|||||||
return id;
|
return id;
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectMoreAvatar = (url) => {
|
const selectMoreAvatar = (item) => {
|
||||||
currentAvatar.value = url;
|
currentAvatar.value = item;
|
||||||
closeMorePopup();
|
closeMorePopup();
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleFrame = (frame) => {
|
const toggleFrame = (frame) => {
|
||||||
if (selectedFrame.value === frame) {
|
if (selectedFrame.value === frame) {
|
||||||
selectedFrame.value = "";
|
selectedFrame.value = null;
|
||||||
} else {
|
} else {
|
||||||
selectedFrame.value = frame;
|
selectedFrame.value = frame;
|
||||||
}
|
}
|
||||||
@@ -424,7 +447,10 @@ const useWeChatAvatar = () => {
|
|||||||
if (!isLoggedIn.value) {
|
if (!isLoggedIn.value) {
|
||||||
loginPopupRef.value.open();
|
loginPopupRef.value.open();
|
||||||
} else {
|
} 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;
|
const size = 600;
|
||||||
canvas.width = size;
|
canvas.width = size;
|
||||||
canvas.height = size;
|
canvas.height = size;
|
||||||
const avatarPath = await loadCanvasImage(currentAvatar.value);
|
const avatarPath = await loadCanvasImage(currentAvatar.value.imageUrl);
|
||||||
ctx.clearRect(0, 0, size, size);
|
ctx.clearRect(0, 0, size, size);
|
||||||
ctx.drawImage(avatarPath, 0, 0, size, size);
|
ctx.drawImage(avatarPath, 0, 0, size, size);
|
||||||
if (selectedFrame.value) {
|
if (selectedFrame.value) {
|
||||||
const framePath = await loadCanvasImage(selectedFrame.value);
|
const framePath = await loadCanvasImage(selectedFrame.value.imageUrl);
|
||||||
ctx.drawImage(framePath, 0, 0, size, size);
|
ctx.drawImage(framePath, 0, 0, size, size);
|
||||||
}
|
}
|
||||||
if (selectedDecor.value) {
|
if (selectedDecor.value) {
|
||||||
const decorPath = await loadCanvasImage(selectedDecor.value);
|
const decorPath = await loadCanvasImage(selectedDecor.value.imageUrl);
|
||||||
ctx.save();
|
ctx.save();
|
||||||
// 映射 rpx 坐标到 Canvas 坐标 (假设 1rpx = 1 unit for 600x600 canvas logic)
|
// 映射 rpx 坐标到 Canvas 坐标 (假设 1rpx = 1 unit for 600x600 canvas logic)
|
||||||
// Canvas size is 600, Preview is 600rpx. Ratio is 1:1 in logical space.
|
// Canvas size is 600, Preview is 600rpx. Ratio is 1:1 in logical space.
|
||||||
@@ -553,7 +579,10 @@ const saveAndUse = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveByCanvas();
|
const tempPath = saveByCanvas(true);
|
||||||
|
const id = createAvatarId();
|
||||||
|
saveRecordRequest(tempPath, id, "avatar_download");
|
||||||
|
completeCardInfo(id);
|
||||||
return;
|
return;
|
||||||
// 调用avatarDownloadRecord API记录下载次数
|
// 调用avatarDownloadRecord API记录下载次数
|
||||||
// await avatarDownloadRecord({
|
// await avatarDownloadRecord({
|
||||||
@@ -605,7 +634,13 @@ const saveAndUse = async () => {
|
|||||||
const completeCardInfo = async (id) => {
|
const completeCardInfo = async (id) => {
|
||||||
const tempPath = await saveByCanvas(false);
|
const tempPath = await saveByCanvas(false);
|
||||||
const imageUrl = await uploadImage(tempPath);
|
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 () => {
|
onShareAppMessage(async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user