mirror of
https://github.com/LiuYuYang01/ThriveX-Blog.git
synced 2026-05-07 06:07:34 +08:00
删除关于我页面的技术栈容器,重命名获取用户数据的 API 为获取作者数据,优化朋友圈页面的组件结构,移除不必要的 API 调用,简化记录页面的渲染逻辑,替换图片列表组件为记录卡片组件,并更新数据注入逻辑以获取作者信息。
This commit is contained in:
@@ -2,6 +2,6 @@ import { User } from '@/types/app/user'
|
||||
import Request from '@/utils/request'
|
||||
|
||||
// 获取作者信息
|
||||
export const getUserDataAPI = async () => {
|
||||
export const getAuthorDataAPI = async () => {
|
||||
return await Request<User>('GET', '/user/author')
|
||||
}
|
||||
@@ -1,13 +1,14 @@
|
||||
import { getUserDataAPI } from '@/api/user';
|
||||
import { User } from '@/types/app/user';
|
||||
'use client';
|
||||
|
||||
import { useAuthorStore } from '@/stores';
|
||||
|
||||
const Copyright = async () => {
|
||||
const { data } = (await getUserDataAPI()) || { data: {} as User };
|
||||
const author = useAuthorStore((state) => state.author);
|
||||
|
||||
return (
|
||||
<div className="p-3 space-y-2 border-l-[3px] border-primary bg-[#ecf7fe] rounded-md text-sm text-black-b">
|
||||
<p>作者:{data?.name}</p>
|
||||
<p>版权:此文章版权归 {data?.name} 所有,如有转载,请注明出处!</p>
|
||||
<p>作者:{author?.name}</p>
|
||||
<p>版权:此文章版权归 {author?.name} 所有,如有转载,请注明出处!</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
97
src/app/friend/index.tsx
Normal file
97
src/app/friend/index.tsx
Normal file
@@ -0,0 +1,97 @@
|
||||
'use client';
|
||||
|
||||
import Link from 'next/link';
|
||||
|
||||
import { ToastContainer } from 'react-toastify';
|
||||
|
||||
import Slide from '@/components/Slide';
|
||||
import Starry from '@/components/Starry';
|
||||
import ApplyForAdd from './components/ApplyForAdd';
|
||||
import CopyableText from './components/CopyableText';
|
||||
|
||||
import { Web } from '@/types/app/web';
|
||||
|
||||
import { useConfigStore, useAuthorStore } from '@/stores';
|
||||
|
||||
export default ({ data }: { data: { [string: string]: { order: number; list: Web[] } } }) => {
|
||||
const web = useConfigStore((state) => state.web);
|
||||
const author = useAuthorStore((state) => state.author);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Slide isRipple={false}>
|
||||
{/* 星空背景组件 */}
|
||||
<Starry />
|
||||
|
||||
<div className="absolute top-[30%] left-[50%] transform -translate-x-1/2 flex flex-col items-center">
|
||||
<div className="text-white text-[20px] xs:text-[25px] sm:text-[30px] whitespace-nowrap custom_text_shadow">一个人的寂寞,一群人的狂欢!</div>
|
||||
<div className="mt-4 sm:mt-8">
|
||||
<ApplyForAdd />
|
||||
</div>
|
||||
</div>
|
||||
</Slide>
|
||||
|
||||
<div className="bg-[linear-gradient(180deg,#edf6ff_0%,#ffffff_100%)] dark:bg-[linear-gradient(to_right,#232931_0%,#232931_100%)]">
|
||||
<div className="relative -top-20 xs:-top-20 sm:-top-32 md:-top-36 w-[90%] xl:w-[1200px] p-10 pt-2 mx-auto bg-white dark:bg-black-b border dark:border-black-b rounded-2xl space-y-8 ">
|
||||
<div>
|
||||
<h3 className="w-full text-center text-xl p-4 dark:text-white ">本站信息</h3>
|
||||
|
||||
<div className="mx-auto p-3 space-y-2 border-l-[3px] border-primary bg-[#ecf7fe] dark:bg-[#333b48] rounded-md text-sm text-black-b dark:text-gray-300">
|
||||
<p>
|
||||
站点名称:<CopyableText text={web?.title}>{web?.title}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
站点介绍:<CopyableText text={web?.description}>{web?.description}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
站点图标:<CopyableText text={author?.avatar || ''}>{author?.avatar}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
站点地址:<CopyableText text={web?.url}>{web?.url}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
Rss地址:<CopyableText text={web?.url + '/api/rss'}>{web?.url + '/api/rss'}</CopyableText>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{Object.keys(data)?.map((type, index) => (
|
||||
<div key={index}>
|
||||
<h3 className="w-full text-center text-xl p-4 dark:text-white ">{type}</h3>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2">
|
||||
{type === '全站置顶' && (
|
||||
<Link href="https://liuyuyang.net" target="_blank" className="group">
|
||||
<div className="flex items-center p-3 border group-hover:border-2 dark:border-[#3d4653] group-hover:!border-primary group-hover:shadow-[0_10px_20px_1px_rgb(83,157,253,.1)] rounded-md ">
|
||||
<img src="https://q1.qlogo.cn/g?b=qq&nk=3311118881&s=640" alt="项目作者" className="w-14 h-14 mr-4 rounded-full" />
|
||||
|
||||
<div className="flex flex-col space-y-2">
|
||||
<h4 className="text-sm text-gray-700 dark:text-white group-hover:text-primary">宇阳</h4>
|
||||
<p className="text-xs text-[#8c9ab1] line-clamp-2">ThriveX 博客管理系统作者</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{data[type].list?.map((item: Web) => (
|
||||
<Link key={item.id} href={item.url} target="_blank" className="group">
|
||||
<div key={item.id} className="flex items-center p-3 border group-hover:border-2 dark:border-[#3d4653] group-hover:!border-primary group-hover:shadow-[0_10px_20px_1px_rgb(83,157,253,.1)] rounded-md ">
|
||||
<img src={item.image} alt={item.title} className="w-14 h-14 mr-4 rounded-full" />
|
||||
|
||||
<div className="flex flex-col space-y-2">
|
||||
<h4 className="text-sm text-gray-700 dark:text-white group-hover:text-primary">{item.title}</h4>
|
||||
<p className="text-xs text-[#8c9ab1] line-clamp-2">{item.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ToastContainer />
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -1,19 +1,9 @@
|
||||
import Link from 'next/link';
|
||||
import { Metadata } from 'next';
|
||||
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { getWebListAPI, getWebTypeListAPI } from '@/api/web';
|
||||
import { Web as WebLink, WebType } from '@/types/app/web';
|
||||
|
||||
import Slide from '@/components/Slide';
|
||||
import Starry from '@/components/Starry';
|
||||
import ApplyForAdd from './components/ApplyForAdd';
|
||||
import CopyableText from './components/CopyableText';
|
||||
|
||||
import { ToastContainer } from 'react-toastify';
|
||||
import { getUserDataAPI } from '@/api/user';
|
||||
import { User } from '@/types/app/user';
|
||||
import { Web } from '@/types/app/config';
|
||||
import Friend from './index';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: '😇 朋友圈',
|
||||
@@ -21,10 +11,6 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
export default async () => {
|
||||
const { data: user } = (await getUserDataAPI()) || { data: {} as User };
|
||||
const {
|
||||
data: { value: web },
|
||||
} = (await getWebConfigDataAPI<{ value: Web }>('web')) || { data: { value: {} as Web } };
|
||||
const { data: linkList } = (await getWebListAPI()) || { data: [] as WebLink[] };
|
||||
const { data: typeList } = (await getWebTypeListAPI()) || { data: [] as WebType[] };
|
||||
|
||||
@@ -49,81 +35,5 @@ export default async () => {
|
||||
dataTemp.sort((a, b) => a[1].order - b[1].order);
|
||||
data = Object.fromEntries(dataTemp);
|
||||
|
||||
return (
|
||||
<>
|
||||
<Slide isRipple={false}>
|
||||
{/* 星空背景组件 */}
|
||||
<Starry />
|
||||
|
||||
<div className="absolute top-[30%] left-[50%] transform -translate-x-1/2 flex flex-col items-center">
|
||||
<div className="text-white text-[20px] xs:text-[25px] sm:text-[30px] whitespace-nowrap custom_text_shadow">一个人的寂寞,一群人的狂欢!</div>
|
||||
<div className="mt-4 sm:mt-8">
|
||||
<ApplyForAdd />
|
||||
</div>
|
||||
</div>
|
||||
</Slide>
|
||||
|
||||
<div className="bg-[linear-gradient(180deg,#edf6ff_0%,#ffffff_100%)] dark:bg-[linear-gradient(to_right,#232931_0%,#232931_100%)]">
|
||||
<div className="relative -top-20 xs:-top-20 sm:-top-32 md:-top-36 w-[90%] xl:w-[1200px] p-10 pt-2 mx-auto bg-white dark:bg-black-b border dark:border-black-b rounded-2xl space-y-8 ">
|
||||
<div>
|
||||
<h3 className="w-full text-center text-xl p-4 dark:text-white ">本站信息</h3>
|
||||
|
||||
<div className="mx-auto p-3 space-y-2 border-l-[3px] border-primary bg-[#ecf7fe] dark:bg-[#333b48] rounded-md text-sm text-black-b dark:text-gray-300">
|
||||
<p>
|
||||
站点名称:<CopyableText text={web?.title}>{web?.title}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
站点介绍:<CopyableText text={web?.description}>{web?.description}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
站点图标:<CopyableText text={user?.avatar || ''}>{user?.avatar}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
站点地址:<CopyableText text={web?.url}>{web?.url}</CopyableText>
|
||||
</p>
|
||||
<p>
|
||||
Rss地址:<CopyableText text={web?.url + '/api/rss'}>{web?.url + '/api/rss'}</CopyableText>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{Object.keys(data)?.map((type, index) => (
|
||||
<div key={index}>
|
||||
<h3 className="w-full text-center text-xl p-4 dark:text-white ">{type}</h3>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-2">
|
||||
{type === '全站置顶' && (
|
||||
<Link href="https://liuyuyang.net" target="_blank" className="group">
|
||||
<div className="flex items-center p-3 border group-hover:border-2 dark:border-[#3d4653] group-hover:!border-primary group-hover:shadow-[0_10px_20px_1px_rgb(83,157,253,.1)] rounded-md ">
|
||||
<img src="https://q1.qlogo.cn/g?b=qq&nk=3311118881&s=640" alt="项目作者" className="w-14 h-14 mr-4 rounded-full" />
|
||||
|
||||
<div className="flex flex-col space-y-2">
|
||||
<h4 className="text-sm text-gray-700 dark:text-white group-hover:text-primary">宇阳</h4>
|
||||
<p className="text-xs text-[#8c9ab1] line-clamp-2">ThriveX 博客管理系统作者</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{data[type].list?.map((item: WebLink) => (
|
||||
<Link key={item.id} href={item.url} target="_blank" className="group">
|
||||
<div key={item.id} className="flex items-center p-3 border group-hover:border-2 dark:border-[#3d4653] group-hover:!border-primary group-hover:shadow-[0_10px_20px_1px_rgb(83,157,253,.1)] rounded-md ">
|
||||
<img src={item.image} alt={item.title} className="w-14 h-14 mr-4 rounded-full" />
|
||||
|
||||
<div className="flex flex-col space-y-2">
|
||||
<h4 className="text-sm text-gray-700 dark:text-white group-hover:text-primary">{item.title}</h4>
|
||||
<p className="text-xs text-[#8c9ab1] line-clamp-2">{item.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ToastContainer />
|
||||
</>
|
||||
);
|
||||
return <Friend data={data} />;
|
||||
};
|
||||
|
||||
@@ -10,17 +10,19 @@ interface Props {
|
||||
export default ({ list }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<div className={`flex justify-center ${list.length && 'mt-4'} w-full sm:w-3/6`}>
|
||||
<PhotoProvider speed={() => 800} easing={(type) => (type === 2 ? 'cubic-bezier(0.36, 0, 0.66, -0.56)' : 'cubic-bezier(0.34, 1.56, 0.64, 1)')}>
|
||||
<div className={`grid gap-2 ${list.length === 1 ? 'justify-center' : 'grid-cols-2'}`}>
|
||||
{list?.map((url, index) => (
|
||||
<PhotoView key={index} src={url}>
|
||||
<img src={url} alt="闪念图片" className="rounded-2xl w-full h-full object-cover cursor-pointer" />
|
||||
</PhotoView>
|
||||
))}
|
||||
</div>
|
||||
</PhotoProvider>
|
||||
</div>
|
||||
{!!list?.length && (
|
||||
<div className={`flex justify-center mt-4 w-full sm:w-3/6`}>
|
||||
<PhotoProvider speed={() => 800} easing={(type) => (type === 2 ? 'cubic-bezier(0.36, 0, 0.66, -0.56)' : 'cubic-bezier(0.34, 1.56, 0.64, 1)')}>
|
||||
<div className={`grid gap-2 ${list.length === 1 ? 'grid-cols-1 justify-center' : 'grid-cols-2 md:grid-cols-3'}`}>
|
||||
{list.map((url, index) => (
|
||||
<PhotoView key={index} src={url}>
|
||||
<img src={url} alt="闪念图片" className="rounded-2xl w-full h-full object-cover cursor-pointer" />
|
||||
</PhotoView>
|
||||
))}
|
||||
</div>
|
||||
</PhotoProvider>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
44
src/app/record/components/RecordCard.tsx
Normal file
44
src/app/record/components/RecordCard.tsx
Normal file
@@ -0,0 +1,44 @@
|
||||
import ImageList from './ImageList';
|
||||
import Editor from './Editor';
|
||||
import { dayFormat } from '@/utils';
|
||||
import { User } from '@/types/app/user';
|
||||
|
||||
interface RecordItemProps {
|
||||
id: number | string;
|
||||
content: string;
|
||||
images: string | string[] | null;
|
||||
createTime?: string | number | Date;
|
||||
user: Pick<User, 'avatar' | 'name'> | null;
|
||||
}
|
||||
|
||||
export default function RecordCard({ id, content, images, createTime, user }: RecordItemProps) {
|
||||
const imageList: string[] = Array.isArray(images) ? images : JSON.parse((images as string) || '[]');
|
||||
|
||||
return (
|
||||
<div key={id} className="flex flex-col sm:flex-row">
|
||||
<img src={user?.avatar} alt="作者头像" width={56} height={56} className="hidden sm:block rounded-lg border dark:border-black-b h-14 mr-2" />
|
||||
|
||||
<div className="flex sm:hidden">
|
||||
<img src={user?.avatar} alt="作者头像" width={44} height={44} className="rounded-lg border dark:border-black-b h-11 mr-2" />
|
||||
|
||||
<div className="flex sm:hidden items-center my-1.5 ml-2 space-x-4">
|
||||
<h3>{user?.name}</h3>
|
||||
<span className="text-xs">{dayFormat(createTime as any)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-2 sm:mt-0 w-full">
|
||||
<div className="hidden sm:flex items-center my-1.5 ml-4 space-x-4">
|
||||
<h3>{user?.name}</h3>
|
||||
<span className="text-xs">{dayFormat(createTime as any)}</span>
|
||||
</div>
|
||||
|
||||
<div className="w-full p-4 border dark:border-black-b rounded-3xl rounded-tl-none bg-[rgba(255,255,255,0.7)] dark:bg-[rgba(30,36,46,0.9)] backdrop-blur-sm">
|
||||
<Editor value={content} />
|
||||
|
||||
<ImageList list={imageList} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
import ImageList from './components/ImageList';
|
||||
import RecordCard from './components/RecordCard';
|
||||
import { getRecordPagingAPI } from '@/api/record';
|
||||
import { getUserDataAPI } from '@/api/user';
|
||||
import { getAuthorDataAPI } from '@/api/user';
|
||||
import { Record } from '@/types/app/record';
|
||||
import { User } from '@/types/app/user';
|
||||
import { dayFormat } from '@/utils';
|
||||
import Pagination from '@/components/Pagination';
|
||||
import Empty from '@/components/Empty';
|
||||
import Show from '@/components/Show';
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { Theme } from '@/types/app/config';
|
||||
import Editor from './components/Editor';
|
||||
|
||||
interface Props {
|
||||
searchParams: Promise<{ page: number }>;
|
||||
@@ -19,7 +17,7 @@ export default async (props: Props) => {
|
||||
const searchParams = await props.searchParams;
|
||||
const page = searchParams.page || 1;
|
||||
|
||||
const { data: user } = (await getUserDataAPI()) || { data: {} as User };
|
||||
const { data: user } = (await getAuthorDataAPI()) || { data: {} as User };
|
||||
const { data: record } = (await getRecordPagingAPI({ pagination: { page, size: 8 } })) || { data: {} as Paginate<Record[]> };
|
||||
const {
|
||||
data: { value: theme },
|
||||
@@ -41,32 +39,14 @@ export default async (props: Props) => {
|
||||
<div className="space-y-12">
|
||||
{!!record?.result?.length &&
|
||||
record?.result.map((item) => (
|
||||
<div key={item.id} className="flex flex-col sm:flex-row">
|
||||
<img src={user?.avatar} alt="作者头像" width={56} height={56} className="hidden sm:block rounded-lg border dark:border-black-b h-14 mr-2 " />
|
||||
|
||||
<div className="flex sm:hidden">
|
||||
<img src={user?.avatar} alt="作者头像" width={44} height={44} className="rounded-lg border dark:border-black-b h-11 mr-2 " />
|
||||
|
||||
<div className="flex sm:hidden items-center my-1.5 ml-2 space-x-4">
|
||||
<h3>{user?.name}</h3>
|
||||
<span className="text-xs">{dayFormat(item?.createTime)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-2 sm:mt-0 w-full">
|
||||
<div className="hidden sm:flex items-center my-1.5 ml-4 space-x-4">
|
||||
<h3>{user?.name}</h3>
|
||||
<span className="text-xs">{dayFormat(item?.createTime)}</span>
|
||||
</div>
|
||||
|
||||
<div className="w-full p-4 border dark:border-black-b rounded-3xl rounded-tl-none bg-[rgba(255,255,255,0.7)] dark:bg-[rgba(30,36,46,0.9)] backdrop-blur-sm ">
|
||||
<Editor value={item?.content} />
|
||||
|
||||
<ImageList list={JSON.parse((item?.images as string) || '[]')} />
|
||||
{/* <Comment /> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<RecordCard
|
||||
key={item.id}
|
||||
id={item.id as any}
|
||||
content={item.content as any}
|
||||
images={item.images as any}
|
||||
createTime={item.createTime as any}
|
||||
user={user as any}
|
||||
/>
|
||||
))}
|
||||
|
||||
<Show is={!record?.result?.length}>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Link from 'next/link';
|
||||
import Image from 'next/image';
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { getUserDataAPI } from '@/api/user';
|
||||
import { getAuthorDataAPI } from '@/api/user';
|
||||
import { User } from '@/types/app/user';
|
||||
import { Web } from '@/types/app/config';
|
||||
import Tooltip from './components/Tooltip';
|
||||
@@ -10,7 +10,7 @@ import animals from './images/animals.webp';
|
||||
import ICP from './images/ICP.png';
|
||||
|
||||
export default async () => {
|
||||
const { data: user } = (await getUserDataAPI()) || { data: {} as User };
|
||||
const { data: user } = (await getAuthorDataAPI()) || { data: {} as User };
|
||||
const {
|
||||
data: { value: web },
|
||||
} = (await getWebConfigDataAPI<{ value: Web }>('web')) || { data: { value: {} as Web } };
|
||||
|
||||
@@ -3,10 +3,20 @@
|
||||
import { useEffect } from 'react';
|
||||
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { useConfigStore } from '@/stores';
|
||||
import { useAuthorStore, useConfigStore } from '@/stores';
|
||||
import { Web, Theme, Other } from '@/types/app/config';
|
||||
import { getAuthorDataAPI } from '@/api/user';
|
||||
import { User } from '@/types/app/user';
|
||||
|
||||
export default () => {
|
||||
const setAuthor = useAuthorStore((state) => state.setAuthor);
|
||||
|
||||
// 获取作者信息
|
||||
const getAuthorData = async () => {
|
||||
const { data: user } = (await getAuthorDataAPI()) || { data: {} as User };
|
||||
setAuthor(user);
|
||||
};
|
||||
|
||||
const { setWeb, setTheme, setOther } = useConfigStore();
|
||||
|
||||
// 获取项目配置
|
||||
@@ -28,6 +38,7 @@ export default () => {
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getAuthorData();
|
||||
getConfigData();
|
||||
}, []);
|
||||
|
||||
|
||||
@@ -9,13 +9,13 @@ import Juejin from '@/assets/svg/socializing/Juejin.svg';
|
||||
import QQ from '@/assets/svg/socializing/QQ.svg';
|
||||
import Weixin from '@/assets/svg/socializing/Weixin.svg';
|
||||
|
||||
import { getUserDataAPI } from '@/api/user';
|
||||
import { getAuthorDataAPI } from '@/api/user';
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { User } from '@/types/app/user';
|
||||
import { Social, Theme } from '@/types/app/config';
|
||||
|
||||
const Author = async () => {
|
||||
const { data: user } = (await getUserDataAPI()) || { data: {} as User };
|
||||
const { data: user } = (await getAuthorDataAPI()) || { data: {} as User };
|
||||
const {
|
||||
data: { value: theme },
|
||||
} = (await getWebConfigDataAPI<{ value: Theme }>('theme')) || { data: { value: {} as Theme } };
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import Ripple from '@/components/Ripple';
|
||||
import { getRandom } from '@/utils';
|
||||
import { getWebConfigDataAPI } from '@/api/config';
|
||||
import { Theme } from '@/types/app/config';
|
||||
import { useConfigStore } from '@/stores';
|
||||
|
||||
interface Props {
|
||||
src?: string; // 图片列表
|
||||
@@ -10,12 +11,9 @@ interface Props {
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export default async ({ src, isRipple = true, children }: Props) => {
|
||||
const {
|
||||
data: { value: data },
|
||||
} = (await getWebConfigDataAPI<{ value: Theme }>('theme')) || { data: { value: {} as Theme } };
|
||||
|
||||
const covers = data.covers || [];
|
||||
export default ({ src, isRipple = true, children }: Props) => {
|
||||
const theme = useConfigStore((state) => state.theme);
|
||||
const covers = theme.covers || [];
|
||||
|
||||
const sty = {
|
||||
backgroundImage: `url(${src ? src : covers[getRandom(0, covers.length - 1)]})`,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import useConfigStore from './modules/config'
|
||||
import useAuthorStore from './modules/author'
|
||||
|
||||
export { useConfigStore }
|
||||
export { useConfigStore, useAuthorStore };
|
||||
13
src/stores/modules/author.ts
Normal file
13
src/stores/modules/author.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
import { create } from 'zustand';
|
||||
import { User } from '@/types/app/user';
|
||||
|
||||
interface AuthorState {
|
||||
// 作者信息
|
||||
author: User;
|
||||
setAuthor: (data: User) => void;
|
||||
}
|
||||
|
||||
export default create<AuthorState>((set) => ({
|
||||
author: {} as User,
|
||||
setAuthor: (data: User) => set(() => ({ author: data })),
|
||||
}));
|
||||
Reference in New Issue
Block a user