补充上传协议和实名认证

This commit is contained in:
Eamon
2026-09-11 17:06:29 +08:00
parent 8d8c9deba7
commit 8aaf43ed79
31 changed files with 301 additions and 108 deletions

View File

@@ -48,7 +48,7 @@ export default function HelpPage() {
}
setArticles(transformArticles(res.data.List ?? []))
}
void load()
load()
return () => {
cancelled = true
}

View File

@@ -59,20 +59,22 @@ export default function LoginPage() {
<Button
variant="ghost"
onClick={() => setTab("login")}
className={`flex-1 py-2 rounded-md transition-all ${tab === "login"
className={`flex-1 py-2 rounded-md transition-all ${
tab === "login"
? "bg-white shadow-sm text-blue-600 font-medium"
: "text-gray-600 hover:text-gray-900"
}`}
}`}
>
登录
</Button>
<Button
variant="ghost"
onClick={() => setTab("register")}
className={`flex-1 py-2 rounded-md transition-all ${tab === "register"
className={`flex-1 py-2 rounded-md transition-all ${
tab === "register"
? "bg-white shadow-sm text-blue-600 font-medium"
: "text-gray-600 hover:text-gray-900"
}`}
}`}
>
注册
</Button>

View File

@@ -8,6 +8,7 @@ import {
type RechargeOrderResult,
} from "@/api/order"
import { QrCodeImage } from "@/components/qrCodeImage"
import RealNameCheck from "@/components/realNameCheck"
import { Button } from "@/components/ui/button"
import { clearOrderPay, notifyPayPaid, readOrderPay } from "@/lib/recharge"
import alipay from "../_assets/alipay.svg"
@@ -44,8 +45,8 @@ function usePayPolling(
}
}
void poll()
const timer = window.setInterval(() => void poll(), POLL_INTERVAL)
poll()
const timer = window.setInterval(() => poll(), POLL_INTERVAL)
return () => {
stopped = true
window.clearInterval(timer)
@@ -59,7 +60,12 @@ export default function PayPage() {
const [searchParams] = useSearchParams()
const mode = searchParams.get("mode")
return mode === "order" ? <OrderPay /> : <RechargePay />
return (
<>
<RealNameCheck />
{mode === "order" ? <OrderPay /> : <RechargePay />}
</>
)
}
// ==================== 充值模式 ====================

View File

@@ -2,6 +2,7 @@ import { useEffect, useState } from "react"
import { useLocation, useNavigate } from "react-router-dom"
import { toast } from "sonner"
import { createOrder } from "@/api/order"
import RealNameCheck from "@/components/realNameCheck"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
@@ -385,6 +386,7 @@ export default function BuyPage() {
return (
<Wrap className="bg-white min-h-screen flex items-start justify-center pt-24">
<RealNameCheck />
<div className="w-full max-w-2xl px-0 md:px-8">
{/* 标题 */}
<div className="text-center mb-6 space-y-2">

View File

@@ -2,6 +2,7 @@ import { useEffect, useState } from "react"
import { useLocation, useNavigate } from "react-router-dom"
import { toast } from "sonner"
import { createOrder } from "@/api/order"
import RealNameCheck from "@/components/realNameCheck"
import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
@@ -388,6 +389,7 @@ export default function BuyStaticPage() {
const [regionSearch, setRegionSearch] = useState("")
return (
<Wrap className="bg-white min-h-screen flex items-start justify-center pt-24">
<RealNameCheck />
<div className="w-full max-w-2xl px-0 md:px-8">
{/* 标题 */}
<div className="text-center mb-3">
@@ -616,7 +618,7 @@ export default function BuyStaticPage() {
</Button>
<Button
className="flex-1 h-12 rounded-xl text-base bg-linear-to-r from-blue-500 to-cyan-400 text-white hover:opacity-90 transition-all"
onClick={() => void handlePay()}
onClick={() => handlePay()}
disabled={submitting}
>
{submitting ? "提交中..." : "确认支付"}

View File

@@ -8,6 +8,7 @@ import {
fetchGameList,
fetchHttpBalance,
} from "@/api/http"
import RealNameCheck from "@/components/realNameCheck"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
@@ -218,11 +219,11 @@ export default function HttpPage() {
const seq = gameSeqRef.current + 1
gameSeqRef.current = seq
setGame(next)
void loadGamePrice(next, seq)
loadGamePrice(next, seq)
}
const selectAbroad = (isAbroad: number) => {
void applyGame(
applyGame(
{
...gameRef.current,
isAbroad,
@@ -236,31 +237,31 @@ export default function HttpPage() {
const selectShareType = (shareType: number) => {
if (shareType === 1) {
void applyGame({
applyGame({
...gameRef.current,
shareType,
lineType: 1,
gameId: 0,
})
} else {
void applyGame({ ...gameRef.current, shareType }, { fetchGames: true })
applyGame({ ...gameRef.current, shareType }, { fetchGames: true })
}
}
const changeRelay = (isRelayed: number) => {
void applyGame({ ...gameRef.current, isRelayed })
applyGame({ ...gameRef.current, isRelayed })
}
const changeIsp = (isp: number) => {
void applyGame({ ...gameRef.current, isp })
applyGame({ ...gameRef.current, isp })
}
const changeCity = (cityCode: number) => {
void applyGame({ ...gameRef.current, cityCode })
applyGame({ ...gameRef.current, cityCode })
}
const changeGameId = (gameId: number) => {
void applyGame({ ...gameRef.current, gameId })
applyGame({ ...gameRef.current, gameId })
}
const openGamePay = async () => {
@@ -315,7 +316,7 @@ export default function HttpPage() {
const handleTabClick = (id: string) => {
setActiveTab(id)
if (id === "game") {
void applyGame(
applyGame(
{ ...gameRef.current, periodType: 1 },
{
fetchCities: true,
@@ -374,6 +375,7 @@ export default function HttpPage() {
return (
<>
<Toaster position="top-center" richColors />
<RealNameCheck />
<Wrap className="bg-white">
<section className="py-20">
<div className="text-center mb-6">
@@ -908,7 +910,7 @@ export default function HttpPage() {
<PriceBar
price={gamePrice}
loading={gamePriceLoading}
onPay={() => void openGamePay()}
onPay={() => openGamePay()}
/>
</div>
)}
@@ -1016,7 +1018,7 @@ export default function HttpPage() {
<DialogFooter>
<Button
onClick={() => void payGameOrder()}
onClick={() => payGameOrder()}
disabled={gamePaying}
className="w-full bg-linear-to-r from-blue-500 to-cyan-400 text-white hover:opacity-90 py-3"
>

View File

@@ -1,4 +1,5 @@
import { useState } from "react"
import RealNameCheck from "@/components/realNameCheck"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
import { Card, CardContent } from "@/components/ui/card"
@@ -120,6 +121,7 @@ export default function RouterosPage() {
return (
<Wrap className="flex flex-col gap-10 pt-30 pb-16 bg-white">
<RealNameCheck />
<div className="flex flex-col lg:flex-row gap-10">
<div className="lg:w-5/12">
<Card className="overflow-hidden border-0 shadow-md">