181 lines
5.3 KiB
TypeScript
181 lines
5.3 KiB
TypeScript
// 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>
|
||
);
|
||
}
|