feat(init): 完成 Phase 1 基础架构搭建

- 完成 T-001A: 前端项目初始化 (Next.js 14 + TypeScript + Tailwind CSS)
- 完成 T-001B: 后端项目初始化 (FastAPI + SQLAlchemy + asyncpg)
- 完成 T-002: 数据库配置 (KolVideo 模型 + 索引 + 测试)
- 完成 T-003: 基础 UI 框架 (Header/Footer 组件 + 品牌色系)
- 完成 T-004: 环境变量配置 (前后端环境变量)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
zfc
2026-01-28 14:26:46 +08:00
co-authored by Claude
commit ac0f086821
75 changed files with 13285 additions and 0 deletions
View File
View File
View File
+28
View File
@@ -0,0 +1,28 @@
from pydantic_settings import BaseSettings, SettingsConfigDict
from typing import List
class Settings(BaseSettings):
"""Application settings."""
model_config = SettingsConfigDict(
env_file=".env",
env_file_encoding="utf-8",
)
# Database
DATABASE_URL: str = "postgresql+asyncpg://user:password@localhost:5432/yuntu_kol"
# CORS
CORS_ORIGINS: List[str] = ["http://localhost:3000"]
# Brand API
BRAND_API_BASE_URL: str = "https://api.internal.intelligrow.cn"
# API Settings
MAX_QUERY_LIMIT: int = 1000
BRAND_API_TIMEOUT: float = 3.0
BRAND_API_CONCURRENCY: int = 10
settings = Settings()
View File
+34
View File
@@ -0,0 +1,34 @@
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase
from app.config import settings
# 创建异步引擎
engine = create_async_engine(
settings.DATABASE_URL,
echo=False,
pool_pre_ping=True,
pool_size=10,
max_overflow=20,
)
# 创建异步会话工厂
async_session_maker = async_sessionmaker(
engine,
class_=AsyncSession,
expire_on_commit=False,
)
class Base(DeclarativeBase):
"""Base class for all models."""
pass
async def get_db() -> AsyncSession:
"""Dependency to get database session."""
async with async_session_maker() as session:
try:
yield session
finally:
await session.close()
+31
View File
@@ -0,0 +1,31 @@
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from app.config import settings
app = FastAPI(
title="KOL Insight API",
description="KOL 视频数据查询与分析 API",
version="1.0.0",
)
# CORS 配置
app.add_middleware(
CORSMiddleware,
allow_origins=settings.CORS_ORIGINS,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/")
async def root():
"""Root endpoint."""
return {"message": "KOL Insight API", "version": "1.0.0"}
@app.get("/health")
async def health():
"""Health check endpoint."""
return {"status": "healthy"}
+3
View File
@@ -0,0 +1,3 @@
from app.models.kol_video import KolVideo
__all__ = ["KolVideo"]
+52
View File
@@ -0,0 +1,52 @@
from sqlalchemy import Column, String, Integer, Float, DateTime, Index
from app.database import Base
class KolVideo(Base):
"""KOL 视频数据模型."""
__tablename__ = "kol_videos"
# 主键
item_id = Column(String, primary_key=True)
# 基础信息
title = Column(String, nullable=True)
viral_type = Column(String, nullable=True)
video_url = Column(String, nullable=True)
star_id = Column(String, nullable=False)
star_unique_id = Column(String, nullable=False)
star_nickname = Column(String, nullable=False)
publish_time = Column(DateTime, nullable=True)
# 曝光指标
natural_play_cnt = Column(Integer, default=0)
heated_play_cnt = Column(Integer, default=0)
total_play_cnt = Column(Integer, default=0)
# 互动指标
total_interact = Column(Integer, default=0)
like_cnt = Column(Integer, default=0)
share_cnt = Column(Integer, default=0)
comment_cnt = Column(Integer, default=0)
# 效果指标
new_a3_rate = Column(Float, nullable=True)
after_view_search_uv = Column(Integer, default=0)
return_search_cnt = Column(Integer, default=0)
# 商业信息
industry_id = Column(String, nullable=True)
industry_name = Column(String, nullable=True)
brand_id = Column(String, nullable=True)
estimated_video_cost = Column(Float, default=0)
# 索引定义
__table_args__ = (
Index("idx_star_id", "star_id"),
Index("idx_star_unique_id", "star_unique_id"),
Index("idx_star_nickname", "star_nickname"),
)
def __repr__(self):
return f"<KolVideo(item_id={self.item_id}, title={self.title})>"
View File
View File