feat(Component): Add Collect component.

mack-mac
mackt 8 months ago
parent 16cf6aadba
commit 143f4ac065

@ -0,0 +1,5 @@
<svg width="54" height="54" viewBox="0 0 54 54" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="27" cy="27" r="27" fill="#B44343"/>
<rect x="20.7" y="18.9" width="4.5" height="16.2" rx="0.736" fill="white"/>
<rect x="28.8" y="18.9" width="4.5" height="16.2" rx="0.736" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 303 B

@ -4,22 +4,22 @@ import Image from 'next/image';
import Link from 'next/link'; import Link from 'next/link';
import { notFound } from 'next/navigation'; import { notFound } from 'next/navigation';
import { JournalCard, SongCardList, HotJournalList, Comment } from '@/components'; import { JournalCard, SongCardList, HotJournalList, Comment, Coolect } from '@/components';
import { apiGetJournalInfoById, apiGetSongsByJournalNo } from '@/services'; import { apiGetJournalInfoById, apiGetSongsByJournalNo, apiCollect } from '@/services';
const getData = async (journalId: string) => { const getData = async (journalId: string) => {
const [journalInfoRes, songListRes] = await Promise.all([ const [journalInfoRes, songListRes] = await Promise.all([
apiGetJournalInfoById({ id: journalId }), apiGetJournalInfoById({ id: journalId }),
apiGetSongsByJournalNo({ id: journalId }), apiGetSongsByJournalNo({ id: journalId }),
]); ]);
if (!(journalInfoRes.code === 200 && songListRes.code === 200)) return notFound();
return { journalInfo: journalInfoRes.data, songList: songListRes.data };
};
if (journalInfoRes.code === 200 && songListRes.code === 200) { // 收藏/取消收藏
return { const handleCollect = async ({ isAdd, id }: { isAdd: boolean; id: string }) => {
journalInfo: journalInfoRes.data, const res = await apiCollect({ isAdd: !isAdd, objectId: id, collectType: '1' });
songList: songListRes.data, if (res.code === 200) {
};
} else {
return notFound();
} }
}; };
@ -59,8 +59,16 @@ export default async function JournalDetail({ params: { journalId } }: { params:
</div> </div>
</div> </div>
{/* 收藏 */} {/* 收藏 */}
<div className="flex flex-row items-center gap-[9px]"> <Coolect
haveCollect={journalInfo.haveCollect}
count={journalInfo.totalCommentReply}
text="人收藏"
id={journalInfo.id}
type="1"
/>
{/* <div className="flex flex-row items-center gap-[9px]">
<p className="text-[rgba(0,0,0,0.4)] text-[13px] leading-[18.2px]">{`${journalInfo.totalCommentReply}人收藏`}</p> <p className="text-[rgba(0,0,0,0.4)] text-[13px] leading-[18.2px]">{`${journalInfo.totalCommentReply}人收藏`}</p>
<div onClick={() => handleCollect({ id: journalInfo.id, isAdd: !journalInfo.haveCollect })}>
<Image <Image
width={24} width={24}
height={24} height={24}
@ -68,6 +76,7 @@ export default async function JournalDetail({ params: { journalId } }: { params:
alt="collect" alt="collect"
/> />
</div> </div>
</div> */}
</div> </div>
{/* 内容 */} {/* 内容 */}
<div <div

@ -0,0 +1,47 @@
'use client';
import { useEffect, useState } from 'react';
import { apiCollect } from '@/services';
interface Props {
haveCollect: boolean;
id: string;
type: string;
size?: number;
count?: string;
text?: string;
}
export default function Collect({ haveCollect, id, type, size = 24, count = '0', text = '' }: Props) {
const [state, setState] = useState<boolean>(false); // 收藏状态
useEffect(() => {
setState(haveCollect);
}, [haveCollect]);
// 收藏/取消收藏
const handleCollect = async () => {
setState(!state);
const res = await apiCollect({ isAdd: !state, objectId: id, collectType: type });
if (res.code !== 200) {
setState(!state);
}
};
return (
<div className="flex flex-row items-center gap-[9px] cursor-pointer group" onClick={handleCollect}>
{/* 文案 */}
{!!text && (
<p className="text-[rgba(0,0,0,0.4)] text-[13px] leading-[18.2px] group-hover:text-theme">
{`${count}${text}`}
</p>
)}
{/* 图标 */}
<div
className={`w-[${size}px] h-[${size}px] ${state ? 'bg-[url(/img/icon/love-active.svg)]' : 'bg-[url(/img/icon/love.svg)]'} group-hover:bg-[url(/img/icon/love-active.svg)]`}
/>
</div>
);
}

@ -9,10 +9,10 @@ export default function JournalItem({ title, image, totalCommentReply, journalNo
</Link> </Link>
<div className="flex flex-col justify-between h-full ml-[20px] py-[6px]"> <div className="flex flex-col justify-between h-full ml-[20px] py-[6px]">
<p className="w-[200px] text-[15px] leading-[21px] cursor-pointer hover:color-theme overflow-hidden whitespace-nowrap truncate"> <p className="w-[200px] text-[15px] leading-[21px] cursor-pointer hover:text-theme overflow-hidden whitespace-nowrap truncate">
{title} {title}
</p> </p>
<p className="text-[13px] leading-[18.2px] cursor-pointer hover:color-theme">{`${totalCommentReply}人收藏`}</p> <p className="text-[13px] leading-[18.2px] cursor-pointer hover:text-theme">{`${totalCommentReply}人收藏`}</p>
</div> </div>
</div> </div>
); );

@ -18,7 +18,7 @@ export default function JournalItem({
<JournalCard image={image} title={title} journalNo={journalNo} /> <JournalCard image={image} title={title} journalNo={journalNo} />
</Link> </Link>
{/* 摘要 */} {/* 摘要 */}
<p className="w-full mt-[15px] mb-[12px] text-[17px] leading-[23.8px] text-base hover:color-theme cursor-pointer overflow-hidden whitespace-nowrap truncate"> <p className="w-full mt-[15px] mb-[12px] text-[17px] leading-[23.8px] text-base hover:text-theme cursor-pointer overflow-hidden whitespace-nowrap truncate">
{summary} {summary}
</p> </p>
{/* 精选评论 */} {/* 精选评论 */}
@ -32,7 +32,7 @@ export default function JournalItem({
</div> </div>
)} )}
</div> </div>
<p className="w-[270px] text-[14px] leading-[20px] text-[rgba(0,0,0,0.7)] hover:color-theme cursor-pointer overflow-hidden whitespace-nowrap truncate"> <p className="w-[270px] text-[14px] leading-[20px] text-[rgba(0,0,0,0.7)] hover:text-theme cursor-pointer overflow-hidden whitespace-nowrap truncate">
{commentList[0].content} {commentList[0].content}
</p> </p>
</div> </div>
@ -41,7 +41,7 @@ export default function JournalItem({
{/* 评论 & 收藏 */} {/* 评论 & 收藏 */}
<div className="flex flex-row items-center"> <div className="flex flex-row items-center">
<Image width={24} height={24} src={'/img/icon/comment.svg'} alt="comment" unoptimized /> <Image width={24} height={24} src={'/img/icon/comment.svg'} alt="comment" unoptimized />
<p className="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4) cursor-pointer hover:color-theme"> <p className="w-[42px] ml-[6px] mr-[24px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4) cursor-pointer hover:text-theme">
{totalCommentReply} {totalCommentReply}
</p> </p>
<Image <Image
@ -51,7 +51,7 @@ export default function JournalItem({
alt="love" alt="love"
unoptimized unoptimized
/> />
<p className="ml-[6px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4) cursor-pointer hover:color-theme"> <p className="ml-[6px] text-[14px] leading-[16px] text-[rgba(0,0,0,0.4) cursor-pointer hover:text-theme">
{totalCommentReply} {totalCommentReply}
</p> </p>
</div> </div>

@ -37,3 +37,5 @@ export { default as CommentHeader } from './Comment/CommentHeader';
export { default as CommentForm } from './Comment/CommentForm'; export { default as CommentForm } from './Comment/CommentForm';
export { default as CommentItem } from './Comment/CommentItem'; export { default as CommentItem } from './Comment/CommentItem';
export { default as CommentList } from './Comment/CommentList'; export { default as CommentList } from './Comment/CommentList';
export { default as Coolect } from './Collect';

@ -0,0 +1,46 @@
import clientHttp from '@/utils/request/client';
/**
* @description ///
* @objectId ///id
* @collectType 0:1:2:3:
*/
export const apiCollectAdd = async (params: { objectId: string; collectType: string }) => {
const result: FetchResponse<string> = await clientHttp.post('/queyueapi/user/collect', params);
return result;
};
/**
* @description ///
* @objectId ///id
* @collectType 0:1:2:3:
*/
export const apiCollectRemove = async ({ objectId, collectType }: { objectId: string; collectType: string }) => {
const result: FetchResponse<string> = await clientHttp.delete(
`/queyueapi/user/collect?objectId=${objectId}&collectType=${collectType}`,
{},
);
return result;
};
/**
* @description / ///
* @isAdd
* @objectId ///id
* @collectType 0:1:2:3:
*/
export const apiCollect = async ({
isAdd,
objectId,
collectType,
}: {
isAdd: boolean;
objectId: string;
collectType: string;
}) => {
if (isAdd) {
return await apiCollectAdd({ objectId, collectType });
} else {
return await apiCollectRemove({ objectId, collectType });
}
};

@ -9,3 +9,4 @@ export * from './server/journal';
* @description client request * @description client request
*/ */
export * from './client/user'; export * from './client/user';
export * from './client/operate';

@ -0,0 +1,18 @@
export type IAuthType = 'noToken' | 'default' | 'ai';
export interface IOptions {
headers?: { [key: string]: string };
body?: any;
authType?: IAuthType;
requestUrl: string;
}
export interface IResponse<T> {
code: number;
data: T;
message: string;
}
export type IQueryParams = {
[key: string]: any;
};

@ -33,17 +33,21 @@ export const get = async <T>(url: string, data: any = null, revalidate = 20): Pr
return await handleResponse(response); return await handleResponse(response);
}; };
export const remove = async <T>(url: string, data: any = null, revalidate = 20): Promise<IResponse<T>> => { export const remove = async <T>(url: string, data: any, revalidate = 20): Promise<IResponse<T>> => {
const token = await getAuthorization(); const token = await getAuthorization();
const response = await fetch(url, { const response = await fetch(url, {
headers: { headers: {
Authorization: token || '', Authorization: token || '',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
Connection: 'keep-alive',
}, },
method: 'DELETE', method: 'DELETE',
body: data && createFormBody(data),
next: { next: {
revalidate: revalidate, revalidate: revalidate,
}, },
}); });
return await handleResponse(response); return await handleResponse(response);
}; };
@ -63,7 +67,7 @@ export const uploadFile = async <T>(url: string, file: File): Promise<IResponse<
const clientHttp = { const clientHttp = {
get, get,
remove, delete: remove,
post, post,
uploadFile, uploadFile,
}; };

@ -82,7 +82,6 @@ export const getAuthorization = async () => {
// setSession("local", tokenKey, res?.data); // setSession("local", tokenKey, res?.data);
// authorization = `Bearer ${res?.data}`; // authorization = `Bearer ${res?.data}`;
} }
console.log({ authorization });
return authorization; return authorization;
}; };

@ -13,7 +13,6 @@ export default defineConfig({
], ],
rules: [ rules: [
['color-theme', { color: '#B44343' }],
['bg-theme', { 'background-color': '#B44343' }], ['bg-theme', { 'background-color': '#B44343' }],
['text-flow', { 'text-overflow': 'ellipsis', 'white-space': 'nowrap', overflow: 'hidden' }], ['text-flow', { 'text-overflow': 'ellipsis', 'white-space': 'nowrap', overflow: 'hidden' }],
], ],

Loading…
Cancel
Save