diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..c48917f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "postman.settings.dotenv-detection-notification-visibility": false +} \ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index a0b95ef..06d9a57 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,6 +3,7 @@ import { ClubSelector } from "./components/GameSelector"; import type { IEventInfo } from "./types"; import { useNavigate } from "react-router"; import "./index.css"; +import { FindUserButton } from "./components/FindUser"; export function App() { const navigate = useNavigate(); @@ -14,6 +15,7 @@ export function App() {

开球网比赛分组预测

+
); } diff --git a/src/components/FindUser/index.tsx b/src/components/FindUser/index.tsx new file mode 100644 index 0000000..17042ec --- /dev/null +++ b/src/components/FindUser/index.tsx @@ -0,0 +1,70 @@ +import { SearchOutlined } from "@ant-design/icons"; +import { useLocalStorageState, useRequest } from "ahooks"; +import { FloatButton, Drawer, Input, Table } from "antd"; +import { useState } from "react"; +import type { XCXFindUser, XCXFindUserResp } from "../../types"; +import User from "../User"; +import { SEX } from "../../utils"; +import dayjs from "dayjs"; + +export function FindUserButton() { + const [open, setOpen] = useState(false); + const [searchKey, setSearchKey] = useLocalStorageState('findUser:searchKey'); + const findUserReq = useRequest(async (page: number = 1) => { + const findOutUsers: XCXFindUserResp = await (await fetch(`/api/user/find?page=${page}&key=${searchKey}`)).json(); + return findOutUsers; + }, { manual: true, refreshDeps: [searchKey], cacheKey: 'findUser:result' }); + return ( + <> + } + onClick={() => setOpen(true)} + /> + setOpen(false)} + loading={findUserReq.loading} + size="80vh" + > + setSearchKey(e.target.value)} + onSearch={async () => findUserReq.runAsync()} + /> + e.uid} + dataSource={findUserReq.data?.data} + pagination={{ + total: findUserReq.data?.total, + current: findUserReq.data?.current_page, + pageSize: findUserReq.data?.per_page, + onChange(page) { + findUserReq.run(page); + }, + }} + > + ( + + )} + /> + + + SEX[sex]} /> + dayjs().diff(dayjs(year), 'year')} /> +
+
+ + ); +} \ No newline at end of file diff --git a/src/components/GameTable.tsx b/src/components/GameTable.tsx index 593b728..967ef40 100644 --- a/src/components/GameTable.tsx +++ b/src/components/GameTable.tsx @@ -70,6 +70,19 @@ export function GameTable(props: Props) { )} > i + 1} /> + { + const { uid1 } = record; + const { team1, team2 } = toTeams(record); + return ( + + + + ); + })} + /> {props.name} + if (!Number(props.uid)) return {props.name} return ( {props.name} ); diff --git a/src/index.tsx b/src/index.tsx index ac0ce8d..dd67bba 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -34,6 +34,15 @@ const server = serve({ return Response.json(data); } }, + "/api/user/find": { + async GET(req) { + const searchParams = new URL(req.url).searchParams; + const key = searchParams.get('key') ?? ''; + const page = Number(searchParams.get('page')); + const users = await xcxApi.findUser(key, page); + return Response.json(users); + } + }, "/api/user/:uid": { async GET(req) { const uid = req.params.uid; diff --git a/src/page/ProfilePage.tsx b/src/page/ProfilePage.tsx index 35e4e69..a8caf9c 100644 --- a/src/page/ProfilePage.tsx +++ b/src/page/ProfilePage.tsx @@ -67,13 +67,14 @@ function Raket(props: { profile?: XCXProfile | null }) { } function PlayerList(props: { title: string; names?: string[]; uids?: string[] }) { - if (!props.names?.length) return null; + const { names = [], uids = [] } = props; + if (!names.length) return null; return ( <> {props.title} - {props.names.map((e, i) => ( - + {names.map((e, i) => ( + ))} @@ -96,7 +97,7 @@ export default function ProfilePage() { 积分:{profile?.score} { - ([profile?.province, profile?.sex, profile?.bg ?? '', ...(profile?.allCities ?? [])] as React.ReactNode[]) + ([profile?.province, profile?.sex, profile?.bg ?? '', ...Object.values(profile?.allCities ?? [])] as React.ReactNode[]) .filter(Boolean) .reduce((a, b) => (<>{a}{b})) } diff --git a/src/services/xcxApi.ts b/src/services/xcxApi.ts index 1d157b9..443cc93 100644 --- a/src/services/xcxApi.ts +++ b/src/services/xcxApi.ts @@ -1,4 +1,4 @@ -import type { GamesData, XCXMember, XCXProfile, XCXTag } from "../types"; +import type { GamesData, XCXFindUser, XCXFindUserResp, XCXMember, XCXProfile, XCXTag } from "../types"; import { BASE_URL } from "../utils"; const XCX_BASE_URL = `${BASE_URL}/xcx/public/index.php`; @@ -51,4 +51,9 @@ export class XCXAPI { const url = `/api/User/getGames?uid=${uid}&page=${page}&size=50`; return (await this.#fetch<{ data: GamesData[] }>(url))?.data; } + async findUser(key: string = '', page: number = 1) { + if (!key) return; + const url = `/api/user/lists?page=${page}&key=${key}`; + return (await this.#fetch(url)); + } } \ No newline at end of file diff --git a/src/types/index.ts b/src/types/index.ts index ed1600a..f10edc0 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -34,4 +34,25 @@ export interface XCXMember extends BasePlayer { name: string; number: number; age: string; +} + +export interface XCXFindUser extends BasePlayer { + name: never; + username2: string; + realname: string; + residecity: string; + resideprovince: string; + minscore: string; + maxscore: string; + birthyear: string; + sex: string; + th?: string; +} + +export interface XCXFindUserResp { + current_page: number; + last_page: number; + per_page: number; + total: number; + data: XCXFindUser[]; } \ No newline at end of file diff --git a/src/utils.ts b/src/utils.ts index d2251be..552f6c9 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -114,4 +114,9 @@ export function sneckGroup(size: number, groupLen: number) { newGroups.push(group); } return newGroups; +} + +export enum SEX { + '男' = 1, + '女' = 2, } \ No newline at end of file