├── 模块详细设计文档.md ├── app ├── __init__.py ├── schemas.py ├── utils.py ├── requirements.txt └── static │ └── html2image.js ├── tools ├── __init__.py ├── card.png ├── output.png ├── output_selenium.png ├── output_images │ ├── card_1.png │ ├── page_1.png │ ├── card_1_thresh.png │ ├── card_1_connected.png │ ├── card_1_card_boundary.png │ └── card_1_content_regions.png ├── html2pic.py ├── html2pdf.py ├── html2pic2.py ├── prompt_config.py ├── test │ └── html2image.js ├── selenium2img.py ├── llm_prompt.py └── card_extractor.py ├── image ├── p1.png ├── p2.png ├── p3.png ├── p4.png └── image.png ├── static ├── p1.png ├── p2.png ├── p3.png ├── p4.png └── image.png ├── requirements.txt ├── game_card ├── static │ ├── 算力.png │ ├── deepseek-copy.png │ └── deepseek-copy.svg ├── test.html ├── test_red.html ├── test_blue.html ├── test_cyan.html ├── test_green.html ├── test_orange.html ├── test_purple.html └── test_yellow.html ├── smart-card-react ├── postcss.config.mjs ├── src │ ├── app │ │ ├── favicon.ico │ │ ├── page.tsx │ │ ├── showcase │ │ │ └── page.tsx │ │ ├── globals.css │ │ ├── layout.tsx │ │ └── auth │ │ │ ├── signup │ │ │ └── page.tsx │ │ │ └── signin │ │ │ └── page.tsx │ ├── modules │ │ ├── html-editor │ │ │ ├── index.ts │ │ │ ├── components │ │ │ │ ├── Portal.tsx │ │ │ │ ├── Leaf.tsx │ │ │ │ ├── ToolbarButton.tsx │ │ │ │ ├── Element.tsx │ │ │ │ ├── HTMLEditor.css │ │ │ │ ├── HoveringToolbar.tsx │ │ │ │ └── HTMLEditor.tsx │ │ │ └── utils │ │ │ │ └── editor.ts │ │ ├── home │ │ │ ├── index.ts │ │ │ └── pages │ │ │ │ └── HomePage.tsx │ │ ├── showcase │ │ │ ├── index.ts │ │ │ ├── pages │ │ │ │ └── ShowcasePage.tsx │ │ │ └── components │ │ │ │ └── ShowcaseCard.tsx │ │ ├── ai │ │ │ ├── index.ts │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ └── api │ │ │ │ └── index.ts │ │ ├── webscraper │ │ │ ├── index.ts │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ └── api │ │ │ │ └── index.ts │ │ ├── index.ts │ │ ├── common │ │ │ ├── index.ts │ │ │ ├── types │ │ │ │ └── index.ts │ │ │ ├── store │ │ │ │ └── toastStore.ts │ │ │ ├── api │ │ │ │ └── httpClient.ts │ │ │ └── utils.ts │ │ └── card │ │ │ ├── index.ts │ │ │ ├── components │ │ │ └── create │ │ │ │ └── index.tsx │ │ │ ├── types │ │ │ └── index.ts │ │ │ ├── api │ │ │ └── index.ts │ │ │ └── store │ │ │ └── index.ts │ ├── components │ │ ├── ui │ │ │ ├── index.ts │ │ │ ├── Card.tsx │ │ │ ├── Badge.tsx │ │ │ ├── LoadingSpinner.tsx │ │ │ ├── Button.tsx │ │ │ └── Input.tsx │ │ ├── index.ts │ │ ├── ShowcaseCard.tsx │ │ ├── HtmlPaster.tsx │ │ └── UIFineTuner.tsx │ ├── doc │ │ ├── auth_api.md │ │ ├── creation_api.md │ │ └── dashboard_api.md │ ├── types │ │ └── index.ts │ ├── services │ │ └── api.ts │ └── data │ │ └── mock-showcase-data.ts ├── public │ ├── vercel.svg │ ├── file.svg │ ├── window.svg │ ├── globe.svg │ └── next.svg ├── next.config.ts ├── eslint.config.mjs ├── .gitignore ├── tsconfig.json ├── package.json ├── PROJECT_INFO.md ├── tailwind.config.js ├── .github │ └── copilot-instructions.md └── README.md ├── .gitignore ├── setup.py ├── README.md └── templates └── html2image-demo.html /模块详细设计文档.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/schemas.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /image/p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/image/p1.png -------------------------------------------------------------------------------- /image/p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/image/p2.png -------------------------------------------------------------------------------- /image/p3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/image/p3.png -------------------------------------------------------------------------------- /image/p4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/image/p4.png -------------------------------------------------------------------------------- /static/p1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/static/p1.png -------------------------------------------------------------------------------- /static/p2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/static/p2.png -------------------------------------------------------------------------------- /static/p3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/static/p3.png -------------------------------------------------------------------------------- /static/p4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/static/p4.png -------------------------------------------------------------------------------- /tools/card.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/card.png -------------------------------------------------------------------------------- /image/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/image/image.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | uvicorn[standard] 3 | httpx 4 | html2image 5 | pyppeteer 6 | jinja2 7 | -------------------------------------------------------------------------------- /static/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/static/image.png -------------------------------------------------------------------------------- /tools/output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output.png -------------------------------------------------------------------------------- /game_card/static/算力.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/game_card/static/算力.png -------------------------------------------------------------------------------- /tools/output_selenium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output_selenium.png -------------------------------------------------------------------------------- /tools/output_images/card_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output_images/card_1.png -------------------------------------------------------------------------------- /tools/output_images/page_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output_images/page_1.png -------------------------------------------------------------------------------- /game_card/static/deepseek-copy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/game_card/static/deepseek-copy.png -------------------------------------------------------------------------------- /smart-card-react/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /smart-card-react/src/app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/smart-card-react/src/app/favicon.ico -------------------------------------------------------------------------------- /tools/output_images/card_1_thresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output_images/card_1_thresh.png -------------------------------------------------------------------------------- /tools/output_images/card_1_connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output_images/card_1_connected.png -------------------------------------------------------------------------------- /tools/output_images/card_1_card_boundary.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output_images/card_1_card_boundary.png -------------------------------------------------------------------------------- /smart-card-react/public/vercel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/html-editor/index.ts: -------------------------------------------------------------------------------- 1 | import HTMLEditor from './components/HTMLEditor'; 2 | 3 | export { HTMLEditor }; 4 | export default HTMLEditor; -------------------------------------------------------------------------------- /tools/output_images/card_1_content_regions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/datawhalechina/smart-card-workshop/HEAD/tools/output_images/card_1_content_regions.png -------------------------------------------------------------------------------- /app/utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | 4 | def cleanup_old_files(directory: str, max_age_hours: int = 24): 5 | """清理旧文件""" 6 | # 实现可以根据需要添加 7 | pass -------------------------------------------------------------------------------- /smart-card-react/src/modules/home/index.ts: -------------------------------------------------------------------------------- 1 | // home模块导出 2 | export { default as HomePage } from './components/HomePage'; 3 | export { default as HomePageContainer } from './pages/HomePage'; -------------------------------------------------------------------------------- /smart-card-react/src/components/ui/index.ts: -------------------------------------------------------------------------------- 1 | // UI 组件的导出 2 | export { Button } from './Button'; 3 | export { Input, Textarea } from './Input'; 4 | export { Card } from './Card'; 5 | export { LoadingSpinner } from './LoadingSpinner'; 6 | export { Badge } from './Badge'; 7 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/showcase/index.ts: -------------------------------------------------------------------------------- 1 | // showcase模块导出 2 | export { default as ShowcaseCard } from './components/ShowcaseCard'; 3 | export { default as ShowcasePage } from './components/ShowcasePage'; 4 | export { default as ShowcasePageContainer } from './pages/ShowcasePage'; -------------------------------------------------------------------------------- /smart-card-react/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import HomePage from '@/components/HomePage'; 4 | 5 | /** 6 | * 应用程序的根页面,渲染首页组件。 7 | * @returns {React.ReactElement} 首页组件。 8 | */ 9 | export default function Home(): React.ReactElement { 10 | return ; 11 | } 12 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/ai/index.ts: -------------------------------------------------------------------------------- 1 | // AI模块入口文件 2 | export * from './components/AIGenerator'; 3 | export * from './types'; 4 | export * from './api'; 5 | 6 | // 默认导出 7 | import AIGenerator from './components/AIGenerator'; 8 | import { aiApi } from './api'; 9 | 10 | export default { 11 | AIGenerator, 12 | aiApi, 13 | }; -------------------------------------------------------------------------------- /app/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi 2 | uvicorn[standard] 3 | httpx 4 | jinja2 5 | pyppeteer 6 | opencv-python 7 | numpy 8 | openai 9 | python-dotenv # Added for loading .env files 10 | selenium # Added for browser automation 11 | # webdriver-manager # Removed as WebDriver is now handled directly 12 | requests # Added for HTTP requests to Jina API 13 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/home/pages/HomePage.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import React from 'react'; 4 | import HomePage from '../components/HomePage'; 5 | 6 | /** 7 | * 主页页面组件 8 | * 封装HomePage组件,便于在app目录中使用 9 | */ 10 | const HomePageContainer: React.FC = () => { 11 | return ; 12 | }; 13 | 14 | export default HomePageContainer; -------------------------------------------------------------------------------- /smart-card-react/src/modules/webscraper/index.ts: -------------------------------------------------------------------------------- 1 | // 网页抓取模块入口文件 2 | export * from './components/WebScraper'; 3 | export * from './types'; 4 | export * from './api'; 5 | 6 | // 默认导出 7 | import WebScraper from './components/WebScraper'; 8 | import { webscraperApi } from './api'; 9 | 10 | export default { 11 | WebScraper, 12 | webscraperApi, 13 | }; -------------------------------------------------------------------------------- /smart-card-react/next.config.ts: -------------------------------------------------------------------------------- 1 | import { type NextConfig } from 'next'; 2 | 3 | const nextConfig: NextConfig = { 4 | images: { 5 | remotePatterns: [ 6 | { 7 | protocol: 'https', 8 | hostname: 'images.unsplash.com', 9 | port: '', 10 | pathname: '/**', 11 | }, 12 | ], 13 | }, 14 | }; 15 | 16 | export default nextConfig; 17 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/showcase/pages/ShowcasePage.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import React from 'react'; 4 | import ShowcasePage from '../components/ShowcasePage'; 5 | 6 | /** 7 | * 展示页面组件 8 | * 封装ShowcasePage组件,便于在app目录中使用 9 | */ 10 | const ShowcasePageContainer: React.FC = () => { 11 | return ; 12 | }; 13 | 14 | export default ShowcasePageContainer; -------------------------------------------------------------------------------- /smart-card-react/src/app/showcase/page.tsx: -------------------------------------------------------------------------------- 1 | import ShowcasePage from '@/components/ShowcasePage'; 2 | import React from 'react'; 3 | 4 | /** 5 | * Renders the showcase page for exploring creative cards. 6 | * @returns {React.ReactElement} The showcase page component. 7 | */ 8 | export default function ShowcaseRoutePage(): React.ReactElement { 9 | return ; 10 | } -------------------------------------------------------------------------------- /smart-card-react/public/file.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /smart-card-react/public/window.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/ai/types/index.ts: -------------------------------------------------------------------------------- 1 | // AI生成模块类型定义 2 | 3 | export interface AIGenerationRequest { 4 | prompt: string; 5 | template?: string; 6 | style?: string; 7 | language?: string; 8 | } 9 | 10 | export interface AIGenerationResponse { 11 | success: boolean; 12 | htmlContent: string; 13 | error?: string; 14 | metadata?: { 15 | tokenUsed: number; 16 | processingTime: number; 17 | }; 18 | } -------------------------------------------------------------------------------- /smart-card-react/src/modules/index.ts: -------------------------------------------------------------------------------- 1 | // 模块总入口文件 2 | export * from './card'; 3 | export * from './ai'; 4 | export * from './webscraper'; 5 | export * from './common'; 6 | 7 | // 默认导出 8 | import cardModule from './card'; 9 | import aiModule from './ai'; 10 | import webscraperModule from './webscraper'; 11 | import commonModule from './common'; 12 | 13 | export default { 14 | card: cardModule, 15 | ai: aiModule, 16 | webscraper: webscraperModule, 17 | common: commonModule, 18 | }; -------------------------------------------------------------------------------- /smart-card-react/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ]; 15 | 16 | export default eslintConfig; 17 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/webscraper/types/index.ts: -------------------------------------------------------------------------------- 1 | // 网页抓取模块类型定义 2 | 3 | export interface WebScrapingRequest { 4 | url: string; 5 | extractionType: 'summary' | 'content' | 'structured'; 6 | customPrompt?: string; 7 | } 8 | 9 | export interface WebScrapingResponse { 10 | success: boolean; 11 | title: string; 12 | content: string; 13 | summary?: string; 14 | structuredData?: Record; 15 | error?: string; 16 | metadata?: { 17 | processingTime: number; 18 | wordCount: number; 19 | }; 20 | } -------------------------------------------------------------------------------- /smart-card-react/src/components/index.ts: -------------------------------------------------------------------------------- 1 | // 组件导出文件 - 重新导出所有组件,保持向后兼容 2 | 3 | // 从模块中导出组件 - 为了向后兼容 4 | export { HomePage } from '@/modules/home'; 5 | export { ShowcaseCard, ShowcasePage } from '@/modules/showcase'; 6 | export { CardPreview } from '@/modules/card'; 7 | export { AIGenerator } from '@/modules/ai'; 8 | export { WebScraper } from '@/modules/webscraper'; 9 | 10 | // 导出UI组件 11 | export * from './ui'; 12 | 13 | // 导出其他组件 14 | export { default as HtmlPaster } from './HtmlPaster'; 15 | export { default as UIFineTuner } from './UIFineTuner'; -------------------------------------------------------------------------------- /smart-card-react/src/modules/common/index.ts: -------------------------------------------------------------------------------- 1 | // 通用模块入口文件 2 | export * from './types'; 3 | export * from './api/httpClient'; 4 | export * from './store/toastStore'; 5 | export * from './utils'; 6 | 7 | // 默认导出 8 | import { httpClient } from './api/httpClient'; 9 | import { useToastStore } from './store/toastStore'; 10 | import { cn, formatDate, debounce, throttle } from './utils'; 11 | 12 | export default { 13 | httpClient, 14 | useToastStore, 15 | utils: { 16 | cn, 17 | formatDate, 18 | debounce, 19 | throttle 20 | } 21 | }; -------------------------------------------------------------------------------- /smart-card-react/src/modules/common/types/index.ts: -------------------------------------------------------------------------------- 1 | // 通用模块类型定义 2 | 3 | export interface AppConfig { 4 | apiEndpoint: string; 5 | arkApiKey: string; 6 | jinaApiKey: string; 7 | maxCardSize: number; 8 | supportedFormats: string[]; 9 | defaultTemplate: string; 10 | } 11 | 12 | export interface AppState { 13 | isLoading: boolean; 14 | error: string | null; 15 | config: AppConfig; 16 | } 17 | 18 | export interface ToastProps { 19 | title: string; 20 | description?: string; 21 | type: 'success' | 'error' | 'warning' | 'info'; 22 | duration?: number; 23 | } -------------------------------------------------------------------------------- /smart-card-react/src/modules/html-editor/components/Portal.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | 4 | interface PortalProps { 5 | children: React.ReactNode; 6 | } 7 | 8 | export const Portal: React.FC = ({ children }) => { 9 | const [mounted, setMounted] = useState(false); 10 | 11 | useEffect(() => { 12 | setMounted(true); 13 | return () => setMounted(false); 14 | }, []); 15 | 16 | return mounted 17 | ? ReactDOM.createPortal( 18 | children, 19 | document.body 20 | ) 21 | : null; 22 | }; -------------------------------------------------------------------------------- /smart-card-react/src/app/globals.css: -------------------------------------------------------------------------------- 1 | @import "tailwindcss"; 2 | 3 | :root { 4 | --background: #ffffff; 5 | --foreground: #171717; 6 | } 7 | 8 | @theme inline { 9 | --color-background: var(--background); 10 | --color-foreground: var(--foreground); 11 | --font-sans: var(--font-geist-sans); 12 | --font-mono: var(--font-geist-mono); 13 | } 14 | 15 | @media (prefers-color-scheme: dark) { 16 | :root { 17 | --background: #0a0a0a; 18 | --foreground: #ededed; 19 | } 20 | } 21 | 22 | body { 23 | background: var(--background); 24 | color: var(--foreground); 25 | font-family: Arial, Helvetica, sans-serif; 26 | } 27 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/card/index.ts: -------------------------------------------------------------------------------- 1 | // 卡片模块入口文件 2 | export * from './components/CardPreview'; 3 | export * from './pages/DashboardPage'; 4 | export * from './pages/CreatePage'; 5 | export * from './types'; 6 | export * from './api'; 7 | export * from './store'; 8 | 9 | // 默认导出 10 | import CardPreview from './components/CardPreview'; 11 | import DashboardPage from './pages/DashboardPage'; 12 | import CreatePage from './pages/CreatePage'; 13 | import { cardApi } from './api'; 14 | import { useCardStore } from './store'; 15 | 16 | export default { 17 | CardPreview, 18 | DashboardPage, 19 | CreatePage, 20 | cardApi, 21 | useCardStore, 22 | }; -------------------------------------------------------------------------------- /smart-card-react/src/components/ui/Card.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { clsx } from 'clsx'; 3 | 4 | interface CardProps { 5 | children: React.ReactNode; 6 | className?: string; 7 | padding?: 'sm' | 'md' | 'lg'; 8 | } 9 | 10 | export const Card: React.FC = ({ 11 | children, 12 | className, 13 | padding = 'md' 14 | }) => { 15 | const paddings = { 16 | sm: 'p-4', 17 | md: 'p-6', 18 | lg: 'p-8', 19 | }; 20 | 21 | return ( 22 |
27 | {children} 28 |
29 | ); 30 | }; 31 | -------------------------------------------------------------------------------- /smart-card-react/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debugß 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | 43 | #history 44 | .history 45 | -------------------------------------------------------------------------------- /smart-card-react/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*"] 23 | } 24 | }, 25 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 26 | "exclude": ["node_modules"] 27 | } 28 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/ai/api/index.ts: -------------------------------------------------------------------------------- 1 | import { httpClient } from '@/modules/common/api/httpClient'; 2 | import { AIGenerationRequest, AIGenerationResponse } from '@/modules/ai/types'; 3 | 4 | // AI模块API服务 5 | export const aiApi = { 6 | // AI 内容生成 7 | async generateContent(request: AIGenerationRequest): Promise { 8 | try { 9 | const response = await httpClient.client.post('/ai/generate', request); 10 | return response.data; 11 | } catch (error) { 12 | console.error('AI Generation Error:', error); 13 | return { 14 | success: false, 15 | htmlContent: '', 16 | error: error instanceof Error ? error.message : 'AI 生成失败', 17 | }; 18 | } 19 | } 20 | }; 21 | 22 | export default aiApi; -------------------------------------------------------------------------------- /smart-card-react/src/modules/webscraper/api/index.ts: -------------------------------------------------------------------------------- 1 | import { httpClient } from '@/modules/common/api/httpClient'; 2 | import { WebScrapingRequest, WebScrapingResponse } from '@/modules/webscraper/types'; 3 | 4 | // 网页抓取模块API服务 5 | export const webscraperApi = { 6 | // 网页内容抓取 7 | async scrapeWebsite(request: WebScrapingRequest): Promise { 8 | try { 9 | const response = await httpClient.client.post('/scrape/website', request); 10 | return response.data; 11 | } catch (error) { 12 | console.error('Web Scraping Error:', error); 13 | return { 14 | success: false, 15 | title: '', 16 | content: '', 17 | error: error instanceof Error ? error.message : '网页抓取失败', 18 | }; 19 | } 20 | } 21 | }; 22 | 23 | export default webscraperApi; -------------------------------------------------------------------------------- /smart-card-react/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from "next"; 2 | import { Geist, Geist_Mono } from "next/font/google"; 3 | import "./globals.css"; 4 | 5 | const geistSans = Geist({ 6 | variable: "--font-geist-sans", 7 | subsets: ["latin"], 8 | }); 9 | 10 | const geistMono = Geist_Mono({ 11 | variable: "--font-geist-mono", 12 | subsets: ["latin"], 13 | }); 14 | 15 | export const metadata: Metadata = { 16 | title: "Create Next App", 17 | description: "Generated by create next app", 18 | }; 19 | 20 | export default function RootLayout({ 21 | children, 22 | }: Readonly<{ 23 | children: React.ReactNode; 24 | }>) { 25 | return ( 26 | 27 | 30 | {children} 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /smart-card-react/src/components/ui/Badge.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { clsx } from 'clsx'; 3 | 4 | interface BadgeProps { 5 | children: React.ReactNode; 6 | variant?: 'primary' | 'secondary' | 'success' | 'warning' | 'error'; 7 | className?: string; 8 | } 9 | 10 | export const Badge: React.FC = ({ 11 | children, 12 | variant = 'primary', 13 | className 14 | }) => { 15 | const variants = { 16 | primary: 'bg-blue-100 text-blue-800', 17 | secondary: 'bg-gray-100 text-gray-800', 18 | success: 'bg-green-100 text-green-800', 19 | warning: 'bg-yellow-100 text-yellow-800', 20 | error: 'bg-red-100 text-red-800', 21 | }; 22 | 23 | return ( 24 | 29 | {children} 30 | 31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /smart-card-react/src/components/ui/LoadingSpinner.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { clsx } from 'clsx'; 3 | 4 | interface LoadingSpinnerProps { 5 | size?: 'sm' | 'md' | 'lg'; 6 | className?: string; 7 | } 8 | 9 | export const LoadingSpinner: React.FC = ({ 10 | size = 'md', 11 | className 12 | }) => { 13 | const sizes = { 14 | sm: 'h-4 w-4', 15 | md: 'h-6 w-6', 16 | lg: 'h-8 w-8', 17 | }; 18 | 19 | return ( 20 |
21 | 22 | 23 | 24 | 25 |
26 | ); 27 | }; 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Python相关忽略 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | *.so 6 | .Python 7 | build/ 8 | develop-eggs/ 9 | dist/ 10 | downloads/ 11 | eggs/ 12 | .eggs/ 13 | lib/ 14 | lib64/ 15 | parts/ 16 | sdist/ 17 | var/ 18 | wheels/ 19 | *.egg-info/ 20 | .installed.cfg 21 | *.egg 22 | MANIFEST 23 | 24 | # 虚拟环境 25 | .env 26 | .venv 27 | env/ 28 | venv/ 29 | ENV/ 30 | env.bak/ 31 | venv.bak/ 32 | .python-version 33 | 34 | # uv相关文件 35 | .uv/ 36 | .uvroot 37 | 38 | # 项目输出文件 39 | output/ 40 | # static/ 41 | # *.png 42 | *.pdf 43 | *.html 44 | !templates/*.html 45 | 46 | # IDE相关 47 | .idea/ 48 | .vscode/ 49 | *.swp 50 | *.swo 51 | .DS_Store 52 | 53 | # 日志文件 54 | *.log 55 | logs/ 56 | 57 | # 本地配置 58 | tools/.env 59 | 60 | # 测试相关 61 | .coverage 62 | htmlcov/ 63 | .pytest_cache/ 64 | nosetests.xml 65 | coverage.xml 66 | *.cover 67 | 68 | # 临时文件 69 | temp/ 70 | tmp/ 71 | .temp/ 72 | .tmp/ 73 | 74 | # Chrome WebDriver 75 | chromedriver* 76 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/common/store/toastStore.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'zustand'; 2 | import { devtools } from 'zustand/middleware'; 3 | import { ToastProps } from '@/modules/common/types'; 4 | 5 | interface ToastState { 6 | toasts: ToastProps[]; 7 | } 8 | 9 | interface ToastActions { 10 | addToast: (toast: ToastProps) => void; 11 | removeToast: (index: number) => void; 12 | clearToasts: () => void; 13 | } 14 | 15 | export type ToastStore = ToastState & ToastActions; 16 | 17 | // Toast 通知 Store 18 | export const useToastStore = create()( 19 | devtools((set) => ({ 20 | toasts: [], 21 | 22 | addToast: (toast) => 23 | set((state) => ({ 24 | toasts: [...state.toasts, { ...toast, duration: toast.duration || 3000 }], 25 | })), 26 | 27 | removeToast: (index) => 28 | set((state) => ({ 29 | toasts: state.toasts.filter((_, i) => i !== index), 30 | })), 31 | 32 | clearToasts: () => set({ toasts: [] }), 33 | })) 34 | ); -------------------------------------------------------------------------------- /smart-card-react/src/modules/html-editor/components/Leaf.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { RenderLeafProps } from 'slate-react'; 3 | 4 | export const Leaf: React.FC = ({ attributes, children, leaf }) => { 5 | let element = <>{children}; 6 | 7 | if (leaf.bold) { 8 | element = {element}; 9 | } 10 | 11 | if (leaf.code) { 12 | element = {element}; 13 | } 14 | 15 | if (leaf.italic) { 16 | element = {element}; 17 | } 18 | 19 | if (leaf.underline) { 20 | element = {element}; 21 | } 22 | 23 | const style: React.CSSProperties = {}; 24 | 25 | if (leaf.color) { 26 | style.color = leaf.color; 27 | } 28 | 29 | if (leaf.fontSize) { 30 | style.fontSize = leaf.fontSize; 31 | } 32 | 33 | if (leaf.backgroundColor) { 34 | style.backgroundColor = leaf.backgroundColor; 35 | } 36 | 37 | return ( 38 | 39 | {element} 40 | 41 | ); 42 | }; -------------------------------------------------------------------------------- /smart-card-react/src/modules/html-editor/components/ToolbarButton.tsx: -------------------------------------------------------------------------------- 1 | import React, { PropsWithChildren } from 'react'; 2 | 3 | interface ToolbarButtonProps { 4 | active?: boolean; 5 | onMouseDown?: (event: React.MouseEvent) => void; 6 | title?: string; 7 | } 8 | 9 | export const ToolbarButton: React.FC> = ({ 10 | active, 11 | onMouseDown, 12 | title, 13 | children, 14 | }) => { 15 | return ( 16 | 34 | ); 35 | }; -------------------------------------------------------------------------------- /smart-card-react/public/globe.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tools/html2pic.py: -------------------------------------------------------------------------------- 1 | import imgkit 2 | 3 | def html_to_image(html_path, output_path, options=None): 4 | """ 5 | 将HTML文件转换为图片 6 | 7 | 参数: 8 | html_path: HTML文件路径或HTML字符串 9 | output_path: 输出图片路径(如'output.png') 10 | options: 可选配置字典 11 | """ 12 | default_options = { 13 | 'encoding': "UTF-8", 14 | 'enable-local-file-access': None, 15 | 'custom-header': [ 16 | ('Accept-Language', 'zh-CN,zh;q=0.9') 17 | ], 18 | 'quiet': None, 19 | 'quality':100, 20 | 'disable-smart-width': None, 21 | 'width': 500, 22 | 'minimum-font-size': 16, 23 | 'zoom': 100, 24 | } 25 | 26 | if options: 27 | default_options.update(options) 28 | 29 | try: 30 | imgkit.from_file(html_path, output_path, options=default_options) 31 | print(f"图片已成功保存到 {output_path},已优化中文字体和图像清晰度") 32 | except Exception as e: 33 | print(f"转换失败: {str(e)}") 34 | 35 | # 使用示例 36 | html_to_image('./1c6ccb00-f117-4cc0-af04-90b008c2744c.html', 'output.png') -------------------------------------------------------------------------------- /tools/html2pdf.py: -------------------------------------------------------------------------------- 1 | import pdfkit 2 | 3 | def html_to_pdf(html_path, output_path, options=None): 4 | """ 5 | 将HTML转换为PDF 6 | 7 | 参数: 8 | html_path: HTML文件路径或HTML字符串 9 | output_path: 输出PDF路径(如'output.pdf') 10 | options: 可选配置字典 11 | """ 12 | default_options = { 13 | 'encoding': "UTF-8", 14 | 'quiet': '', 15 | 'enable-local-file-access': None # 允许访问本地文件 16 | } 17 | 18 | if options: 19 | default_options.update(options) 20 | 21 | try: 22 | # 判断输入是文件还是HTML字符串 23 | if html_path.endswith('.html'): 24 | pdfkit.from_file(html_path, output_path, options=default_options) 25 | else: 26 | pdfkit.from_string(html_path, output_path, options=default_options) 27 | 28 | print(f"PDF已成功保存到 {output_path}") 29 | except Exception as e: 30 | print(f"转换失败: {str(e)}") 31 | 32 | # 使用示例 33 | html_to_pdf('./1c6ccb00-f117-4cc0-af04-90b008c2744c.html', 'output_weasyprint.pdf')# 或直接使用HTML字符串 34 | # html_to_pdf('

