|
|
@@ -1,11 +1,24 @@
|
|
|
<script setup lang="ts">
|
|
|
import { useUserStore } from "@/store/user";
|
|
|
-import { computed } from "vue";
|
|
|
+import { computed, ref } from "vue";
|
|
|
+import { upgradeGuest } from "@/services/api";
|
|
|
|
|
|
const userStore = useUserStore();
|
|
|
const isLoggedIn = computed(() => !!userStore.token);
|
|
|
+const isGuest = computed(() => {
|
|
|
+ return userStore.userInfo?.vipLevel === "guest";
|
|
|
+});
|
|
|
const emit = defineEmits(["show-login"]);
|
|
|
|
|
|
+const showUpgradeDialog = ref(false);
|
|
|
+const upgradeForm = ref({
|
|
|
+ name: null,
|
|
|
+ password: null,
|
|
|
+ email: undefined,
|
|
|
+ phone: undefined,
|
|
|
+});
|
|
|
+const isLoading = ref(false);
|
|
|
+
|
|
|
const handleLogout = () => {
|
|
|
userStore.logout();
|
|
|
};
|
|
|
@@ -13,6 +26,43 @@ const handleLogout = () => {
|
|
|
const showLoginDialog = () => {
|
|
|
emit("show-login");
|
|
|
};
|
|
|
+
|
|
|
+const handleUpgrade = async () => {
|
|
|
+ if (!upgradeForm.value.name || !upgradeForm.value.password) {
|
|
|
+ alert("请填写用户名和密码");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ isLoading.value = true;
|
|
|
+ try {
|
|
|
+ const response = await upgradeGuest(
|
|
|
+ userStore.userInfo.id,
|
|
|
+ upgradeForm.value.name,
|
|
|
+ upgradeForm.value.password,
|
|
|
+ upgradeForm.value.email || undefined,
|
|
|
+ upgradeForm.value.phone || undefined
|
|
|
+ );
|
|
|
+
|
|
|
+ // 更新用户信息
|
|
|
+ userStore.setUserInfo(response.user);
|
|
|
+ showUpgradeDialog.value = false;
|
|
|
+
|
|
|
+ // 重置表单
|
|
|
+ upgradeForm.value = {
|
|
|
+ name: null,
|
|
|
+ password: null,
|
|
|
+ email: undefined,
|
|
|
+ phone: undefined,
|
|
|
+ };
|
|
|
+
|
|
|
+ alert("升级成功!");
|
|
|
+ } catch (error) {
|
|
|
+ console.error("升级失败", error);
|
|
|
+ alert("升级失败,请重试");
|
|
|
+ } finally {
|
|
|
+ isLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
</script>
|
|
|
|
|
|
<template>
|
|
|
@@ -50,12 +100,22 @@ const showLoginDialog = () => {
|
|
|
{{ isLoggedIn ? userStore.userInfo?.name || "用户" : "点击登录账号" }}
|
|
|
</h2>
|
|
|
</div>
|
|
|
- <button
|
|
|
- v-if="isLoggedIn"
|
|
|
- class="px-3 py-1.5 rounded-lg bg-brand text-slate-900 text-sm font-medium"
|
|
|
- >
|
|
|
- 开通会员
|
|
|
- </button>
|
|
|
+ <div v-if="isLoggedIn" class="flex gap-2">
|
|
|
+ <button
|
|
|
+ v-if="isGuest"
|
|
|
+ @click="showUpgradeDialog = true"
|
|
|
+ class="px-3 py-1.5 rounded-lg bg-blue-500 text-white text-sm font-medium hover:bg-blue-600 transition"
|
|
|
+ >
|
|
|
+ 成为正式用户
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ class="px-3 py-1.5 rounded-lg bg-brand text-slate-900 text-sm font-medium"
|
|
|
+ :disabled="isGuest"
|
|
|
+ :class="{ 'opacity-50 cursor-not-allowed': isGuest }"
|
|
|
+ >
|
|
|
+ 开通会员
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
<button
|
|
|
v-else
|
|
|
@click="showLoginDialog"
|
|
|
@@ -100,6 +160,86 @@ const showLoginDialog = () => {
|
|
|
</svg>
|
|
|
</button>
|
|
|
</div>
|
|
|
+
|
|
|
+ <!-- 升级弹窗 -->
|
|
|
+ <div
|
|
|
+ v-if="showUpgradeDialog"
|
|
|
+ class="fixed inset-0 bg-black/50 flex items-center justify-center z-50"
|
|
|
+ @click.self="showUpgradeDialog = false"
|
|
|
+ >
|
|
|
+ <div class="bg-white rounded-2xl p-6 w-full max-w-md mx-4">
|
|
|
+ <h3 class="text-xl font-semibold text-gray-900 mb-4">成为正式用户</h3>
|
|
|
+
|
|
|
+ <form @submit.prevent="handleUpgrade" class="space-y-4">
|
|
|
+ <div>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">
|
|
|
+ 用户名 <span class="text-red-500">*</span>
|
|
|
+ </label>
|
|
|
+ <input
|
|
|
+ v-model="upgradeForm.name"
|
|
|
+ type="text"
|
|
|
+ required
|
|
|
+ class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
|
+ placeholder="请输入用户名"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">
|
|
|
+ 密码 <span class="text-red-500">*</span>
|
|
|
+ </label>
|
|
|
+ <input
|
|
|
+ v-model="upgradeForm.password"
|
|
|
+ type="password"
|
|
|
+ required
|
|
|
+ class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
|
+ placeholder="请输入密码"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">
|
|
|
+ 邮箱
|
|
|
+ </label>
|
|
|
+ <input
|
|
|
+ v-model="upgradeForm.email"
|
|
|
+ type="email"
|
|
|
+ class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
|
+ placeholder="请输入邮箱(可选)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div>
|
|
|
+ <label class="block text-sm font-medium text-gray-700 mb-1">
|
|
|
+ 手机号
|
|
|
+ </label>
|
|
|
+ <input
|
|
|
+ v-model="upgradeForm.phone"
|
|
|
+ type="tel"
|
|
|
+ class="w-full px-3 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
|
|
+ placeholder="请输入手机号(可选)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="flex gap-3 pt-4">
|
|
|
+ <button
|
|
|
+ type="button"
|
|
|
+ @click="showUpgradeDialog = false"
|
|
|
+ class="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition"
|
|
|
+ >
|
|
|
+ 取消
|
|
|
+ </button>
|
|
|
+ <button
|
|
|
+ type="submit"
|
|
|
+ :disabled="isLoading"
|
|
|
+ class="flex-1 px-4 py-2 bg-blue-500 text-white rounded-lg hover:bg-blue-600 transition disabled:opacity-50"
|
|
|
+ >
|
|
|
+ {{ isLoading ? "处理中..." : "确认升级" }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+ </form>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</section>
|
|
|
</template>
|
|
|
<style scoped>
|