From ce7d2bab2693f2406a0130e33f3c9dc4800cc671 Mon Sep 17 00:00:00 2001 From: Sleck <15660928620@163.com> Date: Tue, 11 Feb 2025 16:35:36 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=8A=E4=B8=80=E9=A1=B5=E4=B8=8B=E4=B8=80?= =?UTF-8?q?=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../LotteryContentWithDirHandle.tsx | 191 +++++++++++++----- 1 file changed, 144 insertions(+), 47 deletions(-) diff --git a/src/pages/LotteryPage/LotteryContentWithDirHandle.tsx b/src/pages/LotteryPage/LotteryContentWithDirHandle.tsx index 998f897..7b83c0c 100644 --- a/src/pages/LotteryPage/LotteryContentWithDirHandle.tsx +++ b/src/pages/LotteryPage/LotteryContentWithDirHandle.tsx @@ -4,19 +4,26 @@ import { Content } from "antd/es/layout/layout"; import LotteryTree from "./LotteryTree"; import Sider from "antd/es/layout/Sider"; import { useLotteryData } from "./UseLotteryData"; // 引入自定义 hook -import { CloudDownloadOutlined, LoadingOutlined, ReloadOutlined, SaveOutlined } from "@ant-design/icons"; +import { + CloudDownloadOutlined, + LoadingOutlined, + ReloadOutlined, + SaveOutlined +} from "@ant-design/icons"; import { WorkshopPageContext } from "../WorkshopPage/WorkshopPageContext"; -import { NOTION_DATABASE_LOTTERY,WORKSHOP_TYPES } from "../../services/lottery/lotteryNotionQueries"; +import { NOTION_DATABASE_LOTTERY, WORKSHOP_TYPES } from "../../services/lottery/lotteryNotionQueries"; const { Text } = Typography; -const COMMODITY_PATH = 'CodeFunCore/src/main/resources/net/easecation/codefuncore/lottery/notion/'; +const COMMODITY_PATH = "CodeFunCore/src/main/resources/net/easecation/codefuncore/lottery/notion/"; +const PAGE_SIZE = 15; // 每页显示多少个 WORKSHOP_TYPES const LotteryContentWithDirHandle: React.FC = () => { const { token: { colorBgContainer, borderRadiusLG }, } = theme.useToken(); - const { dirHandle, ensurePermission, messageApi, readFile, writeFile } = useContext(WorkshopPageContext); + const { dirHandle, ensurePermission, messageApi, readFile, writeFile } = + useContext(WorkshopPageContext); const [currentType, setCurrentType] = useState(WORKSHOP_TYPES[0]); const [localJson, setLocalJson] = useState<{ [key: string]: any } | null>(null); @@ -27,10 +34,18 @@ const LotteryContentWithDirHandle: React.FC = () => { const [checkedKeys, setCheckedKeys] = useState([]); const [saving, setSaving] = useState(false); + // 分页相关状态 + const [currentPage, setCurrentPage] = useState(0); + const totalPages = Math.ceil(WORKSHOP_TYPES.length / PAGE_SIZE); + // 获取 Lottery 数据 - const { loading: remoteJsonLoading, fileArray: remoteJsonMapData, refetch } = useLotteryData(NOTION_DATABASE_LOTTERY); + const { + loading: remoteJsonLoading, + fileArray: remoteJsonMapData, + refetch, + } = useLotteryData(NOTION_DATABASE_LOTTERY); - // 切换tab时的状态重置 + // 切换 tab 时的状态重置 useEffect(() => { setLoadingLocalJson(false); setLocalJson(null); @@ -64,37 +79,36 @@ const LotteryContentWithDirHandle: React.FC = () => { } }, [dirHandle, currentType, ensurePermission, messageApi]); - // 处理加载远程 Notion 数据 - const handleLoadRemoteJson = async (type: string, flush:boolean) => { + // 从 Notion 拉取数据 + const handleLoadRemoteJson = async (type: string, flush: boolean) => { setRemoteJsonLoadingList((prev) => [...prev, type]); - messageApi.open({ key: "processing", type: "loading", content: `正在从 Notion 加载 ${type} ...`, duration: 0 }); + messageApi.open({ + key: "processing", + type: "loading", + content: `正在从 Notion 加载 ${type} ...`, + duration: 0, + }); // 重新获取 Notion 数据 - if(flush) { + if (flush) { await refetch(); } - setRemoteJsonMap((prev) => ({ ...prev, [type]: remoteJsonMapData[currentType] })); - + setRemoteJsonMap((prev) => ({ ...prev, [type]: remoteJsonMapData[type] })); messageApi.destroy("processing"); setRemoteJsonLoadingList((prev) => prev.filter((item) => item !== type)); messageApi.success(`${type} 处理完成`); }; - const menuItems = WORKSHOP_TYPES.map((value) => ({ - key: value, - label: value, - })); - - -// 在 remoteJsonMapData 加载完毕后,主动更新页面并调用 handleLoadRemoteJson -useEffect(() => { - if (remoteJsonMapData && Object.keys(remoteJsonMapData).length > 0) { - // 获取到数据后,主动调用 handleLoadRemoteJson 来更新页面 - handleLoadRemoteJson(currentType,false); - } -}, [remoteJsonMapData, currentType]); + // 在 remoteJsonMapData 加载完毕后,主动更新页面并调用 handleLoadRemoteJson + useEffect(() => { + if (remoteJsonMapData && Object.keys(remoteJsonMapData).length > 0) { + handleLoadRemoteJson(currentType, false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [remoteJsonMapData, currentType]); + // 同步到本地 const handleSyncRemoteJson = async () => { if (!dirHandle) { messageApi.error("请选择你的代码中的 commodity 文件夹"); @@ -102,9 +116,11 @@ useEffect(() => { if (localJson && remoteJsonMap[currentType]) { setSaving(true); const remoteJson = remoteJsonMap[currentType]; - try { - await writeFile(`${COMMODITY_PATH}${currentType}.json`, JSON.stringify(remoteJson, null, 4)); + await writeFile( + `${COMMODITY_PATH}${currentType}.json`, + JSON.stringify(remoteJson, null, 4) + ); setLocalJson(remoteJson); // 刷新本地 JSON } catch (error: any) { messageApi.error("保存文件出错: " + error?.message); @@ -116,28 +132,90 @@ useEffect(() => { } }; + /** + * 获取当前分页下的 WorkshopType 列表 + */ + const startIndex = currentPage * PAGE_SIZE; + const endIndex = startIndex + PAGE_SIZE; + const currentPageTypes = WORKSHOP_TYPES.slice(startIndex, endIndex); + + /** + * 构造 Menu 的 items + * 这里在顶部和底部各添加两个按钮:“上一页”和“下一页” + */ + const menuItems = [ + { + key: "prev-top", + label: "上一页", + disabled: currentPage === 0, + }, + ...currentPageTypes.map((value) => ({ + key: value, + label: value, + })), + { + key: "next-bottom", + label: "下一页", + disabled: currentPage === totalPages - 1 || totalPages <= 1, + }, + ]; + + /** + * 点击菜单时的处理 + */ + const handleMenuClick = (e: any) => { + if (e.key === "prev-top" || e.key === "prev-bottom") { + setCurrentPage((page) => Math.max(0, page - 1)); + return; + } + if (e.key === "next-top" || e.key === "next-bottom") { + setCurrentPage((page) => Math.min(totalPages - 1, page + 1)); + return; + } + // 普通菜单项 + setCurrentType(e.key); + }; + return ( - + setCurrentType(e.key)} - style={{ border: 'none' }} + onClick={handleMenuClick} + style={{ border: "none" }} /> 本地 ) } > {remoteJsonMap[currentType] ? ( - + ) : ( - - @@ -193,4 +290,4 @@ useEffect(() => { ); }; -export default LotteryContentWithDirHandle; \ No newline at end of file +export default LotteryContentWithDirHandle;