From 7a9724d290fedbae54256a1d0185c65b451ca644 Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Sat, 23 Nov 2024 13:45:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E4=BC=98=E9=9B=85=E7=9A=84?= =?UTF-8?q?=E7=9C=81=E4=BB=BD=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Search.tsx | 42 +++++++++++++++------ src/libs/OIerDb.ts | 76 ++++++++++++++++++++------------------ src/pages/contest/[id].tsx | 29 +++++++++------ 3 files changed, 89 insertions(+), 58 deletions(-) diff --git a/src/components/Search.tsx b/src/components/Search.tsx index a6263e7..a7362e9 100644 --- a/src/components/Search.tsx +++ b/src/components/Search.tsx @@ -1,5 +1,5 @@ -import { useEffect, useState, useTransition } from 'react'; -import { useSearchParams } from 'react-router-dom'; +import { useEffect, useMemo, useState, useTransition } from 'react'; +import { Link, useSearchParams } from 'react-router-dom'; import { Header, Input, @@ -14,10 +14,10 @@ import PersonCard from '@/components/PersonCard'; import getGrade, { currentYear } from '@/utils/getGrade'; import compareGrades from '@/utils/compareGrades'; import { - provinces, type OIer, genders, searchableGenderKeys, + provincesWithId, } from '@/libs/OIerDb'; import styles from './Search.module.less'; @@ -49,6 +49,18 @@ const Search: React.FC = () => { school: '', }); + const provinces = useMemo( + () => + Object.entries(provincesWithId).map(([id, province]) => ({ + key: id, + value: province, + text: `${province} (${id})`, + content: province, + label: { content: id, basic: true, size: 'mini' }, + })), + [] + ); + const province = searchParams.get('province') || ''; const setProvince = (province: string) => setSearchParams({ province }); @@ -70,14 +82,15 @@ const Search: React.FC = () => { startTransition(() => { let result: OIer[] = []; + if (!advanced) { result = OIerDb.oiers.filter( (oier) => oier.lowered_name === input || oier.initials === input ); + } else if (!input && !grade && !school) { + result = []; } else { result = OIerDb.oiers.filter((oier) => { - if (!(input || province || grade || school)) return false; - let res = Boolean(input || province || grade || school || gender); if (input) { @@ -156,11 +169,7 @@ const Search: React.FC = () => { search selection clearable - options={provinces.map((province) => ({ - key: province, - value: province, - text: province, - }))} + options={provinces} defaultValue={province} onChange={(_, { value }) => setProvince(value as string)} /> @@ -231,7 +240,18 @@ const Search: React.FC = () => { <> {input || province || grade || school || gender ? (
- {gender ? '暂时不支持仅按照性别搜索选手。' : '未找到结果。'} + {gender || province ? ( + gender ? ( + '暂时不支持仅按照性别搜索选手。' + ) : ( + <> + 请访问「 + 选手」页面查询某省的所有选手。 + + ) + ) : ( + '未找到结果。' + )}
) : ( <> diff --git a/src/libs/OIerDb.ts b/src/libs/OIerDb.ts index daf76ea..4ad97fe 100644 --- a/src/libs/OIerDb.ts +++ b/src/libs/OIerDb.ts @@ -442,42 +442,46 @@ export const initDb = async (setProgressPercent?: (p: number) => void) => { }; // 省份列表 -export const provinces = [ - '安徽', - '北京', - '福建', - '甘肃', - '广东', - '广西', - '贵州', - '海南', - '河北', - '河南', - '黑龙江', - '湖北', - '湖南', - '吉林', - '江苏', - '江西', - '辽宁', - '内蒙古', - '山东', - '山西', - '陕西', - '上海', - '四川', - '天津', - '新疆', - '浙江', - '重庆', - '宁夏', - '云南', - '澳门', - '香港', - '青海', - '西藏', - '台湾', -] as const; +export const provincesWithId = { + AH: '安徽', + BJ: '北京', + FJ: '福建', + GS: '甘肃', + GD: '广东', + GX: '广西', + GZ: '贵州', + HI: '海南', + HE: '河北', + HA: '河南', + HL: '黑龙江', + HB: '湖北', + HN: '湖南', + JL: '吉林', + JS: '江苏', + JX: '江西', + LN: '辽宁', + NM: '内蒙古', + SD: '山东', + SX: '山西', + SN: '陕西', + SH: '上海', + SC: '四川', + TJ: '天津', + XJ: '新疆', + ZJ: '浙江', + CQ: '重庆', + NX: '宁夏', + YN: '云南', + MO: '澳门', + HK: '香港', + QH: '青海', + XC: '西藏', + TW: '台湾', +} as const; + +export const provinces = Object.values( + provincesWithId +) as (typeof provincesWithId)[keyof typeof provincesWithId][]; // 奖项列表及颜色 export const awardColors = { diff --git a/src/pages/contest/[id].tsx b/src/pages/contest/[id].tsx index 905e12b..1195166 100644 --- a/src/pages/contest/[id].tsx +++ b/src/pages/contest/[id].tsx @@ -20,7 +20,7 @@ import getProgress from '@/utils/getProgress'; import fixContestName from '@/utils/fixContestName'; import Pagination from '@/components/Pagination'; import styles from './[id].module.less'; -import { awardColors, awardLevels } from '@/libs/OIerDb'; +import { awardColors, awardLevels, provincesWithId } from '@/libs/OIerDb'; import compareGrades from '@/utils/compareGrades'; const NotFound = lazy(() => import('@/pages/404')); @@ -52,12 +52,23 @@ const Contest: React.FC = () => { setSearchParams({ grade: String(grade), page: '1' }); }; - const provinces = useMemo( - () => [ + const provinces = useMemo(() => { + const withId2 = Object.fromEntries( + Object.entries(provincesWithId).map(([id, province]) => [province, id]) + ); + + return [ ...new Set(contest.contestants.map((contestant) => contestant.province)), - ], - [id] - ); + ] + .map((province) => ({ + key: withId2[province], + value: province, + text: `${province} (${withId2[province]})`, + content: province, + label: { content: withId2[province], basic: true, size: 'mini' }, + })) + .sort((a, b) => a.key.localeCompare(b.key)); + }, [id]); const grades = useMemo( () => [ @@ -172,11 +183,7 @@ const Contest: React.FC = () => { clearable placeholder="省份" value={province} - options={provinces.map((province) => ({ - key: province, - value: province, - text: province, - }))} + options={provinces} onChange={(_, { value }) => setProvince(value as string)} />