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 { notFound } from 'next/navigation';
import { JournalCard, SongCardList, HotJournalList, Comment } from '@/components';
import { apiGetJournalInfoById, apiGetSongsByJournalNo } from '@/services';
import { JournalCard, SongCardList, HotJournalList, Comment, Coolect } from '@/components';
import { apiGetJournalInfoById, apiGetSongsByJournalNo, apiCollect } from '@/services';
const getData = async (journalId: string) => {
const [journalInfoRes, songListRes] = await Promise.all([
apiGetJournalInfoById({ 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 {
journalInfo: journalInfoRes.data,
songList: songListRes.data,
};
} else {
return notFound();
// 收藏/取消收藏
const handleCollect = async ({ isAdd, id }: { isAdd: boolean; id: string }) => {
const res = await apiCollect({ isAdd: !isAdd, objectId: id, collectType: '1' });
if (res.code === 200) {
}
};
@ -59,15 +59,24 @@ export default async function JournalDetail({ params: { journalId } }: { params:
</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>
<Image
width={24}
height={24}
src={journalInfo.haveCollect ? '/img/icon/love-active.svg' : '/img/icon/love.svg'}
alt="collect"
/>
</div>
<div onClick={() => handleCollect({ id: journalInfo.id, isAdd: !journalInfo.haveCollect })}>
<Image
width={24}
height={24}
src={journalInfo.haveCollect ? '/img/icon/love-active.svg' : '/img/icon/love.svg'}
alt="collect"
/>
</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>
<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}
</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>
);

@ -18,7 +18,7 @@ export default function JournalItem({
<JournalCard image={image} title={title} journalNo={journalNo} />
</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}
</p>
{/* 精选评论 */}
@ -32,7 +32,7 @@ export default function JournalItem({
</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}
</p>
</div>
@ -41,7 +41,7 @@ export default function JournalItem({
{/* 评论 & 收藏 */}
<div className="flex flex-row items-center">
<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}
</p>
<Image
@ -51,7 +51,7 @@ export default function JournalItem({
alt="love"
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}
</p>
</div>

@ -37,3 +37,5 @@ export { default as CommentHeader } from './Comment/CommentHeader';
export { default as CommentForm } from './Comment/CommentForm';
export { default as CommentItem } from './Comment/CommentItem';
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
*/
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);
};
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 response = await fetch(url, {
headers: {
Authorization: token || '',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
Connection: 'keep-alive',
},
method: 'DELETE',
body: data && createFormBody(data),
next: {
revalidate: revalidate,
},
});
return await handleResponse(response);
};
@ -63,7 +67,7 @@ export const uploadFile = async <T>(url: string, file: File): Promise<IResponse<
const clientHttp = {
get,
remove,
delete: remove,
post,
uploadFile,
};

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

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

Loading…
Cancel
Save