Files
gao-customer-h5/src/pages/user/UserInvitePoster.vue
T
2026-08-24 16:16:43 +08:00

143 lines
3.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="poster-page">
<section class="poster-wrap" v-entrance-transition>
<img v-if="posterImage" class="poster" :src="posterImage" alt="邀请注册海报" />
<div v-else class="empty" v-text="message" />
</section>
<div
class="tips gray"
v-entrance-transition="70"
>微信内可能无法发起下载海报,可长按保存为图片、转发连接或使用默认浏览器打开</div>
<div v-if="posterImage" class="actions" v-entrance-transition="140">
<t-button
class="button bg-white"
variant="outline"
theme="primary"
block
@click="copyLink"
>复制链接</t-button>
<t-button
class="button"
theme="primary"
block
:loading="isDownloading"
@click="savePoster"
>下载海报</t-button>
</div>
</div>
</template>
<script setup lang="ts">
import { Message } from "@/utils/message";
import { createInvitePosterImage, downloadInvitePoster } from "@/utils/qrCode";
defineOptions({ name: "UserInvitePoster" });
const route = useRoute();
const posterImage = ref("");
const isDownloading = ref(false);
const message = ref("邀请海报参数无效");
const code = String(route.query.code || "");
const expireAt = Number(route.query.expireAt || 0);
const storeName = String(route.query.storeName || "");
const roleName = String(route.query.roleName || "");
const inviterName = String(route.query.inviterName || "未命名用户");
const registerLink = `${window.location.origin}/gao/invite/register?code=${encodeURIComponent(code)}`;
const posterOptions = computed(() => ({
code: registerLink,
storeName,
roleName,
inviterName,
expireAt
}));
function createPoster(): void {
if (!/^\w{10}$/.test(code) || !expireAt) {
return;
}
posterImage.value = createInvitePosterImage(posterOptions.value);
}
async function savePoster(): Promise<void> {
if (isDownloading.value) {
return;
}
isDownloading.value = true;
try {
await downloadInvitePoster(posterOptions.value, "GAO-邀请注册海报.png");
Message.success("海报已保存");
} catch {
Message.error("海报保存失败");
} finally {
isDownloading.value = false;
}
}
async function copyLink(): Promise<void> {
try {
await navigator.clipboard.writeText(registerLink);
Message.success("注册链接已复制");
} catch {
Message.error("复制失败,请检查浏览器权限");
}
}
onMounted(() => {
try {
createPoster();
} catch {
message.value = "海报生成失败,请重新生成";
}
});
</script>
<style scoped lang="less">
.poster-page {
gap: 1rem;
min-height: 100vh;
padding: calc(var(--app-nav-height) + 1rem) 1rem 6rem;
display: flex;
align-items: center;
flex-direction: column;
.poster-wrap {
width: min(100%, 28rem);
padding: .5rem;
background: #fff;
box-shadow: 0 .75rem 2rem rgba(15, 118, 110, .2);
border-radius: 1.25rem;
.poster {
width: 100%;
display: block;
border-radius: .875rem;
}
}
.tips {
font-size: .875rem;
text-indent: 2em;
}
.empty {
padding: 5rem 1rem;
color: var(--td-text-color-secondary);
text-align: center;
}
.actions {
--td-button-border-radius: 1rem;
gap: .75rem;
width: 100%;
display: flex;
}
}
:global(html.theme-dark) .poster-page {
.poster-wrap {
background: #0f172a;
}
}
</style>