From 21d9bc03f7896cf6edd9ea7f36e62cc2d943db0c Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Mon, 18 Nov 2024 18:10:18 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=8A=A8=E6=80=81=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E6=A8=A1=E5=BC=8F=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/config.js | 1 + pages/404.js | 11 +-- pages/[prefix]/index.js | 10 +- pages/_app.js | 1 - pages/archive/index.js | 17 ++-- pages/auth/index.js | 100 ++++++++++++++++++++ pages/category/[category]/index.js | 12 +-- pages/category/[category]/page/[page].js | 12 +-- pages/category/index.js | 12 +-- pages/dashboard/index.js | 111 +++++++++++++++++++++++ pages/index.js | 11 +-- pages/page/[page].js | 12 +-- pages/search/[keyword]/index.js | 12 +-- pages/search/[keyword]/page/[page].js | 11 +-- pages/search/index.js | 11 +-- pages/sign-in/[[...index]].js | 11 +-- pages/sign-up/[[...index]].js | 11 +-- pages/tag/[tag]/index.js | 12 +-- pages/tag/[tag]/page/[page].js | 11 +-- pages/tag/index.js | 11 +-- themes/starter/components/Header.js | 5 + themes/theme.js | 10 ++ 22 files changed, 294 insertions(+), 121 deletions(-) create mode 100644 pages/auth/index.js create mode 100644 pages/dashboard/index.js diff --git a/lib/config.js b/lib/config.js index 6985b320edf..dadd2efe6a0 100644 --- a/lib/config.js +++ b/lib/config.js @@ -34,6 +34,7 @@ export const siteConfig = (key, defaultVal = null, extendConfig = {}) => { case 'POST_URL_PREFIX_MAPPING_CATEGORY': case 'IS_TAG_COLOR_DISTINGUISHED': case 'TAG_SORT_BY_COUNT': + case 'THEME': case 'LINK': return convertVal(extendConfig[key] || defaultVal || BLOG[key]) default: diff --git a/pages/404.js b/pages/404.js index 782789185b1..97ea16c4614 100644 --- a/pages/404.js +++ b/pages/404.js @@ -1,6 +1,6 @@ import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -9,12 +9,9 @@ import { useRouter } from 'next/router' * @returns */ const NoFound = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps(req) { diff --git a/pages/[prefix]/index.js b/pages/[prefix]/index.js index 6b05f7f1655..a6d6e82f131 100644 --- a/pages/[prefix]/index.js +++ b/pages/[prefix]/index.js @@ -8,7 +8,7 @@ import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents' import { getPasswordQuery } from '@/lib/password' import { uploadDataToAlgolia } from '@/lib/plugins/algolia' import { checkSlugHasNoSlash, getRecommendPost } from '@/lib/utils/post' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import md5 from 'js-md5' import { useRouter } from 'next/router' import { idToUuid } from 'notion-utils' @@ -83,15 +83,11 @@ const Slug = props => { }, [router, lock]) props = { ...props, lock, validPassword } - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) return ( <> {/* 文章布局 */} - + {/* 解锁密码提示框 */} {post?.password && post?.password !== '' && !lock && } {/* 导流工具 */} diff --git a/pages/_app.js b/pages/_app.js index e363b090206..12002916580 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -45,7 +45,6 @@ const MyApp = ({ Component, pageProps }) => { // 整体布局 const GLayout = useCallback( props => { - // 根据页面路径加载不同Layout文件 const Layout = getGlobalLayoutByTheme(queryParam) return }, diff --git a/pages/archive/index.js b/pages/archive/index.js index beecf79c1f9..968803eea73 100644 --- a/pages/archive/index.js +++ b/pages/archive/index.js @@ -3,17 +3,16 @@ import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' import { isBrowser } from '@/lib/utils' import { formatDateFmt } from '@/lib/utils/formatDate' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' import { useEffect } from 'react' +/** + * 归档首页 + * @param {*} props + * @returns + */ const ArchiveIndex = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - useEffect(() => { if (isBrowser) { const anchor = window.location.hash @@ -28,7 +27,9 @@ const ArchiveIndex = props => { } }, []) - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps({ locale }) { diff --git a/pages/auth/index.js b/pages/auth/index.js new file mode 100644 index 00000000000..26aea479c71 --- /dev/null +++ b/pages/auth/index.js @@ -0,0 +1,100 @@ +// pages/sitemap.xml.js +import { getGlobalData } from '@/lib/db/getSiteData' +import axios from 'axios' +import { useRouter } from 'next/router' +import { useEffect } from 'react' +import Slug from '../[prefix]' + +/** + * 根据notion的slug访问页面 + * 解析二级目录 /article/about + * @param {*} props + * @returns + */ +const UI = props => { + const { redirect_pathname, redirect_query } = props + const router = useRouter() + useEffect(() => { + router?.push({ pathname: redirect_pathname, query: redirect_query }) + }, []) + return +} + +/** + * 服务端接收参数处理 + * @param {*} ctx + * @returns + */ +export const getServerSideProps = async ctx => { + const from = `auth` + const props = await getGlobalData({ from }) + delete props.allPages + const code = ctx.query.code + + let params = null + if (code) { + params = await fetchToken(code) + } + + // 授权成功的划保存下用户的workspace信息 + if (params?.status === 200) { + console.log('请求成功', params) + props.redirect_query = { + ...params.data, + msg: '成功了' + JSON.stringify(params.data) + } + console.log('用户信息', JSON.stringify(params.data)) + } else if (!params) { + console.log('请求异常', params) + props.redirect_query = { msg: '无效请求' } + } else { + console.log('请求失败', params) + props.redirect_query = { msg: params.statusText } + } + + props.redirect_pathname = '/auth/result' + + return { + props + } +} + +const fetchToken = async code => { + if (!code) { + return '无效请求' + } + console.log('Auth', code) + const clientId = process.env.OAUTH_CLIENT_ID + const clientSecret = process.env.OAUTH_CLIENT_SECRET + const redirectUri = process.env.OAUTH_REDIRECT_URI + + // encode in base 64 + const encoded = Buffer.from(`${clientId}:${clientSecret}`).toString('base64') + + try { + console.log( + `请求Code换取Token ${clientId}:${clientSecret} -- ${redirectUri}` + ) + const response = await axios.post( + 'https://api.notion.com/v1/oauth/token', + { + grant_type: 'authorization_code', + code: code, + redirect_uri: redirectUri + }, + { + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: `Basic ${encoded}` + } + } + ) + + console.log('Token response', response.data) + return response + } catch (error) { + console.error('Error fetching token', error) + } +} +export default UI diff --git a/pages/category/[category]/index.js b/pages/category/[category]/index.js index ea70b454821..a3a531a1d0b 100644 --- a/pages/category/[category]/index.js +++ b/pages/category/[category]/index.js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -10,13 +10,9 @@ import { useRouter } from 'next/router' * @returns */ export default function Category(props) { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps({ params: { category }, locale }) { diff --git a/pages/category/[category]/page/[page].js b/pages/category/[category]/page/[page].js index 120d762a8e7..9668cdebc7a 100644 --- a/pages/category/[category]/page/[page].js +++ b/pages/category/[category]/page/[page].js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -11,13 +11,9 @@ import { useRouter } from 'next/router' */ export default function Category(props) { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps({ params: { category, page } }) { diff --git a/pages/category/index.js b/pages/category/index.js index 62a3cc9f2e6..4b2f3942d10 100644 --- a/pages/category/index.js +++ b/pages/category/index.js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -10,13 +10,9 @@ import { useRouter } from 'next/router' * @returns */ export default function Category(props) { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps({ locale }) { diff --git a/pages/dashboard/index.js b/pages/dashboard/index.js new file mode 100644 index 00000000000..824ad6f3b4d --- /dev/null +++ b/pages/dashboard/index.js @@ -0,0 +1,111 @@ +import BLOG from '@/blog.config' +import { siteConfig } from '@/lib/config' +import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData' +import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents' +import { uploadDataToAlgolia } from '@/lib/plugins/algolia' +import { getRecommendPost } from '@/lib/utils/post' +import { DynamicLayout } from '@/themes/theme' +import { useRouter } from 'next/router' + +/** + * 根据notion的slug访问页面 + * 只解析一级目录例如 /about + * @param {*} props + * @returns + */ +const Dashboard = props => { + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return +} + +export async function getStaticProps({ locale }) { + const prefix = 'dashboard' + let fullSlug = 'dashboard' + const from = `slug-props-${fullSlug}` + const props = await getGlobalData({ from, locale }) + if (siteConfig('PSEUDO_STATIC', false, props.NOTION_CONFIG)) { + if (!fullSlug.endsWith('.html')) { + fullSlug += '.html' + } + } + + // 在列表内查找文章 + props.post = props?.allPages?.find(p => { + return p.type.indexOf('Menu') < 0 && p.slug === fullSlug + }) + + // 处理非列表内文章的内信息 + if (!props?.post) { + const pageId = prefix + if (pageId.length >= 32) { + const post = await getPost(pageId) + props.post = post + } + } + // 无法获取文章 + if (!props?.post) { + props.post = null + return { + props, + revalidate: process.env.EXPORT + ? undefined + : siteConfig( + 'NEXT_REVALIDATE_SECOND', + BLOG.NEXT_REVALIDATE_SECOND, + props.NOTION_CONFIG + ) + } + } + + // 文章内容加载 + if (!props?.post?.blockMap) { + props.post.blockMap = await getPostBlocks(props.post.id, from) + } + + // 目录默认加载 + if (props.post?.blockMap?.block) { + props.post.content = Object.keys(props.post.blockMap.block).filter( + key => props.post.blockMap.block[key]?.value?.parent_id === props.post.id + ) + props.post.toc = getPageTableOfContents(props.post, props.post.blockMap) + } + + // 生成全文索引 && process.env.npm_lifecycle_event === 'build' && JSON.parse(BLOG.ALGOLIA_RECREATE_DATA) + if (BLOG.ALGOLIA_APP_ID) { + uploadDataToAlgolia(props?.post) + } + + // 推荐关联文章处理 + const allPosts = props.allPages?.filter( + page => page.type === 'Post' && page.status === 'Published' + ) + if (allPosts && allPosts.length > 0) { + const index = allPosts.indexOf(props.post) + props.prev = allPosts.slice(index - 1, index)[0] ?? allPosts.slice(-1)[0] + props.next = allPosts.slice(index + 1, index + 2)[0] ?? allPosts[0] + props.recommendPosts = getRecommendPost( + props.post, + allPosts, + siteConfig('POST_RECOMMEND_COUNT') + ) + } else { + props.prev = null + props.next = null + props.recommendPosts = [] + } + + delete props.allPages + return { + props, + revalidate: process.env.EXPORT + ? undefined + : siteConfig( + 'NEXT_REVALIDATE_SECOND', + BLOG.NEXT_REVALIDATE_SECOND, + props.NOTION_CONFIG + ) + } +} + +export default Dashboard diff --git a/pages/index.js b/pages/index.js index a84c9b3bb46..eaa21167fed 100644 --- a/pages/index.js +++ b/pages/index.js @@ -4,7 +4,7 @@ import { getGlobalData, getPostBlocks } from '@/lib/db/getSiteData' import { generateRobotsTxt } from '@/lib/robots.txt' import { generateRss } from '@/lib/rss' import { generateSitemapXml } from '@/lib/sitemap.xml' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -13,12 +13,9 @@ import { useRouter } from 'next/router' * @returns */ const Index = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } /** diff --git a/pages/page/[page].js b/pages/page/[page].js index 9ccb3b81567..0166aba2f4e 100644 --- a/pages/page/[page].js +++ b/pages/page/[page].js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData, getPostBlocks } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -10,13 +10,9 @@ import { useRouter } from 'next/router' * @returns */ const Page = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticPaths({ locale }) { diff --git a/pages/search/[keyword]/index.js b/pages/search/[keyword]/index.js index 9b491b00abc..179583d825b 100644 --- a/pages/search/[keyword]/index.js +++ b/pages/search/[keyword]/index.js @@ -2,17 +2,13 @@ import BLOG from '@/blog.config' import { getDataFromCache } from '@/lib/cache/cache_manager' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' const Index = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } /** diff --git a/pages/search/[keyword]/page/[page].js b/pages/search/[keyword]/page/[page].js index bebaa9fc787..4ced9f6c499 100644 --- a/pages/search/[keyword]/page/[page].js +++ b/pages/search/[keyword]/page/[page].js @@ -2,19 +2,16 @@ import BLOG from '@/blog.config' import { getDataFromCache } from '@/lib/cache/cache_manager' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' const Index = props => { const { keyword } = props - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) props = { ...props, currentSearch: keyword } - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } /** diff --git a/pages/search/index.js b/pages/search/index.js index 6226a400d38..2000d72eef8 100644 --- a/pages/search/index.js +++ b/pages/search/index.js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -12,12 +12,6 @@ import { useRouter } from 'next/router' const Search = props => { const { posts } = props - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - const router = useRouter() const keyword = router?.query?.s @@ -37,7 +31,8 @@ const Search = props => { props = { ...props, posts: filteredPosts } - return + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } /** diff --git a/pages/sign-in/[[...index]].js b/pages/sign-in/[[...index]].js index 2dca85ef93d..7ed893d5d68 100644 --- a/pages/sign-in/[[...index]].js +++ b/pages/sign-in/[[...index]].js @@ -2,7 +2,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' // import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -11,12 +11,9 @@ import { useRouter } from 'next/router' * @returns */ const SignIn = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps(req) { diff --git a/pages/sign-up/[[...index]].js b/pages/sign-up/[[...index]].js index 39fdbe4eee7..72ba97fc02e 100644 --- a/pages/sign-up/[[...index]].js +++ b/pages/sign-up/[[...index]].js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -10,12 +10,9 @@ import { useRouter } from 'next/router' * @returns */ const SignUp = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps(req) { diff --git a/pages/tag/[tag]/index.js b/pages/tag/[tag]/index.js index 79458257f9a..ff366c5f768 100644 --- a/pages/tag/[tag]/index.js +++ b/pages/tag/[tag]/index.js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -10,13 +10,9 @@ import { useRouter } from 'next/router' * @returns */ const Tag = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps({ params: { tag }, locale }) { diff --git a/pages/tag/[tag]/page/[page].js b/pages/tag/[tag]/page/[page].js index da93f16f353..a13ebe04e33 100644 --- a/pages/tag/[tag]/page/[page].js +++ b/pages/tag/[tag]/page/[page].js @@ -1,16 +1,13 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' const Tag = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps({ params: { tag, page }, locale }) { diff --git a/pages/tag/index.js b/pages/tag/index.js index 5433a0332ff..a04a5b881f4 100644 --- a/pages/tag/index.js +++ b/pages/tag/index.js @@ -1,7 +1,7 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' -import { getLayoutByTheme } from '@/themes/theme' +import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' /** @@ -10,12 +10,9 @@ import { useRouter } from 'next/router' * @returns */ const TagIndex = props => { - // 根据页面路径加载不同Layout文件 - const Layout = getLayoutByTheme({ - theme: siteConfig('THEME'), - router: useRouter() - }) - return + const router = useRouter() + const theme = siteConfig('THEME', BLOG.THEME, props.NOTION_CONFIG) + return } export async function getStaticProps(req) { diff --git a/themes/starter/components/Header.js b/themes/starter/components/Header.js index ef69c077a69..5e3a0ff4431 100644 --- a/themes/starter/components/Header.js +++ b/themes/starter/components/Header.js @@ -86,6 +86,11 @@ export const Header = props => { + + Dashboard + diff --git a/themes/theme.js b/themes/theme.js index aa5c07e55dc..5ec1bf7666b 100644 --- a/themes/theme.js +++ b/themes/theme.js @@ -38,6 +38,16 @@ export const getGlobalLayoutByTheme = themeQuery => { } } +/** + * 动态获取布局 + * @param {*} props + */ +export const DynamicLayout = props => { + const { router, theme } = props + const SelectedLayout = getLayoutByTheme({ router, theme }) + return +} + /** * 加载主题文件 * 如果是 From 7b0efe564753b149c9ccb2bdf75ccb2d510265c1 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Tue, 19 Nov 2024 12:53:35 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=96=B0=E5=A2=9Edashboard=E7=BB=84?= =?UTF-8?q?=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- blog.config.js | 9 ++-- components/ui/dashboard/DashboardBody.js | 41 ++++++++++++++++ components/ui/dashboard/DashboardHeader.js | 41 ++++++++++++++++ components/ui/dashboard/DashboardMenuList.js | 34 ++++++++++++++ lib/utils/formatDate.js | 29 +++++++++--- middleware.ts | 42 ++++++++++------- pages/auth/index.js | 1 + pages/dashboard/{index.js => [[...index]].js} | 47 +++++-------------- themes/starter/components/Header.js | 11 +++-- themes/starter/index.js | 35 ++++++++++++++ themes/theme.js | 47 +++++++------------ 11 files changed, 242 insertions(+), 95 deletions(-) create mode 100644 components/ui/dashboard/DashboardBody.js create mode 100644 components/ui/dashboard/DashboardHeader.js create mode 100644 components/ui/dashboard/DashboardMenuList.js rename pages/dashboard/{index.js => [[...index]].js} (60%) diff --git a/blog.config.js b/blog.config.js index ed0721cccf6..3b827a953ba 100644 --- a/blog.config.js +++ b/blog.config.js @@ -127,7 +127,8 @@ const BLOG = { '/[prefix]/[slug]/[...suffix]': 'LayoutSlug', '/auth/result': 'LayoutAuth', '/sign-in/[[...index]]': 'LayoutSignIn', - '/sign-up/[[...index]]': 'LayoutSignUp' + '/sign-up/[[...index]]': 'LayoutSignUp', + '/dashboard/[[...index]]': 'LayoutDashboard' }, CAN_COPY: process.env.NEXT_PUBLIC_CAN_COPY || true, // 是否允许复制页面内容 默认允许,如果设置为false、则全栈禁止复制内容。 @@ -252,7 +253,7 @@ const BLOG = { ], // 鼠标跟随特效 - MOUSE_FOLLOW: process.env.NEXT_PUBLIC_MOUSE_FOLLOW || true, // 开关 + MOUSE_FOLLOW: process.env.NEXT_PUBLIC_MOUSE_FOLLOW || false, // 开关 // 这两个只有在鼠标跟随特效开启时才生效 // 鼠标类型 1:路劲散点 2:下降散点 3:上升散点 4:边缘向鼠标移动散点 5:跟踪转圈散点 6:路径线条 7:聚集散点 8:聚集网格 9:移动网格 10:上升粒子 11:转圈随机颜色粒子 12:圆锥放射跟随蓝色粒子 MOUSE_FOLLOW_EFFECT_TYPE: 11, // 1-12 @@ -551,7 +552,9 @@ const BLOG = { VERSION: (() => { try { // 优先使用环境变量,否则从package.json中获取版本号 - return process.env.NEXT_PUBLIC_VERSION || require('./package.json').version + return ( + process.env.NEXT_PUBLIC_VERSION || require('./package.json').version + ) } catch (error) { console.warn('Failed to load package.json version:', error) return '1.0.0' // 缺省版本号 diff --git a/components/ui/dashboard/DashboardBody.js b/components/ui/dashboard/DashboardBody.js new file mode 100644 index 00000000000..39805b2775b --- /dev/null +++ b/components/ui/dashboard/DashboardBody.js @@ -0,0 +1,41 @@ +'use client' +import { UserProfile } from '@clerk/nextjs' +import { useRouter } from 'next/router' +import DashboardMenuList from './DashboardMenuList' + +/** + * 仪表盘内容主体 + * 组件懒加载 + * @returns + */ +export default function DashboardBody() { + const asPath = useRouter()?.asPath + + return ( +
+
+ +
+
+ {asPath === '/dashboard' &&
控制台首页
} + {(asPath === '/dashboard/user-profile' || + asPath === '/dashboard/user-profile/security') && ( + + )} + {asPath === '/dashboard/membership' &&
会员
} + {asPath === '/dashboard/order' &&
订单
} + {asPath === '/dashboard/favorite' &&
收藏
} +
+
+ ) +} diff --git a/components/ui/dashboard/DashboardHeader.js b/components/ui/dashboard/DashboardHeader.js new file mode 100644 index 00000000000..53ba3db2ba5 --- /dev/null +++ b/components/ui/dashboard/DashboardHeader.js @@ -0,0 +1,41 @@ +import LazyImage from '@/components/LazyImage' +import { useGlobal } from '@/lib/global' +import formatDate from '@/lib/utils/formatDate' +import { SignOutButton } from '@clerk/nextjs' +/** + * 仪表盘页头 + * @returns + */ +export default function DashboardHeader() { + const { user } = useGlobal() + + return ( +
+ {/* 头像昵称 */} +
+ +
+
{user?.fullName}
+
+ {user?.username} + {formatDate(user?.createdAt)} +
+
+
+ {/* 登出按钮 */} +
+ + + +
+
+ ) +} diff --git a/components/ui/dashboard/DashboardMenuList.js b/components/ui/dashboard/DashboardMenuList.js new file mode 100644 index 00000000000..0a3e6bfef8b --- /dev/null +++ b/components/ui/dashboard/DashboardMenuList.js @@ -0,0 +1,34 @@ +import Link from 'next/link' + +/** + * 仪表盘菜单 + * @returns + */ +export default function DashboardMenuList() { + const dashBoardMenus = [ + { title: '控制台', href: '/dashboard' }, + { title: '基础资料', href: '/dashboard/user-profile' }, + { title: '我的会员', href: '/dashboard/membership' }, + { title: '我的订单', href: '/dashboard/order' }, + { title: '我的收藏', href: '/dashboard/favorite' } + ] + return ( +
    + {dashBoardMenus?.map((item, index) => ( +
  • + + {item.title} + +
  • + ))} +
+ ) +} diff --git a/lib/utils/formatDate.js b/lib/utils/formatDate.js index 29190e3b051..c40a5135341 100644 --- a/lib/utils/formatDate.js +++ b/lib/utils/formatDate.js @@ -1,22 +1,31 @@ +import BLOG from '@/blog.config' + /** * 格式化日期 * @param date * @param local * @returns {string} */ -export default function formatDate (date, local) { +export default function formatDate(date, local = BLOG.LANG) { if (!date || !local) return date || '' const d = new Date(date) const options = { year: 'numeric', month: 'short', day: 'numeric' } const res = d.toLocaleDateString(local, options) // 如果格式是中文日期,则转为横杆 - const format = local.slice(0, 2).toLowerCase() === 'zh' - ? res.replace('年', '-').replace('月', '-').replace('日', '') - : res + const format = + local.slice(0, 2).toLowerCase() === 'zh' + ? res.replace('年', '-').replace('月', '-').replace('日', '') + : res return format } -export function formatDateFmt (timestamp, fmt) { +/** + * 时间戳格式化 + * @param {*} timestamp + * @param {*} fmt + * @returns + */ +export function formatDateFmt(timestamp, fmt) { const date = new Date(timestamp) const o = { 'M+': date.getMonth() + 1, // 月份 @@ -28,11 +37,17 @@ export function formatDateFmt (timestamp, fmt) { S: date.getMilliseconds() // 毫秒 } if (/(y+)/.test(fmt)) { - fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)) + fmt = fmt.replace( + RegExp.$1, + (date.getFullYear() + '').substr(4 - RegExp.$1.length) + ) } for (const k in o) { if (new RegExp('(' + k + ')').test(fmt)) { - fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))) + fmt = fmt.replace( + RegExp.$1, + RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length) + ) } } return fmt.trim() diff --git a/middleware.ts b/middleware.ts index 0ae00a72c9d..dc623d08935 100644 --- a/middleware.ts +++ b/middleware.ts @@ -12,7 +12,9 @@ export const config = { // 限制登录访问的路由 const isTenantRoute = createRouteMatcher([ '/user/organization-selector(.*)', - '/user/orgid/(.*)' + '/user/orgid/(.*)', + '/dashboard', + '/dashboard/(.*)' ]) // 限制权限访问的路由 @@ -32,27 +34,35 @@ const noAuthMiddleware = async (req: any, ev: any) => { // 如果没有配置 Clerk 相关环境变量,返回一个默认响应或者继续处理请求 return NextResponse.next() } - /** * 鉴权中间件 */ const authMiddleware = process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY - ? clerkMiddleware( - (auth, req) => { - // 限制管理员路由访问权限 - if (isTenantAdminRoute(req)) { - auth().protect(has => { - return ( - has({ permission: 'org:sys_memberships:manage' }) || - has({ permission: 'org:sys_domains_manage' }) - ) - }) + ? clerkMiddleware(async (auth, req) => { + const { userId } = auth() + // 处理 /dashboard 路由的登录保护 + if (isTenantRoute(req)) { + if (!userId) { + // 用户未登录,重定向到 /sign-in + const url = new URL('/sign-in', req.url) + url.searchParams.set('redirectTo', req.url) // 保存重定向目标 + return NextResponse.redirect(url) } - // 限制组织路由访问权限 - if (isTenantRoute(req)) auth().protect() } - // { debug: process.env.npm_lifecycle_event === 'dev' } // 开发调试模式打印日志 - ) + + // 处理管理员相关权限保护 + if (isTenantAdminRoute(req)) { + auth().protect(has => { + return ( + has({ permission: 'org:sys_memberships:manage' }) || + has({ permission: 'org:sys_domains_manage' }) + ) + }) + } + + // 默认继续处理请求 + return NextResponse.next() + }) : noAuthMiddleware export default authMiddleware diff --git a/pages/auth/index.js b/pages/auth/index.js index 26aea479c71..cce744d9233 100644 --- a/pages/auth/index.js +++ b/pages/auth/index.js @@ -97,4 +97,5 @@ const fetchToken = async code => { console.error('Error fetching token', error) } } + export default UI diff --git a/pages/dashboard/index.js b/pages/dashboard/[[...index]].js similarity index 60% rename from pages/dashboard/index.js rename to pages/dashboard/[[...index]].js index 824ad6f3b4d..5dfca79f47d 100644 --- a/pages/dashboard/index.js +++ b/pages/dashboard/[[...index]].js @@ -1,9 +1,6 @@ import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData, getPost, getPostBlocks } from '@/lib/db/getSiteData' -import { getPageTableOfContents } from '@/lib/notion/getPageTableOfContents' -import { uploadDataToAlgolia } from '@/lib/plugins/algolia' -import { getRecommendPost } from '@/lib/utils/post' import { DynamicLayout } from '@/themes/theme' import { useRouter } from 'next/router' @@ -63,38 +60,6 @@ export async function getStaticProps({ locale }) { props.post.blockMap = await getPostBlocks(props.post.id, from) } - // 目录默认加载 - if (props.post?.blockMap?.block) { - props.post.content = Object.keys(props.post.blockMap.block).filter( - key => props.post.blockMap.block[key]?.value?.parent_id === props.post.id - ) - props.post.toc = getPageTableOfContents(props.post, props.post.blockMap) - } - - // 生成全文索引 && process.env.npm_lifecycle_event === 'build' && JSON.parse(BLOG.ALGOLIA_RECREATE_DATA) - if (BLOG.ALGOLIA_APP_ID) { - uploadDataToAlgolia(props?.post) - } - - // 推荐关联文章处理 - const allPosts = props.allPages?.filter( - page => page.type === 'Post' && page.status === 'Published' - ) - if (allPosts && allPosts.length > 0) { - const index = allPosts.indexOf(props.post) - props.prev = allPosts.slice(index - 1, index)[0] ?? allPosts.slice(-1)[0] - props.next = allPosts.slice(index + 1, index + 2)[0] ?? allPosts[0] - props.recommendPosts = getRecommendPost( - props.post, - allPosts, - siteConfig('POST_RECOMMEND_COUNT') - ) - } else { - props.prev = null - props.next = null - props.recommendPosts = [] - } - delete props.allPages return { props, @@ -108,4 +73,16 @@ export async function getStaticProps({ locale }) { } } +export const getStaticPaths = async () => { + return { + // 定义需要预渲染的路径 + paths: [ + { params: { index: [''] } }, // 对应 /dashboard + { params: { index: ['membership'] } }, // 对应 /dashboard/membership + { params: { index: ['order'] } }, // 对应 /dashboard/order + { params: { index: ['favorite'] } } // 对应 /dashboard/favorite + ], + fallback: 'blocking' // 或者 true,阻塞式渲染 + } +} export default Dashboard diff --git a/themes/starter/components/Header.js b/themes/starter/components/Header.js index 5e3a0ff4431..8a0e898b7e6 100644 --- a/themes/starter/components/Header.js +++ b/themes/starter/components/Header.js @@ -86,12 +86,13 @@ export const Header = props => { - - Dashboard - + + )} diff --git a/themes/starter/index.js b/themes/starter/index.js index 3ae161f6ea3..0ba751d4356 100644 --- a/themes/starter/index.js +++ b/themes/starter/index.js @@ -27,6 +27,8 @@ import { Style } from './style' import Comment from '@/components/Comment' import replaceSearchResult from '@/components/Mark' import ShareBar from '@/components/ShareBar' +import DashboardBody from '@/components/ui/dashboard/DashboardBody' +import DashboardHeader from '@/components/ui/dashboard/DashboardHeader' import { useGlobal } from '@/lib/global' import { loadWowJS } from '@/lib/plugins/wow' import { SignIn, SignUp } from '@clerk/nextjs' @@ -176,7 +178,39 @@ const LayoutSlug = props => { ) } +/** + * 仪表盘 + * @param {*} props + * @returns + */ +const LayoutDashboard = props => { + const { post } = props + + return ( + <> +
+
+
+ {post && ( +
+ +
+ )} +
+
+
+ {/* 仪表盘 */} + + + + ) +} +/** + * 搜索 + * @param {*} props + * @returns + */ const LayoutSearch = props => { const { keyword } = props const router = useRouter() @@ -491,6 +525,7 @@ export { LayoutArchive, LayoutBase, LayoutCategoryIndex, + LayoutDashboard, LayoutIndex, LayoutPostList, LayoutSearch, diff --git a/themes/theme.js b/themes/theme.js index 5ec1bf7666b..884a26f32eb 100644 --- a/themes/theme.js +++ b/themes/theme.js @@ -50,46 +50,34 @@ export const DynamicLayout = props => { /** * 加载主题文件 - * 如果是 * @param {*} router + * @param {*} theme * @returns */ export const getLayoutByTheme = ({ router, theme }) => { const themeQuery = getQueryParam(router.asPath, 'theme') || theme - if (themeQuery !== BLOG.THEME) { + const layoutName = getLayoutNameByPath(router.pathname, router.asPath) + const isDefaultTheme = !themeQuery || themeQuery === BLOG.THEME + + const loadThemeComponents = componentsSource => { + const components = + componentsSource[layoutName] || componentsSource.LayoutSlug + setTimeout(fixThemeDOM, isDefaultTheme ? 100 : 500) // 根据主题选择延迟时间 + return components + } + + if (isDefaultTheme) { + return loadThemeComponents(ThemeComponents) + } else { return dynamic( - () => - import(`@/themes/${themeQuery}`).then(m => { - setTimeout(() => { - checkThemeDOM() - }, 500) - - const components = - m[getLayoutNameByPath(router.pathname, router.asPath)] - if (components) { - return components - } else { - return m.LayoutSlug - } - }), + () => import(`@/themes/${themeQuery}`).then(m => loadThemeComponents(m)), { ssr: true } ) - } else { - setTimeout(() => { - checkThemeDOM() - }, 100) - const components = - ThemeComponents[getLayoutNameByPath(router.pathname, router.asPath)] - if (components) { - return components - } else { - return ThemeComponents.LayoutSlug - } } } /** - * 根据路径 获取对应的layout + * 根据路径 获取对应的layout名称 * @param {*} path * @returns */ @@ -101,8 +89,9 @@ const getLayoutNameByPath = path => { /** * 切换主题时的特殊处理 + * 删除多余的元素 */ -const checkThemeDOM = () => { +const fixThemeDOM = () => { if (isBrowser) { const elements = document.querySelectorAll('[id^="theme-"]') if (elements?.length > 1) { From ed947d866ee257a5d44efcb190a700900bded0c1 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Tue, 19 Nov 2024 14:44:32 +0800 Subject: [PATCH 3/5] =?UTF-8?q?Gitbook=20=E4=B8=BB=E9=A2=98=EF=BC=9B?= =?UTF-8?q?=E5=BA=95=E9=83=A8=E8=8F=9C=E5=8D=95=E6=A0=B7=E5=BC=8F=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/gitbook/components/BottomMenuBar.js | 47 ++++++++++++++----- .../gitbook/components/MobileButtonCatalog.js | 31 ------------ .../gitbook/components/MobileButtonPageNav.js | 30 ------------ 3 files changed, 35 insertions(+), 73 deletions(-) delete mode 100644 themes/gitbook/components/MobileButtonCatalog.js delete mode 100644 themes/gitbook/components/MobileButtonPageNav.js diff --git a/themes/gitbook/components/BottomMenuBar.js b/themes/gitbook/components/BottomMenuBar.js index 478a52eb8f7..c872941b56b 100644 --- a/themes/gitbook/components/BottomMenuBar.js +++ b/themes/gitbook/components/BottomMenuBar.js @@ -1,5 +1,5 @@ -import MobileButtonCatalog from './MobileButtonCatalog' -import MobileButtonPageNav from './MobileButtonPageNav' +import { useGlobal } from '@/lib/global' +import { useGitBookGlobal } from '..' /** * 移动端底部导航 @@ -8,20 +8,43 @@ import MobileButtonPageNav from './MobileButtonPageNav' */ export default function BottomMenuBar({ post, className }) { const showTocButton = post?.toc?.length > 1 + const { locale } = useGlobal() + const { pageNavVisible, changePageNavVisible, tocVisible, changeTocVisible } = + useGitBookGlobal() + const togglePageNavVisible = () => { + changePageNavVisible(!pageNavVisible) + } + + const toggleToc = () => { + changeTocVisible(!tocVisible) + } return ( - <> - {/* 移动端底部导航按钮 */} -
-
- -
+
+
+ + {showTocButton && ( -
- -
+ )}
- +
) } diff --git a/themes/gitbook/components/MobileButtonCatalog.js b/themes/gitbook/components/MobileButtonCatalog.js deleted file mode 100644 index e9e8b4e0ebb..00000000000 --- a/themes/gitbook/components/MobileButtonCatalog.js +++ /dev/null @@ -1,31 +0,0 @@ -import { useGlobal } from '@/lib/global' -import { useGitBookGlobal } from '@/themes/gitbook' - -/** - * 移动端目录按钮 - */ -export default function MobileButtonCatalog() { - const { tocVisible, changeTocVisible } = useGitBookGlobal() - const { locale } = useGlobal() - - const toggleToc = () => { - changeTocVisible(!tocVisible) - } - - return ( - - ) -} diff --git a/themes/gitbook/components/MobileButtonPageNav.js b/themes/gitbook/components/MobileButtonPageNav.js deleted file mode 100644 index 78f038f1f3f..00000000000 --- a/themes/gitbook/components/MobileButtonPageNav.js +++ /dev/null @@ -1,30 +0,0 @@ -import { useGlobal } from '@/lib/global' -import { useGitBookGlobal } from '@/themes/gitbook' - -/** - * 移动端文章导航按钮 - */ -export default function MobileButtonPageNav() { - const { pageNavVisible, changePageNavVisible } = useGitBookGlobal() - const { locale } = useGlobal() - const togglePageNavVisible = () => { - changePageNavVisible(!pageNavVisible) - } - - return ( - - ) -} From 2988426a2f1ebbd376b482aec1e345c1e75ccd20 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Tue, 19 Nov 2024 19:00:57 +0800 Subject: [PATCH 4/5] =?UTF-8?q?starter\magzine\gitbook=20=E4=B8=BB?= =?UTF-8?q?=E9=A2=98dashboard=E5=85=83=E7=B4=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/ui/dashboard/DashboardBody.js | 34 ++- components/ui/dashboard/DashboardButton.js | 27 ++ components/ui/dashboard/DashboardHeader.js | 60 +++-- .../ui/dashboard/DashboardItemAffliate.js | 187 +++++++++++++ .../ui/dashboard/DashboardItemBalance.js | 137 ++++++++++ components/ui/dashboard/DashboardItemHome.js | 64 +++++ .../ui/dashboard/DashboardItemMembership.js | 125 +++++++++ components/ui/dashboard/DashboardItemOrder.js | 246 ++++++++++++++++++ components/ui/dashboard/DashboardMenuList.js | 61 +++-- next.config.js | 1 + pages/404.js | 1 + pages/dashboard/[[...index]].js | 13 +- themes/gitbook/index.js | 39 ++- themes/magzine/components/Header.js | 8 +- themes/magzine/index.js | 34 ++- themes/starter/components/Header.js | 8 +- themes/starter/components/MenuItem.js | 4 +- themes/starter/index.js | 1 + themes/theme.js | 49 +++- 19 files changed, 1018 insertions(+), 81 deletions(-) create mode 100644 components/ui/dashboard/DashboardButton.js create mode 100644 components/ui/dashboard/DashboardItemAffliate.js create mode 100644 components/ui/dashboard/DashboardItemBalance.js create mode 100644 components/ui/dashboard/DashboardItemHome.js create mode 100644 components/ui/dashboard/DashboardItemMembership.js create mode 100644 components/ui/dashboard/DashboardItemOrder.js diff --git a/components/ui/dashboard/DashboardBody.js b/components/ui/dashboard/DashboardBody.js index 39805b2775b..89b60329b42 100644 --- a/components/ui/dashboard/DashboardBody.js +++ b/components/ui/dashboard/DashboardBody.js @@ -1,25 +1,34 @@ 'use client' import { UserProfile } from '@clerk/nextjs' +import dynamic from 'next/dynamic' import { useRouter } from 'next/router' -import DashboardMenuList from './DashboardMenuList' +const DashboardMenuList = dynamic(() => import('./DashboardMenuList')) +const DashboardItemMembership = dynamic( + () => import('./DashboardItemMembership') +) +const DashboardItemBalance = dynamic(() => import('./DashboardItemBalance')) +const DashboardItemHome = dynamic(() => import('./DashboardItemHome')) +const DashboardItemOrder = dynamic(() => import('./DashboardItemOrder')) +const DashboardItemAffliate = dynamic(() => import('./DashboardItemAffliate')) /** * 仪表盘内容主体 * 组件懒加载 * @returns */ export default function DashboardBody() { - const asPath = useRouter()?.asPath - + const { asPath } = useRouter() + // 提取不包含查询参数的路径部分 + const basePath = asPath.split('?')[0] return ( -
-
+
+
-
- {asPath === '/dashboard' &&
控制台首页
} - {(asPath === '/dashboard/user-profile' || - asPath === '/dashboard/user-profile/security') && ( +
+ {basePath === '/dashboard' && } + {(basePath === '/dashboard/user-profile' || + basePath === '/dashboard/user-profile/security') && ( )} - {asPath === '/dashboard/membership' &&
会员
} - {asPath === '/dashboard/order' &&
订单
} - {asPath === '/dashboard/favorite' &&
收藏
} + {basePath === '/dashboard/balance' && } + {basePath === '/dashboard/membership' && } + {basePath === '/dashboard/order' && } + {basePath === '/dashboard/affiliate' && }
) diff --git a/components/ui/dashboard/DashboardButton.js b/components/ui/dashboard/DashboardButton.js new file mode 100644 index 00000000000..5f382f1a8a4 --- /dev/null +++ b/components/ui/dashboard/DashboardButton.js @@ -0,0 +1,27 @@ +import { siteConfig } from '@/lib/config' +import Link from 'next/link' +import { useRouter } from 'next/router' +/** + * 跳转仪表盘的按钮 + * @returns + */ +export default function DashboardButton() { + const { asPath } = useRouter() + const enableDashboardButton = siteConfig('ENABLE_DASHBOARD_BUTTON', false) + + if (!enableDashboardButton) { + return null + } + + if (asPath?.indexOf('/dashboard') === 0) { + return null + } + + return ( + + ) +} diff --git a/components/ui/dashboard/DashboardHeader.js b/components/ui/dashboard/DashboardHeader.js index 53ba3db2ba5..7542eea1cce 100644 --- a/components/ui/dashboard/DashboardHeader.js +++ b/components/ui/dashboard/DashboardHeader.js @@ -2,6 +2,7 @@ import LazyImage from '@/components/LazyImage' import { useGlobal } from '@/lib/global' import formatDate from '@/lib/utils/formatDate' import { SignOutButton } from '@clerk/nextjs' +import Link from 'next/link' /** * 仪表盘页头 * @returns @@ -10,32 +11,43 @@ export default function DashboardHeader() { const { user } = useGlobal() return ( -
- {/* 头像昵称 */} -
- -
-
{user?.fullName}
-
- {user?.username} - {formatDate(user?.createdAt)} + <> +
+ {/* 头像昵称 */} +
+ + +
+
+ {user?.fullName} + + + 普通用户 + + +
+
+ {user?.username} + {formatDate(user?.createdAt)} +
+ + {/* 登出按钮 */} +
+ + + +
- {/* 登出按钮 */} -
- - - -
-
+ ) } diff --git a/components/ui/dashboard/DashboardItemAffliate.js b/components/ui/dashboard/DashboardItemAffliate.js new file mode 100644 index 00000000000..443e0ac7a8d --- /dev/null +++ b/components/ui/dashboard/DashboardItemAffliate.js @@ -0,0 +1,187 @@ +import Link from 'next/link' + +/** + * 联盟行销 + * @returns + */ +export default function DashboardItemAffliate() { + const cards = [ + { + title: '¥0.00', + desc: '累计佣金', + className: 'bg-blue-600 hover:bg-blue-700 text-white' + }, + { + title: '¥0.00', + desc: '已提现', + className: 'bg-cyan-600 hover:bg-cyan-700 text-white' + }, + { + title: '¥0.00', + desc: '提现中', + className: 'bg-pink-600 hover:bg-pink-700 text-white' + }, + { + title: '¥0.00', + desc: '可提现', + className: 'bg-emerald-600 hover:bg-emerald-700 text-white' + } + ] + + return ( +
+
+ {cards?.map((card, index) => ( +
+
+ {card.title} +
+

{card.desc}

+
+ ))} +
+
+
+
+ + +
+
+ + +
+ +
+ + +
+
+ +
+ +
+
+ + +
+ +
+ + +
+
+ +
+
+ +
+ +
+
+ + +
+ +
    +
  • 推广说明:
  • +
  • 这只是一个演示页面,不存在真实功能!
  • +
  • + 如需提现请联系网站管理员,发送您的账号信息和收款码进行人工提现 +
  • +
  • + 如果用户是通过您的推广链接购买的资源或者开通会员,则按照推广佣金比列奖励到您的佣金中 +
  • +
  • + 如果用户是通过您的链接新注册的用户,推荐人是您,该用户购买资都会给你佣金 +
  • +
  • + 如果用户是你的下级,用户使用其他推荐人链接购买,以上下级关系为准,优先给注册推荐人而不是推荐链接 +
  • +
  • 推广奖励金额保留一位小数点四舍五入。0.1之类的奖励金额不计算
  • +
  • + 前台无法查看推广订单详情,如需查看详情可联系管理员截图查看详细记录和时间 +
  • +
+
+
+ ) +} diff --git a/components/ui/dashboard/DashboardItemBalance.js b/components/ui/dashboard/DashboardItemBalance.js new file mode 100644 index 00000000000..4c623f6ee72 --- /dev/null +++ b/components/ui/dashboard/DashboardItemBalance.js @@ -0,0 +1,137 @@ +import { useEffect, useState } from 'react' + +/** + * 余额 + * @returns + */ +export default function DashboardItemBalance() { + const [selectedCard, setSelectedCard] = useState(null) + const [amount, setAmount] = useState(0) + + const cards = [ + { + title: '0 积分', + desc: '当前余额', + className: 'bg-blue-600 hover:bg-blue-700 text-white' + }, + { + title: '0 积分', + desc: '累计消费', + className: 'bg-cyan-600 hover:bg-cyan-700 text-white' + }, + { + title: '0', + desc: '累计佣金', + className: 'bg-pink-600 hover:bg-pink-700 text-white' + } + ] + + const cardData = [ + { points: '1积分', price: '¥1' }, + { points: '10积分', price: '¥10' }, + { points: '50积分', price: '¥50' }, + { points: '100积分', price: '¥100' }, + { points: '300积分', price: '¥300' }, + { points: '500积分', price: '¥500' } + ] + + const handleCardSelect = index => { + setSelectedCard(index) + } + + const handleAmountChange = e => { + const value = e.target.value + setAmount(value) + } + + useEffect(() => { + if (selectedCard !== null) { + // 如果用户选中了充值卡片,则自动更新支付金额 + const selectedPrice = cardData[selectedCard]?.price + if (selectedPrice) { + setAmount(selectedPrice.replace('¥', '')) + } + } + }, [selectedCard]) + + return ( +
+
+

余额充值中心

+
+
+ + {/* 余额卡片 */} +
+ {cards?.map((card, index) => ( +
handleCardSelect(index)}> +
+ {card.title} +
+

{card.desc}

+
+ ))} +
+ +
+
充值项目(充值比例:1元=1积分)
+ {/* 充值选项 */} +
+ {cardData?.map((item, index) => ( +
handleCardSelect(index)}> +

{item.points}

+ {item.price} +
+ ))} +
+
+ +
+
+ + +
+
+ +
+
+ 支付金额:¥{amount} +
+ +
+ +
    +
  • 充值说明:
  • +
  • 这只是一个演示页面,不存在真实功能!
  • +
  • 充值最低额度为1积分
  • +
  • 充值汇率为1元=1积分,人民币和积分不能互相转换
  • +
  • 余额永久有效,无时间限制
  • +
+
+
+ ) +} diff --git a/components/ui/dashboard/DashboardItemHome.js b/components/ui/dashboard/DashboardItemHome.js new file mode 100644 index 00000000000..2988aec3f89 --- /dev/null +++ b/components/ui/dashboard/DashboardItemHome.js @@ -0,0 +1,64 @@ +/** + * 首页组件 + * @returns + */ +export default function DashboardItemHome() { + return ( +
+ {/* 提示消息 */} +
+ 注意!{' '} + 整个后台都只是页面效果,仅供演示查看,没有对接实际功能。 +
+ + {/* 页面说明 */} +
+

+ 欢迎来到用户中心页面!在这里,您可以查看用户的账号信息与业务订单概况。 +

+
+ + {/* 进度条 */} +
+

当前任务进度

+
+
+
+

+ 任务进度:75% +

+
+ + {/* 背景动画块 */} +
+
+
+

实时数据分析

+

监控您的系统数据,查看实时变化

+
+
+ + {/* 数据卡片模块 */} +
+
+

今日访问量

+

1,245

+
+
+

用户总数

+

12,300

+
+
+

+ 系统健康状态 +

+

正常

+
+
+
+ ) +} diff --git a/components/ui/dashboard/DashboardItemMembership.js b/components/ui/dashboard/DashboardItemMembership.js new file mode 100644 index 00000000000..ab0b61b96a5 --- /dev/null +++ b/components/ui/dashboard/DashboardItemMembership.js @@ -0,0 +1,125 @@ +import { useEffect, useState } from 'react' + +/** + * 会员 + * @returns + */ +export default function DashboardItemMembership() { + const [selectedMembership, setSelectedMembership] = useState(null) + const [amount, setAmount] = useState(0) + + const memberships = [ + { + title: '年度会员', + points: 98, + duration: '365天', + benefits: [ + '日更5到20个热门项目', + '全站资源免费获取', + '内部会员专属交流群', + '可补差价升级', + '推广佣金高达40%' + ] + }, + { + title: '永久会员', + points: 138, + duration: '永久', + benefits: [ + '日更5到20个热门项目', + '全站资源免费获取', + '内部会员专属交流群', + '可补差价升级', + '推广佣金高达70%' + ] + }, + { + title: '站长训练营', + points: 1998, + duration: '永久', + benefits: [ + '站长学员请联系助理对接', + '一对一扶持搭建网站', + '提供独家引流技术照做就能成功', + '全站素材直接复刻到学员新站', + '软件一键同步更新', + '学员专属社群及交流群', + '设立高额福利的打卡机制(增强学员执行力)' + ] + } + ] + + const handleMembershipSelect = index => { + setSelectedMembership(index) + setAmount(memberships[index].points) + } + + const handleAmountChange = e => { + const value = e.target.value + setAmount(value) + } + + useEffect(() => { + if (selectedMembership !== null) { + // 如果用户选中了会员,自动更新支付金额 + const selectedPoints = memberships[selectedMembership]?.points + if (selectedPoints) { + setAmount(selectedPoints) + } + } + }, [selectedMembership]) + + return ( +
+
+

会员注册

+
+
+ + {/* 会员卡片 */} +
+ {memberships.map((membership, index) => ( +
handleMembershipSelect(index)}> +
+ {membership.title} +
+

所需积分:{membership.points} 积分

+

会员时长:{membership.duration}

+
    + {membership.benefits.map((benefit, i) => ( +
  • {benefit}
  • + ))} +
+
+ ))} +
+ +
+
+
+ 支付金额:¥{amount} +
+ +
+ +
    +
  • 开通会员说明:
  • +
  • 这只是一个演示页面,不存在真实功能!
  • +
  • 本站会员账号权限为虚拟数字资源,开通后不可退款
  • +
  • 开通会员后可享有对应会员特权的商品折扣,免费权限
  • +
  • 会员特权到期后不享受特权
  • +
  • 重复购买特权到期时间累计增加
  • +
+
+
+ ) +} diff --git a/components/ui/dashboard/DashboardItemOrder.js b/components/ui/dashboard/DashboardItemOrder.js new file mode 100644 index 00000000000..37acc4662a5 --- /dev/null +++ b/components/ui/dashboard/DashboardItemOrder.js @@ -0,0 +1,246 @@ +import { useState } from 'react' + +/** + * 订单列表 + */ +export default function DashboardItemOrder() { + const [currentPage, setCurrentPage] = useState(1) + + const totalPages = 5 + + const columns = [ + { key: 'name', label: '商品名称' }, + { key: 'color', label: '颜色' }, + { key: 'category', label: '分类' }, + { + key: 'accessories', + label: '配件', + render: value => (value ? '是' : '否') + }, + { key: 'available', label: '库存', render: value => (value ? '有' : '无') }, + { key: 'price', label: '价格', render: value => `¥${value}` }, + { key: 'weight', label: '重量' }, + { + key: 'action', + label: '操作', + render: () => ( + + ) + } + ] + + const data = [ + { + name: '苹果 MacBook Pro 17"', + color: '银色', + category: '笔记本', + accessories: true, + available: true, + price: 2999, + weight: '3.0 公斤' + }, + { + name: '微软 Surface Pro', + color: '白色', + category: '笔记本电脑', + accessories: false, + available: true, + price: 1999, + weight: '1.0 公斤' + }, + { + name: 'Magic Mouse 2', + color: '黑色', + category: '配件', + accessories: true, + available: false, + price: 99, + weight: '0.2 公斤' + }, + { + name: '苹果手表', + color: '黑色', + category: '手表', + accessories: true, + available: false, + price: 199, + weight: '0.12 公斤' + }, + { + name: 'iPad Pro', + color: '金色', + category: '平板电脑', + accessories: false, + available: true, + price: 699, + weight: '1.3 公斤' + } + ] + + const onPageChange = page => { + if (page >= 1 && page <= totalPages) { + setCurrentPage(page) + } + } + + return ( +
+
+ + +
    +
  • 订单说明:
  • +
  • 这只是一个演示页面,不存在真实功能!
  • +
+ + + ) +} + +/** + * 分页组件 + */ +const Pagination = ({ currentPage, totalPages, onPageChange }) => { + const pages = Array.from({ length: totalPages }, (_, i) => i + 1) + + return ( + + ) +} + +/** + * 表格组件 + */ +const Table = ({ columns, data }) => { + return ( +
+
+ {/* 表头 */} + + + + {columns.map((column, index) => ( + + ))} + + + {/* 表格内容 */} + + {data.map((item, index) => ( + + + {columns.map((column, colIndex) => ( + + ))} + + ))} + +
+
+ + +
+
+ {column.label} +
+
+ + +
+
+ {column.render + ? column.render(item[column.key]) + : item[column.key]} +
+
+ ) +} diff --git a/components/ui/dashboard/DashboardMenuList.js b/components/ui/dashboard/DashboardMenuList.js index 0a3e6bfef8b..b0ffed2ada4 100644 --- a/components/ui/dashboard/DashboardMenuList.js +++ b/components/ui/dashboard/DashboardMenuList.js @@ -1,34 +1,57 @@ import Link from 'next/link' +/** + * 仪表盘菜单 + * @returns + */ +import { useRouter } from 'next/router' + /** * 仪表盘菜单 * @returns */ export default function DashboardMenuList() { + const { asPath } = useRouter() // 获取当前路径 const dashBoardMenus = [ - { title: '控制台', href: '/dashboard' }, - { title: '基础资料', href: '/dashboard/user-profile' }, - { title: '我的会员', href: '/dashboard/membership' }, - { title: '我的订单', href: '/dashboard/order' }, - { title: '我的收藏', href: '/dashboard/favorite' } + { title: '仪表盘', icon: 'fas fa-gauge', href: '/dashboard' }, + { title: '基础资料', icon: 'fas fa-user', href: '/dashboard/user-profile' }, + { title: '我的余额', icon: 'fas fa-coins', href: '/dashboard/balance' }, + { title: '我的会员', icon: 'fas fa-gem', href: '/dashboard/membership' }, + { + title: '我的订单', + icon: 'fas fa-cart-shopping', + href: '/dashboard/order' + }, + { + title: '推广中心', + icon: 'fas fa-hand-holding-usd', + href: '/dashboard/affiliate' + } ] + return (
    - {dashBoardMenus?.map((item, index) => ( -
  • - - {item.title} - -
  • - ))} + className='side-tabs-list bg-white border rounded-lg shadow-lg p-2 space-y-2 mb-6'> + {dashBoardMenus.map((item, index) => { + // 判断当前菜单是否高亮 + const isActive = asPath === item.href + return ( +
  • + + + {item.title} + +
  • + ) + })}
) } diff --git a/next.config.js b/next.config.js index 00d086651aa..585c54357ed 100644 --- a/next.config.js +++ b/next.config.js @@ -220,6 +220,7 @@ const nextConfig = { // export 静态导出时 忽略/pages/sitemap.xml.js , 否则和getServerSideProps这个动态文件冲突 const pages = { ...defaultPathMap } delete pages['/sitemap.xml'] + delete pages['/auth'] return pages }, publicRuntimeConfig: { diff --git a/pages/404.js b/pages/404.js index 97ea16c4614..4c58031ed8b 100644 --- a/pages/404.js +++ b/pages/404.js @@ -1,3 +1,4 @@ +import BLOG from '@/blog.config' import { siteConfig } from '@/lib/config' import { getGlobalData } from '@/lib/db/getSiteData' import { DynamicLayout } from '@/themes/theme' diff --git a/pages/dashboard/[[...index]].js b/pages/dashboard/[[...index]].js index 5dfca79f47d..0a865d927e4 100644 --- a/pages/dashboard/[[...index]].js +++ b/pages/dashboard/[[...index]].js @@ -75,14 +75,17 @@ export async function getStaticProps({ locale }) { export const getStaticPaths = async () => { return { - // 定义需要预渲染的路径 paths: [ - { params: { index: [''] } }, // 对应 /dashboard - { params: { index: ['membership'] } }, // 对应 /dashboard/membership - { params: { index: ['order'] } }, // 对应 /dashboard/order - { params: { index: ['favorite'] } } // 对应 /dashboard/favorite + { params: { index: [] } }, // 对应首页路径 + { params: { index: ['membership'] } }, + { params: { index: ['balance'] } }, + { params: { index: ['user-profile'] } }, + { params: { index: ['user-profile', 'security'] } }, // 嵌套路由,按结构传递 + { params: { index: ['order'] } }, + { params: { index: ['affiliate'] } } ], fallback: 'blocking' // 或者 true,阻塞式渲染 } } + export default Dashboard diff --git a/themes/gitbook/index.js b/themes/gitbook/index.js index 0fac89b5f9b..07197fdfbc2 100644 --- a/themes/gitbook/index.js +++ b/themes/gitbook/index.js @@ -7,6 +7,8 @@ import LoadingCover from '@/components/LoadingCover' import NotionIcon from '@/components/NotionIcon' import NotionPage from '@/components/NotionPage' import ShareBar from '@/components/ShareBar' +import DashboardBody from '@/components/ui/dashboard/DashboardBody' +import DashboardHeader from '@/components/ui/dashboard/DashboardHeader' import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { isBrowser } from '@/lib/utils' @@ -255,7 +257,9 @@ const LayoutIndex = props => { // 重定向到指定文章 router.push(index).then(() => { setTimeout(() => { - const article = document.querySelector('#article-wrapper #notion-article') + const article = document.querySelector( + '#article-wrapper #notion-article' + ) if (!article) { console.log( '请检查您的Notion数据库中是否包含此slug页面: ', @@ -309,7 +313,9 @@ const LayoutSlug = props => { setTimeout( () => { if (isBrowser) { - const article = document.querySelector('#article-wrapper #notion-article') + const article = document.querySelector( + '#article-wrapper #notion-article' + ) if (!article) { router.push('/404').then(() => { console.warn('找不到页面', router.asPath) @@ -539,11 +545,40 @@ const LayoutSignUp = props => { ) } +/** + * 仪表盘 + * @param {*} props + * @returns + */ +const LayoutDashboard = props => { + const { post } = props + + return ( + <> +
+
+
+ {post && ( +
+ +
+ )} +
+
+
+ {/* 仪表盘 */} + + + + ) +} + export { Layout404, LayoutArchive, LayoutBase, LayoutCategoryIndex, + LayoutDashboard, LayoutIndex, LayoutPostList, LayoutSearch, diff --git a/themes/magzine/components/Header.js b/themes/magzine/components/Header.js index 6464b712a70..3e4c3456825 100644 --- a/themes/magzine/components/Header.js +++ b/themes/magzine/components/Header.js @@ -1,8 +1,9 @@ import Collapse from '@/components/Collapse' import DarkModeButton from '@/components/DarkModeButton' +import DashboardButton from '@/components/ui/dashboard/DashboardButton' import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' -import { SignInButton, SignedOut, UserButton } from '@clerk/nextjs' +import { SignInButton, SignedIn, SignedOut, UserButton } from '@clerk/nextjs' import throttle from 'lodash.throttle' import { useRouter } from 'next/router' import { useEffect, useRef, useState } from 'react' @@ -200,7 +201,10 @@ export default function Header(props) { - + + + + )}
diff --git a/themes/magzine/index.js b/themes/magzine/index.js index e5165bdd771..bdfb2c72ab4 100644 --- a/themes/magzine/index.js +++ b/themes/magzine/index.js @@ -6,6 +6,8 @@ import replaceSearchResult from '@/components/Mark' import NotionPage from '@/components/NotionPage' import ShareBar from '@/components/ShareBar' import WWAds from '@/components/WWAds' +import DashboardBody from '@/components/ui/dashboard/DashboardBody' +import DashboardHeader from '@/components/ui/dashboard/DashboardHeader' import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { isBrowser } from '@/lib/utils' @@ -155,7 +157,9 @@ const LayoutSlug = props => { setTimeout( () => { if (isBrowser) { - const article = document.querySelector('#article-wrapper #notion-article') + const article = document.querySelector( + '#article-wrapper #notion-article' + ) if (!article) { router.push('/404').then(() => { console.warn('找不到页面', router.asPath) @@ -495,11 +499,39 @@ const LayoutSignUp = props => { ) } +/** + * 仪表盘 + * @param {*} props + * @returns + */ +const LayoutDashboard = props => { + const { post } = props + + return ( + <> +
+
+
+ {post && ( +
+ +
+ )} +
+
+
+ {/* 仪表盘 */} + + + + ) +} export { Layout404, LayoutArchive, LayoutBase, LayoutCategoryIndex, + LayoutDashboard, LayoutIndex, LayoutPostList, LayoutSearch, diff --git a/themes/starter/components/Header.js b/themes/starter/components/Header.js index 8a0e898b7e6..7a88df87e8a 100644 --- a/themes/starter/components/Header.js +++ b/themes/starter/components/Header.js @@ -1,4 +1,5 @@ /* eslint-disable no-unreachable */ +import DashboardButton from '@/components/ui/dashboard/DashboardButton' import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { SignedIn, SignedOut, UserButton } from '@clerk/nextjs' @@ -87,12 +88,7 @@ export const Header = props => { - - + )} diff --git a/themes/starter/components/MenuItem.js b/themes/starter/components/MenuItem.js index ff184f36b0e..3e32a08b9b9 100644 --- a/themes/starter/components/MenuItem.js +++ b/themes/starter/components/MenuItem.js @@ -42,7 +42,7 @@ export const MenuItem = ({ link }) => { -
+
{link.subMenus.map((sLink, index) => { return ( { target={link?.target} className='block rounded px-4 py-[10px] text-sm text-body-color hover:text-primary dark:text-dark-6 dark:hover:text-primary'> {/* 子菜单SubMenuItem */} - + {link?.icon && ( )}{' '} diff --git a/themes/starter/index.js b/themes/starter/index.js index 0ba751d4356..c0311b77e31 100644 --- a/themes/starter/index.js +++ b/themes/starter/index.js @@ -178,6 +178,7 @@ const LayoutSlug = props => { ) } + /** * 仪表盘 * @param {*} props diff --git a/themes/theme.js b/themes/theme.js index 884a26f32eb..c8760927231 100644 --- a/themes/theme.js +++ b/themes/theme.js @@ -8,17 +8,50 @@ import { getQueryParam, getQueryVariable, isBrowser } from '../lib/utils' export const { THEMES = [] } = getConfig().publicRuntimeConfig /** - * 获取主体配置 + * 获取主题配置 + * @param {string} themeQuery - 主题查询参数(支持多个主题用逗号分隔) + * @returns {Promise} 主题配置对象 */ export const getThemeConfig = async themeQuery => { - if (themeQuery && themeQuery !== BLOG.THEME) { - const THEME_CONFIG = await import(`@/themes/${themeQuery}`).then( - m => m.THEME_CONFIG - ) - return THEME_CONFIG - } else { - return ThemeComponents?.THEME_CONFIG + // 如果 themeQuery 存在且不等于默认主题,处理多主题情况 + if (typeof themeQuery === 'string' && themeQuery.trim()) { + // 取 themeQuery 中第一个主题(以逗号为分隔符) + const themeName = themeQuery.split(',')[0].trim() + + // 如果 themeQuery 不等于当前默认主题,则加载指定主题的配置 + if (themeName !== BLOG.THEME) { + try { + // 动态导入主题配置 + const THEME_CONFIG = await import(`@/themes/${themeName}`) + .then(m => m.THEME_CONFIG) + .catch(err => { + console.error(`Failed to load theme ${themeName}:`, err) + return null // 主题加载失败时返回 null 或者其他默认值 + }) + + // 如果主题配置加载成功,返回配置 + if (THEME_CONFIG) { + return THEME_CONFIG + } else { + // 如果加载失败,返回默认主题配置 + console.warn( + `Loading ${themeName} failed. Falling back to default theme.` + ) + return ThemeComponents?.THEME_CONFIG + } + } catch (error) { + // 如果 import 过程中出现异常,返回默认主题配置 + console.error( + `Error loading theme configuration for ${themeName}:`, + error + ) + return ThemeComponents?.THEME_CONFIG + } + } } + + // 如果没有 themeQuery 或 themeQuery 与默认主题相同,返回默认主题配置 + return ThemeComponents?.THEME_CONFIG } /** From a1ec646398043f341775449fc62df189eafc26a0 Mon Sep 17 00:00:00 2001 From: "tangly1024.com" Date: Wed, 20 Nov 2024 10:10:06 +0800 Subject: [PATCH 5/5] =?UTF-8?q?4.7.10=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b27d0d6e7d1..c71a1fdf00c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "notion-next", - "version": "4.7.9", + "version": "4.7.10", "homepage": "https://github.com/tangly1024/NotionNext.git", "license": "MIT", "repository": {