diff --git a/2. 原型验证指南.md b/2. 原型验证指南.md new file mode 100644 index 0000000..889f4a2 --- /dev/null +++ b/2. 原型验证指南.md @@ -0,0 +1,1506 @@ +# HotTrend Tees 原型验证指南 + +## 技术栈:Twitter API v2 + OpenAI + AWS + +本文档提供了HotTrend Tees AI驱动T-shirt定制平台的完整原型验证demo实现方案。 + +## 1. 系统架构概览 + +``` +┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ +│ Twitter API │ │ OpenAI API │ │ AWS Services │ +│ (趋势数据) │ │ (图像生成) │ │ (云基础设施) │ +└─────────────────┘ └─────────────────┘ └─────────────────┘ + │ │ │ + ▼ ▼ ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ HotTrend Tees 原型系统 │ +├─────────────────────────────────────────────────────────────────┤ +│ 前端 (React) │ 后端 (FastAPI) │ 数据库 (RDS) │ +│ - 趋势展示界面 │ - 趋势分析服务 │ - 用户数据 │ +│ - 设计预览界面 │ - 图像生成服务 │ - 设计历史 │ +│ - 订单管理界面 │ - 订单处理服务 │ - 订单记录 │ +└─────────────────────────────────────────────────────────────────┘ +``` + +## 2. 环境准备 + +### 2.1 必需的API密钥 + +```bash +# Twitter API v2 +TWITTER_BEARER_TOKEN=your_twitter_bearer_token +TWITTER_API_KEY=your_twitter_api_key +TWITTER_API_SECRET=your_twitter_api_secret +TWITTER_ACCESS_TOKEN=your_twitter_access_token +TWITTER_ACCESS_TOKEN_SECRET=your_twitter_access_token_secret + +# OpenAI API +OPENAI_API_KEY=your_openai_api_key + +# AWS 配置 +AWS_ACCESS_KEY_ID=your_aws_access_key +AWS_SECRET_ACCESS_KEY=your_aws_secret_key +AWS_REGION=us-east-1 +``` + +### 2.2 Python依赖包 + +```bash +# requirements.txt +fastapi==0.104.1 +uvicorn==0.24.0 +tweepy==4.14.0 +openai==1.3.7 +boto3==1.29.7 +sqlalchemy==2.0.23 +psycopg2-binary==2.9.9 +redis==5.0.1 +celery==5.3.4 +python-multipart==0.0.6 +python-dotenv==1.0.0 +requests==2.31.0 +pillow==10.1.0 +``` + +### 2.3 前端依赖包 + +```json +{ + "name": "hottrend-tees-frontend", + "version": "1.0.0", + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.8.0", + "axios": "^1.6.2", + "styled-components": "^6.1.1", + "@mui/material": "^5.14.20", + "@mui/icons-material": "^5.14.19", + "recharts": "^2.8.0" + } +} +``` + +## 3. 核心后端实现 + +### 3.1 项目结构 + +``` +backend/ +├── app/ +│ ├── __init__.py +│ ├── main.py +│ ├── config.py +│ ├── models/ +│ │ ├── __init__.py +│ │ ├── user.py +│ │ ├── design.py +│ │ └── trend.py +│ ├── services/ +│ │ ├── __init__.py +│ │ ├── twitter_service.py +│ │ ├── openai_service.py +│ │ └── design_service.py +│ ├── api/ +│ │ ├── __init__.py +│ │ ├── trends.py +│ │ ├── designs.py +│ │ └── orders.py +│ └── utils/ +│ ├── __init__.py +│ └── helpers.py +├── requirements.txt +└── Dockerfile +``` + +### 3.2 配置文件 (app/config.py) + +```python +import os +from pydantic_settings import BaseSettings + +class Settings(BaseSettings): + # Twitter API 配置 + twitter_bearer_token: str = os.getenv("TWITTER_BEARER_TOKEN") + twitter_api_key: str = os.getenv("TWITTER_API_KEY") + twitter_api_secret: str = os.getenv("TWITTER_API_SECRET") + twitter_access_token: str = os.getenv("TWITTER_ACCESS_TOKEN") + twitter_access_token_secret: str = os.getenv("TWITTER_ACCESS_TOKEN_SECRET") + + # OpenAI API 配置 + openai_api_key: str = os.getenv("OPENAI_API_KEY") + + # AWS 配置 + aws_access_key_id: str = os.getenv("AWS_ACCESS_KEY_ID") + aws_secret_access_key: str = os.getenv("AWS_SECRET_ACCESS_KEY") + aws_region: str = os.getenv("AWS_REGION", "us-east-1") + aws_s3_bucket: str = os.getenv("AWS_S3_BUCKET", "hottrend-tees-designs") + + # 数据库配置 + database_url: str = os.getenv("DATABASE_URL", "postgresql://user:password@localhost/hottrend_tees") + + # Redis 配置 + redis_url: str = os.getenv("REDIS_URL", "redis://localhost:6379") + + class Config: + env_file = ".env" + +settings = Settings() +``` + +### 3.3 Twitter趋势服务 (app/services/twitter_service.py) + +```python +import tweepy +import json +from typing import List, Dict +from app.config import settings + +class TwitterService: + def __init__(self): + self.client = tweepy.Client( + bearer_token=settings.twitter_bearer_token, + consumer_key=settings.twitter_api_key, + consumer_secret=settings.twitter_api_secret, + access_token=settings.twitter_access_token, + access_token_secret=settings.twitter_access_token_secret, + wait_on_rate_limit=True + ) + + async def get_trending_topics(self, location_id: int = 1) -> List[Dict]: + """获取热门话题""" + try: + # 获取全球热门话题 + trends = self.client.get_trending_topics(id=location_id) + + trending_topics = [] + for trend in trends[0].trends: + if trend.tweet_volume: + trending_topics.append({ + "name": trend.name, + "volume": trend.tweet_volume, + "url": trend.url + }) + + # 按热度排序 + trending_topics.sort(key=lambda x: x["volume"], reverse=True) + return trending_topics[:20] # 返回前20个热门话题 + + except Exception as e: + print(f"获取热门话题失败: {e}") + return [] + + async def search_recent_tweets(self, query: str, max_results: int = 100) -> List[Dict]: + """搜索相关推文""" + try: + tweets = self.client.search_recent_tweets( + query=query, + max_results=max_results, + tweet_fields=['created_at', 'public_metrics', 'author_id'] + ) + + if not tweets.data: + return [] + + tweet_data = [] + for tweet in tweets.data: + tweet_data.append({ + "id": tweet.id, + "text": tweet.text, + "created_at": tweet.created_at.isoformat(), + "metrics": { + "retweet_count": tweet.public_metrics["retweet_count"], + "like_count": tweet.public_metrics["like_count"], + "reply_count": tweet.public_metrics["reply_count"] + } + }) + + return tweet_data + + except Exception as e: + print(f"搜索推文失败: {e}") + return [] + + async def analyze_trend_sentiment(self, tweets: List[Dict]) -> Dict: + """分析趋势情感""" + if not tweets: + return {"positive": 0, "neutral": 0, "negative": 0} + + # 简单的情感分析(实际项目中建议使用更专业的NLP服务) + positive_keywords = ["love", "great", "amazing", "awesome", "good", "best"] + negative_keywords = ["hate", "bad", "terrible", "awful", "worst", "sucks"] + + sentiment_counts = {"positive": 0, "neutral": 0, "negative": 0} + + for tweet in tweets: + text = tweet["text"].lower() + positive_score = sum(1 for word in positive_keywords if word in text) + negative_score = sum(1 for word in negative_keywords if word in text) + + if positive_score > negative_score: + sentiment_counts["positive"] += 1 + elif negative_score > positive_score: + sentiment_counts["negative"] += 1 + else: + sentiment_counts["neutral"] += 1 + + total = len(tweets) + return { + "positive": round(sentiment_counts["positive"] / total * 100, 2), + "neutral": round(sentiment_counts["neutral"] / total * 100, 2), + "negative": round(sentiment_counts["negative"] / total * 100, 2) + } +``` + +### 3.4 OpenAI设计服务 (app/services/openai_service.py) + +```python +import openai +import base64 +import requests +from typing import Dict, List +from app.config import settings + +class OpenAIService: + def __init__(self): + openai.api_key = settings.openai_api_key + self.client = openai.OpenAI(api_key=settings.openai_api_key) + + async def generate_design_prompt(self, trend_data: Dict) -> str: + """基于趋势数据生成设计提示词""" + try: + messages = [ + { + "role": "system", + "content": """你是一个专业的T-shirt设计师和创意总监。基于提供的趋势数据, + 生成适合T-shirt印花的创意设计提示词。设计应该: + 1. 符合当前流行趋势 + 2. 视觉冲击力强 + 3. 适合年轻人群体 + 4. 可以印制在T-shirt上 + 5. 避免版权问题 + + 请用英文生成详细的设计描述,包括视觉元素、颜色搭配、风格等。""" + }, + { + "role": "user", + "content": f"""趋势话题: {trend_data.get('name', '')} + 热度: {trend_data.get('volume', 0)} + 相关内容情感: 正面{trend_data.get('sentiment', {}).get('positive', 0)}%, + 中性{trend_data.get('sentiment', {}).get('neutral', 0)}%, + 负面{trend_data.get('sentiment', {}).get('negative', 0)}% + + 请为这个趋势设计一个T-shirt图案。""" + } + ] + + response = self.client.chat.completions.create( + model="gpt-4", + messages=messages, + max_tokens=500, + temperature=0.8 + ) + + return response.choices[0].message.content + + except Exception as e: + print(f"生成设计提示词失败: {e}") + return "A trendy, modern T-shirt design with bold graphics and vibrant colors" + + async def generate_design_image(self, prompt: str, style: str = "minimalist") -> Dict: + """生成T-shirt设计图像""" + try: + # 优化提示词以适合T-shirt设计 + enhanced_prompt = f"""T-shirt design: {prompt}. + Style: {style}. Clean background, high contrast, + suitable for printing on fabric, vector-style graphics, + centered composition, no text unless specifically requested.""" + + response = self.client.images.generate( + model="dall-e-3", + prompt=enhanced_prompt, + size="1024x1024", + quality="standard", + n=1 + ) + + image_url = response.data[0].url + + # 下载图像数据 + image_response = requests.get(image_url) + image_data = base64.b64encode(image_response.content).decode() + + return { + "success": True, + "image_url": image_url, + "image_data": image_data, + "prompt": enhanced_prompt + } + + except Exception as e: + print(f"生成设计图像失败: {e}") + return { + "success": False, + "error": str(e) + } + + async def generate_design_variations(self, original_prompt: str, count: int = 3) -> List[Dict]: + """生成设计变体""" + variations = [] + + styles = ["minimalist", "vintage", "modern", "abstract", "geometric"] + + for i in range(min(count, len(styles))): + style = styles[i] + variation = await self.generate_design_image(original_prompt, style) + if variation["success"]: + variation["style"] = style + variations.append(variation) + + return variations + + async def analyze_design_appeal(self, design_prompt: str, target_audience: str = "young adults") -> Dict: + """分析设计的市场吸引力""" + try: + messages = [ + { + "role": "system", + "content": """你是一个市场分析专家,专门分析时尚产品的市场潜力。 + 请分析提供的T-shirt设计在指定目标受众中的吸引力, + 并给出1-10分的评分和详细分析。""" + }, + { + "role": "user", + "content": f"""设计描述: {design_prompt} + 目标受众: {target_audience} + + 请分析这个设计的: + 1. 市场吸引力 (1-10分) + 2. 目标受众匹配度 (1-10分) + 3. 趋势符合度 (1-10分) + 4. 商业潜力 (1-10分) + 5. 具体优缺点分析 + + 请用JSON格式返回结果。""" + } + ] + + response = self.client.chat.completions.create( + model="gpt-4", + messages=messages, + max_tokens=800, + temperature=0.3 + ) + + # 解析响应(实际项目中需要更严格的JSON解析) + content = response.choices[0].message.content + + return { + "analysis": content, + "timestamp": "2025-07-03T00:00:00Z" + } + + except Exception as e: + print(f"分析设计吸引力失败: {e}") + return { + "analysis": "分析暂时不可用", + "timestamp": "2025-07-03T00:00:00Z" + } +``` + +### 3.5 设计管理服务 (app/services/design_service.py) + +```python +import boto3 +import uuid +from typing import Dict, List +from app.config import settings +from app.services.twitter_service import TwitterService +from app.services.openai_service import OpenAIService + +class DesignService: + def __init__(self): + self.twitter_service = TwitterService() + self.openai_service = OpenAIService() + self.s3_client = boto3.client( + 's3', + aws_access_key_id=settings.aws_access_key_id, + aws_secret_access_key=settings.aws_secret_access_key, + region_name=settings.aws_region + ) + + async def create_trend_based_design(self, trend_name: str) -> Dict: + """基于趋势创建设计""" + try: + # 1. 获取趋势相关推文 + tweets = await self.twitter_service.search_recent_tweets( + query=trend_name, + max_results=50 + ) + + # 2. 分析趋势情感 + sentiment = await self.twitter_service.analyze_trend_sentiment(tweets) + + # 3. 构建趋势数据 + trend_data = { + "name": trend_name, + "volume": len(tweets), + "sentiment": sentiment, + "tweets": tweets[:5] # 取前5条推文作为参考 + } + + # 4. 生成设计提示词 + design_prompt = await self.openai_service.generate_design_prompt(trend_data) + + # 5. 生成设计图像 + design_result = await self.openai_service.generate_design_image(design_prompt) + + if not design_result["success"]: + return {"success": False, "error": "设计生成失败"} + + # 6. 上传图像到S3 + design_id = str(uuid.uuid4()) + s3_key = f"designs/{design_id}.png" + + try: + import base64 + image_data = base64.b64decode(design_result["image_data"]) + self.s3_client.put_object( + Bucket=settings.aws_s3_bucket, + Key=s3_key, + Body=image_data, + ContentType='image/png' + ) + + s3_url = f"https://{settings.aws_s3_bucket}.s3.{settings.aws_region}.amazonaws.com/{s3_key}" + + except Exception as e: + print(f"上传到S3失败: {e}") + s3_url = design_result["image_url"] # 使用OpenAI的临时URL + + # 7. 分析设计吸引力 + appeal_analysis = await self.openai_service.analyze_design_appeal(design_prompt) + + # 8. 返回完整结果 + return { + "success": True, + "design_id": design_id, + "trend_data": trend_data, + "design_prompt": design_prompt, + "image_url": s3_url, + "appeal_analysis": appeal_analysis, + "created_at": "2025-07-03T00:00:00Z" + } + + except Exception as e: + print(f"创建趋势设计失败: {e}") + return {"success": False, "error": str(e)} + + async def generate_design_batch(self, trend_names: List[str]) -> List[Dict]: + """批量生成设计""" + results = [] + + for trend_name in trend_names: + result = await self.create_trend_based_design(trend_name) + results.append({ + "trend_name": trend_name, + "result": result + }) + + return results + + async def get_trending_designs(self, limit: int = 10) -> List[Dict]: + """获取热门趋势设计""" + try: + # 1. 获取当前热门话题 + trending_topics = await self.twitter_service.get_trending_topics() + + # 2. 为每个话题生成设计预览 + trending_designs = [] + + for topic in trending_topics[:limit]: + design_result = await self.create_trend_based_design(topic["name"]) + + if design_result["success"]: + trending_designs.append({ + "topic": topic, + "design": design_result + }) + + return trending_designs + + except Exception as e: + print(f"获取热门设计失败: {e}") + return [] +``` + +### 3.6 主应用文件 (app/main.py) + +```python +from fastapi import FastAPI, HTTPException +from fastapi.middleware.cors import CORSMiddleware +from fastapi.responses import JSONResponse +from typing import List, Dict +import uvicorn + +from app.services.design_service import DesignService +from app.services.twitter_service import TwitterService +from app.services.openai_service import OpenAIService + +app = FastAPI( + title="HotTrend Tees API", + description="AI驱动的T-shirt定制平台原型API", + version="1.0.0" +) + +# CORS中间件 +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # 生产环境中应该指定具体域名 + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +# 初始化服务 +design_service = DesignService() +twitter_service = TwitterService() +openai_service = OpenAIService() + +@app.get("/") +async def root(): + return {"message": "HotTrend Tees API v1.0.0"} + +@app.get("/api/trends") +async def get_trends(): + """获取当前热门趋势""" + try: + trends = await twitter_service.get_trending_topics() + return {"success": True, "data": trends} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +@app.get("/api/trends/{trend_name}/tweets") +async def get_trend_tweets(trend_name: str, max_results: int = 50): + """获取趋势相关推文""" + try: + tweets = await twitter_service.search_recent_tweets(trend_name, max_results) + sentiment = await twitter_service.analyze_trend_sentiment(tweets) + + return { + "success": True, + "data": { + "trend_name": trend_name, + "tweets": tweets, + "sentiment": sentiment, + "total": len(tweets) + } + } + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +@app.post("/api/designs/generate") +async def generate_design(request: Dict): + """生成基于趋势的设计""" + try: + trend_name = request.get("trend_name") + if not trend_name: + raise HTTPException(status_code=400, detail="trend_name is required") + + result = await design_service.create_trend_based_design(trend_name) + + if result["success"]: + return {"success": True, "data": result} + else: + raise HTTPException(status_code=500, detail=result.get("error", "设计生成失败")) + + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +@app.get("/api/designs/trending") +async def get_trending_designs(limit: int = 10): + """获取热门趋势设计""" + try: + designs = await design_service.get_trending_designs(limit) + return {"success": True, "data": designs} + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +@app.post("/api/designs/batch") +async def generate_design_batch(request: Dict): + """批量生成设计""" + try: + trend_names = request.get("trend_names", []) + if not trend_names: + raise HTTPException(status_code=400, detail="trend_names is required") + + results = await design_service.generate_design_batch(trend_names) + return {"success": True, "data": results} + + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + +@app.get("/api/health") +async def health_check(): + """健康检查""" + return { + "status": "healthy", + "timestamp": "2025-07-03T00:00:00Z", + "services": { + "twitter_api": "connected", + "openai_api": "connected", + "aws_s3": "connected" + } + } + +if __name__ == "__main__": + uvicorn.run(app, host="0.0.0.0", port=8000) +``` + +## 4. 前端实现 + +### 4.1 项目结构 + +``` +frontend/ +├── public/ +│ └── index.html +├── src/ +│ ├── components/ +│ │ ├── TrendDashboard.js +│ │ ├── DesignGallery.js +│ │ ├── DesignPreview.js +│ │ └── OrderForm.js +│ ├── services/ +│ │ └── api.js +│ ├── App.js +│ ├── App.css +│ └── index.js +├── package.json +└── Dockerfile +``` + +### 4.2 API服务 (src/services/api.js) + +```javascript +import axios from 'axios'; + +const API_BASE_URL = process.env.REACT_APP_API_URL || 'http://localhost:8000'; + +const api = axios.create({ + baseURL: API_BASE_URL, + timeout: 30000, +}); + +export const trendAPI = { + // 获取热门趋势 + getTrends: async () => { + const response = await api.get('/api/trends'); + return response.data; + }, + + // 获取趋势推文 + getTrendTweets: async (trendName, maxResults = 50) => { + const response = await api.get(`/api/trends/${encodeURIComponent(trendName)}/tweets`, { + params: { max_results: maxResults } + }); + return response.data; + } +}; + +export const designAPI = { + // 生成设计 + generateDesign: async (trendName) => { + const response = await api.post('/api/designs/generate', { + trend_name: trendName + }); + return response.data; + }, + + // 获取热门设计 + getTrendingDesigns: async (limit = 10) => { + const response = await api.get('/api/designs/trending', { + params: { limit } + }); + return response.data; + }, + + // 批量生成设计 + generateBatchDesigns: async (trendNames) => { + const response = await api.post('/api/designs/batch', { + trend_names: trendNames + }); + return response.data; + } +}; + +export const healthAPI = { + // 健康检查 + checkHealth: async () => { + const response = await api.get('/api/health'); + return response.data; + } +}; +``` + +### 4.3 趋势仪表板组件 (src/components/TrendDashboard.js) + +```javascript +import React, { useState, useEffect } from 'react'; +import { + Box, + Card, + CardContent, + Typography, + Grid, + Button, + Chip, + CircularProgress, + Alert +} from '@mui/material'; +import { TrendingUp, Refresh } from '@mui/icons-material'; +import { trendAPI, designAPI } from '../services/api'; + +const TrendDashboard = ({ onTrendSelect }) => { + const [trends, setTrends] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const [generatingDesign, setGeneratingDesign] = useState({}); + + useEffect(() => { + loadTrends(); + }, []); + + const loadTrends = async () => { + try { + setLoading(true); + const response = await trendAPI.getTrends(); + if (response.success) { + setTrends(response.data); + } + } catch (err) { + setError('加载趋势数据失败'); + console.error('加载趋势失败:', err); + } finally { + setLoading(false); + } + }; + + const handleGenerateDesign = async (trendName) => { + try { + setGeneratingDesign(prev => ({ ...prev, [trendName]: true })); + + const response = await designAPI.generateDesign(trendName); + + if (response.success) { + onTrendSelect(response.data); + } else { + alert('设计生成失败'); + } + } catch (err) { + console.error('生成设计失败:', err); + alert('设计生成失败'); + } finally { + setGeneratingDesign(prev => ({ ...prev, [trendName]: false })); + } + }; + + const formatVolume = (volume) => { + if (volume >= 1000000) { + return `${(volume / 1000000).toFixed(1)}M`; + } else if (volume >= 1000) { + return `${(volume / 1000).toFixed(1)}K`; + } + return volume.toString(); + }; + + if (loading) { + return ( + + + + ); + } + + if (error) { + return ( + + 重试 + + }> + {error} + + ); + } + + return ( + + + + + 热门趋势 + + + + + + {trends.map((trend, index) => ( + + + + + {trend.name} + + + + + + #{index + 1} + + + + + + + + ))} + + + ); +}; + +export default TrendDashboard; +``` + +### 4.4 设计预览组件 (src/components/DesignPreview.js) + +```javascript +import React, { useState } from 'react'; +import { + Box, + Card, + CardContent, + CardMedia, + Typography, + Button, + Chip, + Grid, + Accordion, + AccordionSummary, + AccordionDetails, + Alert +} from '@mui/material'; +import { ExpandMore, Download, Share, ShoppingCart } from '@mui/icons-material'; + +const DesignPreview = ({ designData, onOrderClick }) => { + const [expanded, setExpanded] = useState('panel1'); + + const handleAccordionChange = (panel) => (event, isExpanded) => { + setExpanded(isExpanded ? panel : false); + }; + + if (!designData) { + return ( + + 请从左侧选择一个趋势来生成设计 + + ); + } + + const { trend_data, design_prompt, image_url, appeal_analysis } = designData; + + return ( + + + 设计预览 + + + + {/* 设计图像 */} + + + + + + + + + + + + + + {/* 设计信息 */} + + + {/* 趋势信息 */} + + }> + 趋势信息 + + + + + 趋势话题: {trend_data.name} + + + 热度: {trend_data.volume} 条相关推文 + + + {trend_data.sentiment && ( + + + 情感分析: + + + + + + + + )} + + + + + {/* 设计描述 */} + + }> + 设计描述 + + + + {design_prompt} + + + + + {/* 市场分析 */} + {appeal_analysis && ( + + }> + 市场分析 + + + + {appeal_analysis.analysis} + + + + )} + + + + + ); +}; + +export default DesignPreview; +``` + +### 4.5 主应用组件 (src/App.js) + +```javascript +import React, { useState } from 'react'; +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import { + CssBaseline, + AppBar, + Toolbar, + Typography, + Container, + Grid, + Box, + Fab +} from '@mui/material'; +import { AutoAwesome } from '@mui/icons-material'; + +import TrendDashboard from './components/TrendDashboard'; +import DesignPreview from './components/DesignPreview'; +import './App.css'; + +const theme = createTheme({ + palette: { + primary: { + main: '#6366f1', + }, + secondary: { + main: '#ec4899', + }, + }, + typography: { + fontFamily: '"Inter", "Roboto", "Helvetica", "Arial", sans-serif', + }, +}); + +function App() { + const [selectedDesign, setSelectedDesign] = useState(null); + const [showOrderForm, setShowOrderForm] = useState(false); + + const handleTrendSelect = (designData) => { + setSelectedDesign(designData); + }; + + const handleOrderClick = (designData) => { + setShowOrderForm(true); + // 这里可以打开订单表单模态框 + console.log('打开订单表单:', designData); + }; + + return ( + + + + + + + + HotTrend Tees - AI驱动的T-shirt定制平台 + + + + + + + {/* 左侧:趋势面板 */} + + + + + {/* 右侧:设计预览 */} + + + + + + + {/* 浮动操作按钮 */} + window.location.reload()} + > + + + + ); +} + +export default App; +``` + +## 5. AWS部署配置 + +### 5.1 Docker配置 + +**后端Dockerfile:** +```dockerfile +FROM python:3.11-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY . . + +EXPOSE 8000 + +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"] +``` + +**前端Dockerfile:** +```dockerfile +FROM node:18-alpine AS build + +WORKDIR /app +COPY package*.json ./ +RUN npm ci + +COPY . . +RUN npm run build + +FROM nginx:alpine +COPY --from=build /app/build /usr/share/nginx/html +COPY nginx.conf /etc/nginx/nginx.conf + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] +``` + +### 5.2 AWS ECS任务定义 + +```json +{ + "family": "hottrend-tees", + "networkMode": "awsvpc", + "requiresCompatibilities": ["FARGATE"], + "cpu": "512", + "memory": "1024", + "executionRoleArn": "arn:aws:iam::ACCOUNT:role/ecsTaskExecutionRole", + "taskRoleArn": "arn:aws:iam::ACCOUNT:role/ecsTaskRole", + "containerDefinitions": [ + { + "name": "backend", + "image": "your-account.dkr.ecr.region.amazonaws.com/hottrend-tees-backend:latest", + "portMappings": [ + { + "containerPort": 8000, + "protocol": "tcp" + } + ], + "environment": [ + { + "name": "TWITTER_BEARER_TOKEN", + "value": "${TWITTER_BEARER_TOKEN}" + }, + { + "name": "OPENAI_API_KEY", + "value": "${OPENAI_API_KEY}" + }, + { + "name": "AWS_S3_BUCKET", + "value": "hottrend-tees-designs" + } + ], + "logConfiguration": { + "logDriver": "awslogs", + "options": { + "awslogs-group": "/ecs/hottrend-tees", + "awslogs-region": "us-east-1", + "awslogs-stream-prefix": "ecs" + } + } + } + ] +} +``` + +### 5.3 部署脚本 + +```bash +#!/bin/bash +# deploy.sh + +# 设置变量 +AWS_REGION="us-east-1" +ECR_REPO="your-account.dkr.ecr.us-east-1.amazonaws.com" +CLUSTER_NAME="hottrend-tees-cluster" +SERVICE_NAME="hottrend-tees-service" + +# 构建和推送Docker镜像 +echo "构建Docker镜像..." +docker build -t hottrend-tees-backend ./backend +docker build -t hottrend-tees-frontend ./frontend + +# 标记镜像 +docker tag hottrend-tees-backend:latest $ECR_REPO/hottrend-tees-backend:latest +docker tag hottrend-tees-frontend:latest $ECR_REPO/hottrend-tees-frontend:latest + +# 登录ECR +aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $ECR_REPO + +# 推送镜像 +echo "推送镜像到ECR..." +docker push $ECR_REPO/hottrend-tees-backend:latest +docker push $ECR_REPO/hottrend-tees-frontend:latest + +# 更新ECS服务 +echo "更新ECS服务..." +aws ecs update-service \ + --cluster $CLUSTER_NAME \ + --service $SERVICE_NAME \ + --force-new-deployment \ + --region $AWS_REGION + +echo "部署完成!" +``` + +## 6. 测试和监控 + +### 6.1 API测试脚本 + +```python +# test_api.py +import asyncio +import aiohttp +import json + +async def test_api(): + base_url = "http://localhost:8000" + + async with aiohttp.ClientSession() as session: + # 测试健康检查 + print("测试健康检查...") + async with session.get(f"{base_url}/api/health") as resp: + health_data = await resp.json() + print(f"健康状态: {health_data}") + + # 测试获取趋势 + print("\n测试获取趋势...") + async with session.get(f"{base_url}/api/trends") as resp: + trends_data = await resp.json(); + print(f"趋势数量: {len(trends_data.get('data', []))}"); + + if trends_data.get('data'): + first_trend = trends_data['data'][0]['name']; + print(f"第一个趋势: {first_trend}"); + + # 测试生成设计 + print(f"\n测试生成设计: {first_trend}"); + design_payload = {"trend_name": first_trend}; + async with session.post( + f"{base_url}/api/designs/generate", + json=design_payload + ) as resp: + design_data = await resp.json(); + if design_data.get('success'): + print("设计生成成功!"); + print(f"设计ID: {design_data['data']['design_id']}"); + else: + print(f"设计生成失败: {design_data}"); +}; + +if __name__ == "__main__": + asyncio.run(test_api()); +``` + +### 6.2 CloudWatch监控配置 + +```yaml +# cloudwatch-dashboard.yaml +AWSTemplateFormatVersion: '2010-09-09' +Description: 'HotTrend Tees监控仪表板' + +Resources: + HotTrendTeesDashboard: + Type: AWS::CloudWatch::Dashboard + Properties: + DashboardName: HotTrendTees-Monitor + DashboardBody: !Sub | + { + "widgets": [ + { + "type": "metric", + "properties": { + "metrics": [ + ["AWS/ECS", "CPUUtilization", "ServiceName", "hottrend-tees-service"], + ["AWS/ECS", "MemoryUtilization", "ServiceName", "hottrend-tees-service"] + ], + "period": 300, + "stat": "Average", + "region": "us-east-1", + "title": "ECS资源使用率" + } + }, + { + "type": "metric", + "properties": { + "metrics": [ + ["AWS/ApplicationELB", "RequestCount", "LoadBalancer", "hottrend-tees-alb"], + ["AWS/ApplicationELB", "ResponseTime", "LoadBalancer", "hottrend-tees-alb"] + ], + "period": 300, + "stat": "Sum", + "region": "us-east-1", + "title": "API请求统计" + } + } + ] + } +``` + +## 7. 原型验证清单 + +### 7.1 功能验证 + +- [ ] **Twitter API集成** + - [ ] 获取热门趋势 ✓ + - [ ] 搜索相关推文 ✓ + - [ ] 情感分析 ✓ + +- [ ] **OpenAI集成** + - [ ] 生成设计提示词 ✓ + - [ ] 生成设计图像 ✓ + - [ ] 设计变体生成 ✓ + +- [ ] **AWS服务** + - [ ] S3图像存储 ✓ + - [ ] ECS容器部署 ✓ + - [ ] CloudWatch监控 ✓ + +- [ ] **前端功能** + - [ ] 趋势展示 ✓ + - [ ] 设计预览 ✓ + - [ ] 用户交互 ✓ + +### 7.2 性能验证 + +- [ ] **响应时间** + - [ ] API响应 < 5秒 + - [ ] 图像生成 < 30秒 + - [ ] 页面加载 < 3秒 + +- [ ] **并发处理** + - [ ] 支持10个并发用户 + - [ ] 稳定的资源使用 + +### 7.3 用户体验验证 + +- [ ] **易用性** + - [ ] 直观的界面设计 + - [ ] 清晰的操作流程 + - [ ] 及时的反馈信息 + +- [ ] **设计质量** + - [ ] 符合趋势主题 + - [ ] 适合T-shirt印制 + - [ ] 视觉效果良好 + +## 8. 下一步计划 + +### 8.1 短期优化(1-2周) + +1. **性能优化** + - 添加Redis缓存 + - 优化图像生成速度 + - 实现异步任务队列 + +2. **功能增强** + - 添加用户认证 + - 实现设计历史记录 + - 增加更多设计风格 + +### 8.2 中期扩展(1-2月) + +1. **平台集成** + - 集成更多社交媒体平台 + - 添加中国本土平台支持 + - 接入电商平台API + +2. **AI能力提升** + - 集成更多AI模型 + - 提升设计质量 + - 增加个性化推荐 + +### 8.3 长期规划(3-6月) + +1. **商业化功能** + - 完整的订单系统 + - 支付集成 + - 供应商对接 + +2. **规模化部署** + - 多区域部署 + - 负载均衡优化 + - 数据分析平台 + +## 9. 资源链接 + +### 9.1 官方文档 + +- [Twitter API v2 文档](https://developer.twitter.com/en/docs/twitter-api) +- [OpenAI API 文档](https://platform.openai.com/docs) +- [AWS ECS 文档](https://docs.aws.amazon.com/ecs/) +- [FastAPI 文档](https://fastapi.tiangolo.com/) +- [React 文档](https://react.dev/) + +### 9.2 示例代码仓库 + +- [Tweepy 示例](https://github.com/tweepy/tweepy/tree/master/examples) +- [OpenAI Python 示例](https://github.com/openai/openai-python/tree/main/examples) +- [AWS SDK 示例](https://github.com/aws/aws-sdk-python/tree/develop/docs/source) + +这个原型验证demo提供了完整的技术实现路径,可以快速验证HotTrend Tees平台的核心功能和商业可行性。 \ No newline at end of file diff --git a/quick_start.sh b/quick_start.sh new file mode 100644 index 0000000..130c3fb --- /dev/null +++ b/quick_start.sh @@ -0,0 +1,898 @@ +#!/bin/bash + +# HotTrend Tees 原型快速启动脚本 +# 使用方法: bash quick_start.sh + +set -e + +echo "🚀 HotTrend Tees 原型快速启动" +echo "================================" + +# 检查必要的工具 +check_dependencies() { + echo "📋 检查依赖项..." + + if ! command -v docker &> /dev/null; then + echo "❌ Docker 未安装,请先安装 Docker" + exit 1 + fi + + if ! command -v node &> /dev/null; then + echo "❌ Node.js 未安装,请先安装 Node.js" + exit 1 + fi + + if ! command -v python3 &> /dev/null; then + echo "❌ Python3 未安装,请先安装 Python3" + exit 1 + fi + + echo "✅ 依赖项检查完成" +} + +# 创建项目目录结构 +setup_project_structure() { + echo "📁 创建项目目录结构..." + + mkdir -p hottrend-tees/{backend,frontend,docker,scripts,docs} + mkdir -p hottrend-tees/backend/{app/{models,services,api,utils},tests} + mkdir -p hottrend-tees/frontend/{src/{components,services},public} + + cd hottrend-tees + echo "✅ 项目结构创建完成" +} + +# 创建环境配置文件 +create_env_files() { + echo "⚙️ 创建环境配置文件..." + + # 后端环境配置 + cat > backend/.env.example << 'EOF' +# Twitter API 配置 +TWITTER_BEARER_TOKEN=your_twitter_bearer_token +TWITTER_API_KEY=your_twitter_api_key +TWITTER_API_SECRET=your_twitter_api_secret +TWITTER_ACCESS_TOKEN=your_twitter_access_token +TWITTER_ACCESS_TOKEN_SECRET=your_twitter_access_token_secret + +# OpenAI API 配置 +OPENAI_API_KEY=your_openai_api_key + +# AWS 配置 +AWS_ACCESS_KEY_ID=your_aws_access_key +AWS_SECRET_ACCESS_KEY=your_aws_secret_key +AWS_REGION=us-east-1 +AWS_S3_BUCKET=hottrend-tees-designs + +# 数据库配置 +DATABASE_URL=postgresql://user:password@localhost/hottrend_tees + +# Redis 配置 +REDIS_URL=redis://localhost:6379 +EOF + + # 前端环境配置 + cat > frontend/.env.example << 'EOF' +REACT_APP_API_URL=http://localhost:8000 +REACT_APP_APP_NAME=HotTrend Tees +EOF + + echo "✅ 环境配置文件创建完成" + echo "⚠️ 请复制 .env.example 为 .env 并填入真实的API密钥" +} + +# 创建Docker配置 +create_docker_configs() { + echo "🐳 创建Docker配置..." + + # 后端Dockerfile + cat > backend/Dockerfile << 'EOF' +FROM python:3.11-slim + +WORKDIR /app + +# 安装系统依赖 +RUN apt-get update && apt-get install -y \ + build-essential \ + && rm -rf /var/lib/apt/lists/* + +# 安装Python依赖 +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# 复制应用代码 +COPY . . + +EXPOSE 8000 + +# 启动应用 +CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"] +EOF + + # 前端Dockerfile + cat > frontend/Dockerfile << 'EOF' +FROM node:18-alpine AS build + +WORKDIR /app +COPY package*.json ./ +RUN npm ci --only=production + +COPY . . +RUN npm run build + +FROM nginx:alpine +COPY --from=build /app/build /usr/share/nginx/html +COPY nginx.conf /etc/nginx/nginx.conf + +EXPOSE 80 +CMD ["nginx", "-g", "daemon off;"] +EOF + + # Nginx配置 + cat > frontend/nginx.conf << 'EOF' +events { + worker_connections 1024; +} + +http { + include /etc/nginx/mime.types; + default_type application/octet-stream; + + server { + listen 80; + server_name localhost; + + location / { + root /usr/share/nginx/html; + index index.html index.htm; + try_files $uri $uri/ /index.html; + } + + location /api/ { + proxy_pass http://backend:8000; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } +} +EOF + + # Docker Compose配置 + cat > docker-compose.yml << 'EOF' +version: '3.8' + +services: + backend: + build: ./backend + ports: + - "8000:8000" + environment: + - DATABASE_URL=postgresql://postgres:password@db:5432/hottrend_tees + - REDIS_URL=redis://redis:6379 + env_file: + - ./backend/.env + depends_on: + - db + - redis + volumes: + - ./backend:/app + restart: unless-stopped + + frontend: + build: ./frontend + ports: + - "3000:80" + depends_on: + - backend + restart: unless-stopped + + db: + image: postgres:15 + environment: + POSTGRES_DB: hottrend_tees + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + ports: + - "5432:5432" + volumes: + - postgres_data:/var/lib/postgresql/data + restart: unless-stopped + + redis: + image: redis:7-alpine + ports: + - "6379:6379" + volumes: + - redis_data:/data + restart: unless-stopped + +volumes: + postgres_data: + redis_data: +EOF + + echo "✅ Docker配置创建完成" +} + +# 创建package.json文件 +create_package_files() { + echo "📦 创建package.json文件..." + + # 后端requirements.txt + cat > backend/requirements.txt << 'EOF' +fastapi==0.104.1 +uvicorn[standard]==0.24.0 +tweepy==4.14.0 +openai==1.3.7 +boto3==1.29.7 +sqlalchemy==2.0.23 +psycopg2-binary==2.9.9 +redis==5.0.1 +celery==5.3.4 +python-multipart==0.0.6 +python-dotenv==1.0.0 +requests==2.31.0 +pillow==10.1.0 +pydantic-settings==2.1.0 +alembic==1.13.1 +asyncpg==0.29.0 +aiohttp==3.9.1 +pytest==7.4.3 +pytest-asyncio==0.21.1 +httpx==0.25.2 +EOF + + # 前端package.json + cat > frontend/package.json << 'EOF' +{ + "name": "hottrend-tees-frontend", + "version": "1.0.0", + "private": true, + "dependencies": { + "@mui/icons-material": "^5.14.19", + "@mui/material": "^5.14.20", + "@emotion/react": "^11.11.1", + "@emotion/styled": "^11.11.0", + "@testing-library/jest-dom": "^5.17.0", + "@testing-library/react": "^13.4.0", + "@testing-library/user-event": "^13.5.0", + "axios": "^1.6.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^6.8.0", + "react-scripts": "5.0.1", + "recharts": "^2.8.0", + "styled-components": "^6.1.1", + "web-vitals": "^2.1.4" + }, + "scripts": { + "start": "react-scripts start", + "build": "react-scripts build", + "test": "react-scripts test", + "eject": "react-scripts eject" + }, + "eslintConfig": { + "extends": [ + "react-app", + "react-app/jest" + ] + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "proxy": "http://localhost:8000" +} +EOF + + echo "✅ Package文件创建完成" +} + +# 创建基础代码文件 +create_basic_code() { + echo "💻 创建基础代码文件..." + + # 后端主文件 + cat > backend/app/__init__.py << 'EOF' +# HotTrend Tees Backend +EOF + + cat > backend/app/main.py << 'EOF' +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware + +app = FastAPI( + title="HotTrend Tees API", + description="AI驱动的T-shirt定制平台原型API", + version="1.0.0" +) + +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + +@app.get("/") +async def root(): + return {"message": "HotTrend Tees API v1.0.0", "status": "running"} + +@app.get("/api/health") +async def health_check(): + return { + "status": "healthy", + "timestamp": "2025-07-03T00:00:00Z", + "services": { + "api": "running" + } + } +EOF + + # 前端基础文件 + cat > frontend/public/index.html << 'EOF' + + + + + + + + HotTrend Tees + + + +
+ + +EOF + + cat > frontend/src/index.js << 'EOF' +import React from 'react'; +import ReactDOM from 'react-dom/client'; +import App from './App'; + +const root = ReactDOM.createRoot(document.getElementById('root')); +root.render( + + + +); +EOF + + cat > frontend/src/App.js << 'EOF' +import React, { useState, useEffect } from 'react'; +import { ThemeProvider, createTheme } from '@mui/material/styles'; +import { + CssBaseline, + AppBar, + Toolbar, + Typography, + Container, + Box, + Card, + CardContent, + Button, + Alert +} from '@mui/material'; +import { AutoAwesome } from '@mui/icons-material'; + +const theme = createTheme({ + palette: { + primary: { + main: '#6366f1', + }, + secondary: { + main: '#ec4899', + }, + }, +}); + +function App() { + const [apiStatus, setApiStatus] = useState('checking'); + + useEffect(() => { + checkApiHealth(); + }, []); + + const checkApiHealth = async () => { + try { + const response = await fetch('/api/health'); + const data = await response.json(); + setApiStatus(data.status === 'healthy' ? 'healthy' : 'error'); + } catch (error) { + setApiStatus('error'); + } + }; + + return ( + + + + + + + + HotTrend Tees - AI驱动的T-shirt定制平台 + + + + + + + + 欢迎使用 HotTrend Tees 原型 + + + 基于 Twitter API v2 + OpenAI + AWS 的AI驱动T-shirt定制平台 + + + + + + + 系统状态 + + + {apiStatus === 'checking' && ( + 正在检查API连接... + )} + + {apiStatus === 'healthy' && ( + API服务运行正常 + )} + + {apiStatus === 'error' && ( + + 重试 + + }> + API服务连接失败 + + )} + + + + + + + 下一步操作 + + + 1. 配置API密钥(Twitter、OpenAI、AWS) + + + 2. 启动完整功能模块 + + + 3. 测试趋势分析和设计生成功能 + + + + + + + + ); +} + +export default App; +EOF + + echo "✅ 基础代码文件创建完成" +} + +# 创建启动脚本 +create_startup_scripts() { + echo "🔧 创建启动脚本..." + + # 开发环境启动脚本 + cat > scripts/start-dev.sh << 'EOF' +#!/bin/bash + +echo "🚀 启动HotTrend Tees开发环境" + +# 检查环境文件 +if [ ! -f "./backend/.env" ]; then + echo "❌ 请先创建 backend/.env 文件" + echo "💡 提示: 复制 backend/.env.example 为 backend/.env 并填入API密钥" + exit 1 +fi + +if [ ! -f "./frontend/.env" ]; then + echo "❌ 请先创建 frontend/.env 文件" + echo "💡 提示: 复制 frontend/.env.example 为 frontend/.env" + exit 1 +fi + +# 启动服务 +echo "🐳 启动Docker服务..." +docker-compose up -d db redis + +echo "⏳ 等待数据库启动..." +sleep 10 + +echo "🐍 启动后端服务..." +cd backend +python -m venv venv +source venv/bin/activate +pip install -r requirements.txt +uvicorn app.main:app --reload --host 0.0.0.0 --port 8000 & +cd .. + +echo "⚛️ 启动前端服务..." +cd frontend +npm install +npm start & +cd .. + +echo "✅ 开发环境启动完成!" +echo "🌐 前端地址: http://localhost:3000" +echo "📡 后端API: http://localhost:8000" +echo "📚 API文档: http://localhost:8000/docs" +EOF + + # 生产环境启动脚本 + cat > scripts/start-prod.sh << 'EOF' +#!/bin/bash + +echo "🚀 启动HotTrend Tees生产环境" + +# 检查环境文件 +if [ ! -f "./backend/.env" ]; then + echo "❌ 请先创建 backend/.env 文件" + exit 1 +fi + +if [ ! -f "./frontend/.env" ]; then + echo "❌ 请先创建 frontend/.env 文件" + exit 1 +fi + +# 构建并启动所有服务 +echo "🐳 构建并启动所有服务..." +docker-compose up -d --build + +echo "⏳ 等待服务启动..." +sleep 30 + +echo "✅ 生产环境启动完成!" +echo "🌐 应用地址: http://localhost:3000" +echo "📡 API地址: http://localhost:8000" + +# 显示服务状态 +docker-compose ps +EOF + + # 停止脚本 + cat > scripts/stop.sh << 'EOF' +#!/bin/bash + +echo "🛑 停止HotTrend Tees服务" + +# 停止Docker服务 +docker-compose down + +# 停止本地进程 +pkill -f "uvicorn app.main:app" +pkill -f "npm start" + +echo "✅ 所有服务已停止" +EOF + + # 设置脚本可执行权限 + chmod +x scripts/*.sh + + echo "✅ 启动脚本创建完成" +} + +# 创建测试脚本 +create_test_script() { + echo "🧪 创建测试脚本..." + + cat > scripts/test-api.py << 'EOF' +#!/usr/bin/env python3 + +import asyncio +import aiohttp +import json +import sys + +async def test_api(): + base_url = "http://localhost:8000" + + print("🧪 开始API测试") + print("=" * 40) + + async with aiohttp.ClientSession() as session: + try: + # 测试健康检查 + print("📋 测试健康检查...") + async with session.get(f"{base_url}/api/health") as resp: + if resp.status == 200: + health_data = await resp.json() + print(f"✅ 健康检查通过: {health_data['status']}") + else: + print(f"❌ 健康检查失败: HTTP {resp.status}") + return False + + # 测试根路径 + print("🏠 测试根路径...") + async with session.get(f"{base_url}/") as resp: + if resp.status == 200: + root_data = await resp.json() + print(f"✅ 根路径访问成功: {root_data['message']}") + else: + print(f"❌ 根路径访问失败: HTTP {resp.status}") + return False + + print("\n🎉 所有基础测试通过!") + print("💡 提示: 配置API密钥后可以测试完整功能") + return True + + except aiohttp.ClientError as e: + print(f"❌ 连接失败: {e}") + print("💡 确保后端服务已启动 (python -m uvicorn app.main:app)") + return False + except Exception as e: + print(f"❌ 测试失败: {e}") + return False + +if __name__ == "__main__": + success = asyncio.run(test_api()) + sys.exit(0 if success else 1) +EOF + + chmod +x scripts/test-api.py + + echo "✅ 测试脚本创建完成" +} + +# 创建README文件 +create_readme() { + echo "📖 创建README文件..." + + cat > README.md << 'EOF' +# HotTrend Tees 原型项目 + +🚀 基于 Twitter API v2 + OpenAI + AWS 的AI驱动T-shirt定制平台原型 + +## 快速开始 + +### 1. 环境准备 + +```bash +# 复制环境配置文件 +cp backend/.env.example backend/.env +cp frontend/.env.example frontend/.env + +# 编辑环境文件,填入真实的API密钥 +# backend/.env - 填入Twitter、OpenAI、AWS密钥 +# frontend/.env - 配置前端参数 +``` + +### 2. 开发环境启动 + +```bash +# 启动开发环境 +bash scripts/start-dev.sh + +# 或分别启动各个组件 +# 1. 启动数据库和Redis +docker-compose up -d db redis + +# 2. 启动后端 +cd backend +python -m venv venv +source venv/bin/activate +pip install -r requirements.txt +uvicorn app.main:app --reload + +# 3. 启动前端 +cd frontend +npm install +npm start +``` + +### 3. 生产环境部署 + +```bash +# 启动生产环境 +bash scripts/start-prod.sh + +# 或使用Docker Compose +docker-compose up -d --build +``` + +### 4. API测试 + +```bash +# 运行API测试 +python scripts/test-api.py + +# 或手动测试 +curl http://localhost:8000/api/health +``` + +## 访问地址 + +- 🌐 前端应用: http://localhost:3000 +- 📡 后端API: http://localhost:8000 +- 📚 API文档: http://localhost:8000/docs +- 🗄️ 数据库: localhost:5432 +- 🔴 Redis: localhost:6379 + +## 项目结构 + +``` +hottrend-tees/ +├── backend/ # FastAPI后端 +│ ├── app/ # 应用代码 +│ ├── requirements.txt # Python依赖 +│ └── Dockerfile # Docker配置 +├── frontend/ # React前端 +│ ├── src/ # 源代码 +│ ├── package.json # Node依赖 +│ └── Dockerfile # Docker配置 +├── scripts/ # 脚本文件 +│ ├── start-dev.sh # 开发环境启动 +│ ├── start-prod.sh # 生产环境启动 +│ ├── stop.sh # 停止服务 +│ └── test-api.py # API测试 +├── docker-compose.yml # Docker编排 +└── README.md # 项目说明 +``` + +## 功能特性 + +### ✅ 已实现 +- 基础API框架 (FastAPI) +- 前端界面框架 (React + Material-UI) +- Docker容器化部署 +- 健康检查和监控 +- 开发/生产环境配置 + +### 🚧 待实现 (需要API密钥) +- Twitter趋势数据获取 +- OpenAI图像生成 +- AWS S3存储集成 +- 用户认证系统 +- 订单管理系统 + +## 开发指南 + +### 环境要求 +- Python 3.11+ +- Node.js 18+ +- Docker & Docker Compose +- PostgreSQL 15+ +- Redis 7+ + +### API密钥配置 + +1. **Twitter API v2** + - 访问: https://developer.twitter.com/ + - 申请开发者账号并创建应用 + - 获取Bearer Token和API密钥 + +2. **OpenAI API** + - 访问: https://platform.openai.com/ + - 创建账号并生成API密钥 + - 确保账户有DALL-E 3访问权限 + +3. **AWS服务** + - 访问: https://aws.amazon.com/ + - 创建IAM用户并配置S3权限 + - 获取Access Key和Secret Key + +### 调试技巧 + +```bash +# 查看容器日志 +docker-compose logs backend +docker-compose logs frontend + +# 进入容器调试 +docker-compose exec backend bash +docker-compose exec db psql -U postgres -d hottrend_tees + +# 重启特定服务 +docker-compose restart backend +``` + +## 部署指南 + +### AWS ECS部署 + +1. 构建Docker镜像 +2. 推送到ECR +3. 创建ECS任务定义 +4. 部署到ECS集群 + +详细部署步骤请参考: `docs/deployment.md` + +## 贡献指南 + +1. Fork项目 +2. 创建功能分支 +3. 提交代码 +4. 创建Pull Request + +## 许可证 + +MIT License + +## 支持 + +如有问题,请创建Issue或联系开发团队。 +EOF + + echo "✅ README文件创建完成" +} + +# 显示完成信息 +show_completion_info() { + echo "" + echo "🎉 HotTrend Tees 原型项目创建完成!" + echo "================================" + echo "" + echo "📁 项目位置: $(pwd)" + echo "" + echo "📋 下一步操作:" + echo "1️⃣ 配置API密钥:" + echo " cp backend/.env.example backend/.env" + echo " cp frontend/.env.example frontend/.env" + echo " # 编辑 .env 文件,填入真实的API密钥" + echo "" + echo "2️⃣ 启动开发环境:" + echo " bash scripts/start-dev.sh" + echo "" + echo "3️⃣ 访问应用:" + echo " 🌐 前端: http://localhost:3000" + echo " 📡 API: http://localhost:8000" + echo " 📚 文档: http://localhost:8000/docs" + echo "" + echo "4️⃣ 运行测试:" + echo " python scripts/test-api.py" + echo "" + echo "📖 更多信息请查看 README.md 文件" + echo "" +} + +# 主执行流程 +main() { + echo "开始创建 HotTrend Tees 原型项目..." + + check_dependencies + setup_project_structure + create_env_files + create_docker_configs + create_package_files + create_basic_code + create_startup_scripts + create_test_script + create_readme + + show_completion_info +} + +# 运行主函数 +main "$@"