feat: 添加邀请页面,包含邀请信息和二维码,优化邀请功能和样式
This commit is contained in:
BIN
src/assets/images/invite-banner.jpg
Normal file
BIN
src/assets/images/invite-banner.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 225 KiB |
@@ -39,6 +39,10 @@ const routes: Array<RouteRecordRaw> = [
|
||||
path: "/signup",
|
||||
component: () => import("@/views/signup/index.vue"),
|
||||
},
|
||||
{
|
||||
path: "/invite",
|
||||
component: () => import("@/views/invite/index.vue"),
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
|
||||
@@ -68,7 +68,7 @@ const router = useRouter();
|
||||
const quickActions = ref([
|
||||
{ id: 1, name: "签到", icon: calendarOutline, color: "#c32120" },
|
||||
{ id: 2, name: "团队中心", icon: peopleOutline, color: "#c32120" },
|
||||
{ id: 3, name: "战略改革", icon: rocketOutline, color: "#c32120" },
|
||||
{ id: 3, name: "邀请好友", icon: rocketOutline, color: "#c32120" },
|
||||
{ id: 4, name: "在线客服", icon: chatbubblesOutline, color: "#c32120" },
|
||||
]);
|
||||
|
||||
@@ -80,6 +80,9 @@ function handleQuickAction(action: any) {
|
||||
case 2:
|
||||
console.log("团队中心");
|
||||
break;
|
||||
case 3:
|
||||
router.push("/invite");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
337
src/views/invite/index.vue
Normal file
337
src/views/invite/index.vue
Normal file
@@ -0,0 +1,337 @@
|
||||
<script lang='ts' setup>
|
||||
import { Clipboard } from "@capacitor/clipboard";
|
||||
import {
|
||||
checkmarkCircleOutline,
|
||||
copyOutline,
|
||||
downloadOutline,
|
||||
linkOutline,
|
||||
peopleOutline,
|
||||
qrCodeOutline,
|
||||
shareOutline,
|
||||
ticketOutline,
|
||||
} from "ionicons/icons";
|
||||
|
||||
// 邀请信息
|
||||
const inviteInfo = ref({
|
||||
inviteCode: "ABCD1234",
|
||||
inviteLink: "https://example.com/invite?code=ABCD1234",
|
||||
downloadLink: "https://example.com/download",
|
||||
qrCodeUrl: "https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=https://example.com/invite?code=ABCD1234",
|
||||
totalInvites: 28,
|
||||
todayInvites: 3,
|
||||
});
|
||||
|
||||
// 复制状态
|
||||
const copyStatus = ref({
|
||||
link: false,
|
||||
code: false,
|
||||
download: false,
|
||||
});
|
||||
|
||||
async function handleCopy(text: string, type: "link" | "code" | "download") {
|
||||
try {
|
||||
await Clipboard.write({
|
||||
string: text,
|
||||
});
|
||||
|
||||
// 显示复制成功状态
|
||||
copyStatus.value[type] = true;
|
||||
|
||||
// 2秒后恢复
|
||||
setTimeout(() => {
|
||||
copyStatus.value[type] = false;
|
||||
}, 2000);
|
||||
|
||||
console.log(`已复制${type}:`, text);
|
||||
}
|
||||
catch (error) {
|
||||
console.error("复制失败:", error);
|
||||
// 降级方案:使用浏览器API
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
copyStatus.value[type] = true;
|
||||
setTimeout(() => {
|
||||
copyStatus.value[type] = false;
|
||||
}, 2000);
|
||||
}
|
||||
catch (err) {
|
||||
console.error("浏览器复制也失败:", err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function handleInvite() {
|
||||
console.log("立即邀请");
|
||||
// TODO: 实现分享功能
|
||||
}
|
||||
|
||||
function handleDownloadQR() {
|
||||
console.log("下载二维码");
|
||||
// TODO: 实现下载二维码功能
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ion-page>
|
||||
<ion-content :fullscreen="true">
|
||||
<!-- 顶部横幅 -->
|
||||
<img src="@/assets/images/invite-banner.jpg" class="w-full object-cover" alt="邀请横幅">
|
||||
|
||||
<div class="ion-padding-horizontal">
|
||||
<!-- 邀请统计卡片 -->
|
||||
<section class="mb-4">
|
||||
<div class="card rounded-2xl shadow-lg p-6">
|
||||
<div class="flex items-center justify-center gap-2 mb-4">
|
||||
<ion-icon :icon="peopleOutline" class="text-3xl" />
|
||||
<div class="text-xl font-bold text-[#1a1a1a]">
|
||||
邀请统计
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-2 gap-4 mb-4">
|
||||
<div class="bg-white/20 backdrop-blur-sm rounded-xl p-4 text-center">
|
||||
<div class="text-xs opacity-90 mb-1">
|
||||
累计邀请
|
||||
</div>
|
||||
<div class="text-4xl font-bold mb-1">
|
||||
{{ inviteInfo.totalInvites }}
|
||||
</div>
|
||||
<div class="text-xs opacity-80">
|
||||
人
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white/20 backdrop-blur-sm rounded-xl p-4 text-center">
|
||||
<div class="text-xs opacity-90 mb-1">
|
||||
今日邀请
|
||||
</div>
|
||||
<div class="text-4xl font-bold mb-1">
|
||||
{{ inviteInfo.todayInvites }}
|
||||
</div>
|
||||
<div class="text-xs opacity-80">
|
||||
人
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 立即邀请按钮 -->
|
||||
<ion-button
|
||||
expand="block"
|
||||
@click="handleInvite"
|
||||
>
|
||||
<ion-icon slot="start" :icon="shareOutline" class="text-xl" />
|
||||
立即邀请好友
|
||||
</ion-button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="mb-4">
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<img src="@/assets/images/icon.png" class="size-7">
|
||||
<div class="text-lg font-bold text-[#1a1a1a]">
|
||||
我的邀请码
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 邀请码 -->
|
||||
<div class="mb-5 flex items-center justify-between bg-gradient-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]" />
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs text-[#999] mb-1">
|
||||
邀请码
|
||||
</div>
|
||||
<div class="text-xl font-bold text-[#c41e3a] tracking-wider">
|
||||
{{ inviteInfo.inviteCode }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ion-button
|
||||
fill="clear"
|
||||
class="copy-btn"
|
||||
@click="handleCopy(inviteInfo.inviteCode, 'code')"
|
||||
>
|
||||
<ion-icon
|
||||
slot="icon-only"
|
||||
:icon="copyStatus.code ? checkmarkCircleOutline : copyOutline"
|
||||
:class="copyStatus.code ? 'text-green-500' : 'text-[#c41e3a]'"
|
||||
class="text-2xl"
|
||||
/>
|
||||
</ion-button>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<img src="@/assets/images/icon.png" class="size-7">
|
||||
<div class="text-lg font-bold text-[#1a1a1a]">
|
||||
推广链接
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-5 bg-gray-50 rounded-xl p-4">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<div class="text-xs text-[#999] mb-1">
|
||||
分享此链接邀请好友
|
||||
</div>
|
||||
<div class="text-sm text-[#333] truncate">
|
||||
{{ inviteInfo.inviteLink }}
|
||||
</div>
|
||||
</div>
|
||||
<ion-button
|
||||
fill="solid"
|
||||
size="small"
|
||||
class="copy-link-btn"
|
||||
@click="handleCopy(inviteInfo.inviteLink, 'link')"
|
||||
>
|
||||
<ion-icon
|
||||
slot="icon-only"
|
||||
:icon="copyStatus.link ? checkmarkCircleOutline : copyOutline"
|
||||
class="text-lg"
|
||||
/>
|
||||
</ion-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<img src="@/assets/images/icon.png" class="size-7">
|
||||
<div class="text-lg font-bold text-[#1a1a1a]">
|
||||
下载链接
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-5 bg-gray-50 rounded-xl p-4">
|
||||
<div class="flex items-center justify-between gap-3">
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<div class="text-xs text-[#999] mb-1">
|
||||
分享下载地址
|
||||
</div>
|
||||
<div class="text-sm text-[#333] truncate">
|
||||
{{ inviteInfo.downloadLink }}
|
||||
</div>
|
||||
</div>
|
||||
<ion-button
|
||||
fill="solid"
|
||||
size="small"
|
||||
class="copy-link-btn"
|
||||
@click="handleCopy(inviteInfo.downloadLink, 'download')"
|
||||
>
|
||||
<ion-icon
|
||||
slot="icon-only"
|
||||
:icon="copyStatus.download ? checkmarkCircleOutline : copyOutline"
|
||||
class="text-lg"
|
||||
/>
|
||||
</ion-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 邀请二维码 -->
|
||||
<section class="mb-5">
|
||||
<div class="card rounded-2xl shadow-lg p-5">
|
||||
<div class="flex items-center gap-2 mb-3">
|
||||
<img src="@/assets/images/icon.png" class="size-7">
|
||||
<div class="text-lg font-bold text-[#1a1a1a]">
|
||||
邀请二维码
|
||||
</div>
|
||||
</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">
|
||||
<img
|
||||
:src="inviteInfo.qrCodeUrl"
|
||||
alt="邀请二维码"
|
||||
class="w-50 h-50"
|
||||
>
|
||||
</div>
|
||||
<p class="text-xs text-[#999] text-center mb-3">
|
||||
扫描二维码或长按保存分享给好友
|
||||
</p>
|
||||
<ion-button
|
||||
expand="block"
|
||||
fill="outline"
|
||||
class="download-qr-btn w-full"
|
||||
@click="handleDownloadQR"
|
||||
>
|
||||
<ion-icon slot="start" :icon="downloadOutline" />
|
||||
下载二维码
|
||||
</ion-button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 邀请说明 -->
|
||||
<section class="mb-5">
|
||||
<div class="bg-gradient-to-br from-[#fff7f0] to-[#ffe8e8] rounded-2xl p-5">
|
||||
<h4 class="text-base font-bold text-[#c41e3a] mb-3">
|
||||
邀请奖励说明
|
||||
</h4>
|
||||
<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" />
|
||||
<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" />
|
||||
<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" />
|
||||
<span>邀请越多,奖励越丰厚,上不封顶</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</ion-content>
|
||||
</ion-page>
|
||||
</template>
|
||||
|
||||
<style lang='css' scoped>
|
||||
.card {
|
||||
background: linear-gradient(180deg, #ffeef1, #ffffff 15%);
|
||||
}
|
||||
.invite-btn {
|
||||
--background: white;
|
||||
--color: #c41e3a;
|
||||
--border-radius: 12px;
|
||||
--box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
height: 50px;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.invite-btn::part(native) {
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
--padding-start: 8px;
|
||||
--padding-end: 8px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.copy-link-btn {
|
||||
--background: #c41e3a;
|
||||
--background-activated: #8b1a2e;
|
||||
--border-radius: 8px;
|
||||
--padding-start: 12px;
|
||||
--padding-end: 12px;
|
||||
height: 36px;
|
||||
min-width: 36px;
|
||||
}
|
||||
|
||||
.download-qr-btn {
|
||||
--border-color: #c41e3a;
|
||||
--color: #c41e3a;
|
||||
--border-radius: 12px;
|
||||
--border-width: 2px;
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
height: 44px;
|
||||
text-transform: none;
|
||||
}
|
||||
|
||||
.download-qr-btn::part(native) {
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user