增加菜单栏帮助中心和登录页面相关协议的文档1.0版本 & allowedDevOrigins添加IP地址
This commit is contained in:
@@ -15,6 +15,7 @@ export default createMDX({
|
||||
output: 'standalone',
|
||||
allowedDevOrigins: [
|
||||
'192.168.3.42',
|
||||
'192.168.3.14',
|
||||
],
|
||||
images: {
|
||||
localPatterns: [
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
'use client'
|
||||
import Link from 'next/link'
|
||||
import Image, {StaticImageData} from 'next/image'
|
||||
import Wrap from '@/components/wrap'
|
||||
@@ -24,18 +25,18 @@ export default function HelpMenu() {
|
||||
icon={h02}
|
||||
title="使用教程"
|
||||
items={[
|
||||
{lead: '快速入手', href: '/help/tutorials/quick-start'},
|
||||
{lead: '代码下载', href: '#'},
|
||||
{lead: 'API文档', href: '#'},
|
||||
{lead: '官方教程', href: '/help/tutorials/official-tutorial/browser-proxy'},
|
||||
{lead: '客户端教程', href: '/help/tutorials/client-tutorial/ios-proxy'},
|
||||
{lead: '操作指南', href: '/help/tutorials/operation-guide/windows7-proxy'},
|
||||
]}
|
||||
/>
|
||||
<Column
|
||||
icon={h03}
|
||||
title="产品功能"
|
||||
items={[
|
||||
{lead: '常见问题', href: '/prodFeat'},
|
||||
{lead: '产品介绍', href: '#'},
|
||||
{lead: '行业资讯', href: '#'},
|
||||
{lead: '常见问题', href: '/help/features/faq/faq-general'},
|
||||
{lead: '产品介绍', href: '/help/features/product-intro/product-overview'},
|
||||
{lead: '新闻资讯', href: '/help/features/news/news-latest'},
|
||||
]}
|
||||
/>
|
||||
<Image src={banner} alt="banner" className="hidden lg:block"/>
|
||||
@@ -67,8 +68,8 @@ function Column(props: {
|
||||
href={item.href}
|
||||
className="px-4 py-2"
|
||||
onClick={() => {
|
||||
ctx.setMenu(false) // 点击时关闭菜单
|
||||
router.push(item.href) // 跳转页面
|
||||
ctx.setMenu(false)
|
||||
router.push(item.href)
|
||||
}}
|
||||
>
|
||||
{item.lead}
|
||||
|
||||
60
src/app/(home)/help/features/[section]/[key]/page.tsx
Normal file
60
src/app/(home)/help/features/[section]/[key]/page.tsx
Normal file
@@ -0,0 +1,60 @@
|
||||
import Wrap from '@/components/wrap'
|
||||
|
||||
interface Props {
|
||||
params: Promise<{section: string, key: string}>
|
||||
}
|
||||
|
||||
// 根据 key 返回对应的组件
|
||||
async function getContentComponent(key: string) {
|
||||
switch (key) {
|
||||
case 'faq-general':
|
||||
const {default: FaqGeneral} = await import('@/docs/faq-general.mdx')
|
||||
return FaqGeneral
|
||||
case 'product-overview':
|
||||
const {default: ProductOverview} = await import('@/docs/product-overview.mdx')
|
||||
return ProductOverview
|
||||
case 'news-latest':
|
||||
const {default: NewsLatest} = await import('@/docs/news-latest.mdx')
|
||||
return NewsLatest
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// 标题
|
||||
function getTitle(key: string) {
|
||||
const titleMap: Record<string, string> = {
|
||||
'faq-general': '常见问题总览',
|
||||
'faq-billing': '计费与套餐问题',
|
||||
'product-overview': '产品概述',
|
||||
'product-features': '产品功能',
|
||||
'news-latest': '最新动态',
|
||||
'news-announce': '公告',
|
||||
}
|
||||
return titleMap[key] || '功能'
|
||||
}
|
||||
|
||||
export default async function FeatureContentPage({params}: Props) {
|
||||
const {key} = await params
|
||||
|
||||
// 动态获取组件
|
||||
const Content = await getContentComponent(key)
|
||||
const title = getTitle(key)
|
||||
|
||||
return (
|
||||
<main>
|
||||
<Wrap className="flex flex-col">
|
||||
<div className="flex">
|
||||
{Content ? (
|
||||
<Content/>
|
||||
) : (
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold mb-4">{title}</h2>
|
||||
<p className="text-slate-600">此页面内容开发中...</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Wrap>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -1,63 +1,185 @@
|
||||
'use client'
|
||||
import React from 'react'
|
||||
|
||||
export type MenuItem = {key: string, label: string, desc?: string, icon?: string}
|
||||
export type Section = {title: string, items: MenuItem[]}
|
||||
|
||||
export const MENU: Section[] = [
|
||||
{
|
||||
title: '官网教程',
|
||||
items: [
|
||||
{key: 'browser-proxy', label: '浏览器设置代理教程'},
|
||||
{key: 'code-download', label: '代码下载'},
|
||||
{key: 'api-docs', label: 'API 文档'},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '客户端教程',
|
||||
items: [
|
||||
{key: 'client-install', label: '客户端安装与配置'},
|
||||
{key: 'client-usage', label: '客户端使用指南'},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '操作指南',
|
||||
items: [
|
||||
{key: 'faq', label: '常见问题', desc: '常见问题与解答'},
|
||||
{key: 'troubleshoot', label: '故障排查', desc: '排查与解决常见故障'},
|
||||
],
|
||||
},
|
||||
]
|
||||
import React, {useState, useMemo, useCallback, useEffect} from 'react'
|
||||
import Link from 'next/link'
|
||||
import {useParams, usePathname, useSearchParams} from 'next/navigation'
|
||||
import {ChevronRight} from 'lucide-react'
|
||||
|
||||
type Props = {
|
||||
collapsed?: boolean
|
||||
selected?: string
|
||||
onSelect?: (key: string) => void
|
||||
onToggle?: () => void
|
||||
}
|
||||
|
||||
export default function Sidebar({collapsed = false, selected, onSelect, onToggle}: Props) {
|
||||
const [expanded, setExpanded] = React.useState<Record<string, boolean>>(() => {
|
||||
const s: Record<string, boolean> = {}
|
||||
MENU.forEach((section, idx) => (s[section.title] = idx === 0))
|
||||
return s
|
||||
})
|
||||
// 菜单结构
|
||||
const MENU_CONFIG = {
|
||||
tutorials: [
|
||||
{
|
||||
title: '官网教程',
|
||||
sectionKey: 'official-tutorial',
|
||||
items: [
|
||||
{key: 'browser-proxy', label: '浏览器设置代理教程'},
|
||||
{key: 'package-operations', label: '套餐续费、合并、修改时效、补重操作'},
|
||||
{key: 'fixed-package', label: '长效固定套餐操作手册'},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '客户端教程',
|
||||
sectionKey: 'client-tutorial',
|
||||
items: [
|
||||
{key: 'ios-proxy', label: 'iOS设置代理教程'},
|
||||
{key: 'windows10-proxy', label: 'Windows10电脑设置代理教程'},
|
||||
{key: 'android-proxy', label: '安卓手机设置代理教程'},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '操作指南',
|
||||
sectionKey: 'operation-guide',
|
||||
items: [
|
||||
{key: 'windows7-proxy', label: 'Windows7电脑设置代理教程'},
|
||||
{key: 'mac-proxy', label: 'MAC设置代理教程'},
|
||||
{key: 'firefox-proxy', label: '火狐浏览器设置代理'},
|
||||
{key: 'socks5-usage', label: 'Socks5代理使用教程'},
|
||||
],
|
||||
},
|
||||
],
|
||||
features: [
|
||||
{
|
||||
title: '产品介绍',
|
||||
sectionKey: 'product-intro',
|
||||
items: [
|
||||
{key: 'product-overview', label: '产品概述'},
|
||||
{key: 'product-features', label: '产品功能'},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '常见问题',
|
||||
sectionKey: 'faq',
|
||||
items: [
|
||||
{key: 'faq-general', label: '常见问题总览'},
|
||||
{key: 'faq-billing', label: '计费与套餐问题'},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: '新闻资讯',
|
||||
sectionKey: 'news',
|
||||
items: [
|
||||
{key: 'news-latest', label: '最新动态'},
|
||||
{key: 'news-announce', label: '公告'},
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
export default function Sidebar({collapsed = false}: Props) {
|
||||
const params = useParams()
|
||||
const pathname = usePathname()
|
||||
|
||||
// 判断当前所处的 help 子模块
|
||||
const getCategory = useCallback(() => {
|
||||
if (!pathname) return 'tutorials'
|
||||
if (pathname.includes('/help/features')) return 'features'
|
||||
if (pathname.includes('/help/tutorials')) return 'tutorials'
|
||||
return 'tutorials'
|
||||
}, [pathname])
|
||||
|
||||
const category = getCategory()
|
||||
const MENU = category === 'features' ? MENU_CONFIG.features : MENU_CONFIG.tutorials
|
||||
|
||||
// 获取当前 sectionKey 和 itemKey
|
||||
const getCurrentKeys = useCallback(() => {
|
||||
const pathParts = pathname?.split('/') || []
|
||||
let sectionKey = ''
|
||||
let itemKey = ''
|
||||
|
||||
if (pathParts.length >= 4) {
|
||||
sectionKey = pathParts[3]
|
||||
}
|
||||
if (pathParts.length >= 5) {
|
||||
itemKey = pathParts[4]
|
||||
}
|
||||
|
||||
// 如果从 params 获取
|
||||
if (!sectionKey && params?.section) {
|
||||
sectionKey = String(params.section)
|
||||
}
|
||||
if (!itemKey && params?.key) {
|
||||
itemKey = String(params.key)
|
||||
}
|
||||
|
||||
return {sectionKey, itemKey}
|
||||
}, [pathname, params])
|
||||
|
||||
const {sectionKey: currentSectionKey, itemKey: currentItemKey} = getCurrentKeys()
|
||||
|
||||
const expandedSections = useMemo(() => {
|
||||
const newExpanded: Record<string, boolean> = {}
|
||||
const hasActiveSection = MENU.some(s => s.sectionKey === currentSectionKey)
|
||||
|
||||
MENU.forEach((section, index) => {
|
||||
if (section.sectionKey === currentSectionKey) {
|
||||
newExpanded[section.title] = true
|
||||
}
|
||||
else if (!hasActiveSection && index === 0) {
|
||||
newExpanded[section.title] = true
|
||||
}
|
||||
else {
|
||||
newExpanded[section.title] = false
|
||||
}
|
||||
})
|
||||
|
||||
return newExpanded
|
||||
}, [MENU, currentSectionKey])
|
||||
|
||||
// 使用 state 来跟踪用户的手动切换
|
||||
const [userToggles, setUserToggles] = useState<Record<string, boolean>>({})
|
||||
|
||||
// 合并自动展开和用户手动切换的状态
|
||||
const finalExpandedSections = useMemo(() => {
|
||||
const result = {...expandedSections}
|
||||
|
||||
Object.keys(userToggles).forEach((title) => {
|
||||
const section = MENU.find(s => s.title === title)
|
||||
if (section && section.sectionKey !== currentSectionKey) {
|
||||
result[title] = userToggles[title]
|
||||
}
|
||||
})
|
||||
|
||||
return result
|
||||
}, [expandedSections, userToggles, MENU, currentSectionKey])
|
||||
|
||||
const toggleSection = (title: string) => {
|
||||
setExpanded(prev => ({...prev, [title]: !prev[title]}))
|
||||
const section = MENU.find(s => s.title === title)
|
||||
if (!section) return
|
||||
if (section.sectionKey === currentSectionKey) {
|
||||
setUserToggles(prev => ({
|
||||
...prev,
|
||||
[title]: !finalExpandedSections[title],
|
||||
}))
|
||||
}
|
||||
else {
|
||||
setUserToggles(prev => ({
|
||||
...prev,
|
||||
[title]: !prev[title],
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
// 构建链接地址
|
||||
const getItemHref = useCallback((sectionKey: string, itemKey: string) => {
|
||||
return category === 'features'
|
||||
? `/help/features/${sectionKey}/${itemKey}`
|
||||
: `/help/tutorials/${sectionKey}/${itemKey}`
|
||||
}, [category])
|
||||
|
||||
return (
|
||||
<aside className={`bg-white rounded p-3 transition-all duration-200 flex-shrink-0 ${collapsed ? 'w-20' : 'w-72'}`}>
|
||||
<aside className={`bg-white border rounded p-3 transition-all duration-200 shrink-0 ${collapsed ? 'w-20' : 'w-72'}`}>
|
||||
<nav className="space-y-2">
|
||||
{MENU.map(section => (
|
||||
<div key={section.title}>
|
||||
<div
|
||||
onClick={() => toggleSection(section.title)}
|
||||
className={`flex items-center gap-2 cursor-pointer px-3 py-2 rounded-sm transition-colors ${expanded[section.title] && !collapsed ? 'bg-blue-50' : 'hover:bg-slate-50'}`}
|
||||
className={`flex items-center gap-2 cursor-pointer px-3 py-2 rounded-sm transition-colors ${finalExpandedSections[section.title] && !collapsed ? 'bg-blue-50' : 'hover:bg-slate-50'}`}
|
||||
>
|
||||
<div className={`w-4 flex items-center justify-center text-sm text-slate-400 transform transition-transform ${expanded[section.title] ? 'rotate-90' : ''}`}>
|
||||
▸
|
||||
<div className={`w-4 flex items-center justify-center text-sm text-slate-400 transform transition-transform ${finalExpandedSections[section.title] ? 'rotate-90' : ''}`}>
|
||||
<ChevronRight size={16}/>
|
||||
</div>
|
||||
|
||||
{!collapsed && (
|
||||
@@ -67,17 +189,22 @@ export default function Sidebar({collapsed = false, selected, onSelect, onToggle
|
||||
)}
|
||||
</div>
|
||||
|
||||
{expanded[section.title] && (
|
||||
{finalExpandedSections[section.title] && (
|
||||
<ul className={`mt-1 text-base ${collapsed ? 'hidden' : 'block'}`}>
|
||||
{section.items.map((item) => {
|
||||
const active = selected === item.key
|
||||
const isActive = currentItemKey === item.key
|
||||
const href = getItemHref(section.sectionKey, item.key)
|
||||
|
||||
return (
|
||||
<li
|
||||
key={item.key}
|
||||
onClick={() => onSelect?.(item.key)}
|
||||
className={`pl-8 py-2 text-base cursor-pointer transition-colors ${active ? 'text-blue-600 font-semibold' : 'text-slate-700 hover:text-slate-900'}`}
|
||||
>
|
||||
{item.label}
|
||||
<li key={item.key}>
|
||||
<Link
|
||||
href={href}
|
||||
className={`block pl-8 py-2 text-base cursor-pointer transition-colors ${
|
||||
isActive ? 'bg-blue-50 font-semibold' : 'text-slate-700 hover:text-slate-900 hover:bg-slate-50'
|
||||
}`}
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
</li>
|
||||
)
|
||||
})}
|
||||
|
||||
69
src/app/(home)/help/tutorials/[section]/[key]/page.tsx
Normal file
69
src/app/(home)/help/tutorials/[section]/[key]/page.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import Wrap from '@/components/wrap'
|
||||
|
||||
// 只导入真正需要的 MDX 文件(按需导入,避免一次性导入太多)
|
||||
interface Props {
|
||||
params: Promise<{section: string, key: string}>
|
||||
}
|
||||
|
||||
// 根据 key 返回对应的组件
|
||||
async function getContentComponent(key: string) {
|
||||
switch (key) {
|
||||
case 'browser-proxy':
|
||||
const {default: BrowserProxy} = await import('@/docs/browser-proxy.mdx')
|
||||
return BrowserProxy
|
||||
case 'package-operations':
|
||||
const {default: PackageOperations} = await import('@/docs/package-operations.mdx')
|
||||
return PackageOperations
|
||||
case 'ios-proxy':
|
||||
const {default: IosProxy} = await import('@/docs/ios-proxy.mdx')
|
||||
return IosProxy
|
||||
case 'windows7-proxy':
|
||||
const {default: Windows7Proxy} = await import('@/docs/windows7-proxy.mdx')
|
||||
return Windows7Proxy
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
// 标题
|
||||
function getTitle(key: string) {
|
||||
const titleMap: Record<string, string> = {
|
||||
'browser-proxy': '浏览器设置代理教程',
|
||||
'package-operations': '套餐续费、合并、修改时效、补重操作',
|
||||
'fixed-package': '长效固定套餐操作手册',
|
||||
'ios-proxy': 'iOS设置代理教程',
|
||||
'windows10-proxy': 'Windows10电脑设置代理教程',
|
||||
'android-proxy': '安卓手机设置代理教程',
|
||||
'windows7-proxy': 'Windows7电脑设置代理教程',
|
||||
'mac-proxy': 'MAC设置代理教程',
|
||||
'firefox-proxy': '火狐浏览器怎么设置HTTP/Socks5代理服务器',
|
||||
'socks5-usage': '怎么使用Socks5代理IP上网',
|
||||
'http-notes': '使用HTTP代理注意的点',
|
||||
}
|
||||
return titleMap[key] || '教程'
|
||||
}
|
||||
|
||||
export default async function TutorialContentPage({params}: Props) {
|
||||
const {key} = await params
|
||||
|
||||
// 动态获取组件
|
||||
const Content = await getContentComponent(key)
|
||||
const title = getTitle(key)
|
||||
|
||||
return (
|
||||
<main>
|
||||
<Wrap className="flex flex-col">
|
||||
<div className="flex">
|
||||
{Content ? (
|
||||
<Content/>
|
||||
) : (
|
||||
<div>
|
||||
<h2 className="text-2xl font-semibold mb-4">{title}</h2>
|
||||
<p className="text-slate-600">此页面内容开发中...</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Wrap>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
'use client'
|
||||
import QuickStart from '@/components/docs/quick-start.mdx'
|
||||
|
||||
export default function CollectPage() {
|
||||
return (
|
||||
<QuickStart/>
|
||||
)
|
||||
}
|
||||
8
src/app/privacyPolicy/page.tsx
Normal file
8
src/app/privacyPolicy/page.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
'use client'
|
||||
import PrivacyPolicy from '@/docs/privacyPolicy.mdx'
|
||||
|
||||
export default function CollectPage() {
|
||||
return (
|
||||
<PrivacyPolicy/>
|
||||
)
|
||||
}
|
||||
8
src/app/userAgreement/page.tsx
Normal file
8
src/app/userAgreement/page.tsx
Normal file
@@ -0,0 +1,8 @@
|
||||
'use client'
|
||||
import UserAgreement from '@/docs/userAgreement.mdx'
|
||||
|
||||
export default function CollectPage() {
|
||||
return (
|
||||
<UserAgreement/>
|
||||
)
|
||||
}
|
||||
@@ -18,7 +18,7 @@ import {toast} from 'sonner'
|
||||
import {merge} from '@/lib/utils'
|
||||
import {Combobox} from '@/components/ui/combobox'
|
||||
import cities from './_assets/cities.json'
|
||||
import ExtractDocs from '@/components/docs/extract.mdx'
|
||||
import ExtractDocs from '@/docs/extract.mdx'
|
||||
import Link from 'next/link'
|
||||
import {useProfileStore} from '@/components/stores-provider'
|
||||
|
||||
@@ -71,14 +71,16 @@ export default function Extract(props: ExtractProps) {
|
||||
)}
|
||||
>
|
||||
<CardSection>
|
||||
<Alert variant="warn" className="flex items-center">
|
||||
<CircleAlert/>
|
||||
<AlertTitle className="flex">提取IP前需要将本机IP添加到白名单后才可使用</AlertTitle>
|
||||
<Alert variant="warn" className="flex items-center justify-between">
|
||||
<span className="flex items-center gap-2">
|
||||
<CircleAlert/>
|
||||
<AlertTitle className="flex text-gray-900">提取IP前需要将本机IP添加到白名单后才可使用</AlertTitle>
|
||||
</span>
|
||||
<Link
|
||||
href="/admin/whitelist"
|
||||
className="flex-none text-blue-600 hover:text-blue-800 hover:underline font-medium ml-2 flex gap-0.5 items-center"
|
||||
className="flex-none text-orange-600 font-medium ml-2 flex gap-0.5 items-center"
|
||||
>
|
||||
<span>去添加</span>
|
||||
<span>添加白名单</span>
|
||||
<ArrowRight className="size-4"/>
|
||||
</Link>
|
||||
</Alert>
|
||||
@@ -335,6 +337,8 @@ function SelectResource() {
|
||||
setStatus('load')
|
||||
try {
|
||||
const resp = await allResource()
|
||||
console.log(resp, '套餐管理resprespresp')
|
||||
|
||||
if (!resp.success) {
|
||||
console.log(11111)
|
||||
throw new Error('获取套餐失败,请稍后再试')
|
||||
@@ -392,12 +396,15 @@ function SelectResource() {
|
||||
<Timer size={20}/>
|
||||
<span>{name(resource)}</span>
|
||||
</div>
|
||||
<div className="flex text-xs text-weak">
|
||||
<span>{resource.resource_no}</span>
|
||||
</div>
|
||||
<div className="flex justify-between gap-2 text-xs text-weak">
|
||||
<span>
|
||||
到期时间:
|
||||
{format(resource.short.expire, 'yyyy-MM-dd HH:mm')}
|
||||
{format(resource.short.expire_at, 'yyyy-MM-dd HH:mm')}
|
||||
</span>
|
||||
<span>{intlFormatDistance(resource.short.expire, new Date())}</span>
|
||||
<span>{intlFormatDistance(resource.short.expire_at, new Date())}</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@@ -407,6 +414,9 @@ function SelectResource() {
|
||||
<Box size={20}/>
|
||||
<span>{name(resource)}</span>
|
||||
</div>
|
||||
<div className="flex text-xs text-weak">
|
||||
<span>{resource.resource_no}</span>
|
||||
</div>
|
||||
<div className="flex justify-between gap-2 text-xs text-weak">
|
||||
<span>
|
||||
提取数量:
|
||||
@@ -428,12 +438,15 @@ function SelectResource() {
|
||||
<Timer size={20}/>
|
||||
<span>{name(resource)}</span>
|
||||
</div>
|
||||
<div className="flex text-xs text-weak">
|
||||
<span>{resource.resource_no}</span>
|
||||
</div>
|
||||
<div className="flex justify-between gap-2 text-xs text-weak">
|
||||
<span>
|
||||
到期时间:
|
||||
{format(resource.long.expire, 'yyyy-MM-dd HH:mm')}
|
||||
{format(resource.long.expire_at, 'yyyy-MM-dd HH:mm')}
|
||||
</span>
|
||||
<span>{intlFormatDistance(resource.long.expire, new Date())}</span>
|
||||
<span>{intlFormatDistance(resource.long.expire_at, new Date())}</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
@@ -443,6 +456,9 @@ function SelectResource() {
|
||||
<Box size={20}/>
|
||||
<span>{name(resource)}</span>
|
||||
</div>
|
||||
<div className="flex text-xs text-weak">
|
||||
<span>{resource.resource_no}</span>
|
||||
</div>
|
||||
<div className="flex justify-between gap-2 text-xs text-weak">
|
||||
<span>
|
||||
提取数量:
|
||||
|
||||
@@ -29,12 +29,14 @@ export default function UserCenter(props: UserCenterProps) {
|
||||
const pathname = usePathname()
|
||||
const isAdminPage = pathname.startsWith('/admin') // 判断是否在后台页面
|
||||
const displayName = () => {
|
||||
if (props.profile.username) return props.profile.username // 优先显示用户名
|
||||
if (props.profile.phone) {
|
||||
const phone = props.profile.phone
|
||||
return `${phone.substring(0, 3)}****${phone.substring(7)}`
|
||||
const {username, email, phone} = props.profile
|
||||
|
||||
switch (true) {
|
||||
case !!username: return username
|
||||
case !!phone: return `${phone.substring(0, 3)}****${phone.substring(7)}`
|
||||
case !!email: return email
|
||||
default: return null
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const handleAvatarClick = () => {
|
||||
@@ -55,22 +57,14 @@ export default function UserCenter(props: UserCenterProps) {
|
||||
<AvatarImage src={props.profile.avatar} alt="avatar"/>
|
||||
<AvatarFallback className="bg-primary-muted"><UserIcon/></AvatarFallback>
|
||||
</Avatar>
|
||||
{/* 根据是否在后台页面显示不同内容 */}
|
||||
{isAdminPage ? (
|
||||
<span>{displayName() || '用户'}</span> // 后台显示姓名/脱敏手机号/默认"用户"
|
||||
<span>{displayName() || '用户'}</span>
|
||||
) : (
|
||||
<span>进入控制台</span> // 前台显示"进入控制台"
|
||||
<span>进入控制台</span>
|
||||
)}
|
||||
</Button>
|
||||
</HoverCardTrigger>
|
||||
<HoverCardContent className="w-36 p-1" align="end">
|
||||
{/* <Button
|
||||
theme="ghost"
|
||||
className="w-full justify-start text-sm h-9 px-3"
|
||||
onClick={() => router.push('/admin/profile')}>
|
||||
<UserPenIcon/>
|
||||
个人中心
|
||||
</Button> */}
|
||||
<Button
|
||||
theme="ghost"
|
||||
color="fail"
|
||||
|
||||
46
src/components/ui/badge.tsx
Normal file
46
src/components/ui/badge.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import * as React from 'react'
|
||||
import {Slot} from '@radix-ui/react-slot'
|
||||
import {cva, type VariantProps} from 'class-variance-authority'
|
||||
|
||||
import {merge} from '@/lib/utils'
|
||||
|
||||
const badgeVariants = cva(
|
||||
'inline-flex items-center justify-center rounded-full border px-2 py-0.5 text-xs font-medium w-fit whitespace-nowrap shrink-0 [&>svg]:size-3 gap-1 [&>svg]:pointer-events-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive transition-[color,box-shadow] overflow-hidden',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
'border-transparent bg-primary text-primary-foreground [a&]:hover:bg-primary/90',
|
||||
secondary:
|
||||
'border-transparent bg-secondary text-secondary-foreground [a&]:hover:bg-secondary/90',
|
||||
destructive:
|
||||
'border-transparent bg-destructive text-white [a&]:hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60',
|
||||
outline:
|
||||
'text-foreground [a&]:hover:bg-accent [a&]:hover:text-accent-foreground',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: 'default',
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
function Badge({
|
||||
className,
|
||||
variant,
|
||||
asChild = false,
|
||||
...props
|
||||
}: React.ComponentProps<'span'> &
|
||||
VariantProps<typeof badgeVariants> & {asChild?: boolean}) {
|
||||
const Comp = asChild ? Slot : 'span'
|
||||
|
||||
return (
|
||||
<Comp
|
||||
data-slot="badge"
|
||||
className={merge(badgeVariants({variant}), className)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export {Badge, badgeVariants}
|
||||
4
src/docs/android-proxy.mdx
Normal file
4
src/docs/android-proxy.mdx
Normal file
@@ -0,0 +1,4 @@
|
||||
# 安卓手机设置代理教程
|
||||
|
||||
在安卓设备上代理一般通过 Wi‑Fi 配置或使用支持代理的客户端 App。
|
||||
- Wi‑Fi → 长按网络 → 修改网络 → 高级选项 → 代理
|
||||
10
src/docs/browser-proxy.mdx
Normal file
10
src/docs/browser-proxy.mdx
Normal file
@@ -0,0 +1,10 @@
|
||||
# 浏览器设置代理教程
|
||||
|
||||
本指南演示如何在常见浏览器中设置 HTTP/Socks5 代理。
|
||||
|
||||
## Chrome / Edge
|
||||
1. 打开设置 → 系统 → 打开代理设置
|
||||
2. 按照运营商提供的代理地址和端口填写
|
||||
|
||||
## 注意
|
||||
请确保代理地址与端口正确,并启用认证(如需要)。
|
||||
3
src/docs/faq-billing.mdx
Normal file
3
src/docs/faq-billing.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 计费与套餐问题
|
||||
|
||||
计费相关常见问题(占位)。
|
||||
3
src/docs/faq-general.mdx
Normal file
3
src/docs/faq-general.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 常见问题(总览)
|
||||
|
||||
常见问题汇总(占位)。
|
||||
3
src/docs/firefox-proxy.mdx
Normal file
3
src/docs/firefox-proxy.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# Firefox 设置 HTTP/Socks5 代理
|
||||
|
||||
Firefox → 选项 → 网络设置 → 手动代理配置,填写地址/端口。
|
||||
7
src/docs/fixed-package.mdx
Normal file
7
src/docs/fixed-package.mdx
Normal file
@@ -0,0 +1,7 @@
|
||||
# 长效固定套餐操作手册
|
||||
|
||||
本页介绍长效固定套餐的购买、续费与管理。
|
||||
|
||||
- 购买流程
|
||||
- 配置说明
|
||||
- 常见问题
|
||||
5
src/docs/http-notes.mdx
Normal file
5
src/docs/http-notes.mdx
Normal file
@@ -0,0 +1,5 @@
|
||||
# 使用 HTTP 代理注意事项
|
||||
|
||||
- 注意隐私与安全
|
||||
- 检查代理是否支持 HTTPS
|
||||
- 避免在不受信任网络输入敏感信息
|
||||
6
src/docs/ios-proxy.mdx
Normal file
6
src/docs/ios-proxy.mdx
Normal file
@@ -0,0 +1,6 @@
|
||||
# iOS 设置代理教程
|
||||
|
||||
指导在 iPhone / iPad 上设置 HTTP/Socks5 代理的步骤。
|
||||
|
||||
1. 设置 → Wi-Fi → 点击当前网络 → 配置代理
|
||||
2. 填写服务器地址与端口,保存
|
||||
3
src/docs/mac-proxy.mdx
Normal file
3
src/docs/mac-proxy.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# macOS 设置代理教程
|
||||
|
||||
系统偏好设置 → 网络 → 高级 → 代理,按需选择 HTTP/SOCKS 并填写地址。
|
||||
3
src/docs/news-announce.mdx
Normal file
3
src/docs/news-announce.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 公告
|
||||
|
||||
公告占位页。
|
||||
3
src/docs/news-latest.mdx
Normal file
3
src/docs/news-latest.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 最新动态
|
||||
|
||||
新闻资讯占位页。
|
||||
3
src/docs/online-ip-proxy.mdx
Normal file
3
src/docs/online-ip-proxy.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 在线 IP 代理地址
|
||||
|
||||
如何获取在线 IP 代理地址并在客户端或浏览器中配置和测试。
|
||||
7
src/docs/package-operations.mdx
Normal file
7
src/docs/package-operations.mdx
Normal file
@@ -0,0 +1,7 @@
|
||||
# 套餐续费 / 合并 / 修改时效 / 补重 操作
|
||||
|
||||
说明如何在控制台进行套餐续费、合并以及调整时效等操作。
|
||||
|
||||
- 续费:进入订单页面 → 选择续费
|
||||
- 合并:在套餐管理选择合并操作
|
||||
- 补重:联系客服或使用补重入口
|
||||
166
src/docs/privacyPolicy.mdx
Normal file
166
src/docs/privacyPolicy.mdx
Normal file
@@ -0,0 +1,166 @@
|
||||
# 隐私政策
|
||||
神龙HTTP(以下或简称“我们”)尊重并保护用户信息,并将以高度的责任感和谨慎的态度对待这些信息。当您使用神龙HTTP提供的代理服务时,我们将根据本隐私政策来收集、处理及分享您的信息。我们希望通过本隐私政策向您清晰地说明我们如何处理您的信息。因此,我们建议您完整阅读本隐私政策,以便了解如何保护您的隐私权。如果您有任何疑问、意见或建议,可以通过神龙HTTP提供的联系方式与我们联系。本政策将帮助您了解以下内容:
|
||||
|
||||
一、适用范围
|
||||
|
||||
1.1 本隐私政策适用于神龙HTTP网站提供的所有服务。服务包括提供页面浏览、网站登录服务,以及通过神龙HTTP网站提供的网络服务。
|
||||
|
||||
1.2 本隐私政策不适用于其他第三方提供的服务。
|
||||
|
||||
1.3 特别说明,如果您使用神龙HTTP的网络服务为您的用户提供服务,您的业务数据归您所有,您应当与您的用户另行约定隐私政策。
|
||||
|
||||
二、用户信息的收集和使用
|
||||
|
||||
2.1 协助您成为我们的会员
|
||||
|
||||
2.1.1 当您在神龙HTTP网站创建账户时,您需要选择会员身份类型(个人、企业),并向我们提供会员名、单位名称及联系人姓名(用于账户实名认证及开票抬头)、设置并确认您的登录密码、可用电子邮箱、所在区域(国家、省份、城市),以及您在中国境内的手机号码。您提供的手机号码将用于注册、登录、绑定账户、找回密码,并作为您与神龙HTTP联系的方式之一,接收相关业务通知或进行业务沟通。
|
||||
|
||||
2.1.2 如果您仅需使用浏览、搜索等基本服务,您无需注册成为我们的会员及提供上述信息。
|
||||
|
||||
2.2 提供网络服务时您向我们提供的信息包括:
|
||||
|
||||
2.2.1 根据中国法律,在使用特定网络服务时,您需要通过账号提供真实身份信息。注册账户后,请根据账户类型(个人/企业),完成相应的实名操作。
|
||||
|
||||
2.2.2 在您使用服务过程中,我们会根据您在注册、登录账号及使用产品时授予的权限,接收并记录您所使用的设备相关信息(如设备型号、操作系统版本、浏览器cookies、唯一设备标识符等软硬件特征信息)、设备所在位置相关信息(如IP地址、MAC地址、GPS位置以及能够提供相关信息的Wi-Fi接入点、蓝牙和基站等传感器信息)。我们可能会将这些信息与您的账户信息关联,以便在不同设备上为您提供一致的服务。
|
||||
|
||||
2.2.3 日志信息:当您使用我们的网站或代理IP服务时,我们会自动收集您对我们服务的详细使用情况,作为有关网络日志保存(例如:您进入神龙HTTP站的搜索查询内容、登录账号、IP地址、浏览器类型、电信运营商、使用的语言、访问日期及代理IP使用中的详细日志信息等)。
|
||||
|
||||
2.2.4 请注意,单独的设备信息、日志信息等是无法识别特定自然人身份的信息。如果我们将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。
|
||||
|
||||
2.2.5 用户账户的支持信息:基于您使用神龙HTTP服务而产生的咨询记录、保障记录和针对用户故障的排障过程(如通信或通话记录),我们将通过记录、分析这些信息以便更及时响应您的帮助请求,以及用于改进服务。
|
||||
|
||||
2.3 我们出于如下目的使用您提交及我们收集的用户信息:
|
||||
|
||||
2.3.1 为了向您提供服务(如实名认证信息、用于接收验证码的手机号,是继续获得服务的前提);
|
||||
|
||||
2.3.2 为了维护、改进服务(如您提交的业务联系人手机等用来接收业务通知和进行业务沟通);
|
||||
|
||||
2.3.3 在法律法规允许的前提下,向您推荐产品;
|
||||
|
||||
2.3.4 为提高您使用我们及我们关联公司、合作伙伴提供服务的安全性,保护您或其他用户或公众的人身财产安全免遭侵害,更好地预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络侵入等安全风险,更准确地识别违反法律法规或神龙HTTP相关协议、规则的情况,我们可能使用您的会员信息、并整合设备信息、有关网络日志以及我们关联公司、合作伙伴分享的信息,来进行判断账户及交易风险、进行身份验证、安全事件的检测及防范,并依法采取必要的记录、审计、分析、处置措施;
|
||||
|
||||
2.3.5 如超出收集用户信息时所声明的目的或超出具有直接或合理关联的范围后使用用户信息前,我们会再次向您告知并征得您的明确同意。
|
||||
|
||||
2.4 在您与我们及我们关联公司、合作伙伴之间的服务终止后,我们将停止对您个人信息的收集和使用。
|
||||
|
||||
三、用户信息的共享、转让和公开披露
|
||||
|
||||
3.1 共享
|
||||
|
||||
我们不会与其他组织和个人共享您的用户信息,但以下情况除外:
|
||||
|
||||
3.1.1 在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的用户信息;
|
||||
|
||||
3.1.2 在法定情形下的共享:我们可能会根据法律法规规定、诉讼、仲裁解决需要,或按行政、司法机关依法提出的要求,对外共享您的用户信息;
|
||||
|
||||
3.1.3 为了促成交易或协助解决争议,某些情况下只有共享您的用户信息,才能促成交易或处理您与他人的纠纷或争议,例如,在神龙HTTP上创建的某一交易中,如交易任何一方履行或部分履行了交易义务并提出信息披露请求的,神龙HTTP有权决定向该用户提供其交易对方的联络方式等必要信息,以促成交易的完成;
|
||||
|
||||
3.2 转让
|
||||
|
||||
我们不会将您的用户信息转让给任何公司、组织和个人,但以下情况除外:
|
||||
|
||||
3.2.1 在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的用户信息;
|
||||
|
||||
3.2.2 在我们与其他法律主体者发生合并、收购或破产清算情形,或其他涉及合并、收购或破产清算情形时,如涉及到用户信息转让,我们会要求新的持有您用户信息的公司、组织继续受本政策的约束,否则我们将要求该公司、组织和个人重新向您征求授权同意。
|
||||
|
||||
3.3 公开披露
|
||||
|
||||
我们仅会在以下情况下,公开披露您的用户信息:
|
||||
|
||||
3.3.1 获得您明确同意或基于您的主动选择,我们可能会公开披露您的用户信息;
|
||||
|
||||
3.3.2 或为保护神龙HTTP平台及其关联公司用户或公众的人身财产安全免遭侵害,我们可能依据适用的法律或神龙HTTP平台相关协议、规则披露关于您的用户信息。
|
||||
|
||||
3.4 共享、转让、公开披露用户信息时事先征得授权同意的例外
|
||||
|
||||
以下情形中,共享、转让、公开披露您的用户信息无需事先征得您的授权同意:
|
||||
|
||||
3.4.1 与国家安全、国防安全有关的;
|
||||
|
||||
3.4.2 与公共安全、公共卫生、重大公共利益有关的;
|
||||
|
||||
3.4.3 与犯罪侦查、起诉、审判和判决执行等有关的;
|
||||
|
||||
3.4.4 出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;
|
||||
|
||||
3.4.5 您自行向社会公众公开的个人信息;
|
||||
|
||||
3.4.6 从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
|
||||
|
||||
四、用户业务数据和公开信息
|
||||
|
||||
4.1 用户业务数据
|
||||
|
||||
4.1.1 您通过神龙HTTP提供的代理IP服务,从事加工、存储、上传、下载、分发以及通过其他方式处理的数据,均为您的用户业务数据,您完全拥有您的用户业务数据。作为代理IP服务提供商,我们只会严格执行您的指示处理您的业务数据,除按与您协商一致或执行明确的法律法规要求外,我们不会对您的业务数据进行任何非授权的使用或披露。
|
||||
|
||||
4.1.2 您应对您的用户业务数据来源及内容负责,我们提醒您谨慎判断数据来源及内容的合法性。因您的用户业务数据内容违反法律法规、部门规章或国家政策而造成的全部结果及责任均由您自行承担。
|
||||
|
||||
4.2 公开信息
|
||||
|
||||
4.2.1 公开信息是指您公开分享的任何信息,任何人都可以在使用和未使用神龙HTTP网站服务期间查看或访问这些信息。
|
||||
|
||||
4.2.2 在使用神龙HTTP网站时,如您发现自己的个人信息泄露,尤其是您的账户或密码发生泄露,请您立即联络神龙HTTP客服,以便我们采取相应措施。
|
||||
|
||||
五、用户信息的管理
|
||||
|
||||
5.1 您可以登录神龙HTTP网站查看您填写提交的基本业务信息(基本资料)和联系人等信息。
|
||||
|
||||
5.2 您在神龙HTTP注册账号并完成实名认证以后,为保障您在平台的合法权益,我们将不支持任何形式变更实名认证的操作,充分有效保障账户的安全与一致性。
|
||||
|
||||
5.3 在以下情形中,您可以向我们提出删除用户信息的请求:
|
||||
|
||||
5.3.1 如果我们处理用户信息的行为违反法律法规;
|
||||
|
||||
5.3.2 如果我们收集、使用您的用户信息,却未征得您的明确同意;
|
||||
|
||||
5.3.3 如果我们处理个人信息的行为严重违反了与您的约定。
|
||||
|
||||
为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。
|
||||
|
||||
六、Cookie 和同类技术的使用
|
||||
|
||||
6.1 为确保网站正常运转、为您获得更轻松的访问体验、向您推荐您可能感兴趣的内容,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。神龙HTTP只能读取神龙HTTP提供的cookies。
|
||||
|
||||
七、用户信息的安全
|
||||
|
||||
7.1 我们非常重视您的信息安全。我们努力采取各种合理的物理、电子和管理方面的安全措施来保护您的用户信息。防止用户信息遭到未经授权访问、公开披露、使用、修改、损坏或丢失。我们会使用加密技术提高用户信息的安全性;我们会使用受信赖的保护机制防止用户信息遭到恶意攻击;我们会部署访问控制机制,尽力确保只有授权人员才可访问用户信息;
|
||||
|
||||
7.2 我们会采取合理可行的措施,尽力避免收集无关的用户信息。我们只会在达成本政策所述目的所需的期限内保留您的用户信息,除非需要延长保留期或受到法律的允许。超出上述用户信息保存期限后,我们会对您的个人信息进行删除或匿名化处理。
|
||||
|
||||
7.3 请使用复杂密码,协助我们保证您的账号安全。我们会尽力保障您发送给我们的任何信息的安全性。如果我们的物理、技术或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
|
||||
|
||||
7.4 在不幸发生用户信息安全事件(泄露、丢失等)后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们会及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知用户信息主体时,我们会采取合理、有效的方式发布公告。
|
||||
|
||||
7.5 同时,我们还将按照监管部门要求,上报用户信息安全事件的处置情况。
|
||||
|
||||
7.6 我们将收集到的您的用户信息存放在中华人民共和国境内,如在符合适用法律规定的情形下因业务需要向境外传输个人信息的,我们会事先征得您的同意,并向您告知用户信息出境的目的、接收方、安全保障措施、安全风险等情况。
|
||||
|
||||
7.7 如出现神龙HTTP产品和服务停止运营的情形,我们会采取合理措施保护您用户信息安全,包括及时停止继续收集用户信息的活动;停止运营的通知将以逐一送达或公告的形式通知用户;并对所持有的个人信息进行删除或匿名化处理等。
|
||||
|
||||
八、未成年人用户信息的特别约定
|
||||
|
||||
8.1 我们主要面向成人提供产品和服务。如您为未成年人,我们要求您请您的父母或监护人仔细阅读本隐私权政策,并在征得您的父母或监护人同意的前提下使用我们的服务或向我们提供信息。
|
||||
|
||||
8.2 对于经父母或监护人同意使用我们的产品或服务而收集未成年人个人信息的情况,我们只会在法律法规允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。
|
||||
|
||||
九、隐私权政策的更新
|
||||
|
||||
9.1 我们的隐私权政策可能会修订。
|
||||
|
||||
9.2 未经您明确同意,我们不会限制您按照本隐私权政策所应享有的权利。我们会在专门页面上发布对隐私权政策所做的任何修订。
|
||||
|
||||
9.3 对于重大修订,我们还会提供更为显著的通知(包括对于某些服务,我们会通过网站公示的方式进行通知,说明隐私权政策的具体变更内容)。
|
||||
|
||||
9.4 本政策所指的重大变更包括但不限于:
|
||||
|
||||
9.4.1 我们的服务模式发生重大变化。如处理用户信息的目的、处理的用户信息类型、用户信息的使用方式等;
|
||||
|
||||
9.4.2 我们在控制权、组织架构等方面发生重大变化。如业务调整、破产并购等引起的所有者变更等;
|
||||
|
||||
9.4.3 用户信息共享、转让或公开披露的主要对象发生变化;
|
||||
|
||||
9.4.4 您参与用户信息处理方面的权利及其行使方式发生重大变化;
|
||||
|
||||
9.4.5 我们负责处理用户信息安全的责任部门、联络方式及投诉渠道发生变化时;
|
||||
|
||||
9.4.6 用户信息安全影响评估报告表明存在高风险时。
|
||||
3
src/docs/product-cert.mdx
Normal file
3
src/docs/product-cert.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 实名认证与证书
|
||||
|
||||
关于实名认证、证书相关说明(占位)。
|
||||
3
src/docs/product-features.mdx
Normal file
3
src/docs/product-features.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 产品功能
|
||||
|
||||
产品功能列表与说明(占位)。
|
||||
3
src/docs/product-overview.mdx
Normal file
3
src/docs/product-overview.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 产品概述
|
||||
|
||||
这里展示产品概述内容,示例占位文本。可替换为真实文档。
|
||||
3
src/docs/realname-auth.mdx
Normal file
3
src/docs/realname-auth.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# HTTP 代理实名认证操作
|
||||
|
||||
说明实名认证流程、所需材料与常见问题。
|
||||
3
src/docs/socks5-usage.mdx
Normal file
3
src/docs/socks5-usage.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# 使用 Socks5 代理上网
|
||||
|
||||
介绍 Socks5 与 HTTP 代理的区别以及如何在客户端配置 Socks5。
|
||||
166
src/docs/userAgreement.mdx
Normal file
166
src/docs/userAgreement.mdx
Normal file
@@ -0,0 +1,166 @@
|
||||
# 用户协议
|
||||
神龙HTTP(以下或简称“我们”)尊重并保护用户信息,并将以高度的责任感和谨慎的态度对待这些信息。当您使用神龙HTTP提供的代理服务时,我们将根据本隐私政策来收集、处理及分享您的信息。我们希望通过本隐私政策向您清晰地说明我们如何处理您的信息。因此,我们建议您完整阅读本隐私政策,以便了解如何保护您的隐私权。如果您有任何疑问、意见或建议,可以通过神龙HTTP提供的联系方式与我们联系。本政策将帮助您了解以下内容:
|
||||
|
||||
一、适用范围
|
||||
|
||||
1.1 本隐私政策适用于神龙HTTP网站提供的所有服务。服务包括提供页面浏览、网站登录服务,以及通过神龙HTTP网站提供的网络服务。
|
||||
|
||||
1.2 本隐私政策不适用于其他第三方提供的服务。
|
||||
|
||||
1.3 特别说明,如果您使用神龙HTTP的网络服务为您的用户提供服务,您的业务数据归您所有,您应当与您的用户另行约定隐私政策。
|
||||
|
||||
二、用户信息的收集和使用
|
||||
|
||||
2.1 协助您成为我们的会员
|
||||
|
||||
2.1.1 当您在神龙HTTP网站创建账户时,您需要选择会员身份类型(个人、企业),并向我们提供会员名、单位名称及联系人姓名(用于账户实名认证及开票抬头)、设置并确认您的登录密码、可用电子邮箱、所在区域(国家、省份、城市),以及您在中国境内的手机号码。您提供的手机号码将用于注册、登录、绑定账户、找回密码,并作为您与神龙HTTP联系的方式之一,接收相关业务通知或进行业务沟通。
|
||||
|
||||
2.1.2 如果您仅需使用浏览、搜索等基本服务,您无需注册成为我们的会员及提供上述信息。
|
||||
|
||||
2.2 提供网络服务时您向我们提供的信息包括:
|
||||
|
||||
2.2.1 根据中国法律,在使用特定网络服务时,您需要通过账号提供真实身份信息。注册账户后,请根据账户类型(个人/企业),完成相应的实名操作。
|
||||
|
||||
2.2.2 在您使用服务过程中,我们会根据您在注册、登录账号及使用产品时授予的权限,接收并记录您所使用的设备相关信息(如设备型号、操作系统版本、浏览器cookies、唯一设备标识符等软硬件特征信息)、设备所在位置相关信息(如IP地址、MAC地址、GPS位置以及能够提供相关信息的Wi-Fi接入点、蓝牙和基站等传感器信息)。我们可能会将这些信息与您的账户信息关联,以便在不同设备上为您提供一致的服务。
|
||||
|
||||
2.2.3 日志信息:当您使用我们的网站或代理IP服务时,我们会自动收集您对我们服务的详细使用情况,作为有关网络日志保存(例如:您进入神龙HTTP站的搜索查询内容、登录账号、IP地址、浏览器类型、电信运营商、使用的语言、访问日期及代理IP使用中的详细日志信息等)。
|
||||
|
||||
2.2.4 请注意,单独的设备信息、日志信息等是无法识别特定自然人身份的信息。如果我们将其与个人信息结合使用,则在结合使用期间,这类非个人信息将被视为个人信息,除取得您授权或法律法规另有规定外,我们会将该类个人信息做匿名化、去标识化处理。
|
||||
|
||||
2.2.5 用户账户的支持信息:基于您使用神龙HTTP服务而产生的咨询记录、保障记录和针对用户故障的排障过程(如通信或通话记录),我们将通过记录、分析这些信息以便更及时响应您的帮助请求,以及用于改进服务。
|
||||
|
||||
2.3 我们出于如下目的使用您提交及我们收集的用户信息:
|
||||
|
||||
2.3.1 为了向您提供服务(如实名认证信息、用于接收验证码的手机号,是继续获得服务的前提);
|
||||
|
||||
2.3.2 为了维护、改进服务(如您提交的业务联系人手机等用来接收业务通知和进行业务沟通);
|
||||
|
||||
2.3.3 在法律法规允许的前提下,向您推荐产品;
|
||||
|
||||
2.3.4 为提高您使用我们及我们关联公司、合作伙伴提供服务的安全性,保护您或其他用户或公众的人身财产安全免遭侵害,更好地预防钓鱼网站、欺诈、网络漏洞、计算机病毒、网络攻击、网络侵入等安全风险,更准确地识别违反法律法规或神龙HTTP相关协议、规则的情况,我们可能使用您的会员信息、并整合设备信息、有关网络日志以及我们关联公司、合作伙伴分享的信息,来进行判断账户及交易风险、进行身份验证、安全事件的检测及防范,并依法采取必要的记录、审计、分析、处置措施;
|
||||
|
||||
2.3.5 如超出收集用户信息时所声明的目的或超出具有直接或合理关联的范围后使用用户信息前,我们会再次向您告知并征得您的明确同意。
|
||||
|
||||
2.4 在您与我们及我们关联公司、合作伙伴之间的服务终止后,我们将停止对您个人信息的收集和使用。
|
||||
|
||||
三、用户信息的共享、转让和公开披露
|
||||
|
||||
3.1 共享
|
||||
|
||||
我们不会与其他组织和个人共享您的用户信息,但以下情况除外:
|
||||
|
||||
3.1.1 在获取明确同意的情况下共享:获得您的明确同意后,我们会与其他方共享您的用户信息;
|
||||
|
||||
3.1.2 在法定情形下的共享:我们可能会根据法律法规规定、诉讼、仲裁解决需要,或按行政、司法机关依法提出的要求,对外共享您的用户信息;
|
||||
|
||||
3.1.3 为了促成交易或协助解决争议,某些情况下只有共享您的用户信息,才能促成交易或处理您与他人的纠纷或争议,例如,在神龙HTTP上创建的某一交易中,如交易任何一方履行或部分履行了交易义务并提出信息披露请求的,神龙HTTP有权决定向该用户提供其交易对方的联络方式等必要信息,以促成交易的完成;
|
||||
|
||||
3.2 转让
|
||||
|
||||
我们不会将您的用户信息转让给任何公司、组织和个人,但以下情况除外:
|
||||
|
||||
3.2.1 在获取明确同意的情况下转让:获得您的明确同意后,我们会向其他方转让您的用户信息;
|
||||
|
||||
3.2.2 在我们与其他法律主体者发生合并、收购或破产清算情形,或其他涉及合并、收购或破产清算情形时,如涉及到用户信息转让,我们会要求新的持有您用户信息的公司、组织继续受本政策的约束,否则我们将要求该公司、组织和个人重新向您征求授权同意。
|
||||
|
||||
3.3 公开披露
|
||||
|
||||
我们仅会在以下情况下,公开披露您的用户信息:
|
||||
|
||||
3.3.1 获得您明确同意或基于您的主动选择,我们可能会公开披露您的用户信息;
|
||||
|
||||
3.3.2 或为保护神龙HTTP平台及其关联公司用户或公众的人身财产安全免遭侵害,我们可能依据适用的法律或神龙HTTP平台相关协议、规则披露关于您的用户信息。
|
||||
|
||||
3.4 共享、转让、公开披露用户信息时事先征得授权同意的例外
|
||||
|
||||
以下情形中,共享、转让、公开披露您的用户信息无需事先征得您的授权同意:
|
||||
|
||||
3.4.1 与国家安全、国防安全有关的;
|
||||
|
||||
3.4.2 与公共安全、公共卫生、重大公共利益有关的;
|
||||
|
||||
3.4.3 与犯罪侦查、起诉、审判和判决执行等有关的;
|
||||
|
||||
3.4.4 出于维护您或其他个人的生命、财产等重大合法权益但又很难得到本人同意的;
|
||||
|
||||
3.4.5 您自行向社会公众公开的个人信息;
|
||||
|
||||
3.4.6 从合法公开披露的信息中收集个人信息的,如合法的新闻报道、政府信息公开等渠道。
|
||||
|
||||
四、用户业务数据和公开信息
|
||||
|
||||
4.1 用户业务数据
|
||||
|
||||
4.1.1 您通过神龙HTTP提供的代理IP服务,从事加工、存储、上传、下载、分发以及通过其他方式处理的数据,均为您的用户业务数据,您完全拥有您的用户业务数据。作为代理IP服务提供商,我们只会严格执行您的指示处理您的业务数据,除按与您协商一致或执行明确的法律法规要求外,我们不会对您的业务数据进行任何非授权的使用或披露。
|
||||
|
||||
4.1.2 您应对您的用户业务数据来源及内容负责,我们提醒您谨慎判断数据来源及内容的合法性。因您的用户业务数据内容违反法律法规、部门规章或国家政策而造成的全部结果及责任均由您自行承担。
|
||||
|
||||
4.2 公开信息
|
||||
|
||||
4.2.1 公开信息是指您公开分享的任何信息,任何人都可以在使用和未使用神龙HTTP网站服务期间查看或访问这些信息。
|
||||
|
||||
4.2.2 在使用神龙HTTP网站时,如您发现自己的个人信息泄露,尤其是您的账户或密码发生泄露,请您立即联络神龙HTTP客服,以便我们采取相应措施。
|
||||
|
||||
五、用户信息的管理
|
||||
|
||||
5.1 您可以登录神龙HTTP网站查看您填写提交的基本业务信息(基本资料)和联系人等信息。
|
||||
|
||||
5.2 您在神龙HTTP注册账号并完成实名认证以后,为保障您在平台的合法权益,我们将不支持任何形式变更实名认证的操作,充分有效保障账户的安全与一致性。
|
||||
|
||||
5.3 在以下情形中,您可以向我们提出删除用户信息的请求:
|
||||
|
||||
5.3.1 如果我们处理用户信息的行为违反法律法规;
|
||||
|
||||
5.3.2 如果我们收集、使用您的用户信息,却未征得您的明确同意;
|
||||
|
||||
5.3.3 如果我们处理个人信息的行为严重违反了与您的约定。
|
||||
|
||||
为保障安全,您可能需要提供书面请求,或以其他方式证明您的身份。我们可能会先要求您验证自己的身份,然后再处理您的请求。
|
||||
|
||||
六、Cookie 和同类技术的使用
|
||||
|
||||
6.1 为确保网站正常运转、为您获得更轻松的访问体验、向您推荐您可能感兴趣的内容,我们会在您的计算机或移动设备上存储名为 Cookie 的小数据文件。Cookie 通常包含标识符、站点名称以及一些号码和字符。神龙HTTP只能读取神龙HTTP提供的cookies。
|
||||
|
||||
七、用户信息的安全
|
||||
|
||||
7.1 我们非常重视您的信息安全。我们努力采取各种合理的物理、电子和管理方面的安全措施来保护您的用户信息。防止用户信息遭到未经授权访问、公开披露、使用、修改、损坏或丢失。我们会使用加密技术提高用户信息的安全性;我们会使用受信赖的保护机制防止用户信息遭到恶意攻击;我们会部署访问控制机制,尽力确保只有授权人员才可访问用户信息;
|
||||
|
||||
7.2 我们会采取合理可行的措施,尽力避免收集无关的用户信息。我们只会在达成本政策所述目的所需的期限内保留您的用户信息,除非需要延长保留期或受到法律的允许。超出上述用户信息保存期限后,我们会对您的个人信息进行删除或匿名化处理。
|
||||
|
||||
7.3 请使用复杂密码,协助我们保证您的账号安全。我们会尽力保障您发送给我们的任何信息的安全性。如果我们的物理、技术或管理防护设施遭到破坏,导致信息被非授权访问、公开披露、篡改或毁坏,导致您的合法权益受损,我们将承担相应的法律责任。
|
||||
|
||||
7.4 在不幸发生用户信息安全事件(泄露、丢失等)后,我们将按照法律法规的要求,及时向您告知:安全事件的基本情况和可能的影响、我们已采取或将要采取的处置措施、您可自主防范和降低风险的建议、对您的补救措施等。我们会及时将事件相关情况以邮件、信函、电话、推送通知等方式告知您,难以逐一告知用户信息主体时,我们会采取合理、有效的方式发布公告。
|
||||
|
||||
7.5 同时,我们还将按照监管部门要求,上报用户信息安全事件的处置情况。
|
||||
|
||||
7.6 我们将收集到的您的用户信息存放在中华人民共和国境内,如在符合适用法律规定的情形下因业务需要向境外传输个人信息的,我们会事先征得您的同意,并向您告知用户信息出境的目的、接收方、安全保障措施、安全风险等情况。
|
||||
|
||||
7.7 如出现神龙HTTP产品和服务停止运营的情形,我们会采取合理措施保护您用户信息安全,包括及时停止继续收集用户信息的活动;停止运营的通知将以逐一送达或公告的形式通知用户;并对所持有的个人信息进行删除或匿名化处理等。
|
||||
|
||||
八、未成年人用户信息的特别约定
|
||||
|
||||
8.1 我们主要面向成人提供产品和服务。如您为未成年人,我们要求您请您的父母或监护人仔细阅读本隐私权政策,并在征得您的父母或监护人同意的前提下使用我们的服务或向我们提供信息。
|
||||
|
||||
8.2 对于经父母或监护人同意使用我们的产品或服务而收集未成年人个人信息的情况,我们只会在法律法规允许、父母或监护人明确同意或者保护未成年人所必要的情况下使用、共享、转让或披露此信息。
|
||||
|
||||
九、隐私权政策的更新
|
||||
|
||||
9.1 我们的隐私权政策可能会修订。
|
||||
|
||||
9.2 未经您明确同意,我们不会限制您按照本隐私权政策所应享有的权利。我们会在专门页面上发布对隐私权政策所做的任何修订。
|
||||
|
||||
9.3 对于重大修订,我们还会提供更为显著的通知(包括对于某些服务,我们会通过网站公示的方式进行通知,说明隐私权政策的具体变更内容)。
|
||||
|
||||
9.4 本政策所指的重大变更包括但不限于:
|
||||
|
||||
9.4.1 我们的服务模式发生重大变化。如处理用户信息的目的、处理的用户信息类型、用户信息的使用方式等;
|
||||
|
||||
9.4.2 我们在控制权、组织架构等方面发生重大变化。如业务调整、破产并购等引起的所有者变更等;
|
||||
|
||||
9.4.3 用户信息共享、转让或公开披露的主要对象发生变化;
|
||||
|
||||
9.4.4 您参与用户信息处理方面的权利及其行使方式发生重大变化;
|
||||
|
||||
9.4.5 我们负责处理用户信息安全的责任部门、联络方式及投诉渠道发生变化时;
|
||||
|
||||
9.4.6 用户信息安全影响评估报告表明存在高风险时。
|
||||
5
src/docs/windows10-proxy.mdx
Normal file
5
src/docs/windows10-proxy.mdx
Normal file
@@ -0,0 +1,5 @@
|
||||
# Windows10 电脑设置代理教程
|
||||
|
||||
- 打开 设置 → 网络和 Internet → 代理
|
||||
- 填写手动代理服务器地址和端口
|
||||
- 保存并测试连接
|
||||
3
src/docs/windows7-proxy.mdx
Normal file
3
src/docs/windows7-proxy.mdx
Normal file
@@ -0,0 +1,3 @@
|
||||
# Windows7 电脑设置代理教程
|
||||
|
||||
同样在网络设置里配置代理地址与端口,或在浏览器中单独设置代理。
|
||||
@@ -88,9 +88,11 @@ export type Channel = {
|
||||
expiration: Date
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
proxy: Proxy
|
||||
proxy?: Proxy
|
||||
port: number
|
||||
expired_at: Date
|
||||
host: string
|
||||
batch_no: string
|
||||
}
|
||||
export type Proxy = {
|
||||
id: number
|
||||
|
||||
@@ -3,14 +3,15 @@ type ResourceShort = {
|
||||
resource_id: number
|
||||
type: number
|
||||
live: number
|
||||
expire: Date
|
||||
expire_at: Date
|
||||
quota: number
|
||||
used: number
|
||||
daily_limit: number
|
||||
daily_used: number
|
||||
daily_last: Date
|
||||
last_at: Date
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
daily: number
|
||||
}
|
||||
|
||||
type ResourceLong = {
|
||||
@@ -18,14 +19,15 @@ type ResourceLong = {
|
||||
resource_id: number
|
||||
type: number
|
||||
live: number
|
||||
expire: Date
|
||||
expire_at: Date
|
||||
quota: number
|
||||
used: number
|
||||
daily_limit: number
|
||||
daily_used: number
|
||||
daily_last: Date
|
||||
last_at: Date
|
||||
created_at: Date
|
||||
updated_at: Date
|
||||
daily: number
|
||||
}
|
||||
|
||||
export type Resource<T extends 1 | 2 = 1 | 2> = {
|
||||
|
||||
Reference in New Issue
Block a user