update(page): journal dynamic routing

mack-mac
mackt 8 months ago
parent 969ff466de
commit 78e23bb68f

@ -0,0 +1,21 @@
import { JournalCard, HotJournalList } from '@/components';
import { apiGetJournalById, apiGetByJournalNo } from '@/services/server';
export default async function JournalDetail({ params: { journalId } }: { params: { journalId: string } }) {
// const router = useRouter();
const journalInfo: JournalInfo = await apiGetByJournalNo({ id: journalId });
const songList: SongInfo[] = await apiGetJournalById({ id: journalId });
return (
<main className="flex flex-row justify-between w-[1200px] mx-auto items-left pt-[80px] pb-[104px] ">
<div>
<JournalCard image={journalInfo.image} title={journalInfo.title} journalNo={journalInfo.journalNo} />
</div>
<div className="w-[346px] mt-[217px]">
{/* 热门推荐 */}
<HotJournalList type="hot" />
</div>
</main>
);
}

@ -0,0 +1,26 @@
import { Category, JournalList, HotJournalList } from '@/components';
import { apiSearchCategory } from '@/services/server';
export default async function Journal({ params }: { params: { category?: string; page?: number } }) {
const { category = 'all', page = 1 } = params;
const categoryList: Category[] = await apiSearchCategory();
const categoryInfo: Category | undefined = categoryList.find((item: Category) => item.nameEn === category);
return (
<main className="flex flex-row justify-between w-[1200px] mx-auto items-left pt-[80px] pb-[104px] ">
{/* 左侧 */}
<div className="w-[712px] mt-[50px]">
{/* category */}
<Category current={categoryInfo?.nameEn ?? 'all'} />
{/* 期刊列表 */}
<JournalList categoryId={categoryInfo?.id ?? '0'} nameCh={categoryInfo?.nameCh ?? '全部'} pageNum={page} />
</div>
{/* 右侧 */}
<div className="w-[346px] mt-[217px]">
{/* 热门推荐 */}
<HotJournalList type="hot" />
</div>
</main>
);
}

@ -1,40 +0,0 @@
import { Category, JournalList, HotJournalList } from '@/components';
import { apiSearchCategory } from '@/services/server';
export async function generateStaticParams() {
const tagNameList: Category[] = await apiSearchCategory();
tagNameList.push({
id: '0',
nameCh: '全部',
nameEn: 'all',
image: '',
thumbnail: '',
description: '',
});
return tagNameList.map((item: Category) => ({ category: item.nameEn }));
}
export default async function Journal({ params }: { params: { category: string } }) {
const tagNameList: Category[] = await apiSearchCategory();
const currentTag: Category | undefined = tagNameList.find((item: Category) => item.nameEn === params.category);
const page = 1;
return (
<main className="flex flex-row justify-between w-[1200px] mx-auto items-left pt-[80px] pb-[104px] ">
{/* 左侧 */}
<div className="w-[712px] mt-[50px]">
{/* category */}
<Category current={currentTag?.nameEn ?? 'all'} />
{/* 期刊列表 */}
<JournalList categoryId={currentTag?.id ?? '0'} nameCh={currentTag?.nameCh ?? '全部'} pageNum={page} />
</div>
{/* 右侧 */}
<div className="w-[346px] mt-[217px]">
{/* 热门推荐 */}
<HotJournalList categoryId="1" />
</div>
</main>
);
}

@ -23,10 +23,6 @@ export default function Header() {
name: '关于我们',
path: '/about',
},
{
name: 'test',
path: '/vol/list/interview',
},
];
const [showLoginModal, setShowLoginModal] = useState(false);

