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

181 lines
5.3 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';
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);
}; */
// MinIO下载URL构建函数
const buildDownloadUrl = (filePath: string): string => {
// 使用实际的MinIO配置
const minioHost = 'http://nas.7bm.co:9000';
const bucketName = 'docauditai';
// 确保文件路径不以/开头
const cleanPath = filePath.startsWith('/') ? filePath.substring(1) : filePath;
return `${minioHost}/${bucketName}/${cleanPath}`;
};
// 下载文件函数
const downloadFile = async (filePath: string, fileName: string) => {
try {
const downloadUrl = buildDownloadUrl(filePath);
// 清理文件名,移除可能导致问题的字符
const cleanFileName = fileName.replace(/[<>:"/\\|?*]/g, '_');
// 创建临时下载链接
const link = document.createElement('a');
link.href = downloadUrl;
link.download = cleanFileName;
link.target = '_blank';
// 触发下载
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
console.log('开始下载文件:', cleanFileName);
} catch (error) {
console.error('下载文件失败:', error);
alert('下载失败,请稍后重试');
}
};
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}`;
downloadFile(template.file_path, fileName);
} else {
alert('文件路径不存在,无法下载');
}
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>
);
}