diff --git a/components/ui/dashboard/DashboardBody.js b/components/ui/dashboard/DashboardBody.js index 39805b27..89b60329 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 00000000..5f382f1a --- /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 53ba3db2..7542eea1 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 00000000..443e0ac7 --- /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 00000000..4c623f6e --- /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 00000000..2988aec3 --- /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 00000000..ab0b61b9 --- /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 00000000..37acc466 --- /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 0a3e6bfe..b0ffed2a 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 00d08665..585c5435 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 97ea16c4..4c58031e 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 5dfca79f..0a865d92 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 0fac89b5..07197fdf 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 6464b712..3e4c3456 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 e5165bdd..bdfb2c72 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 8a0e898b..7a88df87 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 ff184f36..3e32a08b 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 0ba751d4..c0311b77 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 884a26f3..c8760927 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 } /**