docs: 添加项目开发规范文档
- 添加项目概览文档 - 添加前端开发规范 - 添加后端开发规范 - 添加数据库设计规范 - 添加UI/UX设计规范 - 添加开发指南 - 为项目提供完整的开发标准和最佳实践
This commit is contained in:
531
.promptx/development-guide.md
Normal file
531
.promptx/development-guide.md
Normal file
@@ -0,0 +1,531 @@
|
||||
# MixVideo 开发指南
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 环境准备
|
||||
```bash
|
||||
# 检查环境要求
|
||||
node --version # >= 18.0.0
|
||||
rustc --version # >= 1.70.0
|
||||
pnpm --version # >= 8.0.0
|
||||
|
||||
# 克隆项目
|
||||
git clone <repository-url>
|
||||
cd mixvideo
|
||||
|
||||
# 安装依赖
|
||||
pnpm install
|
||||
|
||||
# 启动开发环境
|
||||
pnpm tauri:dev
|
||||
```
|
||||
|
||||
### 项目结构概览
|
||||
```
|
||||
mixvideo/
|
||||
├── .promptx/ # 开发规范文档
|
||||
├── apps/desktop/ # 主应用
|
||||
│ ├── src/ # React前端
|
||||
│ └── src-tauri/ # Rust后端
|
||||
├── docs/ # 项目文档
|
||||
├── package.json # 根配置
|
||||
├── pnpm-workspace.yaml # 工作空间配置
|
||||
└── Cargo.toml # Rust工作空间
|
||||
```
|
||||
|
||||
## 开发工作流
|
||||
|
||||
### 1. 功能开发流程
|
||||
```bash
|
||||
# 1. 创建功能分支
|
||||
git checkout -b feature/新功能名称
|
||||
|
||||
# 2. 开发和测试
|
||||
pnpm tauri:dev # 启动开发服务器
|
||||
pnpm test # 运行测试
|
||||
|
||||
# 3. 代码检查
|
||||
pnpm lint # ESLint检查
|
||||
pnpm format # Prettier格式化
|
||||
cargo clippy # Rust代码检查
|
||||
|
||||
# 4. 提交代码
|
||||
git add .
|
||||
git commit -m "feat: 添加新功能描述"
|
||||
|
||||
# 5. 推送和合并
|
||||
git push origin feature/新功能名称
|
||||
# 创建Pull Request
|
||||
```
|
||||
|
||||
### 2. 提交信息规范
|
||||
```bash
|
||||
# 提交类型
|
||||
feat: 新功能
|
||||
fix: 修复bug
|
||||
docs: 文档更新
|
||||
style: 代码格式调整
|
||||
refactor: 重构代码
|
||||
test: 测试相关
|
||||
chore: 构建工具或辅助工具的变动
|
||||
|
||||
# 示例
|
||||
git commit -m "feat: 添加AI视频分类功能"
|
||||
git commit -m "fix: 修复素材导入时的路径问题"
|
||||
git commit -m "docs: 更新API文档"
|
||||
```
|
||||
|
||||
### 3. 代码审查清单
|
||||
- [ ] 功能是否按需求实现
|
||||
- [ ] 代码是否遵循项目规范
|
||||
- [ ] 是否有适当的错误处理
|
||||
- [ ] 是否有相应的测试覆盖
|
||||
- [ ] 性能是否有考虑
|
||||
- [ ] 安全性是否有保障
|
||||
- [ ] 文档是否更新
|
||||
|
||||
## 核心开发模式
|
||||
|
||||
### 前端开发模式
|
||||
|
||||
#### 1. 组件开发
|
||||
```typescript
|
||||
// 1. 定义类型
|
||||
interface ComponentProps {
|
||||
id: string;
|
||||
title: string;
|
||||
onAction?: (data: any) => void;
|
||||
}
|
||||
|
||||
// 2. 实现组件
|
||||
export const Component: FC<ComponentProps> = ({ id, title, onAction }) => {
|
||||
// Hooks
|
||||
const [state, setState] = useState();
|
||||
const { data, loading } = useCustomHook();
|
||||
|
||||
// 事件处理
|
||||
const handleAction = useCallback(() => {
|
||||
onAction?.(data);
|
||||
}, [onAction, data]);
|
||||
|
||||
// 渲染
|
||||
return (
|
||||
<div className="component-container">
|
||||
{/* 组件内容 */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
#### 2. 状态管理
|
||||
```typescript
|
||||
// 使用Zustand进行状态管理
|
||||
export const useFeatureStore = create<FeatureState>((set, get) => ({
|
||||
// 状态
|
||||
data: [],
|
||||
loading: false,
|
||||
error: null,
|
||||
|
||||
// 操作
|
||||
fetchData: async () => {
|
||||
set({ loading: true });
|
||||
try {
|
||||
const data = await api.getData();
|
||||
set({ data, loading: false });
|
||||
} catch (error) {
|
||||
set({ error: error.message, loading: false });
|
||||
}
|
||||
},
|
||||
}));
|
||||
```
|
||||
|
||||
#### 3. 服务层调用
|
||||
```typescript
|
||||
// 调用Tauri命令
|
||||
export class FeatureService {
|
||||
static async getData(): Promise<Data[]> {
|
||||
try {
|
||||
return await invoke<Data[]>('get_data');
|
||||
} catch (error) {
|
||||
throw new Error(`获取数据失败: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 后端开发模式
|
||||
|
||||
#### 1. 数据模型
|
||||
```rust
|
||||
// 定义数据模型
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Entity {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
impl Entity {
|
||||
pub fn new(name: String) -> Self {
|
||||
let now = Utc::now();
|
||||
Self {
|
||||
id: uuid::Uuid::new_v4().to_string(),
|
||||
name,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 仓库层
|
||||
```rust
|
||||
// 数据访问层
|
||||
pub struct EntityRepository {
|
||||
database: Arc<Database>,
|
||||
}
|
||||
|
||||
impl EntityRepository {
|
||||
pub async fn create(&self, entity: &Entity) -> Result<()> {
|
||||
let conn = self.database.get_connection().await?;
|
||||
// 数据库操作
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn get_by_id(&self, id: &str) -> Result<Option<Entity>> {
|
||||
let conn = self.database.get_read_connection().await?;
|
||||
// 查询操作
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 业务服务
|
||||
```rust
|
||||
// 业务逻辑层
|
||||
pub struct EntityService;
|
||||
|
||||
impl EntityService {
|
||||
pub async fn create_entity(
|
||||
repository: &EntityRepository,
|
||||
request: CreateEntityRequest,
|
||||
) -> Result<Entity> {
|
||||
// 业务验证
|
||||
if request.name.trim().is_empty() {
|
||||
return Err(anyhow!("名称不能为空"));
|
||||
}
|
||||
|
||||
// 创建实体
|
||||
let entity = Entity::new(request.name);
|
||||
|
||||
// 保存到数据库
|
||||
repository.create(&entity).await?;
|
||||
|
||||
Ok(entity)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. Tauri命令
|
||||
```rust
|
||||
// 表现层命令
|
||||
#[command]
|
||||
pub async fn create_entity(
|
||||
state: State<'_, AppState>,
|
||||
request: CreateEntityRequest,
|
||||
) -> Result<Entity, String> {
|
||||
let repository = state.get_entity_repository()
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
EntityService::create_entity(&repository, request)
|
||||
.await
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
```
|
||||
|
||||
## 测试策略
|
||||
|
||||
### 前端测试
|
||||
```typescript
|
||||
// 组件测试
|
||||
describe('Component', () => {
|
||||
it('应该正确渲染', () => {
|
||||
render(<Component id="1" title="Test" />);
|
||||
expect(screen.getByText('Test')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('应该处理用户交互', async () => {
|
||||
const onAction = vi.fn();
|
||||
render(<Component id="1" title="Test" onAction={onAction} />);
|
||||
|
||||
fireEvent.click(screen.getByRole('button'));
|
||||
await waitFor(() => {
|
||||
expect(onAction).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Hook测试
|
||||
describe('useCustomHook', () => {
|
||||
it('应该返回正确的数据', async () => {
|
||||
const { result } = renderHook(() => useCustomHook());
|
||||
|
||||
await waitFor(() => {
|
||||
expect(result.current.data).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### 后端测试
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_create_entity() {
|
||||
// 准备测试数据
|
||||
let db = setup_test_database().await;
|
||||
let repository = EntityRepository::new(db);
|
||||
let request = CreateEntityRequest {
|
||||
name: "Test Entity".to_string(),
|
||||
};
|
||||
|
||||
// 执行测试
|
||||
let result = EntityService::create_entity(&repository, request).await;
|
||||
|
||||
// 验证结果
|
||||
assert!(result.is_ok());
|
||||
let entity = result.unwrap();
|
||||
assert_eq!(entity.name, "Test Entity");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 调试技巧
|
||||
|
||||
### 前端调试
|
||||
```typescript
|
||||
// 1. 使用浏览器开发者工具
|
||||
console.log('调试信息:', data);
|
||||
console.error('错误信息:', error);
|
||||
|
||||
// 2. React DevTools
|
||||
// 安装React DevTools浏览器扩展
|
||||
|
||||
// 3. Zustand DevTools
|
||||
const useStore = create(
|
||||
devtools((set, get) => ({
|
||||
// store实现
|
||||
}))
|
||||
);
|
||||
|
||||
// 4. 网络请求调试
|
||||
// 在Network面板查看Tauri命令调用
|
||||
```
|
||||
|
||||
### 后端调试
|
||||
```rust
|
||||
// 1. 使用tracing进行日志记录
|
||||
use tracing::{info, warn, error, debug};
|
||||
|
||||
#[instrument]
|
||||
async fn debug_function() {
|
||||
info!("函数开始执行");
|
||||
debug!("调试信息: {:?}", data);
|
||||
warn!("警告信息");
|
||||
error!("错误信息: {}", error);
|
||||
}
|
||||
|
||||
// 2. 使用dbg!宏
|
||||
let result = dbg!(some_calculation());
|
||||
|
||||
// 3. 条件编译调试代码
|
||||
#[cfg(debug_assertions)]
|
||||
println!("调试模式下的输出");
|
||||
```
|
||||
|
||||
### 数据库调试
|
||||
```sql
|
||||
-- 查看查询计划
|
||||
EXPLAIN QUERY PLAN SELECT * FROM materials WHERE project_id = ?;
|
||||
|
||||
-- 检查索引使用
|
||||
.schema materials
|
||||
.indices materials
|
||||
|
||||
-- 分析表统计
|
||||
ANALYZE;
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 前端性能优化
|
||||
```typescript
|
||||
// 1. 组件优化
|
||||
const OptimizedComponent = memo(({ data }) => {
|
||||
const memoizedValue = useMemo(() => {
|
||||
return expensiveCalculation(data);
|
||||
}, [data]);
|
||||
|
||||
const memoizedCallback = useCallback(() => {
|
||||
handleAction(data);
|
||||
}, [data]);
|
||||
|
||||
return <div>{memoizedValue}</div>;
|
||||
});
|
||||
|
||||
// 2. 懒加载
|
||||
const LazyComponent = lazy(() => import('./LazyComponent'));
|
||||
|
||||
// 3. 虚拟化长列表
|
||||
import { FixedSizeList as List } from 'react-window';
|
||||
|
||||
const VirtualList = ({ items }) => (
|
||||
<List
|
||||
height={600}
|
||||
itemCount={items.length}
|
||||
itemSize={80}
|
||||
>
|
||||
{({ index, style }) => (
|
||||
<div style={style}>
|
||||
<Item data={items[index]} />
|
||||
</div>
|
||||
)}
|
||||
</List>
|
||||
);
|
||||
```
|
||||
|
||||
### 后端性能优化
|
||||
```rust
|
||||
// 1. 数据库连接池
|
||||
let pool = ConnectionPool::new(database_url, pool_config)?;
|
||||
|
||||
// 2. 批量操作
|
||||
async fn batch_insert(items: &[Item]) -> Result<()> {
|
||||
let conn = pool.get().await?;
|
||||
let tx = conn.transaction()?;
|
||||
|
||||
for item in items {
|
||||
tx.execute("INSERT INTO ...", params![...])?;
|
||||
}
|
||||
|
||||
tx.commit()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// 3. 异步并发
|
||||
use futures::future::join_all;
|
||||
|
||||
let futures: Vec<_> = items.iter()
|
||||
.map(|item| process_item(item))
|
||||
.collect();
|
||||
|
||||
let results = join_all(futures).await;
|
||||
```
|
||||
|
||||
## 常见问题解决
|
||||
|
||||
### 1. 构建问题
|
||||
```bash
|
||||
# 清理缓存
|
||||
pnpm clean
|
||||
rm -rf node_modules
|
||||
rm -rf target
|
||||
pnpm install
|
||||
|
||||
# Rust编译问题
|
||||
cargo clean
|
||||
cargo build
|
||||
```
|
||||
|
||||
### 2. 开发环境问题
|
||||
```bash
|
||||
# 端口冲突
|
||||
lsof -ti:1420 | xargs kill -9
|
||||
|
||||
# 权限问题
|
||||
sudo chown -R $(whoami) ~/.cargo
|
||||
```
|
||||
|
||||
### 3. 数据库问题
|
||||
```rust
|
||||
// 数据库锁定
|
||||
// 检查是否有其他进程占用数据库
|
||||
// 使用WAL模式减少锁定
|
||||
|
||||
// 迁移失败
|
||||
// 检查SQL语法
|
||||
// 验证外键约束
|
||||
```
|
||||
|
||||
### 4. 前端问题
|
||||
```typescript
|
||||
// 状态更新问题
|
||||
// 检查依赖数组
|
||||
// 使用useCallback和useMemo
|
||||
|
||||
// 渲染性能问题
|
||||
// 使用React DevTools Profiler
|
||||
// 检查不必要的重渲染
|
||||
```
|
||||
|
||||
## 部署指南
|
||||
|
||||
### 开发环境部署
|
||||
```bash
|
||||
# 启动开发服务器
|
||||
pnpm tauri:dev
|
||||
```
|
||||
|
||||
### 生产环境构建
|
||||
```bash
|
||||
# 构建应用
|
||||
pnpm tauri:build
|
||||
|
||||
# 构建产物位置
|
||||
# Windows: target/release/bundle/msi/
|
||||
# macOS: target/release/bundle/dmg/
|
||||
# Linux: target/release/bundle/deb/
|
||||
```
|
||||
|
||||
### 发布流程
|
||||
```bash
|
||||
# 1. 更新版本号
|
||||
# 修改 package.json 和 Cargo.toml 中的版本号
|
||||
|
||||
# 2. 创建发布标签
|
||||
git tag v0.2.1
|
||||
git push origin v0.2.1
|
||||
|
||||
# 3. GitHub Actions自动构建和发布
|
||||
# 查看 .github/workflows/ 中的配置
|
||||
```
|
||||
|
||||
## 最佳实践总结
|
||||
|
||||
### 代码质量
|
||||
1. **遵循规范**: 严格按照项目编码规范开发
|
||||
2. **测试驱动**: 为核心功能编写测试
|
||||
3. **代码审查**: 所有代码都要经过审查
|
||||
4. **文档更新**: 及时更新相关文档
|
||||
|
||||
### 性能考虑
|
||||
1. **数据库优化**: 合理使用索引和查询优化
|
||||
2. **前端优化**: 使用虚拟化、懒加载等技术
|
||||
3. **内存管理**: 避免内存泄漏和过度使用
|
||||
4. **网络优化**: 减少不必要的网络请求
|
||||
|
||||
### 安全意识
|
||||
1. **输入验证**: 严格验证所有用户输入
|
||||
2. **错误处理**: 不泄露敏感信息
|
||||
3. **权限控制**: 实施适当的访问控制
|
||||
4. **数据保护**: 保护用户数据安全
|
||||
|
||||
### 用户体验
|
||||
1. **响应式设计**: 支持多种设备和屏幕尺寸
|
||||
2. **加载状态**: 提供清晰的加载反馈
|
||||
3. **错误提示**: 友好的错误信息和恢复建议
|
||||
4. **无障碍性**: 支持键盘导航和屏幕阅读器
|
||||
Reference in New Issue
Block a user