Files
leaudit-platform-frontend/app/components/contract-template/TemplateCard.tsx
T

177 lines
5.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// import { useState } from 'react';
import { useNavigate } from '@remix-run/react';
// 导入统一的下载方法和提示服务
import { downloadFile } from '~/api/axios-client';
import { toastService } from '~/components/ui/Toast';
interface Template {
id: string;
title: string;
// type: string;
description: string;
updateTime: string;
// useCount: number;
// rating: number;
category: string;
file_path?: string;
file_format?: string;
}
interface TemplateCardProps {
template: Template;
onClick: () => void;
}
export function TemplateCard({ template, onClick }: TemplateCardProps) {
// 注释掉收藏功能,后续版本再开发
// const [isFavorited, setIsFavorited] = useState(false);
const navigate = useNavigate();
/* const handleFavoriteClick = (e: React.MouseEvent) => {
e.stopPropagation();
setIsFavorited(!isFavorited);
}; */
// 使用统一的下载方法(与 rules-files.tsx 相同)
const handleDownloadFile = async (filePath: string, fileName: string) => {
try {
// 使用axios封装的下载方法
const blob = await downloadFile(filePath);
// 创建Blob URL
const blobUrl = URL.createObjectURL(blob);
// 清理文件名,移除可能导致问题的字符
const cleanFileName = fileName.replace(/[<>:"/\\|?*]/g, '_');
// 创建一个隐藏的a标签并点击它
const a = document.createElement('a');
a.style.display = 'none';
a.href = blobUrl;
a.download = cleanFileName;
document.body.appendChild(a);
a.click();
// 清理
setTimeout(() => {
document.body.removeChild(a);
URL.revokeObjectURL(blobUrl);
}, 100);
} catch (error) {
console.error('下载文件失败:', error);
toastService.error(`下载文件失败: ${error instanceof Error ? error.message : '未知错误'}`);
}
};
const handleActionClick = (e: React.MouseEvent, action: string) => {
e.stopPropagation();
switch (action) {
case '立即下载':
if (template.file_path) {
// 构建文件名,使用模板标题和文件格式
const fileExtension = template.file_format || 'docx';
const fileName = `${template.title}.${fileExtension}`;
handleDownloadFile(template.file_path, fileName);
} else {
toastService.error('文件路径不存在,无法下载');
}
break;
case '预览':
// 导航到模板详情页面
navigate(`/contract-template/detail/${template.id}`);
break;
default:
// console.log(`执行操作: ${action}`, template.id);
}
};
/* const renderStars = (rating: number) => {
const stars = [];
const fullStars = Math.floor(rating);
const hasHalfStar = rating % 1 !== 0;
for (let i = 0; i < 5; i++) {
if (i < fullStars) {
stars.push(<i key={i} className="ri-star-fill text-xs"></i>);
} else if (i === fullStars && hasHalfStar) {
stars.push(<i key={i} className="ri-star-half-fill text-xs"></i>);
} else {
stars.push(<i key={i} className="ri-star-line text-xs"></i>);
}
}
return stars;
}; */
const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
onClick();
}
};
return (
<div
className="template-card"
onClick={onClick}
onKeyDown={handleKeyDown}
role="button"
tabIndex={0}
aria-label={`查看${template.title}详情`}
>
{/* 注释掉头部的type和rating显示 */}
{/* <div className="template-header">
<div className="template-type">{template.type}</div>
<div className="flex items-center gap-1 text-yellow-500">
{renderStars(template.rating)}
<span className="text-xs ml-1">{template.rating}</span>
</div>
</div> */}
<h3 className="template-title">{template.title}</h3>
<p
className="template-desc"
style={{
height: '4.5rem', // 固定高度约3行文字
overflow: 'hidden',
textOverflow: 'ellipsis',
display: '-webkit-box',
WebkitLineClamp: 3, // 限制3行
WebkitBoxOrient: 'vertical',
lineHeight: '1.5rem'
}}
>
{template.description}
</p>
<div className="template-meta">
<span>{template.updateTime}</span>
{/* 注释掉使用次数显示 */}
{/* <span>使用次数:{template.useCount.toLocaleString()}</span> */}
</div>
<div className="template-actions mt-3">
<button
className="action-btn primary"
onClick={(e) => handleActionClick(e, '立即下载')}
>
</button>
<button
className="action-btn"
onClick={(e) => handleActionClick(e, '预览')}
>
</button>
{/* 注释掉收藏按钮 */}
{/* <button
className="action-btn"
onClick={handleFavoriteClick}
title={isFavorited ? '取消收藏' : '收藏'}
>
<i className={isFavorited ? 'ri-star-fill text-yellow-500' : 'ri-star-line'}></i>
</button> */}
</div>
</div>
);
}