@ -1,6 +1,6 @@
import Image from 'next/image';
export default function JournalCard({ title, image, totalCommentReply }: JournalInfo) {
export default function JournalItem({ title, image, totalCommentReply }: JournalInfo) {
return (
<div className="flex flex-row items-center h-[56px]">
<Image src={image} alt={title} width={80} height={56} unoptimized className="w-[80px] h-[56px] rounded-[3px]" />

@ -2,10 +2,22 @@ import HotJournalCard from './HotJournalCard';
import { apiJournalRecommend } from '@/services/server/journal';
const RecommondJournal = async ({ categoryId }: { categoryId: string }) => {
const journalList: JournalInfo[] = await apiJournalRecommend({
id: categoryId,
});
interface HotProp {
type: 'hot';
}
interface JournalProp {
type: 'journal';
journalId: string;
}
const RecommondJournal = async (prop: HotProp | JournalProp) => {
let journalList: JournalInfo[] = [];
if (prop.type === 'journal') {
journalList = await apiJournalRecommend({ id: prop.journalId });
} else {
// journalList = await apiJournalRecommend({ id: journalId });
}
return (
<div className="flex flex-col mt-[33px]">

@ -1,76 +1,38 @@
import Image from 'next/image';
import Avatar from '@/components/Avatar';
export default function JournalCard({
journalNo,
title,
showTitle = false,
image,
summary,
haveCollect,
totalCommentReply,
commentList,
}: JournalInfo) {
title,
journalNo,
}: {
showTitle?: boolean;
image: string;
title: string;
journalNo: string;
}) {
return (
<div className="flex flex-col w-[712px] rounded-[6px] bg-[#fff] ">
{/* banner container */}
<div className={`relative w-full h-[420px] rounded-[6px] overflow-hidden bg-[url(${image})]`}>
{/* 左上角标 */}
<div className="flex flex-col justify-between absolute top-0 left-0 w-[64px] h-[64px] mt-[16px] ml-[16px] pt-[9.35px] pb-[9.2px] px-[11.13px] rounded-[2px] bg-[rgba(255,255,255,0.9)] z-2">
<p className="h-[23.2px] w-full text-[16px] leading-[23.2px] text-[#000] text-left">{journalNo}</p>
<div className="w-[37.1px] h-[1.4px] bg-gradient-to-r from-red-700 via-red-700 to-transparent" />
<p className="w-full text-[10px] leading-[18px] text-[rgba(0,0,0,0.4)]">VOL</p>
</div>
{/* banner */}
<Image
width={712}
height={420}
src={image}
unoptimized
alt={title}
className="absolute bottom-0 cursor-pointer"
/>
{/* 标题 */}
<p className="absolute bottom-[23px] left-[23px] text-[#fff] text-[24px] leading-[33.6px]">{title}</p>
/* banner container */
<div className={`relative w-full h-[420px] rounded-[6px] overflow-hidden bg-[url(${image})]`}>
{/* 左上角标 */}
<div className="flex flex-col justify-between absolute top-0 left-0 w-[64px] h-[64px] mt-[16px] ml-[16px] pt-[9.35px] pb-[9.2px] px-[11.13px] rounded-[2px] bg-[rgba(255,255,255,0.9)] z-2">
<p className="h-[23.2px] w-full text-[16px] leading-[23.2px] text-[#000] text-left">{journalNo}</p>
<div className="w-[37.1px] h-[1.4px] bg-gradient-to-r from-red-700 via-red-700 to-transparent" />
<p className="w-full text-[10px] leading-[18px] text-[rgba(0,0,0,0.4)]">VOL</p>
</div>
{/* 摘要 */}
<p className="w-full mt-[15px] mb-[12px] text-[17px] leading-[23.8px] text-[#000] overflow-hidden whitespace-nowrap overflow-ellipsis truncate">
{summary}
</p>
{/* 评论 */}
{commentList.length && (
<div className="flex flex-row mb-[24px]">
<div className={`flex flex-row relative w-[25px] h-[15px] mr-[9px]`}>
{commentList?.[0]?.avatar && <Avatar className="absolute" size={15} src={commentList[0].avatar} />}
{commentList?.[1]?.avatar && (
<div className=" flex justify-center items-center absolute left-[9px] w-[16px] h-[16px] rounded-[50%] bg-[#fff] overflow-hidden">
<Avatar size={15} src={commentList[1].avatar} />
</div>
)}
</div>
<p className="w-[270px] text-[14px] leading-[20px] text-[rgba(0,0,0,0.7)] overflow-hidden whitespace-nowrap overflow-ellipsis truncate">
{commentList[0].content}
</p>
</div>
{/* banner */}
<Image
width={712}
height={420}
src={image}
unoptimized
alt={title}
className="absolute bottom-0 cursor-pointer"
/>
{/* 标题 */}
{showTitle && (
<p className="absolute bottom-[23px] left-[23px] text-[#fff] text-[24px] leading-[33.6px]">{title}</p>
)}
{/* 评论 & 收藏 */}
<div className="flex flex-row items-center">
<Image
width={24}
height={24}
src={haveCollect ? '/img/icon/love-active.svg' : '/img/icon/love.svg'}
alt="love"
unoptimized
/>
<p className="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4)]">
{totalCommentReply}
</p>
<Image width={24} height={24} src={'/img/icon/comment.svg'} alt="comment" unoptimized />
<p className="ml-[6px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4)]">{totalCommentReply}</p>
</div>
</div>
);
}

@ -0,0 +1,55 @@
import Image from 'next/image';
import { Avatar, JournalCard } from '@/components';
export default function JournalItem({
journalNo,
title,
image,
summary,
haveCollect,
totalCommentReply,
commentList,
}: JournalInfo) {
return (
<div className="flex flex-col w-[712px] rounded-[6px] bg-[#fff] ">
<JournalCard showTitle image={image} title={title} journalNo={journalNo} />
{/* 摘要 */}
<p className="w-full mt-[15px] mb-[12px] text-[17px] leading-[23.8px] text-[#000] overflow-hidden whitespace-nowrap overflow-ellipsis truncate">
{summary}
</p>
{/* 评论 */}
{commentList.length && (
<div className="flex flex-row mb-[24px]">
<div className={`flex flex-row relative w-[25px] h-[15px] mr-[9px]`}>
{commentList?.[0]?.avatar && <Avatar className="absolute" size={15} src={commentList[0].avatar} />}
{commentList?.[1]?.avatar && (
<div className=" flex justify-center items-center absolute left-[9px] w-[16px] h-[16px] rounded-[50%] bg-[#fff] overflow-hidden">
<Avatar size={15} src={commentList[1].avatar} />
</div>
)}
</div>
<p className="w-[270px] text-[14px] leading-[20px] text-[rgba(0,0,0,0.7)] overflow-hidden whitespace-nowrap overflow-ellipsis truncate">
{commentList[0].content}
</p>
</div>
)}
{/* 评论 & 收藏 */}
<div className="flex flex-row items-center">
<Image
width={24}
height={24}
src={haveCollect ? '/img/icon/love-active.svg' : '/img/icon/love.svg'}
alt="love"
unoptimized
/>
<p className="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4)]">
{totalCommentReply}
</p>
<Image width={24} height={24} src={'/img/icon/comment.svg'} alt="comment" unoptimized />
<p className="ml-[6px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4)]">{totalCommentReply}</p>
</div>
</div>
);
}

@ -1,22 +1,18 @@
import Image from 'next/image';
import JournalCard from './JournalCard';
import JournalItem from './JournalItem';
import { apiJournalList } from '@/services/server/journal';
const JournalList = async ({
categoryId,
nameCh,
journalNoRange,
pageNum,
pageSize,
}: {
interface Props {
categoryId?: string;
nameCh: string;
journalNoRange?: string;
pageNum?: number;
pageSize?: number;
}) => {
}
const JournalList = async ({ categoryId, nameCh, journalNoRange, pageNum, pageSize }: Props) => {
const journalList: JournalList = await apiJournalList({
categoryId,
journalNoRange,
@ -24,6 +20,8 @@ const JournalList = async ({
pageSize,
});
console.log({ journalList });
return (
<div className="flex flex-col mt-[33px]">
{/* 分类 & 电台 */}
@ -38,7 +36,7 @@ const JournalList = async ({
{/* 期刊 list */}
<div className="flex flex-col gap-[60px] mt-[17px]">
{journalList?.rows.length &&
journalList.rows.map((item: JournalInfo) => <JournalCard key={item.id} {...item} />)}
journalList.rows.map((item: JournalInfo) => <JournalItem key={item.id} {...item} />)}
</div>
</div>
);

@ -11,6 +11,7 @@ export { default as LoginModal } from './Login/LoginModal';
export { default as LoginForm } from './Login/LoginForm';
// Journal
export { default as JournalItem } from './Journal/JournalItem';
export { default as JournalCard } from './Journal/JournalCard';
export { default as JournalList } from './Journal/JournalList';
export { default as HotJournalCard } from './Journal/HotJournalCard';
@ -20,6 +21,7 @@ export { default as HotJournalList } from './Journal/HotJournalList';
export { default as Input } from './common/Input';
export { default as Button } from './common/Button';
export { default as AutoScrollContainer } from './common/AutoScrollContainer';
export { default as Avatar } from './Avatar';
// Audio Player
export { default as PlayerBar } from './AudioPlayer/PlayerBar';

@ -56,6 +56,29 @@ declare interface Comment {
userId: string;
}
declare interface SongInfo {
/** ID */
id: string;
/** 歌曲号 */
songNo: string;
/** 歌曲名 */
title: string;
/** 歌手/乐队名 */
artist: string;
/** 专辑名 */
album: string;
/** 已收藏 */
haveCollect: boolean;
/** 剘刊号 */
journalNo: string;
/** 歌词 */
lrc: string;
/** 歌曲专辑封面 */
pic: string;
/** 歌曲链接 */
src: string;
}
declare interface JournalInfo {
/** 期刊评论top5 */
commentList: Comment[];

Loading…
Cancel
Save