接口调试

This commit is contained in:
2025-12-30 01:25:08 -08:00
parent 11c05de565
commit de6dfb5e20
15 changed files with 468 additions and 85 deletions
+1 -1
View File
@@ -7,7 +7,7 @@ import ArrowIcon from './arrow-icon2.svg?component'
const faqList = ref([
{
id: 1,
question: '登公共 Apple ID 时,出现“双重验证”提示,且要求输入验证码怎么办?',
question: '登公共 Apple ID 时,出现“双重验证”提示,且要求输入验证码怎么办?',
answer:
'这是由于有其他用户没有按照教程操作,将公共 Apple ID 绑定手机号码,开启了双重验证所导致。\n\n解决办法:请您先清除浏览器缓存,再刷新本页面,获取新的公共 Apple ID,接着请按照教程一步一步操作。',
},
+1 -1
View File
@@ -52,7 +52,7 @@
</div>
<div v-show="activeIndex === 1">
<div class="pt-[34px] pb-[15px] text-center font-[900]">
海外 Apple ID 后再点击下方下载按钮
海外 Apple ID 后再点击下方下载按钮
</div>
</div>
<!-- tab2 -->
+62
View File
@@ -0,0 +1,62 @@
<template>
<Teleport to="body">
<Transition name="fade">
<div
v-if="visible"
class="!pointer-events-auto fixed inset-0 z-[100] flex items-center justify-center p-4"
>
<div
class="backdrop-blur-[2px z-[110]] absolute inset-0 bg-black/40"
@click.stop="hide"
></div>
<div
class="relative z-10 w-full max-w-[280px] rounded-[40px] border border-white/10 bg-[#999999] p-8 shadow-2xl"
@click.stop
>
<div class="space-y-2 text-black">
<h3 class="flex items-start text-lg font-black"><span class="mr-1">*</span>重要提示</h3>
<p class="text-[15px] leading-relaxed font-bold tracking-tight">
验证邮件已发送至邮箱如无法找到请检查垃圾邮件箱或营销邮件箱
</p>
</div>
</div>
</div>
</Transition>
</Teleport>
</template>
<script setup lang="ts">
import { ref, onBeforeUnmount } from 'vue'
const visible = ref(false)
const timer: ReturnType<typeof setTimeout> | null = null
const show = () => {
visible.value = true
}
const hide = () => {
console.log('hide')
visible.value = false
}
// 组件卸载前清除计时器防止内存泄漏
onBeforeUnmount(() => {
if (timer) clearTimeout(timer)
})
defineExpose({ show, hide })
</script>
<style scoped>
.fade-enter-active,
.fade-leave-active {
transition: all 0.3s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
transform: scale(0.95);
}
</style>
+34 -29
View File
@@ -1,31 +1,3 @@
<script setup lang="ts">
import { ref } from 'vue'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { toast } from 'vue-sonner'
const email = ref('')
const code = ref('')
const countdown = ref(0)
const handleGetCode = () => {
if (!email.value) {
toast('请输入邮箱')
return
}
// 模拟倒计时逻辑
countdown.value = 60
const timer = setInterval(() => {
countdown.value--
if (countdown.value <= 0) clearInterval(timer)
}, 1000)
}
const handleLogin = () => {
console.log('登录提交', { email: email.value, code: code.value })
}
</script>
<template>
<div class="flex flex-col gap-6 text-black">
<div class="overflow-hidden rounded-[20px] bg-[#78788029] px-4">
@@ -62,6 +34,7 @@ const handleLogin = () => {
<div class="flex gap-4 pt-2">
<Button
variant="secondary"
@click="emit('close')"
class="h-[48px] flex-1 cursor-pointer rounded-[25px] bg-[#D1D1D1] text-lg font-medium text-[#757575] hover:bg-[#C1C1C1]"
>
取消
@@ -70,12 +43,44 @@ const handleLogin = () => {
@click="handleLogin"
class="h-[48px] flex-1 cursor-pointer rounded-[25px] bg-[#A8FF53] text-lg font-medium text-black hover:bg-[#96E64A]"
>
/注册
/注册
</Button>
</div>
<CodeSentTip ref="CodeSentTipRef" />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { toast } from 'vue-sonner'
import CodeSentTip from '@/pages/Home/components/CodeSentTip.vue'
const CodeSentTipRef = ref(null)
const email = ref('')
const code = ref('')
const countdown = ref(0)
const emit = defineEmits(['close'])
const handleGetCode = () => {
if (!email.value) {
toast('请输入邮箱')
return
}
CodeSentTipRef.value.show()
// 模拟倒计时逻辑
countdown.value = 60
const timer = setInterval(() => {
countdown.value--
if (countdown.value <= 0) clearInterval(timer)
}, 1000)
}
const handleLogin = () => {
console.log('登录提交', { email: email.value, code: code.value })
}
</script>
<style scoped>
/* 移除 Shadcn Input 的默认边框阴影,保持纯净感 */
input:focus {
+3 -3
View File
@@ -7,12 +7,12 @@
:showCloseButton="false"
>
<DialogHeader class="py-2 pl-2">
<DialogTitle class="text-left">登Hi快帐户</DialogTitle>
<DialogTitle class="text-left">登Hi快帐户</DialogTitle>
<DialogDescription class="text-left text-base text-black">
如使用新邮箱地址,将自动为您创建Hi快帐户
</DialogDescription>
</DialogHeader>
<LoginForm />
<LoginForm @close="isOpen = false" />
</DialogContent>
</Dialog>
</template>
@@ -28,7 +28,7 @@ import {
} from '@/components/ui/dialog'
import LoginForm from './LoginForm.vue'
const isOpen = ref(true)
const isOpen = ref(false)
const setOpen = (value: boolean) => {
isOpen.value = value
+2 -2
View File
@@ -37,7 +37,7 @@
@click="openLoginModal"
class="flex h-[48px] items-center rounded-full bg-[#70C877] px-6 text-sm font-bold backdrop-blur-md transition hover:bg-white/30"
>
/ 注册
/ 注册
</button>
</header>
</div>
@@ -49,7 +49,7 @@
<div class="md:w-1/2">
<div class="mb-[20px] ml-[42px]">
<h2 class="mb-2 text-5xl font-black italic md:text-7xl">
<img :src="Logo" alt="Hi快VPN" class="h-[34px] w-auto" />
<Logo />
</h2>
<p class="font-600 text-3xl md:text-4xl">网在我在, 网快我快</p>
</div>
+31 -30
View File
@@ -1,33 +1,3 @@
<script setup lang="ts">
import { ref } from 'vue'
import PlanCard from '@/components/user-center/PlanCard.vue'
import DeviceList from '@/components/user-center/DeviceList.vue'
import PaymentMethod from '@/components/user-center/PaymentMethod.vue'
import { Button } from '@/components/ui/button'
// --- Mock Data ---
const devices = [
{ id: '1', name: 'XXX的 MacBook Pro 15-inch', type: 'desktop' as const, deviceId: '87654321' },
{ id: '2', name: 'XXX的 iPhone 15 Pro Max', type: 'mobile' as const, deviceId: '12345678' },
]
const plans = [
{ id: 'p1', days: 7, price: 2.79, dailyPrice: '0.39' },
{ id: 'p2', days: 30, price: 5.99, dailyPrice: '0.19', discount: '50% off' },
{ id: 'p3', days: 90, price: 12.99, dailyPrice: '0.14', discount: '64% off' },
{ id: 'p4', days: 365, price: 44.99, dailyPrice: '0.12', discount: '70% off', inverted: true },
]
// --- State ---
const selectedPlanId = ref('p2')
const selectedPayment = ref('alipay')
// --- Handlers ---
const handlePlanSelect = (id: string) => {
selectedPlanId.value = id
}
const currentPlanIndex = ref(3)
</script>
<template>
<!-- Main Neon Green Card -->
<div class="pt-[35px]">
@@ -67,6 +37,37 @@ const currentPlanIndex = ref(3)
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import PlanCard from '@/components/user-center/PlanCard.vue'
import DeviceList from '@/components/user-center/DeviceList.vue'
import PaymentMethod from '@/components/user-center/PaymentMethod.vue'
import { Button } from '@/components/ui/button'
import request from '@/utils/request'
// --- Mock Data ---
const devices = [
{ id: '1', name: 'XXX的 MacBook Pro 15-inch', type: 'desktop' as const, deviceId: '87654321' },
{ id: '2', name: 'XXX的 iPhone 15 Pro Max', type: 'mobile' as const, deviceId: '12345678' },
]
const plans = [
{ id: 'p1', days: 7, price: 2.79, dailyPrice: '0.39' },
{ id: 'p2', days: 30, price: 5.99, dailyPrice: '0.19', discount: '50% off' },
{ id: 'p3', days: 90, price: 12.99, dailyPrice: '0.14', discount: '64% off' },
{ id: 'p4', days: 365, price: 44.99, dailyPrice: '0.12', discount: '70% off', inverted: true },
]
// --- State ---
const selectedPlanId = ref('p2')
const selectedPayment = ref('alipay')
// --- Handlers ---
const handlePlanSelect = (id: string) => {
selectedPlanId.value = id
}
const currentPlanIndex = ref(3)
</script>
<style scoped>
/* Simplified layout font */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap');
+38 -16
View File
@@ -1,19 +1,3 @@
<script setup lang="ts">
import { ref } from 'vue'
import MobileLayout from './MobileLayout/index.vue'
import Logo from '@/pages/Home/logo.svg?component'
import MobileLogo from '@/pages/Home/mobile-logo.svg?component'
// --- State ---
const selectedPlanId = ref('p2')
const selectedPayment = ref('alipay')
// --- Handlers ---
const handlePlanSelect = (id: string) => {
selectedPlanId.value = id
}
</script>
<template>
<div class="min-h-screen bg-black text-black">
<!-- Full Width Header -->
@@ -41,6 +25,44 @@ const handlePlanSelect = (id: string) => {
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import MobileLayout from './MobileLayout/index.vue'
import Logo from '@/pages/Home/logo.svg?component'
import MobileLogo from '@/pages/Home/mobile-logo.svg?component'
import request from '@/utils/request'
// --- State ---
const selectedPlanId = ref('p2')
const selectedPayment = ref('alipay')
// --- Handlers ---
const handlePlanSelect = (id: string) => {
selectedPlanId.value = id
}
const devices = ref([])
function init() {
// 设备列表
request.get('/public/user/devices').then((res) => {
devices.value = res.list
})
// 订阅详情
request.get('/public/subscribe/list').then((res) => {
console.log(222, res.list)
})
// 获取支付方式
request.get('/public/payment/methods').then((res) => {
console.log(33, res)
})
// 订阅列表
request.get('/public/subscribe/list').then((res) => {
console.log(44, res)
})
}
init()
</script>
<style scoped>
/* Simplified layout font */
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700;900&display=swap');