Files
akmon/pages/sport/SUPACLINET_GUIDE.md
2026-01-20 08:04:15 +08:00

260 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 直接使用 AkSupa 链式调用指南
**优势:** 无需 API 包装层,直接使用 `supaClient` 链式调用,代码更简洁高效!
## 基本用法
### 1. 导入 supaClient
```typescript
import supaClient from '@/components/supadb/aksupainstance.uts'
```
### 2. 基本 CRUD 操作
#### 查询数据
```typescript
// 获取所有项目
const result = await supaClient
.from('ak_training_projects')
.select('*')
.execute()
// 带条件查询
const result = await supaClient
.from('ak_assignments')
.select('*, ak_training_projects(*)')
.eq('student_id', studentId)
.eq('status', 'pending')
.order('created_at', { ascending: false })
.limit(20)
.execute()
// 单条记录查询
const result = await supaClient
.from('ak_training_projects')
.select('*')
.eq('id', projectId)
.single()
.execute()
```
#### 插入数据
```typescript
// 创建新记录
const result = await supaClient
.from('ak_training_records')
.insert({
title: '晨跑训练',
duration: 30,
calories: 200,
student_id: 'user123',
created_at: new Date().toISOString()
})
.single()
.execute()
```
#### 更新数据
```typescript
// 更新记录
const result = await supaClient
.from('ak_assignments')
.update({
status: 'completed',
completed_at: new Date().toISOString(),
score: 95
})
.eq('id', assignmentId)
.single()
.execute()
```
#### 删除数据
```typescript
// 删除记录
const result = await supaClient
.from('ak_training_records')
.delete()
.eq('id', recordId)
.execute()
```
### 3. 高级查询
#### 复杂筛选
```typescript
// 多条件筛选
const result = await supaClient
.from('ak_training_projects')
.select('*')
.eq('category', '体能训练')
.gte('difficulty', 3)
.lte('difficulty', 5)
.eq('is_active', true)
.ilike('name', '%跑步%')
.execute()
```
#### 分页查询
```typescript
// 分页获取数据
const result = await supaClient
.from('ak_assignments')
.select('*')
.range(0, 19) // 获取前20条
.order('created_at', { ascending: false })
.execute()
```
#### 聚合查询
```typescript
// 统计查询
const result = await supaClient
.from('ak_training_records')
.select('*', { count: 'exact' })
.eq('student_id', studentId)
.execute()
// result.count 包含总数
```
### 4. 实时订阅
```typescript
export default {
data() {
return {
subscription: null
}
},
onLoad() {
this.setupRealtimeSubscription()
},
onUnload() {
if (this.subscription) {
this.subscription.unsubscribe()
}
},
methods: {
setupRealtimeSubscription() {
this.subscription = supaClient
.from('ak_assignments')
.on('INSERT', (payload) => {
console.log('新作业:', payload.new)
// 更新本地数据
this.assignments.push(payload.new)
})
.on('UPDATE', (payload) => {
console.log('作业更新:', payload.new)
// 更新本地数据
this.updateLocalAssignment(payload.new)
})
.on('DELETE', (payload) => {
console.log('作业删除:', payload.old)
// 从本地数据中移除
this.removeLocalAssignment(payload.old.id)
})
.subscribe()
}
}
}
```
### 5. 文件上传
```typescript
// 上传文件到 Supabase Storage
const result = await supaClient
.storage
.from('training-files')
.upload(`${Date.now()}_${fileName}`, filePath)
.execute()
if (result.success) {
const fileUrl = supaClient.storage
.from('training-files')
.getPublicUrl(result.data.path)
console.log('文件URL', fileUrl)
}
```
### 6. 认证操作
```typescript
// 登录
const result = await supaClient.signInWithPassword(email, password)
// 登出
await supaClient.signOut()
// 获取当前会话
const session = supaClient.getSession()
// 获取当前用户
if (session && session.user) {
const userId = session.user.id
const userEmail = session.user.email
}
```
## 错误处理
```typescript
try {
const result = await supaClient
.from('ak_training_projects')
.select('*')
.execute()
if (result.success) {
// 处理成功结果
this.projects = result.data
} else {
// 处理错误
uni.showToast({
title: result.message || '操作失败',
icon: 'none'
})
}
} catch (error) {
console.error('请求失败:', error)
uni.showToast({
title: '网络错误',
icon: 'none'
})
}
```
## 数据安全访问
使用 `types.uts` 中的安全访问函数:
```typescript
import { safeGet } from '../types.uts'
// 安全获取数据
const projectId = safeGet(project, 'id', '') as string
const projectName = safeGet(project, 'name', '未命名项目') as string
const difficulty = safeGet(project, 'difficulty', 1) as number
```
## 最佳实践
1. **统一错误处理** - 使用 try-catch 包装所有数据库操作
2. **数据验证** - 在插入/更新前验证数据有效性
3. **实时订阅管理** - 在页面卸载时记得取消订阅
4. **安全访问** - 始终使用 `safeGet` 等安全函数访问数据
5. **性能优化** - 合理使用 `limit()` 和分页查询
## 示例页面
参考 `pages/sport/student/simple-records.uvue` 查看完整的实现示例。
---
**总结:** 删除了 `api.uts` 包装层后,直接使用 `supaClient` 链式调用让代码更加简洁、直观和高效!