4 Commits

Author SHA1 Message Date
Eamon-meng
a2187adb05 新增本地构建脚本 2026-02-27 16:41:38 +08:00
Eamon-meng
4b18c91157 修复修改密码弹窗&取消后台显示客服弹窗 & 取消退出登录profile为空抛异常的判断 2026-02-27 15:03:17 +08:00
Eamon-meng
2125f1ef9e 更新首页文档跳转链接&调整后台分页显示 2026-02-26 16:37:50 +08:00
Eamon-meng
85f241e8e3 更新发布v1.1.1版本 2026-01-21 10:19:01 +08:00
11 changed files with 72 additions and 52 deletions

View File

@@ -7,4 +7,7 @@
"[json]": {
"editor.defaultFormatter": "vscode.json-language-features"
},
"[typescriptreact]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
}

View File

@@ -1,6 +1,6 @@
{
"name": "lanhu-web",
"version": "1.1.0",
"version": "1.1.2",
"private": true,
"scripts": {
"dev": "next dev -H 0.0.0.0 --turbopack",

16
publish.ps1 Normal file
View File

@@ -0,0 +1,16 @@
if (-not $args) {
Write-Error "需要指定版本号"
exit 1
}
$confrim = Read-Host "构建版本为 [web:$($args[0])],是否继续?(y/n)"
if ($confrim -ne "y") {
Write-Host "已取消构建"
exit 0
}
docker build -t 43.226.58.254:53000/lanhu/web:latest .
docker build -t 43.226.58.254:53000/lanhu/web:$($args[0]) .
docker push 43.226.58.254:53000/lanhu/web:latest
docker push 43.226.58.254:53000/lanhu/web:$($args[0])

View File

@@ -11,21 +11,21 @@ export function ArticlesSection() {
icon={<BookOpen className="w-12 h-12"/>}
title="浏览器设置代理教程"
description="快速上手5分钟学会在浏览器中配置代理服务器"
href="/docs/client/browser-proxy"
href="/docs/browser-proxy"
/>
<ArticleCard
icon={<Smartphone className="w-12 h-12"/>}
title="Windows10 代理配置"
description="详细图文教程,帮助你在 Windows 系统中设置代理"
href="/docs/client/windows10-proxy"
href="/docs/windows10-proxy"
/>
<ArticleCard
icon={<HelpCircle className="w-12 h-12"/>}
title="常见问题总览"
description="解决使用过程中遇到的各类问题,快速找到答案"
href="/docs/faqs/faq-general"
href="/docs/faq-general"
/>
</div>
</PageSection>

View File

@@ -41,7 +41,7 @@ export default function Footer(props: FooterProps) {
items={[
{name: `产品订购`, href: `/product`},
{name: `获取代理`, href: `/collect`},
{name: `帮助中心`, href: `/docs/faqs/faq-general`},
{name: `帮助中心`, href: `/docs/faq-general`},
{name: `企业服务`, href: `/custom`},
]}
/>
@@ -69,9 +69,9 @@ export default function Footer(props: FooterProps) {
<SiteNavList
title="帮助文档"
items={[
{name: `产品功能`, href: `/docs/product/product-features`},
{name: `使用教程`, href: `/docs/client/browser-proxy`},
{name: `行业资讯`, href: `/docs/news/news-latest`},
{name: `产品功能`, href: `/docs/product-overview`},
{name: `使用教程`, href: `/docs/browser-proxy`},
{name: `行业资讯`, href: `/docs/news-latest`},
]}
/>
</div>

View File

@@ -1,6 +1,7 @@
import {ReactNode} from 'react'
import Header from './header'
import Footer from './footer'
import Script from 'next/script'
export type HomeLayoutProps = {
children: ReactNode
@@ -17,6 +18,8 @@ export default function HomeLayout(props: HomeLayoutProps) {
{/* 页脚 */}
<Footer/>
<Script id="qd2852138148beb7882a4a6a3e5ff5b569436003e7dc" src="https://wp.qiye.qq.com/qidian/2852138148/beb7882a4a6a3e5ff5b569436003e7dc" async defer></Script>
</div>
)
}

View File

@@ -75,19 +75,19 @@ export function Content(props: {children: ReactNode}) {
}
function ContentResolved() {
const profile = use(useProfileStore(store => store.profile))
if (!profile) throw new Error('登录状态异常')
return (
<>
<RealnameAuthDialog
triggerClassName="hidden"
defaultOpen={!profile.id_token}
/>
<ChangePasswordDialog
triggerClassName="hidden"
defaultOpen={!profile.has_password}
/>
</>
)
if (profile)
return (
<>
<RealnameAuthDialog
triggerClassName="hidden"
defaultOpen={!profile.id_token}
/>
<ChangePasswordDialog
triggerClassName="hidden"
defaultOpen={!profile.has_password}
/>
</>
)
}
export function Header() {
@@ -127,8 +127,7 @@ export function Header() {
function HeaderUserCenter() {
const profile = use(useProfileStore(store => store.profile))
if (!profile) throw new Error('登录状态异常')
return <UserCenter profile={profile}/>
if (profile) return <UserCenter profile={profile}/>
}
export function Navbar() {

View File

@@ -25,7 +25,6 @@ export default async function RootLayout(props: Readonly<{
<Effects>{props.children}</Effects>
</StoreProviders>
<Toaster position="top-center" richColors expand/>
<Script id="qd2852138148beb7882a4a6a3e5ff5b569436003e7dc" src="https://wp.qiye.qq.com/qidian/2852138148/beb7882a4a6a3e5ff5b569436003e7dc" async defer></Script>
</body>
</html>
)

View File

@@ -68,7 +68,7 @@ export function ChangePasswordDialog({
})
// 提交处理
const handler = form.handleSubmit(async (value) => {
const handler = async (value: Schema) => {
try {
const resp = await updatePassword({
phone: value.phone,
@@ -90,7 +90,7 @@ export function ChangePasswordDialog({
description: e instanceof Error ? e.message : String(e),
})
}
})
}
return (
<Dialog open={actualOpen} onOpenChange={actualOnOpenChange}>
@@ -98,10 +98,16 @@ export function ChangePasswordDialog({
<Button theme="outline" className={triggerClassName || 'w-24 h-9'}></Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
<Form form={form} handler={handler} className="flex flex-col gap-4 mt-4">
<Form
form={form}
handler={async () => {
const data = form.getValues()
await handler(data)
}}
className="flex flex-col gap-4 mt-4">
<DialogHeader>
<DialogTitle></DialogTitle>
</DialogHeader>
{/* 手机号输入 */}
<FormField<Schema> name="phone" label="手机号" className="flex-auto">
{({field}) => (
@@ -132,22 +138,20 @@ export function ChangePasswordDialog({
<Input {...field} placeholder="请再次输入新密码" type="password" autoComplete="new-password"/>
)}
</FormField>
</Form>
<DialogFooter>
<Button
theme="outline"
type="button"
onClick={() => {
actualOnOpenChange(false)
form.reset()
}}>
</Button>
<Button onClick={handler}>
</Button>
</DialogFooter>
<DialogFooter>
<Button
theme="outline"
type="button"
onClick={() => {
actualOnOpenChange(false)
form.reset()
}}>
</Button>
<Button type="submit"></Button>
</DialogFooter>
</Form>
</DialogContent>
</Dialog>
)

View File

@@ -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 '@/app/(home)/docs/product/api-docs/page.md'
import ExtractDocs from '@/app/(home)/docs/(product)/api-docs/page.md'
import Link from 'next/link'
import {useProfileStore} from '@/components/stores/profile'

View File

@@ -107,13 +107,9 @@ function Pagination({
const paginationItems = generatePaginationItems()
return (
<div className={`flex flex-wrap items-center justify-end gap-4 ${className || ''}`}>
<div className={`flex flex-wrap items-center gap-4 ${className || ''}`}>
<div className="flex-none flex items-center gap-2 text-sm text-muted-foreground">
{' '}
{total}
{' '}
{total}
<Select
value={size.toString()}
onValueChange={handlePageSizeChange}