optimize: avatar page share reward
This commit is contained in:
@@ -107,6 +107,8 @@
|
||||
</view>
|
||||
|
||||
<canvas
|
||||
type="2d"
|
||||
id="avatarCanvas"
|
||||
canvas-id="avatarCanvas"
|
||||
class="hidden-canvas"
|
||||
style="width: 600px; height: 600px"
|
||||
@@ -162,7 +164,13 @@ import {
|
||||
getAvatarSystemList,
|
||||
getAvatarFrameList,
|
||||
getAvatarDecorList,
|
||||
avatarCreateComplete,
|
||||
} from "@/api/avatar.js";
|
||||
import {
|
||||
saveRecordRequest,
|
||||
getShareToken,
|
||||
generateObjectId,
|
||||
} from "@/utils/common.js";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const loginPopupRef = ref(null);
|
||||
@@ -313,6 +321,12 @@ const loadMoreAvatars = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const createAvatarId = () => {
|
||||
const id = generateObjectId();
|
||||
avatarCreateComplete({ id });
|
||||
return id;
|
||||
};
|
||||
|
||||
const selectMoreAvatar = (url) => {
|
||||
currentAvatar.value = url;
|
||||
closeMorePopup();
|
||||
@@ -417,7 +431,109 @@ const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
const saveByCanvas = async (save = true) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const query = uni.createSelectorQuery();
|
||||
query
|
||||
.select("#avatarCanvas")
|
||||
.fields({ node: true, size: true })
|
||||
.exec(async (res) => {
|
||||
if (!res[0] || !res[0].node) {
|
||||
reject("Canvas not found");
|
||||
return;
|
||||
}
|
||||
|
||||
const canvas = res[0].node;
|
||||
const ctx = canvas.getContext("2d");
|
||||
|
||||
const loadCanvasImage = (url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = canvas.createImage();
|
||||
img.onload = () => resolve(img);
|
||||
img.onerror = (e) => reject(e);
|
||||
img.src = url;
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化画布尺寸
|
||||
const size = 600;
|
||||
const avatarPath = await loadCanvasImage(currentAvatar.value);
|
||||
ctx.clearRect(0, 0, size, size);
|
||||
ctx.drawImage(avatarPath, 0, 0, size, size);
|
||||
if (selectedFrame.value) {
|
||||
const framePath = await loadCanvasImage(selectedFrame.value);
|
||||
ctx.drawImage(framePath, 0, 0, size, size);
|
||||
}
|
||||
if (selectedDecor.value) {
|
||||
const decorPath = await loadCanvasImage(selectedDecor.value);
|
||||
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.
|
||||
ctx.translate(decorState.value.x, decorState.value.y);
|
||||
ctx.rotate((decorState.value.rotate * Math.PI) / 180);
|
||||
const scale = decorState.value.scale;
|
||||
// 绘制图片,宽高 240
|
||||
ctx.drawImage(
|
||||
decorPath,
|
||||
-120 * scale,
|
||||
-120 * scale,
|
||||
240 * scale,
|
||||
240 * scale,
|
||||
);
|
||||
ctx.restore();
|
||||
}
|
||||
uni.canvasToTempFilePath({
|
||||
canvas: canvas, // Canvas 2D 必须传 canvas 实例
|
||||
width: 600,
|
||||
height: 600,
|
||||
destWidth: 600,
|
||||
destHeight: 600,
|
||||
success: (res) => {
|
||||
if (save) saveImage(res.tempFilePath);
|
||||
resolve(res.tempFilePath);
|
||||
},
|
||||
fail: (err) => reject(err),
|
||||
});
|
||||
// ctx.draw(false, () => {
|
||||
// uni.canvasToTempFilePath({
|
||||
// canvasId: "avatarCanvas",
|
||||
// success: (res) => {
|
||||
// uni.saveImageToPhotosAlbum({
|
||||
// filePath: res.tempFilePath,
|
||||
// success: () => {
|
||||
// uni.showToast({ title: "已保存到相册", icon: "success" });
|
||||
// },
|
||||
// });
|
||||
// },
|
||||
// });
|
||||
// });
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const saveImage = (path) => {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: path,
|
||||
success() {
|
||||
uni.showToast({ title: "已保存到相册" });
|
||||
},
|
||||
fail() {
|
||||
uni.showModal({
|
||||
title: "提示",
|
||||
content: "请授权保存到相册",
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const saveAndUse = async () => {
|
||||
saveByCanvas();
|
||||
console.log(111111);
|
||||
return;
|
||||
if (!isLoggedIn.value) {
|
||||
loginPopupRef.value.open();
|
||||
return;
|
||||
}
|
||||
const abilityRes = await abilityCheck("avatar_download");
|
||||
if (!abilityRes.canUse) {
|
||||
if (
|
||||
@@ -437,9 +553,10 @@ const saveAndUse = async () => {
|
||||
return;
|
||||
}
|
||||
// 调用avatarDownloadRecord API记录下载次数
|
||||
await avatarDownloadRecord({
|
||||
avatarUrl: currentAvatar.value,
|
||||
});
|
||||
// await avatarDownloadRecord({
|
||||
// avatarUrl: currentAvatar.value,
|
||||
// });
|
||||
// saveRecordRequest('', )
|
||||
const ctx = uni.createCanvasContext("avatarCanvas");
|
||||
const size = 600;
|
||||
const avatarPath = await loadImage(currentAvatar.value);
|
||||
@@ -487,13 +604,16 @@ const share = () => {
|
||||
};
|
||||
|
||||
onShareAppMessage(async () => {
|
||||
const deviceInfo = getDeviceInfo();
|
||||
const shareTokenRes = await createShareToken({
|
||||
targetId: "",
|
||||
scene: "avatar_download",
|
||||
...deviceInfo,
|
||||
});
|
||||
getRewardByShare();
|
||||
getShareReward({ scene: "avatar_download" });
|
||||
if (!isLoggedIn.value) {
|
||||
const shareTokenRes = await getShareToken("avatar_download_not_login", "");
|
||||
return {
|
||||
title: "新春祝福",
|
||||
path: `/pages/index/index?shareToken=${shareTokenRes.shareToken}`,
|
||||
};
|
||||
}
|
||||
const id = createAvatarId();
|
||||
const shareTokenRes = await getShareToken("avatar_download", id);
|
||||
|
||||
return {
|
||||
title: "制作我的新春头像",
|
||||
@@ -503,13 +623,6 @@ onShareAppMessage(async () => {
|
||||
};
|
||||
});
|
||||
|
||||
const getRewardByShare = async () => {
|
||||
const res = await getShareReward({ scene: "avatar_download" });
|
||||
if (res.success) {
|
||||
uni.showToast({ title: "分享成功,可下载头像" });
|
||||
}
|
||||
};
|
||||
|
||||
// onShareTimeline(() => {
|
||||
// return {
|
||||
// title: "制作我的新春头像",
|
||||
|
||||
Reference in New Issue
Block a user