Files
photography/ui/CLAUDE.md
xujiang 73197d8da8 feat: 完善模块化 CLAUDE.md 文档体系
- 新增 admin/CLAUDE.md - 管理后台开发指导文档
  - 修正技术栈为 React + TypeScript + shadcn/ui
  - 提供完整的管理后台架构设计
  - 包含照片管理、分类管理、日志管理等核心功能
  - 详细的开发环境配置和部署指南

- 新增 backend/CLAUDE.md - 后端开发指导文档
  - 基于 Golang + Gin + GORM 技术栈
  - 完整的 API 接口设计和数据库架构
  - 包含认证、权限、文件存储等核心功能
  - 详细的部署和监控配置

- 新增 ui/CLAUDE.md - UI 备份模块管理文档
  - 支持组件备份和 A/B 测试功能
  - 详细的同步策略和实验环境配置
  - 完整的版本管理和协作流程

- 更新 CLAUDE.md 根目录文档
  - 完善模块选择指南和协调机制
  - 新增模块间通信和依赖关系说明
  - 优化文档维护和使用建议
  - 建立完整的模块化开发规范

通过模块化设计最大限度减少 AI 幻觉,提高开发效率。
2025-07-09 14:23:15 +08:00

604 lines
16 KiB
Markdown

# UI 备份模块 - CLAUDE.md
此文件为 Claude Code 在 UI 备份模块工作时提供指导。
## 🎯 模块概览
UI 备份模块是主前端模块 (`frontend/`) 的备份和实验环境,用于保存稳定版本、测试新功能和组件开发。
### 模块用途
- 🔄 主前端代码的备份版本
- 🧪 新功能和组件的实验环境
- 📦 组件库的独立维护
- 🔧 A/B 测试和版本对比
- 🛠️ 紧急回滚的备用版本
### 技术栈
- **前端**: Next.js 15 + React 19 + TypeScript
- **组件**: shadcn/ui + Radix UI
- **样式**: Tailwind CSS
- **构建**: Next.js 内置构建系统
- **包管理**: pnpm (与主前端区分)
## 📁 目录结构
```
ui/
├── CLAUDE.md # 🔍 当前文件 - UI 备份模块指导
├── app/ # Next.js 应用目录
│ ├── globals.css # 全局样式
│ ├── layout.tsx # 根布局
│ └── page.tsx # 主页
├── components/ # 组件目录
│ ├── ui/ # shadcn/ui 组件
│ │ ├── button.tsx # 按钮组件
│ │ ├── card.tsx # 卡片组件
│ │ ├── dialog.tsx # 对话框组件
│ │ └── ... # 其他 UI 组件
│ ├── about-view.tsx # 关于页面组件
│ ├── contact-view.tsx # 联系页面组件
│ ├── filter-bar.tsx # 过滤栏组件
│ ├── loading-spinner.tsx # 加载组件
│ ├── navigation.tsx # 导航组件
│ ├── photo-gallery.tsx # 照片画廊组件
│ ├── photo-modal.tsx # 照片弹窗组件
│ ├── theme-provider.tsx # 主题提供器
│ ├── timeline-stats.tsx # 时间线统计
│ └── timeline-view.tsx # 时间线视图
├── hooks/ # 自定义 Hook
│ ├── use-mobile.tsx # 移动端检测
│ └── use-toast.ts # 提示信息
├── lib/ # 工具库
│ └── utils.ts # 工具函数
├── public/ # 静态资源
│ ├── placeholder-logo.png # 占位图标
│ ├── placeholder-user.jpg # 占位头像
│ └── placeholder.jpg # 占位图片
├── styles/ # 样式文件
│ └── globals.css # 全局样式
├── components.json # shadcn/ui 配置
├── next.config.mjs # Next.js 配置
├── package.json # 依赖配置
├── pnpm-lock.yaml # pnpm 锁文件
├── postcss.config.mjs # PostCSS 配置
├── tailwind.config.ts # Tailwind 配置
├── tsconfig.json # TypeScript 配置
└── README.md # 模块说明
```
## 🔄 与主前端的关系
### 同步策略
```bash
# 从主前端同步到 UI 备份
# 1. 同步核心组件
cp -r frontend/components/ui/* ui/components/ui/
# 2. 同步配置文件
cp frontend/tailwind.config.ts ui/
cp frontend/components.json ui/
# 3. 同步样式文件
cp frontend/app/globals.css ui/app/
cp frontend/styles/globals.css ui/styles/
# 4. 同步工具函数
cp frontend/lib/utils.ts ui/lib/
```
### 版本控制
```bash
# 创建备份分支
git checkout -b ui-backup-v1.0.0
# 标记稳定版本
git tag ui-v1.0.0
# 推送备份版本
git push origin ui-backup-v1.0.0
git push origin ui-v1.0.0
```
## 🧪 实验环境配置
### 开发环境设置
```bash
# 进入 UI 备份目录
cd ui/
# 安装依赖 (使用 pnpm)
pnpm install
# 启动开发服务器
pnpm dev
# 构建项目
pnpm build
# 启动生产预览
pnpm start
```
### 环境变量配置
```bash
# .env.local
NEXT_PUBLIC_API_URL=http://localhost:3001
NEXT_PUBLIC_MOCK_API=true
NEXT_PUBLIC_EXPERIMENTAL_FEATURES=true
```
### 实验性功能开关
```typescript
// lib/experimental.ts
export const experimentalFeatures = {
// 新组件测试
newPhotoGallery: process.env.NEXT_PUBLIC_EXPERIMENTAL_FEATURES === 'true',
// A/B 测试
alternativeNavigation: false,
// 性能优化
optimizedImages: true,
// 新主题
darkModeV2: false,
} as const
// 使用示例
import { experimentalFeatures } from '@/lib/experimental'
export default function PhotoGallery() {
if (experimentalFeatures.newPhotoGallery) {
return <NewPhotoGallery />
}
return <OriginalPhotoGallery />
}
```
## 🎨 组件库管理
### 组件分类
```
components/
├── ui/ # 基础 UI 组件
│ ├── button.tsx # 按钮 - 基础交互
│ ├── input.tsx # 输入框 - 表单控件
│ ├── card.tsx # 卡片 - 内容容器
│ ├── dialog.tsx # 对话框 - 模态框
│ ├── dropdown-menu.tsx # 下拉菜单 - 菜单控件
│ ├── navigation-menu.tsx # 导航菜单 - 导航控件
│ ├── tabs.tsx # 标签页 - 切换控件
│ ├── toast.tsx # 提示信息 - 反馈组件
│ └── ... # 其他基础组件
├── business/ # 业务组件
│ ├── photo-gallery.tsx # 照片画廊
│ ├── photo-modal.tsx # 照片弹窗
│ ├── timeline-view.tsx # 时间线视图
│ ├── filter-bar.tsx # 过滤栏
│ └── navigation.tsx # 站点导航
├── layout/ # 布局组件
│ ├── header.tsx # 页头
│ ├── footer.tsx # 页脚
│ └── sidebar.tsx # 侧边栏
└── experimental/ # 实验性组件
├── new-photo-gallery.tsx # 新照片画廊
├── advanced-filter.tsx # 高级过滤器
└── ai-search.tsx # AI 搜索
```
### 组件开发规范
```typescript
// components/experimental/new-photo-gallery.tsx
import { useState, useCallback } from 'react'
import { Card, CardContent } from '@/components/ui/card'
import { Button } from '@/components/ui/button'
interface Photo {
id: string
src: string
alt: string
title: string
description?: string
}
interface NewPhotoGalleryProps {
photos: Photo[]
onPhotoClick?: (photo: Photo) => void
className?: string
}
export function NewPhotoGallery({
photos,
onPhotoClick,
className
}: NewPhotoGalleryProps) {
const [selectedPhoto, setSelectedPhoto] = useState<Photo | null>(null)
const handlePhotoClick = useCallback((photo: Photo) => {
setSelectedPhoto(photo)
onPhotoClick?.(photo)
}, [onPhotoClick])
return (
<div className={`grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4 ${className}`}>
{photos.map((photo) => (
<Card key={photo.id} className="overflow-hidden hover:shadow-lg transition-shadow">
<CardContent className="p-0">
<div
className="relative aspect-square cursor-pointer"
onClick={() => handlePhotoClick(photo)}
>
<img
src={photo.src}
alt={photo.alt}
className="w-full h-full object-cover"
/>
<div className="absolute inset-0 bg-black/0 hover:bg-black/20 transition-colors" />
</div>
{photo.title && (
<div className="p-3">
<h3 className="font-semibold text-sm">{photo.title}</h3>
{photo.description && (
<p className="text-xs text-muted-foreground mt-1">
{photo.description}
</p>
)}
</div>
)}
</CardContent>
</Card>
))}
</div>
)
}
```
## 🔧 版本管理和同步
### 版本管理策略
```bash
# 1. 创建功能分支
git checkout -b feature/new-component
# 2. 开发和测试
# ... 组件开发 ...
# 3. 合并到 UI 备份主分支
git checkout main
git merge feature/new-component
# 4. 测试稳定后,同步到主前端
cp ui/components/experimental/new-component.tsx frontend/components/
```
### 自动同步脚本
```bash
#!/bin/bash
# scripts/sync-ui-to-frontend.sh
set -e
UI_DIR="ui"
FRONTEND_DIR="frontend"
echo "🔄 开始同步 UI 备份到主前端..."
# 同步基础组件
echo "📦 同步基础组件..."
rsync -av --exclude='experimental' $UI_DIR/components/ui/ $FRONTEND_DIR/components/ui/
# 同步配置文件
echo "⚙️ 同步配置文件..."
cp $UI_DIR/tailwind.config.ts $FRONTEND_DIR/
cp $UI_DIR/components.json $FRONTEND_DIR/
# 同步样式文件
echo "🎨 同步样式文件..."
cp $UI_DIR/app/globals.css $FRONTEND_DIR/app/
cp $UI_DIR/styles/globals.css $FRONTEND_DIR/styles/
# 同步工具函数
echo "🛠️ 同步工具函数..."
cp $UI_DIR/lib/utils.ts $FRONTEND_DIR/lib/
echo "✅ 同步完成!"
```
### 反向同步脚本
```bash
#!/bin/bash
# scripts/sync-frontend-to-ui.sh
set -e
FRONTEND_DIR="frontend"
UI_DIR="ui"
echo "🔄 开始同步主前端到 UI 备份..."
# 创建备份
echo "💾 创建备份..."
timestamp=$(date +%Y%m%d_%H%M%S)
cp -r $UI_DIR $UI_DIR.backup.$timestamp
# 同步核心文件
echo "📦 同步核心文件..."
rsync -av --exclude='experimental' --exclude='backup.*' $FRONTEND_DIR/ $UI_DIR/
# 保留实验性功能
echo "🧪 保留实验性功能..."
if [ -d "$UI_DIR.backup.$timestamp/components/experimental" ]; then
cp -r $UI_DIR.backup.$timestamp/components/experimental $UI_DIR/components/
fi
echo "✅ 同步完成!"
```
## 🧪 A/B 测试和实验
### A/B 测试框架
```typescript
// lib/ab-testing.ts
interface ABTest {
name: string
variants: {
control: React.ComponentType<any>
treatment: React.ComponentType<any>
}
percentage: number // 0-100
enabled: boolean
}
class ABTestManager {
private tests: Map<string, ABTest> = new Map()
registerTest(test: ABTest) {
this.tests.set(test.name, test)
}
getVariant(testName: string): 'control' | 'treatment' | null {
const test = this.tests.get(testName)
if (!test || !test.enabled) return null
// 基于用户 ID 或 session 的一致性分组
const hash = this.hashString(testName + this.getUserId())
const percentage = hash % 100
return percentage < test.percentage ? 'treatment' : 'control'
}
renderComponent(testName: string, props: any) {
const test = this.tests.get(testName)
if (!test) return null
const variant = this.getVariant(testName)
if (variant === 'treatment') {
return <test.variants.treatment {...props} />
}
return <test.variants.control {...props} />
}
private hashString(str: string): number {
let hash = 0
for (let i = 0; i < str.length; i++) {
const char = str.charCodeAt(i)
hash = ((hash << 5) - hash) + char
hash = hash & hash // Convert to 32-bit integer
}
return Math.abs(hash)
}
private getUserId(): string {
// 实现用户 ID 获取逻辑
return sessionStorage.getItem('userId') || 'anonymous'
}
}
export const abTestManager = new ABTestManager()
// 使用示例
abTestManager.registerTest({
name: 'photo-gallery-layout',
variants: {
control: OriginalPhotoGallery,
treatment: NewPhotoGallery
},
percentage: 50,
enabled: true
})
```
### 实验性功能管理
```typescript
// components/experimental/feature-flag.tsx
import { experimentalFeatures } from '@/lib/experimental'
interface FeatureFlagProps {
feature: keyof typeof experimentalFeatures
children: React.ReactNode
fallback?: React.ReactNode
}
export function FeatureFlag({ feature, children, fallback = null }: FeatureFlagProps) {
if (experimentalFeatures[feature]) {
return <>{children}</>
}
return <>{fallback}</>
}
// 使用示例
<FeatureFlag feature="newPhotoGallery" fallback={<OriginalPhotoGallery />}>
<NewPhotoGallery />
</FeatureFlag>
```
## 🚀 构建和部署
### 构建配置
```json
{
"scripts": {
"dev": "next dev -p 3002",
"build": "next build",
"start": "next start -p 3002",
"lint": "next lint",
"type-check": "tsc --noEmit",
"export": "next build && next export",
"sync-from-frontend": "./scripts/sync-frontend-to-ui.sh",
"sync-to-frontend": "./scripts/sync-ui-to-frontend.sh"
}
}
```
### Next.js 配置
```typescript
// next.config.mjs
/** @type {import('next').NextConfig} */
const nextConfig = {
// 输出静态文件
output: 'export',
// 基础路径 (用于部署到子路径)
basePath: '/ui',
// 禁用图片优化 (静态导出)
images: {
unoptimized: true
},
// 实验性功能
experimental: {
appDir: true,
serverComponentsExternalPackages: []
},
// 环境变量
env: {
NEXT_PUBLIC_UI_VERSION: process.env.npm_package_version || '1.0.0'
}
}
export default nextConfig
```
### 部署配置
```bash
# 构建并部署到 UI 预览环境
npm run build
npm run export
# 部署到独立的 UI 预览域名
rsync -av out/ user@server:/var/www/ui-preview/
```
## 🔄 与其他模块的集成
### 与主前端的协作
- 新功能在 UI 备份中实验和测试
- 稳定后同步到主前端
- 主前端的 bug 修复反向同步到 UI 备份
### 与管理后台的关系
- 共享基础组件库
- 管理后台可以复用 UI 备份中的组件
- 保持设计系统的一致性
### 与后端的集成
- 使用相同的 API 接口
- 支持 Mock API 进行独立开发
- 与后端版本保持兼容
## 🐛 问题排查
### 常见问题
1. **组件不同步**: 检查同步脚本和版本控制
2. **样式冲突**: 检查 Tailwind 配置和全局样式
3. **依赖版本不一致**: 检查 package.json 和锁文件
4. **构建失败**: 检查 TypeScript 配置和依赖
### 调试技巧
```bash
# 比较两个版本的差异
diff -r frontend/components ui/components
# 检查依赖差异
diff frontend/package.json ui/package.json
# 清理缓存
rm -rf ui/.next ui/node_modules
cd ui && pnpm install
```
## 📊 监控和分析
### 性能监控
```typescript
// lib/performance.ts
export function measurePerformance(name: string, fn: () => void) {
const start = performance.now()
fn()
const end = performance.now()
console.log(`${name} took ${end - start} milliseconds`)
// 发送到分析服务
if (typeof window !== 'undefined' && (window as any).gtag) {
(window as any).gtag('event', 'timing_complete', {
name: name,
value: Math.round(end - start)
})
}
}
```
### 实验数据收集
```typescript
// lib/analytics.ts
export function trackExperiment(testName: string, variant: string) {
if (typeof window !== 'undefined' && (window as any).gtag) {
(window as any).gtag('event', 'experiment_view', {
experiment_id: testName,
variant_id: variant
})
}
}
export function trackConversion(testName: string, variant: string, action: string) {
if (typeof window !== 'undefined' && (window as any).gtag) {
(window as any).gtag('event', 'experiment_conversion', {
experiment_id: testName,
variant_id: variant,
action: action
})
}
}
```
## 🔮 未来规划
### 功能扩展
- 🔧 可视化组件编辑器
- 📊 实验结果分析面板
- 🎨 设计系统自动化
- 🤖 AI 辅助组件生成
- 📱 响应式设计测试工具
### 工作流优化
- 自动化同步流程
- 持续集成测试
- 可视化差异对比
- 自动化 A/B 测试报告
## 📚 参考资料
- [Next.js 文档](https://nextjs.org/docs)
- [React 19 新特性](https://react.dev/blog/2024/04/25/react-19)
- [shadcn/ui 文档](https://ui.shadcn.com/)
- [Tailwind CSS 文档](https://tailwindcss.com/docs)
- [A/B 测试最佳实践](https://www.optimizely.com/optimization-glossary/ab-testing/)
---
💡 **使用提示**: UI 备份模块主要用于实验和备份,不建议在生产环境中直接使用。所有稳定的功能都应该同步到主前端模块。在进行实验时,请确保做好数据备份,避免影响主前端的稳定性。