feat: 添加二维码下载功能,优化邀请页面的用户体验
This commit is contained in:
2
auto-imports.d.ts
vendored
2
auto-imports.d.ts
vendored
@@ -451,8 +451,6 @@ declare module 'vue' {
|
||||
readonly shallowReactive: UnwrapRef<typeof import('vue')['shallowReactive']>
|
||||
readonly shallowReadonly: UnwrapRef<typeof import('vue')['shallowReadonly']>
|
||||
readonly shallowRef: UnwrapRef<typeof import('vue')['shallowRef']>
|
||||
readonly showSuccessToast: UnwrapRef<typeof import('vant/es')['showSuccessToast']>
|
||||
readonly showToast: UnwrapRef<typeof import('vant/es')['showToast']>
|
||||
readonly storeToRefs: UnwrapRef<typeof import('pinia')['storeToRefs']>
|
||||
readonly syncRef: UnwrapRef<typeof import('@vueuse/core')['syncRef']>
|
||||
readonly syncRefs: UnwrapRef<typeof import('@vueuse/core')['syncRefs']>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<script lang='ts' setup>
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import { Directory, Filesystem } from "@capacitor/filesystem";
|
||||
import { loadingController, toastController } from "@ionic/vue";
|
||||
import html2canvas from "html2canvas";
|
||||
import {
|
||||
checkmarkCircleOutline,
|
||||
copyOutline,
|
||||
@@ -20,6 +23,8 @@ const qrCodeUrl = computed(() => {
|
||||
});
|
||||
const { share, isSupported } = useShare();
|
||||
const { data: leader } = safeClient(() => client.api.team.leader.get(), { silent: true });
|
||||
const qrcodeContainer = useTemplateRef<HTMLElement>("qrcodeContainer");
|
||||
const platform = usePlatform();
|
||||
|
||||
// 复制状态
|
||||
const copyStatus = ref({
|
||||
@@ -81,6 +86,64 @@ function handleInvite() {
|
||||
function handleBindReferralCode() {
|
||||
router.push("/bind_invite");
|
||||
}
|
||||
async function captureQRCode(): Promise<string> {
|
||||
if (!qrcodeContainer.value) {
|
||||
throw new Error("QR code container not found");
|
||||
}
|
||||
try {
|
||||
const canvas = await html2canvas(qrcodeContainer.value, {
|
||||
backgroundColor: "#ffffff",
|
||||
scale: 2,
|
||||
logging: false,
|
||||
useCORS: true,
|
||||
allowTaint: true,
|
||||
});
|
||||
|
||||
return canvas.toDataURL("image/png");
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Capture error:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
async function handleDownloadQR() {
|
||||
const loading = await loadingController.create({
|
||||
message: "正在保存二维码...",
|
||||
});
|
||||
await loading.present();
|
||||
|
||||
try {
|
||||
const dataUrl = await captureQRCode();
|
||||
|
||||
if (platform === "browser") {
|
||||
// 浏览器环境直接下载
|
||||
const link = document.createElement("a");
|
||||
link.download = `qrcode-${userProfile.value?.uid}.png`;
|
||||
link.href = dataUrl;
|
||||
link.click();
|
||||
}
|
||||
else {
|
||||
// 原生环境保存到文档目录
|
||||
const base64Data = dataUrl.split(",")[1];
|
||||
const fileName = `financial-${Date.now()}.png`;
|
||||
|
||||
await Filesystem.writeFile({
|
||||
path: fileName,
|
||||
data: base64Data,
|
||||
directory: Directory.Documents, // iOS 使用 Documents 目录
|
||||
});
|
||||
|
||||
showToast("二维码已保存到您的相册");
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.error("Download error:", error);
|
||||
showToast("保存二维码失败,请重试");
|
||||
}
|
||||
finally {
|
||||
await loading.dismiss();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -207,7 +270,7 @@ function handleBindReferralCode() {
|
||||
</div>
|
||||
|
||||
<!-- 邀请码 -->
|
||||
<div class="mb-5 flex items-center justify-between bg-gradient-to-r from-[#fff7f0] to-[#ffe8e8] rounded-xl p-4">
|
||||
<div class="mb-5 flex items-center justify-between bg-linear-to-r from-[#fff7f0] to-[#ffe8e8] rounded-xl p-4">
|
||||
<div class="flex items-center gap-3">
|
||||
<div class="bg-white rounded-lg p-2 shadow-sm">
|
||||
<ion-icon :icon="ticketOutline" class="text-2xl text-[#c41e3a]" />
|
||||
@@ -309,7 +372,7 @@ function handleBindReferralCode() {
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center">
|
||||
<div class="bg-white p-4 rounded-2xl shadow-md mb-4 border-4 border-[#c41e3a]/20">
|
||||
<div ref="qrcodeContainer" class="bg-white p-4 rounded-2xl shadow-md mb-4 border-4 border-[#f7d4da]">
|
||||
<img
|
||||
:src="qrCodeUrl"
|
||||
alt="邀请二维码"
|
||||
@@ -319,7 +382,7 @@ function handleBindReferralCode() {
|
||||
<p class="text-xs text-[#999] text-center mb-3">
|
||||
扫描二维码或长按保存分享给好友
|
||||
</p>
|
||||
<!-- <ion-button
|
||||
<ion-button
|
||||
expand="block"
|
||||
fill="outline"
|
||||
class="download-qr-btn w-full"
|
||||
@@ -327,28 +390,28 @@ function handleBindReferralCode() {
|
||||
>
|
||||
<ion-icon slot="start" :icon="downloadOutline" />
|
||||
下载二维码
|
||||
</ion-button> -->
|
||||
</ion-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 邀请说明 -->
|
||||
<section class="mb-5">
|
||||
<div class="bg-gradient-to-br from-[#fff7f0] to-[#ffe8e8] rounded-2xl p-5">
|
||||
<div class="bg-linear-to-br from-[#fff7f0] to-[#ffe8e8] rounded-2xl p-5">
|
||||
<div class="text-base font-bold text-[#c41e3a] mb-3">
|
||||
邀请奖励说明
|
||||
</div>
|
||||
<div class="space-y-2 text-sm text-[#666]">
|
||||
<div class="flex items-start gap-2">
|
||||
<div class="w-1.5 h-1.5 rounded-full bg-[#c41e3a] mt-1.5 flex-shrink-0" />
|
||||
<div class="w-1.5 h-1.5 rounded-full bg-[#c41e3a] mt-1.5 shrink-0" />
|
||||
<span>每邀请1位好友注册,即可获得10积分奖励</span>
|
||||
</div>
|
||||
<div class="flex items-start gap-2">
|
||||
<div class="w-1.5 h-1.5 rounded-full bg-[#c41e3a] mt-1.5 flex-shrink-0" />
|
||||
<div class="w-1.5 h-1.5 rounded-full bg-[#c41e3a] mt-1.5 shrink-0" />
|
||||
<span>好友完成首次申购,您将获得额外20积分</span>
|
||||
</div>
|
||||
<div class="flex items-start gap-2">
|
||||
<div class="w-1.5 h-1.5 rounded-full bg-[#c41e3a] mt-1.5 flex-shrink-0" />
|
||||
<div class="w-1.5 h-1.5 rounded-full bg-[#c41e3a] mt-1.5 shrink-0" />
|
||||
<span>邀请越多,奖励越丰厚,上不封顶</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user