add user invite
This commit is contained in:
@@ -0,0 +1,121 @@
|
||||
<template>
|
||||
<div class="poster-page">
|
||||
<section class="poster-wrap">
|
||||
<img v-if="posterImage" class="poster" :src="posterImage" alt="邀请注册海报" />
|
||||
<div v-else class="empty" v-text="message" />
|
||||
</section>
|
||||
<div v-if="posterImage" class="actions">
|
||||
<t-button class="bg-white" variant="outline" theme="primary" block @click="copyLink">复制链接</t-button>
|
||||
<t-button theme="primary" block :loading="isDownloading" @click="savePoster">保存海报</t-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Toast } from "tdesign-mobile-vue";
|
||||
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 registerLink = `${window.location.origin}/gao/invite/register?code=${encodeURIComponent(code)}`;
|
||||
const posterOptions = computed(() => ({
|
||||
code: registerLink,
|
||||
storeName,
|
||||
roleName,
|
||||
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");
|
||||
Toast.success("海报已保存");
|
||||
} catch {
|
||||
Toast.error("海报保存失败");
|
||||
} finally {
|
||||
isDownloading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
async function copyLink(): Promise<void> {
|
||||
try {
|
||||
await navigator.clipboard.writeText(registerLink);
|
||||
Toast.success("注册链接已复制");
|
||||
} catch {
|
||||
Toast.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;
|
||||
}
|
||||
}
|
||||
|
||||
.empty {
|
||||
padding: 5rem 1rem;
|
||||
color: var(--td-text-color-secondary);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.actions {
|
||||
gap: .75rem;
|
||||
left: 1rem;
|
||||
right: 1rem;
|
||||
bottom: calc(.75rem + env(safe-area-inset-bottom, 0));
|
||||
display: grid;
|
||||
position: fixed;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
:global(html.theme-dark) .poster-page {
|
||||
.poster-wrap {
|
||||
background: #0f172a;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user