Hello World

', 'output.pdf') 35 | 36 | -------------------------------------------------------------------------------- /smart-card-react/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "smart-card-react", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev --turbopack", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@radix-ui/react-dialog": "^1.1.14", 13 | "@radix-ui/react-select": "^2.2.5", 14 | "@radix-ui/react-tabs": "^1.1.12", 15 | "@radix-ui/react-toast": "^1.2.14", 16 | "@radix-ui/react-tooltip": "^1.2.7", 17 | "axios": "^1.10.0", 18 | "class-variance-authority": "^0.7.1", 19 | "clsx": "^2.1.1", 20 | "html2canvas": "^1.4.1", 21 | "jspdf": "^3.0.1", 22 | "lucide-react": "^0.525.0", 23 | "next": "15.3.5", 24 | "react": "^19.0.0", 25 | "react-dom": "^19.0.0", 26 | "zustand": "^5.0.6", 27 | "react-colorful": "^5.6.1", 28 | "react-icons": "^5.5.0", 29 | "slate": "^0.117.2", 30 | "slate-history": "^0.113.1", 31 | "slate-react": "^0.117.4" 32 | }, 33 | "devDependencies": { 34 | "@eslint/eslintrc": "^3", 35 | "@tailwindcss/postcss": "^4", 36 | "@types/node": "^20", 37 | "@types/react": "^19", 38 | "@types/react-dom": "^19", 39 | "eslint": "^9", 40 | "eslint-config-next": "15.3.5", 41 | "tailwindcss": "^4", 42 | "typescript": "^5" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/common/api/httpClient.ts: -------------------------------------------------------------------------------- 1 | import axios, { AxiosInstance, AxiosResponse } from 'axios'; 2 | 3 | class HttpClient { 4 | private apiClient: AxiosInstance; 5 | 6 | constructor() { 7 | this.apiClient = axios.create({ 8 | baseURL: process.env.NEXT_PUBLIC_API_BASE_URL || 'http://localhost:8000', 9 | timeout: 30000, 10 | headers: { 11 | 'Content-Type': 'application/json', 12 | }, 13 | }); 14 | 15 | // 请求拦截器 16 | this.apiClient.interceptors.request.use( 17 | (config) => { 18 | console.log('API Request:', config.method?.toUpperCase(), config.url); 19 | return config; 20 | }, 21 | (error) => { 22 | return Promise.reject(error); 23 | } 24 | ); 25 | 26 | // 响应拦截器 27 | this.apiClient.interceptors.response.use( 28 | (response: AxiosResponse) => { 29 | console.log('API Response:', response.status, response.config.url); 30 | return response; 31 | }, 32 | (error) => { 33 | console.error('API Error:', error.response?.data || error.message); 34 | return Promise.reject(error); 35 | } 36 | ); 37 | } 38 | 39 | get client(): AxiosInstance { 40 | return this.apiClient; 41 | } 42 | } 43 | 44 | export const httpClient = new HttpClient(); 45 | export default httpClient; -------------------------------------------------------------------------------- /smart-card-react/public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/common/utils.ts: -------------------------------------------------------------------------------- 1 | import { clsx, type ClassValue } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | /** 5 | * 合并className的工具函数 6 | * 结合clsx和tailwind-merge,可以智能地合并和处理tailwind类名 7 | */ 8 | export function cn(...inputs: ClassValue[]) { 9 | return twMerge(clsx(inputs)); 10 | } 11 | 12 | /** 13 | * 格式化日期为本地字符串 14 | */ 15 | export function formatDate(date: Date | string): string { 16 | if (typeof date === 'string') { 17 | date = new Date(date); 18 | } 19 | return date.toLocaleDateString('zh-CN', { 20 | year: 'numeric', 21 | month: 'long', 22 | day: 'numeric', 23 | }); 24 | } 25 | 26 | /** 27 | * 防抖函数 28 | */ 29 | export function debounce unknown>( 30 | fn: T, 31 | delay: number 32 | ): (...args: Parameters) => void { 33 | let timeout: NodeJS.Timeout; 34 | 35 | return function(...args: Parameters) { 36 | clearTimeout(timeout); 37 | timeout = setTimeout(() => fn(...args), delay); 38 | }; 39 | } 40 | 41 | /** 42 | * 节流函数 43 | */ 44 | export function throttle unknown>( 45 | fn: T, 46 | limit: number 47 | ): (...args: Parameters) => void { 48 | let inThrottle: boolean; 49 | 50 | return function(...args: Parameters) { 51 | if (!inThrottle) { 52 | fn(...args); 53 | inThrottle = true; 54 | setTimeout(() => inThrottle = false, limit); 55 | } 56 | }; 57 | } -------------------------------------------------------------------------------- /smart-card-react/src/doc/auth_api.md: -------------------------------------------------------------------------------- 1 | # 认证模块 API 文档 (`/api/v1/auth`) 2 | 3 | 本模块负责处理用户注册和登录认证。 4 | 5 | --- 6 | 7 | ## 1. 用户注册 8 | 9 | - **Endpoint**: `POST /api/v1/auth/signup` 10 | - **功能描述**: 创建一个新用户账户。 11 | - **请求头**: 12 | ```json 13 | { 14 | "Content-Type": "application/json" 15 | } 16 | ``` 17 | - **请求体 (Pydantic Schema: `UserCreate`)**: 18 | ```json 19 | { 20 | "name": "王小明", 21 | "email": "user@example.com", 22 | "password": "a_strong_password" 23 | } 24 | ``` 25 | - **成功响应 (200 OK - Pydantic Schema: `UserPublic`)**: 26 | ```json 27 | { 28 | "id": "user_uuid_123", 29 | "name": "王小明", 30 | "email": "user@example.com", 31 | "avatar_url": "https://default-avatar-url.com/avatar.png" 32 | } 33 | ``` 34 | - **错误响应 (409 Conflict)**: 35 | ```json 36 | { 37 | "detail": "Email already registered" 38 | } 39 | ``` 40 | 41 | --- 42 | 43 | ## 2. 用户登录 44 | 45 | - **Endpoint**: `POST /api/v1/auth/signin` 46 | - **功能描述**: 使用邮箱和密码进行用户认证,成功后返回JWT。 47 | - **请求头**: 48 | ```json 49 | { 50 | "Content-Type": "application/x-www-form-urlencoded" 51 | } 52 | ``` 53 | - **请求体 (Form Data)**: 54 | - `username`: 用户的邮箱地址 (e.g., `user@example.com`) 55 | - `password`: 用户的密码 (e.g., `a_strong_password`) 56 | - **成功响应 (200 OK)**: 57 | ```json 58 | { 59 | "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", 60 | "token_type": "bearer" 61 | } 62 | ``` 63 | - **错误响应 (401 Unauthorized)**: 64 | ```json 65 | { 66 | "detail": "Incorrect email or password" 67 | } 68 | ``` -------------------------------------------------------------------------------- /tools/html2pic2.py: -------------------------------------------------------------------------------- 1 | from selenium import webdriver 2 | from selenium.webdriver.chrome.options import Options 3 | import os 4 | 5 | def html_to_image_selenium(html_path, output_path): 6 | """ 7 | 使用selenium将HTML转换为图片,并根据内容自动调整尺寸 8 | 9 | 参数: 10 | html_path: HTML文件路径或URL 11 | output_path: 输出图片路径 12 | """ 13 | chrome_options = Options() 14 | chrome_options.add_argument('--headless') 15 | chrome_options.add_argument('--disable-gpu') 16 | chrome_options.add_argument('--no-sandbox') 17 | 18 | try: 19 | driver = webdriver.Chrome(options=chrome_options) 20 | driver.get(f'file://{os.path.abspath(html_path)}' if html_path.endswith('.html') else html_path) 21 | 22 | # 获取内容尺寸,而不是整个body 23 | width = driver.execute_script("return Math.max(document.documentElement.scrollWidth, document.documentElement.clientWidth);") 24 | height = driver.execute_script("return Math.max(document.documentElement.scrollHeight, document.documentElement.clientHeight);") 25 | 26 | # 分析内容是否需要额外边距 27 | has_card = driver.execute_script("return document.querySelector('.card') !== null;") 28 | if has_card: 29 | # 如果有卡片元素,添加一些额外边距 30 | width += 40 31 | height += 40 32 | 33 | driver.set_window_size(width, height) 34 | driver.save_screenshot(output_path) 35 | print(f"图片已成功保存到 {output_path},尺寸: {width}x{height}") 36 | except Exception as e: 37 | print(f"转换失败: {str(e)}") 38 | finally: 39 | if 'driver' in locals(): 40 | driver.quit() 41 | 42 | # 使用示例 43 | html_to_image_selenium('./1c6ccb00-f117-4cc0-af04-90b008c2744c.html', 'output_selenium.png') -------------------------------------------------------------------------------- /smart-card-react/src/modules/card/components/create/index.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from 'react'; 2 | import HTMLEditor from '@/modules/html-editor'; 3 | 4 | const HTMLEditorDemo: React.FC = () => { 5 | const [html, setHtml] = useState(''); 6 | 7 | const handleChange = (value: string) => { 8 | setHtml(value); 9 | console.log('HTML内容已更新:', value); 10 | }; 11 | 12 | return ( 13 |
14 |

