HomePage.tsx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503
  1. import { useState } from 'react';
  2. import { Button } from '@/client/components/ui/button';
  3. import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/client/components/ui/card';
  4. import { Badge } from '@/client/components/ui/badge';
  5. import { Separator } from '@/client/components/ui/separator';
  6. import {
  7. FileText,
  8. Upload,
  9. Download,
  10. Image,
  11. Settings,
  12. CheckCircle,
  13. Zap,
  14. Package,
  15. Rocket,
  16. Shield,
  17. User,
  18. Check,
  19. Clock,
  20. Calendar,
  21. Infinity
  22. } from 'lucide-react';
  23. import { useNavigate } from 'react-router-dom';
  24. import UserInfoModal from '@/client/home/components/UserInfoModal';
  25. import { useAuth } from '@/client/home/hooks/AuthProvider';
  26. import { useQuery } from '@tanstack/react-query';
  27. import { membershipPlanClient } from '@/client/api';
  28. import type { InferResponseType } from 'hono/client';
  29. export default function HomePage() {
  30. const navigate = useNavigate();
  31. const { user, isAuthenticated } = useAuth();
  32. const [hoveredFeature, setHoveredFeature] = useState<number | null>(null);
  33. const [showUserModal, setShowUserModal] = useState(false);
  34. const { data: membershipPlans } = useQuery({
  35. queryKey: ['membership-plans-home'],
  36. queryFn: async () => {
  37. const response = await membershipPlanClient.$get();
  38. if (!response.ok) throw new Error('获取套餐失败');
  39. const data = await response.json();
  40. return data.data.filter((plan: any) => plan.isActive === 1).sort((a: any, b: any) => a.sortOrder - b.sortOrder);
  41. },
  42. });
  43. const features = [
  44. {
  45. icon: <FileText className="h-8 w-8" />,
  46. title: "元亨Word模板批量处理",
  47. description: "支持.docx格式,最大10MB,智能字段替换",
  48. color: "text-blue-600"
  49. },
  50. {
  51. icon: <Image className="h-8 w-8" />,
  52. title: "智能图片处理",
  53. description: "支持6种图片格式,自动尺寸控制,保持比例",
  54. color: "text-green-600"
  55. },
  56. {
  57. icon: <Upload className="h-8 w-8" />,
  58. title: "Excel数据驱动",
  59. description: "一键导入Excel数据,批量生成个性化文档",
  60. color: "text-purple-600"
  61. },
  62. {
  63. icon: <Settings className="h-8 w-8" />,
  64. title: "灵活配置",
  65. description: "自定义图片尺寸,实时预览,进度跟踪",
  66. color: "text-orange-600"
  67. }
  68. ];
  69. const stats = [
  70. { value: "10MB", label: "Word模板上限", icon: <FileText className="h-5 w-5" /> },
  71. { value: "50MB", label: "图片压缩包上限", icon: <Package className="h-5 w-5" /> },
  72. { value: "1000+", label: "支持像素范围", icon: <Image className="h-5 w-5" /> },
  73. { value: "6种", label: "图片格式支持", icon: <CheckCircle className="h-5 w-5" /> }
  74. ];
  75. return (
  76. <div className="min-h-screen bg-gradient-to-br from-slate-50 via-white to-blue-50">
  77. {/* Header Navigation */}
  78. <header className="fixed top-0 left-0 right-0 z-50 bg-white/90 backdrop-blur-sm border-b">
  79. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  80. <div className="flex justify-between items-center h-16">
  81. <div className="flex items-center">
  82. <h1 className="text-xl font-bold text-gray-900">元亨Word</h1>
  83. </div>
  84. <nav className="hidden md:flex items-center space-x-8">
  85. <button
  86. onClick={() => navigate('/templates')}
  87. className="text-gray-700 hover:text-blue-600 transition-colors font-medium"
  88. >
  89. 模板广场
  90. </button>
  91. <button
  92. onClick={() => navigate('/pricing')}
  93. className="text-gray-700 hover:text-blue-600 transition-colors font-medium"
  94. >
  95. 收费标准
  96. </button>
  97. {isAuthenticated ? (
  98. <button
  99. onClick={() => setShowUserModal(true)}
  100. className="flex items-center space-x-2 text-gray-700 hover:text-blue-600 transition-colors font-medium"
  101. >
  102. <User className="h-5 w-5" />
  103. <span>{user?.nickname || user?.username || '个人中心'}</span>
  104. </button>
  105. ) : (
  106. <>
  107. <button
  108. onClick={() => navigate('/login')}
  109. className="text-gray-700 hover:text-blue-600 transition-colors font-medium"
  110. >
  111. 登录
  112. </button>
  113. <button
  114. onClick={() => navigate('/register')}
  115. className="bg-blue-600 text-white px-4 py-2 rounded-lg hover:bg-blue-700 transition-colors font-medium"
  116. >
  117. 注册
  118. </button>
  119. </>
  120. )}
  121. </nav>
  122. </div>
  123. </div>
  124. </header>
  125. {/* Hero Section */}
  126. <div className="relative overflow-hidden">
  127. <div className="absolute inset-0 bg-gradient-to-r from-blue-600/5 to-purple-600/5" />
  128. <div className="relative max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-32 pb-16">
  129. <div className="text-center">
  130. <div className="inline-flex items-center px-4 py-2 rounded-full bg-blue-100 text-blue-800 text-sm font-medium mb-6">
  131. <Zap className="h-4 w-4 mr-2" />
  132. AI驱动的文档批量处理工具
  133. </div>
  134. <h1 className="text-5xl md:text-6xl font-bold text-gray-900 mb-6">
  135. 元亨Word批量处理
  136. <span className="text-transparent bg-clip-text bg-gradient-to-r from-blue-600 to-purple-600">
  137. 增强版
  138. </span>
  139. </h1>
  140. <p className="text-xl text-gray-600 max-w-3xl mx-auto mb-8">
  141. 一键批量生成个性化Word文档,智能图片处理,高效数据驱动,
  142. 让繁琐的文档工作变得简单高效
  143. </p>
  144. <div className="flex flex-col sm:flex-row gap-4 justify-center">
  145. <Button
  146. size="lg"
  147. className="bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700 text-white px-8 py-3 text-lg"
  148. onClick={() => navigate('/word-preview')}
  149. >
  150. <Rocket className="h-5 w-5 mr-2" />
  151. 立即开始
  152. </Button>
  153. <Button
  154. size="lg"
  155. variant="outline"
  156. className="border-2 px-8 py-3 text-lg"
  157. onClick={() => document.getElementById('features')?.scrollIntoView({ behavior: 'smooth' })}
  158. >
  159. 了解更多
  160. </Button>
  161. </div>
  162. </div>
  163. </div>
  164. </div>
  165. {/* Stats Section */}
  166. <div className="bg-white/50 backdrop-blur-sm">
  167. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-16">
  168. <div className="grid grid-cols-2 md:grid-cols-4 gap-8">
  169. {stats.map((stat, index) => (
  170. <div key={index} className="text-center">
  171. <div className="flex justify-center mb-3">
  172. <div className="p-3 bg-blue-100 rounded-full">
  173. {stat.icon}
  174. </div>
  175. </div>
  176. <div className="text-3xl font-bold text-gray-900 mb-1">{stat.value}</div>
  177. <div className="text-sm text-gray-600">{stat.label}</div>
  178. </div>
  179. ))}
  180. </div>
  181. </div>
  182. </div>
  183. {/* Features Section */}
  184. <div id="features" className="py-20 bg-white">
  185. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  186. <div className="text-center mb-16">
  187. <h2 className="text-4xl font-bold text-gray-900 mb-4">
  188. 为什么选择我们
  189. </h2>
  190. <p className="text-xl text-gray-600 max-w-2xl mx-auto">
  191. 专业、高效、智能的文档处理解决方案
  192. </p>
  193. </div>
  194. <div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
  195. {features.map((feature, index) => (
  196. <Card
  197. key={index}
  198. className={`border-0 shadow-lg transition-all duration-300 hover:shadow-xl hover:-translate-y-1 cursor-pointer ${
  199. hoveredFeature === index ? 'shadow-xl -translate-y-1' : ''
  200. }`}
  201. onMouseEnter={() => setHoveredFeature(index)}
  202. onMouseLeave={() => setHoveredFeature(null)}
  203. onClick={() => navigate('/word-preview')}
  204. >
  205. <CardHeader>
  206. <div className={`p-3 rounded-lg bg-gray-50 inline-block mb-4 ${feature.color}`}>
  207. {feature.icon}
  208. </div>
  209. <CardTitle className="text-xl">{feature.title}</CardTitle>
  210. </CardHeader>
  211. <CardContent>
  212. <CardDescription className="text-base">
  213. {feature.description}
  214. </CardDescription>
  215. </CardContent>
  216. </Card>
  217. ))}
  218. </div>
  219. </div>
  220. </div>
  221. {/* Pricing Section */}
  222. <div className="py-20 bg-gradient-to-br from-gray-50 to-blue-50">
  223. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  224. <div className="text-center mb-16">
  225. <h2 className="text-4xl font-bold text-gray-900 mb-4">
  226. 灵活的会员套餐
  227. </h2>
  228. <p className="text-xl text-gray-600">
  229. 选择最适合您的套餐,享受高效文档处理体验
  230. </p>
  231. </div>
  232. <div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
  233. {membershipPlans?.map((plan) => (
  234. <Card
  235. key={plan.id}
  236. className={`relative border-0 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1 ${
  237. plan.type === 'yearly' ? 'ring-2 ring-blue-500' : ''
  238. }`}
  239. >
  240. {plan.type === 'yearly' && (
  241. <div className="absolute -top-3 left-1/2 transform -translate-x-1/2">
  242. <Badge className="bg-gradient-to-r from-blue-600 to-purple-600 text-white">
  243. 推荐
  244. </Badge>
  245. </div>
  246. )}
  247. <CardHeader>
  248. <div className="text-center">
  249. <h3 className="text-2xl font-bold mb-2">{plan.name}</h3>
  250. <div className="text-4xl font-bold text-blue-600 mb-2">
  251. ¥{plan.price}
  252. </div>
  253. <p className="text-gray-600">
  254. {plan.durationDays === 0 ? '永久有效' :
  255. plan.durationDays === 1 ? '24小时有效' :
  256. `${plan.durationDays}天有效`}
  257. </p>
  258. </div>
  259. </CardHeader>
  260. <CardContent>
  261. <ul className="space-y-3">
  262. {plan.features?.map((feature: string, index: number) => (
  263. <li key={index} className="flex items-start">
  264. <Check className="h-5 w-5 text-green-500 mr-2 flex-shrink-0 mt-0.5" />
  265. <span className="text-gray-700 text-sm">{feature}</span>
  266. </li>
  267. )) || (
  268. <>
  269. <li className="flex items-start">
  270. <Check className="h-5 w-5 text-green-500 mr-2 flex-shrink-0 mt-0.5" />
  271. <span className="text-gray-700 text-sm">基础功能</span>
  272. </li>
  273. </>
  274. )}
  275. </ul>
  276. <Button
  277. className="w-full mt-6 bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700"
  278. onClick={() => navigate('/pricing')}
  279. >
  280. 立即选择
  281. </Button>
  282. </CardContent>
  283. </Card>
  284. )) || (
  285. // 默认套餐展示
  286. <>
  287. {[
  288. { name: '单次会员', price: 27, duration: '24小时有效', features: ['基础功能', '24小时使用'], icon: Clock, color: 'text-orange-600' },
  289. { name: '单月会员', price: 86, duration: '30天有效', features: ['全部功能', '无限制使用'], icon: Calendar, color: 'text-blue-600' },
  290. { name: '年会员', price: 286, duration: '365天有效', features: ['全部功能', '无限制使用', '优先支持'], icon: Calendar, color: 'text-green-600' },
  291. { name: '永久会员', price: 688, duration: '永久有效', features: ['全部功能', '永久使用', '终身更新'], icon: Infinity, color: 'text-purple-600' }
  292. ].map((plan, index) => (
  293. <Card key={index} className="border-0 shadow-lg hover:shadow-xl transition-all duration-300 hover:-translate-y-1">
  294. <CardHeader>
  295. <div className="text-center">
  296. <h3 className="text-2xl font-bold mb-2">{plan.name}</h3>
  297. <div className="text-4xl font-bold text-blue-600 mb-2">
  298. ¥{plan.price}
  299. </div>
  300. <p className="text-gray-600">{plan.duration}</p>
  301. </div>
  302. </CardHeader>
  303. <CardContent>
  304. <ul className="space-y-3">
  305. {plan.features.map((feature, idx) => (
  306. <li key={idx} className="flex items-start">
  307. <Check className="h-5 w-5 text-green-500 mr-2 flex-shrink-0 mt-0.5" />
  308. <span className="text-gray-700 text-sm">{feature}</span>
  309. </li>
  310. ))}
  311. </ul>
  312. <Button
  313. className="w-full mt-6 bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-700 hover:to-purple-700"
  314. onClick={() => navigate('/pricing')}
  315. >
  316. 立即选择
  317. </Button>
  318. </CardContent>
  319. </Card>
  320. ))}
  321. </>
  322. )}
  323. </div>
  324. </div>
  325. </div>
  326. {/* How It Works */}
  327. <div className="py-20 bg-white">
  328. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  329. <div className="text-center mb-16">
  330. <h2 className="text-4xl font-bold text-gray-900 mb-4">
  331. 简单三步,完成批量处理
  332. </h2>
  333. <p className="text-xl text-gray-600">
  334. 无需复杂配置,轻松上手
  335. </p>
  336. </div>
  337. <div className="grid md:grid-cols-3 gap-8">
  338. {[
  339. { step: 1, title: "上传模板", description: "选择Word模板文件,支持{字段名}和{%图片名%}占位符", icon: <Upload className="h-8 w-8" /> },
  340. { step: 2, title: "导入数据", description: "上传Excel数据文件,自动匹配模板字段", icon: <FileText className="h-8 w-8" /> },
  341. { step: 3, title: "批量生成", description: "一键生成所有个性化文档,支持批量下载", icon: <Download className="h-8 w-8" /> }
  342. ].map((item, index) => (
  343. <div key={index} className="text-center">
  344. <div className="w-16 h-16 bg-blue-600 text-white rounded-full flex items-center justify-center text-2xl font-bold mx-auto mb-4">
  345. {item.step}
  346. </div>
  347. <h3 className="text-xl font-semibold mb-2">{item.title}</h3>
  348. <p className="text-gray-600">{item.description}</p>
  349. </div>
  350. ))}
  351. </div>
  352. </div>
  353. </div>
  354. {/* Application Scenarios */}
  355. <div className="py-20 bg-white">
  356. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  357. <div className="text-center mb-16">
  358. <h2 className="text-4xl font-bold text-gray-900 mb-4">
  359. 应用场景
  360. </h2>
  361. <p className="text-xl text-gray-600 max-w-3xl mx-auto">
  362. 元亨WORD批量处理广泛应用于各类重复性文档工作场景
  363. </p>
  364. </div>
  365. <div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
  366. {[
  367. {
  368. title: "项目资料安装调试表",
  369. description: "批量生成项目安装调试记录表,自动填充项目名称、设备型号、安装位置等关键信息",
  370. icon: <FileText className="h-8 w-8" />,
  371. color: "text-blue-600"
  372. },
  373. {
  374. title: "项目勘察设计点位表",
  375. description: "快速生成勘察设计点位标记文档,包含坐标、尺寸、材质等详细参数",
  376. icon: <Package className="h-8 w-8" />,
  377. color: "text-green-600"
  378. },
  379. {
  380. title: "合同批量生成",
  381. description: "基于标准合同模板,批量生成个性化合同文档,自动填充客户信息、金额等变量",
  382. icon: <Shield className="h-8 w-8" />,
  383. color: "text-purple-600"
  384. },
  385. {
  386. title: "报告文档自动化",
  387. description: "将固定格式的报告模板与数据源结合,自动生成包含不同数据的完整报告",
  388. icon: <FileText className="h-8 w-8" />,
  389. color: "text-orange-600"
  390. },
  391. {
  392. title: "证书批量制作",
  393. description: "批量生成各类证书、证明文件,自动填充获奖者信息、日期、编号等",
  394. icon: <CheckCircle className="h-8 w-8" />,
  395. color: "text-red-600"
  396. },
  397. {
  398. title: "表格数据填充",
  399. description: "将Excel数据批量填充到Word表格模板中,适用于各类统计报表生成",
  400. icon: <Settings className="h-8 w-8" />,
  401. color: "text-indigo-600"
  402. }
  403. ].map((scenario, index) => (
  404. <Card key={index} className="border-0 shadow-lg hover:shadow-xl transition-all duration-300">
  405. <CardHeader>
  406. <div className={`p-3 rounded-lg bg-gray-50 inline-block mb-4 ${scenario.color}`}>
  407. {scenario.icon}
  408. </div>
  409. <CardTitle className="text-xl">{scenario.title}</CardTitle>
  410. </CardHeader>
  411. <CardContent>
  412. <CardDescription className="text-base">
  413. {scenario.description}
  414. </CardDescription>
  415. </CardContent>
  416. </Card>
  417. ))}
  418. </div>
  419. <div className="mt-12 text-center">
  420. <div className="bg-gradient-to-r from-blue-50 to-purple-50 rounded-xl p-8">
  421. <h3 className="text-2xl font-bold text-gray-900 mb-4">核心技术特征</h3>
  422. <p className="text-lg text-gray-700 max-w-4xl mx-auto">
  423. 适用于所有符合"基础格式固定、核心信息可变量替换"特征的文档场景。
  424. 通过自动化"重复的格式排版、固定内容录入"工作,让您专注于"差异化信息填充",
  425. 大幅减少人工冗余操作,提升工作效率10倍以上。
  426. </p>
  427. </div>
  428. </div>
  429. </div>
  430. </div>
  431. {/* CTA Section */}
  432. <div className="py-20 bg-gradient-to-r from-blue-600 to-purple-600">
  433. <div className="max-w-4xl mx-auto text-center px-4 sm:px-6 lg:px-8">
  434. <h2 className="text-4xl font-bold text-white mb-4">
  435. 开始您的文档批量处理之旅
  436. </h2>
  437. <p className="text-xl text-blue-100 mb-8">
  438. 立即体验高效、智能的文档处理方式
  439. </p>
  440. <Button
  441. size="xl"
  442. className="bg-white text-blue-600 hover:bg-gray-100 px-12 py-4 text-xl font-semibold"
  443. onClick={() => navigate('/word-preview')}
  444. >
  445. <Shield className="h-5 w-5 mr-2" />
  446. 免费开始使用(5份以内3次免费体验)
  447. </Button>
  448. </div>
  449. </div>
  450. {/* Footer */}
  451. <footer className="bg-gray-900 text-white py-12">
  452. <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
  453. <div className="text-center">
  454. <h3 className="text-2xl font-bold mb-4">元亨Word批量处理工具</h3>
  455. <p className="text-gray-400 mb-6">
  456. 让每一份文档都充满个性,让批量处理变得简单
  457. </p>
  458. <div className="flex justify-center space-x-6">
  459. <Button
  460. variant="ghost"
  461. className="text-white hover:text-blue-400"
  462. onClick={() => navigate('/word-preview')}
  463. >
  464. 立即体验
  465. </Button>
  466. </div>
  467. </div>
  468. </div>
  469. </footer>
  470. <UserInfoModal
  471. isOpen={showUserModal}
  472. onClose={() => setShowUserModal(false)}
  473. />
  474. </div>
  475. );
  476. }