feat(dc): Complete Phase 1 - Portal workbench page development

Summary:
- Implement DC module Portal page with 3 tool cards
- Create ToolCard component with decorative background and hover animations
- Implement TaskList component with table layout and progress bars
- Implement AssetLibrary component with tab switching and file cards
- Complete database verification (4 tables confirmed)
- Complete backend API verification (6 endpoints ready)
- Optimize UI to match prototype design (V2.html)

Frontend Components (~715 lines):
- components/ToolCard.tsx - Tool cards with animations
- components/TaskList.tsx - Recent tasks table view
- components/AssetLibrary.tsx - Data asset library with tabs
- hooks/useRecentTasks.ts - Task state management
- hooks/useAssets.ts - Asset state management
- pages/Portal.tsx - Main portal page
- types/portal.ts - TypeScript type definitions

Backend Verification:
- Backend API: 1495 lines code verified
- Database: dc_schema with 4 tables verified
- API endpoints: 6 endpoints tested (templates API works)

Documentation:
- Database verification report
- Backend API test report
- Phase 1 completion summary
- UI optimization report
- Development task checklist
- Development plan for Tool B

Status: Phase 1 completed (100%), ready for browser testing
Next: Phase 2 - Tool B Step 1 and 2 development
This commit is contained in:
2025-12-02 21:53:24 +08:00
parent f240aa9236
commit d4d33528c7
83 changed files with 21863 additions and 1601 deletions

View File

@@ -0,0 +1,123 @@
/**
* DC模块 - 工具卡片组件
*
* 用于Portal页面的3个工具快速启动卡片
* 设计参考智能数据清洗工作台V2.html
*/
import { useNavigate } from 'react-router-dom';
import {
FileSpreadsheet,
Bot,
Table2,
ArrowRight,
LucideIcon
} from 'lucide-react';
import type { ToolCard as ToolCardType } from '../types/portal';
interface ToolCardProps {
tool: ToolCardType;
}
const iconMap: Record<string, LucideIcon> = {
FileSpreadsheet,
Bot,
Table2
};
const colorMap = {
blue: {
bg: 'bg-blue-100',
icon: 'text-blue-600',
decorBg: 'bg-blue-50',
hoverText: 'group-hover:text-blue-600',
actionText: 'text-blue-600'
},
purple: {
bg: 'bg-purple-100',
icon: 'text-purple-600',
decorBg: 'bg-purple-50',
hoverText: 'group-hover:text-purple-600',
actionText: 'text-purple-600'
},
emerald: {
bg: 'bg-emerald-100',
icon: 'text-emerald-600',
decorBg: 'bg-emerald-50',
hoverText: 'group-hover:text-emerald-600',
actionText: 'text-emerald-600'
}
};
const ToolCard = ({ tool }: ToolCardProps) => {
const navigate = useNavigate();
const Icon = iconMap[tool.icon] || Bot;
const colors = colorMap[tool.color];
const isDisabled = tool.status === 'disabled';
const handleClick = () => {
if (!isDisabled) {
navigate(tool.route);
}
};
return (
<div
onClick={handleClick}
className={`
bg-white rounded-xl shadow-sm border border-slate-200 p-6
transition-shadow group relative overflow-hidden
${isDisabled ? 'opacity-60 cursor-not-allowed' : 'hover:shadow-md cursor-pointer'}
`}
>
{/* 装饰性圆形背景 */}
<div className={`
absolute top-0 right-0 w-24 h-24 rounded-bl-full -mr-4 -mt-4
transition-transform
${colors.decorBg}
${!isDisabled && 'group-hover:scale-110'}
`} />
<div className="relative">
{/* 图标 */}
<div className={`
w-12 h-12 ${colors.bg} rounded-lg
flex items-center justify-center mb-4
${colors.icon}
`}>
<Icon className="w-7 h-7" />
</div>
{/* 标题 */}
<h3 className={`
text-lg font-bold text-slate-900 mb-2
transition-colors
${!isDisabled && colors.hoverText}
`}>
{tool.title}
</h3>
{/* 描述 - 固定高度确保对齐 */}
<p className="text-sm text-slate-500 mb-4 h-10 leading-relaxed">
{tool.description}
</p>
{/* 行动按钮 */}
{isDisabled ? (
<div className="flex items-center text-sm font-medium text-slate-400">
<span></span>
</div>
) : (
<div className={`flex items-center text-sm font-medium ${colors.actionText}`}>
<span>{tool.id === 'tool-a' ? '开始合并' : tool.id === 'tool-b' ? '新建提取任务' : '打开编辑器'}</span>
<ArrowRight className="w-4 h-4 ml-1 transition-transform group-hover:translate-x-1" />
</div>
)}
</div>
</div>
);
};
export default ToolCard;