接口调试用户信息
This commit is contained in:
parent
ced65527d5
commit
4392dd4a3e
@ -1,5 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<div class="grid min-h-[76px] grid-cols-2 gap-3">
|
||||||
|
<div
|
||||||
|
v-for="device in devices"
|
||||||
|
:key="device.id"
|
||||||
|
class="h-[76px] rounded-3xl border-2 p-4 text-[10px]"
|
||||||
|
>
|
||||||
|
<div class="flex items-center gap-3">
|
||||||
|
<component
|
||||||
|
:is="getDeviceTypeInfo(device.user_agent)?.iconComponent"
|
||||||
|
class="h-6 w-6 text-white"
|
||||||
|
/>
|
||||||
|
<div class="flex flex-col overflow-hidden">
|
||||||
|
<span class="text-white">设备: {{ getDeviceTypeInfo(device.user_agent)?.type }}</span>
|
||||||
|
<span class="font-mono text-[11px] tracking-tighter uppercase"
|
||||||
|
>SN: {{ device?.identifier?.slice(0, 4) }}{{ device.id }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Laptop, Smartphone } from 'lucide-vue-next'
|
import { Laptop, Smartphone, Tablet, Monitor, Cpu, HelpCircle } from 'lucide-vue-next'
|
||||||
|
|
||||||
interface Device {
|
interface Device {
|
||||||
id: string
|
id: string
|
||||||
@ -11,26 +34,39 @@ interface Device {
|
|||||||
defineProps<{
|
defineProps<{
|
||||||
devices: Device[]
|
devices: Device[]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
interface DeviceTypeInfo {
|
||||||
|
type: string
|
||||||
|
icon: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取设备类型和图标
|
||||||
|
* @param userAgent 浏览器代理字符串
|
||||||
|
*/
|
||||||
|
const getDeviceTypeInfo = (userAgent: string): DeviceTypeInfo => {
|
||||||
|
// 转换为小写以便进行不区分大小写的匹配
|
||||||
|
const ua = userAgent.toLowerCase()
|
||||||
|
|
||||||
|
if (ua.includes('ipad')) {
|
||||||
|
return { type: 'iPad', iconComponent: Tablet }
|
||||||
|
}
|
||||||
|
if (ua.includes('iphone') || ua.includes('ios')) {
|
||||||
|
return { type: 'iPhone', iconComponent: Smartphone }
|
||||||
|
}
|
||||||
|
if (ua.includes('android')) {
|
||||||
|
return { type: 'Android', iconComponent: Smartphone }
|
||||||
|
}
|
||||||
|
if (ua.includes('mac') || ua.includes('macos')) {
|
||||||
|
return { type: 'Mac', iconComponent: Laptop }
|
||||||
|
}
|
||||||
|
if (ua.includes('windows')) {
|
||||||
|
return { type: 'Windows', iconComponent: Monitor }
|
||||||
|
}
|
||||||
|
if (ua.includes('linux')) {
|
||||||
|
return { type: 'Linux', iconComponent: Cpu }
|
||||||
|
}
|
||||||
|
|
||||||
|
return { type: 'Unknown', iconComponent: HelpCircle }
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="flex items-center justify-center gap-3">
|
|
||||||
<div
|
|
||||||
v-for="device in devices"
|
|
||||||
:key="device.id"
|
|
||||||
class="h-[76px] rounded-3xl border-2 p-4 text-[10px]"
|
|
||||||
>
|
|
||||||
<div class="flex items-center gap-3">
|
|
||||||
<Smartphone v-if="device.type === 'mobile'" class="h-5 w-5 text-white" />
|
|
||||||
<Laptop v-else class="h-5 w-5 text-white" />
|
|
||||||
|
|
||||||
<div class="flex flex-col overflow-hidden">
|
|
||||||
<span class="text-white">设备: {{ device.name }}</span>
|
|
||||||
<span class="font-mono text-[11px] tracking-tighter uppercase"
|
|
||||||
>ID: {{ device.deviceId }}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|||||||
@ -1,22 +1,27 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { Button } from '@/components/ui/button'
|
import { Button } from '@/components/ui/button'
|
||||||
|
|
||||||
interface PaymentOption {
|
interface PaymentOption {
|
||||||
label: string
|
label: string
|
||||||
value: number
|
value: number | string
|
||||||
}
|
}
|
||||||
|
|
||||||
const list = ref<PaymentOption[]>([
|
const props = defineProps<{
|
||||||
{ label: '支付宝', value: 1 },
|
methods: any[]
|
||||||
{ label: '微信', value: 2 },
|
}>()
|
||||||
{ label: '国际银行卡', value: 3 },
|
|
||||||
])
|
const list = computed(() =>
|
||||||
|
props.methods.map((item) => ({
|
||||||
|
label: item.name,
|
||||||
|
value: item.id,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
|
||||||
// 当前选中的值,默认选中第一个
|
// 当前选中的值,默认选中第一个
|
||||||
const selectedValue = ref(1)
|
const selectedValue = ref<number | string>(props.methods[0]?.id || 1)
|
||||||
|
|
||||||
const handleSelect = (value: number) => {
|
const handleSelect = (value: number | string) => {
|
||||||
selectedValue.value = value
|
selectedValue.value = value
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -24,7 +24,7 @@
|
|||||||
]"
|
]"
|
||||||
class="absolute top-[20px] -right-[40px] h-[16px] w-[126px] origin-center rotate-45 bg-black text-center text-[14px] leading-[16px] font-[200] text-[#ADFF5B]"
|
class="absolute top-[20px] -right-[40px] h-[16px] w-[126px] origin-center rotate-45 bg-black text-center text-[14px] leading-[16px] font-[200] text-[#ADFF5B]"
|
||||||
>
|
>
|
||||||
111 off%
|
{{ plan.discount }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -4,18 +4,18 @@
|
|||||||
<div class="mb-3 ml-[31px] flex h-[60px] items-center gap-3">
|
<div class="mb-3 ml-[31px] flex h-[60px] items-center gap-3">
|
||||||
<img src="../avatar.png" class="size-[60px]" alt="" />
|
<img src="../avatar.png" class="size-[60px]" alt="" />
|
||||||
<div class="flex h-full flex-col justify-center text-white">
|
<div class="flex h-full flex-col justify-center text-white">
|
||||||
<div class="text-xl font-semibold">11emai</div>
|
<div class="text-xl font-semibold">{{ userInfo.email }}</div>
|
||||||
<div class="text-xs">到期时间: 122222</div>
|
<div class="text-xs">到期时间: {{ userInfo.expireDate }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-5 flex justify-between pr-[25px] pl-[21px] text-white">
|
<div class="mb-5 pr-[25px] pl-[21px] text-white">
|
||||||
<DeviceList :devices="devices" />
|
<DeviceList :devices="devices" />
|
||||||
</div>
|
</div>
|
||||||
<div class="overflow-hidden rounded-4xl bg-[#A8FF53]">
|
<div class="overflow-hidden rounded-4xl bg-[#A8FF53]">
|
||||||
<PlanCard :plans="plans" :currentPlanIndex="currentPlanIndex" />
|
<PlanCard :plans="plans" :currentPlanIndex="currentPlanIndex" @select="handlePlanSelect" />
|
||||||
<div class="pt-2">
|
<div class="pt-2">
|
||||||
<PaymentMethod />
|
<PaymentMethod :methods="payments" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -43,19 +43,13 @@ import PlanCard from '@/components/user-center/PlanCard.vue'
|
|||||||
import DeviceList from '@/components/user-center/DeviceList.vue'
|
import DeviceList from '@/components/user-center/DeviceList.vue'
|
||||||
import PaymentMethod from '@/components/user-center/PaymentMethod.vue'
|
import PaymentMethod from '@/components/user-center/PaymentMethod.vue'
|
||||||
import { Button } from '@/components/ui/button'
|
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 = [
|
const props = defineProps<{
|
||||||
{ id: 'p1', days: 7, price: 2.79, dailyPrice: '0.39' },
|
devices: any[]
|
||||||
{ id: 'p2', days: 30, price: 5.99, dailyPrice: '0.19', discount: '50% off' },
|
plans: any[]
|
||||||
{ id: 'p3', days: 90, price: 12.99, dailyPrice: '0.14', discount: '64% off' },
|
payments: any[]
|
||||||
{ id: 'p4', days: 365, price: 44.99, dailyPrice: '0.12', discount: '70% off', inverted: true },
|
userInfo: { email: string; expireDate: string }
|
||||||
]
|
}>()
|
||||||
|
|
||||||
// --- State ---
|
// --- State ---
|
||||||
const selectedPlanId = ref('p2')
|
const selectedPlanId = ref('p2')
|
||||||
|
|||||||
@ -20,7 +20,12 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- Main Neon Green Card -->
|
<!-- Main Neon Green Card -->
|
||||||
<div class="px-[18px]">
|
<div class="px-[18px]">
|
||||||
<MobileLayout />
|
<MobileLayout
|
||||||
|
:devices="devices"
|
||||||
|
:plans="plans"
|
||||||
|
:payments="payments"
|
||||||
|
:user-info="userSubInfo"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -36,28 +41,49 @@ import request from '@/utils/request'
|
|||||||
const selectedPlanId = ref('p2')
|
const selectedPlanId = ref('p2')
|
||||||
const selectedPayment = ref('alipay')
|
const selectedPayment = ref('alipay')
|
||||||
|
|
||||||
|
const devices = ref([])
|
||||||
|
const plans = ref([])
|
||||||
|
const payments = ref([])
|
||||||
|
const userSubInfo = ref({
|
||||||
|
email: '',
|
||||||
|
expireDate: '',
|
||||||
|
})
|
||||||
|
|
||||||
// --- Handlers ---
|
// --- Handlers ---
|
||||||
const handlePlanSelect = (id: string) => {
|
const handlePlanSelect = (id: string) => {
|
||||||
selectedPlanId.value = id
|
selectedPlanId.value = id
|
||||||
}
|
}
|
||||||
|
|
||||||
const devices = ref([])
|
|
||||||
function init() {
|
function init() {
|
||||||
// 设备列表
|
// 设备列表
|
||||||
request.get('/public/user/devices').then((res) => {
|
// request.get('/public/user/devices').then((res: any) => {
|
||||||
devices.value = res.list
|
// devices.value =
|
||||||
|
// res.list?.map((item: any) => ({
|
||||||
|
// id: item.id,
|
||||||
|
// name: item.user_agent || 'Unknown Device',
|
||||||
|
// type: item.user_agent?.toLowerCase().includes('android') ? 'mobile' : 'desktop',
|
||||||
|
// deviceId: item.id,
|
||||||
|
// })) || []
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 用户信息
|
||||||
|
request.get('/public/user/info').then((res: any) => {
|
||||||
|
const emailInfo = res.auth_methods?.find((item: any) => item.auth_type === 'email')
|
||||||
|
devices.value = res.user_devices
|
||||||
|
console.log(res.user_devices)
|
||||||
|
|
||||||
|
if (emailInfo) {
|
||||||
|
userSubInfo.value.email = emailInfo.auth_identifier
|
||||||
|
}
|
||||||
})
|
})
|
||||||
// 订阅详情
|
// 订阅详情
|
||||||
request.get('/public/subscribe/list').then((res) => {
|
request.get('/public/subscribe/list').then((res: any) => {
|
||||||
console.log(222, res.list)
|
plans.value = res.list
|
||||||
|
console.log(plans.value)
|
||||||
})
|
})
|
||||||
// 获取支付方式
|
// 获取支付方式
|
||||||
request.get('/public/payment/methods').then((res) => {
|
request.get('/public/payment/methods').then((res: any) => {
|
||||||
console.log(33, res)
|
payments.value = res.list || []
|
||||||
})
|
|
||||||
// 订阅列表
|
|
||||||
request.get('/public/subscribe/list').then((res) => {
|
|
||||||
console.log(44, res)
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
init()
|
init()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user