HTML可视化编辑器

15 |

这是一个基于Slate.js的可视化HTML编辑器,支持文本格式化、颜色调整和元素尺寸设置。

16 | 17 |
18 | 19 |
20 | 21 |
22 |

输出结果

23 |
{html}
24 |
25 | 26 | 57 |
58 | ); 59 | }; 60 | 61 | export default HTMLEditorDemo; -------------------------------------------------------------------------------- /tools/prompt_config.py: -------------------------------------------------------------------------------- 1 | """ 2 | Configuration file for LLM system prompts. 3 | """ 4 | 5 | # System prompt for the Ark LLM (Web Designer Role) 6 | SYSTEM_PROMPT_WEB_DESIGNER = """ 7 | ## 角色定位 8 | 你是一位专业的网页设计师与前端开发专家,擅长根据需求快速生成美观、响应式的HTML卡片页面代码。卡片需要适配手机尺寸,一般以iphone15尺寸为准。 9 | 10 | ## 核心能力 11 | 1. 能根据用户需求生成完整的HTML5页面结构 12 | 2. 精通现代CSS布局技术(Flexbox/Grid) 13 | 3. 掌握色彩搭配与UI设计原则 14 | 4. 能实现响应式设计适配不同设备 15 | 5. 熟悉常用设计风格(极简/拟物/毛玻璃等) 16 | 17 | ## 知识储备 18 | - 最新HTML5/CSS3标准 19 | - 主流UI框架设计规范 20 | - WCAG无障碍标准 21 | - 色彩心理学基础 22 | - 排版设计原则 23 | 24 | ## 输出要求 25 | 1. 务必满足生成适合手机尺寸的HTML卡片页面,卡片宽度写死393px 26 | 2. 提供完整的HTML文件代码 27 | 3. 包含内联CSS样式 28 | 4. 使用语义化标签 29 | 5. 添加必要的meta标签 30 | 6. 确保代码整洁规范 31 | 7. 遵循W3C标准 32 | 8. 注意只输出HTML代码,不包含其他内容!!!注意只生成一段完整的HTML代码,不要输出多段。 33 | 9. 落款中加入 © 2025 Deepseek & BreaklmLab的标识 34 | 35 | ## 交互方式 36 | 请用户提供: 37 | 1. 页面用途(企业官网/个人博客/产品展示等) 38 | 2. 期望的设计风格 39 | 3. 需要包含的主要内容区块 40 | 4. 品牌色/偏好色(可选) 41 | 5. 其他特殊需求 42 | """ 43 | 44 | SYSTEM_PROMPT_SUMMARIZE_2MD = """ 45 | ## 角色定位 46 | 你是一位专业的文本分析专家,擅长从复杂内容中提取关键信息并生成结构化摘要。 47 | 48 | ## 核心能力 49 | 1. 精准识别文本核心观点和关键细节 50 | 2. 自动划分逻辑段落并提取主旨 51 | 3. 保持原文语义的同时高度凝练 52 | 4. 生成规范的Markdown格式输出 53 | 5. 根据内容类型调整总结风格 54 | 55 | ## 知识储备 56 | - 信息提取技术 57 | - 自然语言处理 58 | - 结构化写作规范 59 | - 多种文本类型特征(新闻/论文/报告等) 60 | - 关键信息识别方法 61 | 62 | ## 题目书写 63 | - 需要再文章中生成一个小红书爆款标题 64 | - 题目紧扣内容核心 65 | - 题目要求有网感,吸引阅读者目光 66 | 67 | ## 输出要求 68 | 1. 使用Markdown标题分级 69 | 2. 包含3-5个核心要点 70 | 3. 每个要点不超过2句话 71 | 4. 保留关键数据/事实 72 | 5. 总长度不超过原文30% 73 | 6.除了主要内容不要输出额外内容 74 | 75 | ## 交互方式 76 | 请用户提供: 77 | 1. 需要总结的文本内容 78 | 2. 期望的总结深度(简要/详细) 79 | 3. 特定关注点(可选) 80 | 4. 是否需要保留示例/引用(可选) 81 | """ 82 | 83 | # You can add other system prompts here as needed 84 | # SYSTEM_PROMPT_OTHER = """...""" 85 | USER_PROMPT_WEB_DESIGNER = """ 86 | 现在请根据用户提供的信息,生成一个符合要求的HTML卡片页面。卡片需要适配手机尺寸,一般以iphone15尺寸为准。 87 | """ -------------------------------------------------------------------------------- /smart-card-react/PROJECT_INFO.md: -------------------------------------------------------------------------------- 1 | # 智能卡片工坊项目配置 2 | 3 | ## 项目信息 4 | - **项目名称**: 智能卡片工坊 (Smart Card Workshop) 5 | - **版本**: 1.0.0 6 | - **创建时间**: 2025年7月6日 7 | - **技术栈**: Next.js 15 + React 18 + TypeScript + Tailwind CSS 8 | 9 | ## 开发环境 10 | - **Node.js**: 18.0+ 11 | - **包管理器**: npm 12 | - **开发服务器**: http://localhost:3000 13 | - **构建工具**: Next.js with Turbopack 14 | 15 | ## 核心功能 16 | 1. **AI 内容生成**: 基于 ARK 平台的大语言模型 17 | 2. **网页内容抓取**: 使用 Jina API 进行智能抓取 18 | 3. **卡片管理**: 创建、编辑、删除、搜索、分类 19 | 4. **图片导出**: 支持 PNG、JPG、PDF 格式 20 | 5. **响应式设计**: 完美适配桌面和移动设备 21 | 22 | ## 项目结构 23 | ``` 24 | src/ 25 | ├── app/ # Next.js 应用页面 26 | ├── components/ # React 组件 27 | │ ├── ui/ # 基础 UI 组件 28 | │ ├── AIGenerator.tsx 29 | │ ├── WebScraper.tsx 30 | │ └── CardPreview.tsx 31 | ├── services/ # API 服务 32 | ├── store/ # 状态管理 (Zustand) 33 | ├── types/ # TypeScript 类型 34 | └── utils/ # 工具函数 35 | ``` 36 | 37 | ## 环境变量 38 | ``` 39 | NEXT_PUBLIC_API_BASE_URL=http://localhost:8000 40 | NEXT_PUBLIC_ARK_API_KEY=your_ark_api_key 41 | NEXT_PUBLIC_JINA_API_KEY=your_jina_api_key 42 | ``` 43 | 44 | ## 快速开始 45 | 1. 安装依赖: `npm install` 46 | 2. 配置环境变量: 复制 `.env.local.example` 为 `.env.local` 47 | 3. 启动开发服务器: `npm run dev` 48 | 4. 打开浏览器: http://localhost:3000 49 | 50 | ## 可用脚本 51 | - `npm run dev`: 启动开发服务器 52 | - `npm run build`: 构建生产版本 53 | - `npm run start`: 启动生产服务器 54 | - `npm run lint`: 代码检查 55 | 56 | ## 部署选项 57 | - **Vercel**: 推荐的部署平台 58 | - **Docker**: 容器化部署 59 | - **传统服务器**: 静态文件部署 60 | 61 | ## 后续开发计划 62 | 1. 集成后端 API 服务 63 | 2. 添加用户认证系统 64 | 3. 实现实时协作功能 65 | 4. 增加更多卡片模板 66 | 5. 优化性能和 SEO 67 | 68 | ## 技术亮点 69 | - 现代化的 React 架构 70 | - TypeScript 类型安全 71 | - 响应式设计 72 | - 状态管理优化 73 | - 组件化开发 74 | - 优秀的用户体验 75 | 76 | ## 开发者指南 77 | - 遵循 TypeScript 最佳实践 78 | - 使用 ESLint 和 Prettier 79 | - 组件单一职责原则 80 | - 合理的状态管理 81 | - 良好的错误处理 82 | 83 | --- 84 | 更新时间: 2025年7月6日 85 | -------------------------------------------------------------------------------- /smart-card-react/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: [ 4 | './src/pages/**/*.{js,ts,jsx,tsx,mdx}', 5 | './src/components/**/*.{js,ts,jsx,tsx,mdx}', 6 | './src/app/**/*.{js,ts,jsx,tsx,mdx}', 7 | './src/modules/**/*.{js,ts,jsx,tsx,mdx}', 8 | ], 9 | theme: { 10 | extend: { 11 | animation: { 12 | 'ripple': 'ripple 0.6s linear forwards', 13 | }, 14 | keyframes: { 15 | ripple: { 16 | '0%': { opacity: '0.7', transform: 'scale(0)' }, 17 | '100%': { opacity: '0', transform: 'scale(2)' }, 18 | }, 19 | }, 20 | colors: { 21 | border: 'hsl(var(--border))', 22 | input: 'hsl(var(--input))', 23 | ring: 'hsl(var(--ring))', 24 | background: 'hsl(var(--background))', 25 | foreground: 'hsl(var(--foreground))', 26 | primary: { 27 | DEFAULT: 'hsl(var(--primary))', 28 | foreground: 'hsl(var(--primary-foreground))', 29 | }, 30 | secondary: { 31 | DEFAULT: 'hsl(var(--secondary))', 32 | foreground: 'hsl(var(--secondary-foreground))', 33 | }, 34 | destructive: { 35 | DEFAULT: 'hsl(var(--destructive))', 36 | foreground: 'hsl(var(--destructive-foreground))', 37 | }, 38 | muted: { 39 | DEFAULT: 'hsl(var(--muted))', 40 | foreground: 'hsl(var(--muted-foreground))', 41 | }, 42 | accent: { 43 | DEFAULT: 'hsl(var(--accent))', 44 | foreground: 'hsl(var(--accent-foreground))', 45 | }, 46 | popover: { 47 | DEFAULT: 'hsl(var(--popover))', 48 | foreground: 'hsl(var(--popover-foreground))', 49 | }, 50 | card: { 51 | DEFAULT: 'hsl(var(--card))', 52 | foreground: 'hsl(var(--card-foreground))', 53 | }, 54 | }, 55 | }, 56 | }, 57 | plugins: [], 58 | } -------------------------------------------------------------------------------- /smart-card-react/src/modules/html-editor/components/Element.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { RenderElementProps } from 'slate-react'; 3 | 4 | interface ImageElement { 5 | type: 'image'; 6 | url: string; 7 | children: { text: string }[]; 8 | } 9 | 10 | export const Element: React.FC = ({ attributes, children, element }) => { 11 | const style = element.align ? { textAlign: element.align as React.CSSProperties['textAlign'] } : {}; 12 | 13 | switch (element.type) { 14 | case 'block-quote': 15 | return ( 16 |
17 | {children} 18 |
19 | ); 20 | case 'bulleted-list': 21 | return ( 22 |
    23 | {children} 24 |
25 | ); 26 | case 'heading-one': 27 | return ( 28 |

29 | {children} 30 |

31 | ); 32 | case 'heading-two': 33 | return ( 34 |

35 | {children} 36 |

37 | ); 38 | case 'list-item': 39 | return ( 40 |
  • 41 | {children} 42 |
  • 43 | ); 44 | case 'numbered-list': 45 | return ( 46 |
      47 | {children} 48 |
    49 | ); 50 | case 'image': 51 | const imageElement = element as ImageElement; 52 | return ( 53 |
    54 |
    55 | 插入的图片 65 |
    66 | {children} 67 |
    68 | ); 69 | default: 70 | return ( 71 |

    72 | {children} 73 |

    74 | ); 75 | } 76 | }; -------------------------------------------------------------------------------- /smart-card-react/src/components/ui/Button.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Slot } from '@radix-ui/react-slot'; 3 | import { cva, type VariantProps } from 'class-variance-authority'; 4 | import { cn } from '@/lib/utils'; 5 | import { Loader2 } from 'lucide-react'; 6 | 7 | const buttonVariants = cva( 8 | 'inline-flex items-center justify-center font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50', 9 | { 10 | variants: { 11 | variant: { 12 | primary: 'bg-blue-600 text-white hover:bg-blue-700 focus-visible:ring-blue-500', 13 | secondary: 'bg-gray-600 text-white hover:bg-gray-700 focus-visible:ring-gray-500', 14 | outline: 'border border-gray-300 bg-white text-gray-900 hover:bg-gray-50 focus-visible:ring-gray-500', 15 | ghost: 'text-gray-900 hover:bg-gray-100 focus-visible:ring-gray-500', 16 | }, 17 | size: { 18 | sm: 'px-3 py-1.5 text-sm rounded-md', 19 | md: 'px-4 py-2 text-sm rounded-md', 20 | lg: 'px-6 py-3 text-base rounded-lg', 21 | }, 22 | fullWidth: { 23 | true: 'w-full', 24 | } 25 | }, 26 | defaultVariants: { 27 | variant: 'primary', 28 | size: 'md', 29 | }, 30 | } 31 | ); 32 | 33 | export interface ButtonProps 34 | extends React.ButtonHTMLAttributes, 35 | VariantProps { 36 | asChild?: boolean; 37 | icon?: React.ElementType; 38 | loading?: boolean; 39 | } 40 | 41 | const Button = React.forwardRef( 42 | ({ className, variant, size, fullWidth, asChild = false, icon: Icon, children, loading, ...props }, ref) => { 43 | const Comp = asChild ? Slot : 'button'; 44 | return ( 45 | 51 | {loading && } 52 | {Icon && !loading && } 53 | {children} 54 | 55 | ); 56 | } 57 | ); 58 | Button.displayName = 'Button'; 59 | 60 | export { Button, buttonVariants }; 61 | -------------------------------------------------------------------------------- /smart-card-react/src/modules/card/types/index.ts: -------------------------------------------------------------------------------- 1 | // 卡片模块类型定义 2 | import { AppConfig } from '@/modules/common/types'; 3 | 4 | export interface BaseCard { 5 | title: string; 6 | content: string; 7 | htmlContent: string; 8 | imageUrl?: string; 9 | tags: string[]; 10 | author?: string; 11 | category?: string; 12 | } 13 | 14 | export interface Card extends BaseCard { 15 | id: string; 16 | createdAt: string; 17 | updatedAt: string; 18 | } 19 | 20 | export interface ShowcaseCard extends Card { 21 | thumbnailUrl: string; 22 | views: number; 23 | likes: number; 24 | forks: number; 25 | } 26 | 27 | export interface CardTemplate { 28 | id: string; 29 | name: string; 30 | description: string; 31 | htmlTemplate: string; 32 | previewImage: string; 33 | category: string; 34 | tags: string[]; 35 | } 36 | 37 | export interface ImageExportOptions { 38 | format: 'png' | 'jpg' | 'jpeg' | 'pdf'; 39 | quality: number; 40 | width?: number; 41 | height?: number; 42 | scale?: number; 43 | } 44 | 45 | export interface ImageExportResponse { 46 | success: boolean; 47 | imageUrl?: string; 48 | error?: string; 49 | metadata?: { 50 | fileSize: number; 51 | dimensions: { 52 | width: number; 53 | height: number; 54 | }; 55 | }; 56 | } 57 | 58 | export interface CardPreviewProps { 59 | card: Card; 60 | template?: CardTemplate; 61 | onEdit?: (card: Card) => void; 62 | onDelete?: (cardId: string) => void; 63 | onExport?: (card: Card, options: ImageExportOptions) => void; 64 | } 65 | 66 | export interface CardStore { 67 | // State 68 | cards: Card[]; 69 | templates: CardTemplate[]; 70 | currentCard: Card | null; 71 | isLoading: boolean; 72 | error: string | null; 73 | config: AppConfig; 74 | 75 | // Actions 76 | setCards: (cards: Card[]) => void; 77 | setTemplates: (templates: CardTemplate[]) => void; 78 | setCurrentCard: (card: Card | null) => void; 79 | setLoading: (loading: boolean) => void; 80 | setError: (error: string | null) => void; 81 | 82 | // Async actions 83 | loadCards: () => Promise; 84 | loadTemplates: () => Promise; 85 | createCard: (card: Omit) => Promise; 86 | updateCard: (cardId: string, card: Partial) => Promise; 87 | deleteCard: (cardId: string) => Promise; 88 | forkCard: (cardId: string) => Promise; 89 | } -------------------------------------------------------------------------------- /smart-card-react/src/components/ui/Input.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { clsx } from 'clsx'; 3 | 4 | interface InputProps extends React.InputHTMLAttributes { 5 | label?: string; 6 | error?: string; 7 | helperText?: string; 8 | fullWidth?: boolean; 9 | } 10 | 11 | export const Input: React.FC = ({ 12 | label, 13 | error, 14 | helperText, 15 | fullWidth = false, 16 | className, 17 | ...props 18 | }) => { 19 | return ( 20 |
    21 | {label && ( 22 | 25 | )} 26 | 34 | {error && ( 35 |

    {error}

    36 | )} 37 | {helperText && !error && ( 38 |

    {helperText}

    39 | )} 40 |
    41 | ); 42 | }; 43 | 44 | interface TextareaProps extends React.TextareaHTMLAttributes { 45 | label?: string; 46 | error?: string; 47 | helperText?: string; 48 | fullWidth?: boolean; 49 | } 50 | 51 | export const Textarea: React.FC = ({ 52 | label, 53 | error, 54 | helperText, 55 | fullWidth = false, 56 | className, 57 | ...props 58 | }) => { 59 | return ( 60 |
    61 | {label && ( 62 | 65 | )} 66 |