mall数据库文件
This commit is contained in:
875
mall_sql/docs/FRONTEND_BACKEND_DEBUGGING.md
Normal file
875
mall_sql/docs/FRONTEND_BACKEND_DEBUGGING.md
Normal file
@@ -0,0 +1,875 @@
|
||||
# 🔧 前端与后端联调指南
|
||||
|
||||
## 📋 目录
|
||||
1. [联调环境配置](#联调环境配置)
|
||||
2. [本地开发环境搭建](#本地开发环境搭建)
|
||||
3. [前端连接后端](#前端连接后端)
|
||||
4. [调试工具和方法](#调试工具和方法)
|
||||
5. [常见联调场景](#常见联调场景)
|
||||
6. [问题排查](#问题排查)
|
||||
|
||||
---
|
||||
|
||||
## 一、联调环境配置
|
||||
|
||||
### 1.1 环境类型
|
||||
|
||||
#### 开发环境 (Development)
|
||||
- **Supabase 本地实例**: Docker Compose 运行在 `192.168.0.150:8080`
|
||||
- **Supabase 云服务**: 使用开发项目
|
||||
- **前端**: uni-app-x 开发模式
|
||||
|
||||
#### 生产环境 (Production)
|
||||
- **Supabase 云服务**: 生产项目
|
||||
- **前端**: 编译后的应用
|
||||
|
||||
### 1.2 配置文件位置
|
||||
|
||||
#### 前端配置
|
||||
**文件**: `ak/config.uts`
|
||||
|
||||
```typescript
|
||||
// 开发环境 - 本地 Supabase
|
||||
export const SUPA_URL: string = 'http://192.168.0.150:8080'
|
||||
export const SUPA_KEY: string = 'your-anon-key'
|
||||
|
||||
// 生产环境 - Supabase 云服务
|
||||
export const SUPA_URL: string = 'https://ak3.oulog.com'
|
||||
export const SUPA_KEY: string = 'your-anon-key'
|
||||
|
||||
// WebSocket 实时连接
|
||||
export const WS_URL: string = 'wss://ak3.oulog.com/realtime/v1/websocket'
|
||||
```
|
||||
|
||||
#### 后端配置 (Docker)
|
||||
**文件**: `doc_chat/supa.env`
|
||||
|
||||
```env
|
||||
# Supabase 本地配置
|
||||
POSTGRES_HOST=db
|
||||
POSTGRES_DB=postgres
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_PASSWORD=your-password
|
||||
|
||||
# API 配置
|
||||
KONG_HTTP_PORT=8000
|
||||
KONG_HTTPS_PORT=8443
|
||||
|
||||
# Auth 配置
|
||||
API_EXTERNAL_URL=http://localhost:8000
|
||||
SITE_URL=http://localhost:3000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、本地开发环境搭建
|
||||
|
||||
### 2.1 Supabase 本地实例启动
|
||||
|
||||
#### 方式一: Docker Compose (推荐)
|
||||
|
||||
```bash
|
||||
# 1. 进入 Supabase 目录
|
||||
cd doc_chat
|
||||
|
||||
# 2. 启动 Supabase 服务
|
||||
docker-compose -f supa-docker-compose.yml up -d
|
||||
|
||||
# 3. 检查服务状态
|
||||
docker-compose -f supa-docker-compose.yml ps
|
||||
|
||||
# 4. 查看日志
|
||||
docker-compose -f supa-docker-compose.yml logs -f
|
||||
```
|
||||
|
||||
**服务端口**:
|
||||
- **API**: `http://localhost:8000` 或 `http://192.168.0.150:8080`
|
||||
- **PostgreSQL**: `localhost:5432`
|
||||
- **Dashboard**: `http://localhost:3000`
|
||||
|
||||
#### 方式二: Supabase CLI
|
||||
|
||||
```bash
|
||||
# 1. 安装 Supabase CLI
|
||||
npm install -g supabase
|
||||
|
||||
# 2. 初始化项目
|
||||
supabase init
|
||||
|
||||
# 3. 启动本地实例
|
||||
supabase start
|
||||
|
||||
# 4. 查看服务信息
|
||||
supabase status
|
||||
```
|
||||
|
||||
### 2.2 数据库初始化
|
||||
|
||||
```bash
|
||||
# 1. 执行商城数据库脚本
|
||||
psql -h localhost -U postgres -d postgres -f doc_mall/database/complete_mall_database.sql
|
||||
|
||||
# 或使用 Supabase Dashboard SQL Editor
|
||||
# 1. 打开 http://localhost:3000
|
||||
# 2. 进入 SQL Editor
|
||||
# 3. 复制粘贴 complete_mall_database.sql 内容
|
||||
# 4. 执行脚本
|
||||
|
||||
# 2. 插入模拟数据 (可选)
|
||||
psql -h localhost -U postgres -d postgres -f doc_mall/database/mock_data_insert.sql
|
||||
|
||||
# 3. 验证数据库
|
||||
psql -h localhost -U postgres -d postgres -f doc_mall/database/validation_test.sql
|
||||
```
|
||||
|
||||
### 2.3 前端开发环境
|
||||
|
||||
```bash
|
||||
# 1. 安装依赖 (如果使用 npm)
|
||||
npm install
|
||||
|
||||
# 2. 启动 uni-app-x 开发服务器
|
||||
# 在 HBuilderX 中:
|
||||
# - 运行 -> 运行到浏览器/手机模拟器
|
||||
# - 或使用命令行工具
|
||||
|
||||
# 3. 配置开发环境
|
||||
# 修改 ak/config.uts 中的 SUPA_URL 和 SUPA_KEY
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、前端连接后端
|
||||
|
||||
### 3.1 Supabase 客户端初始化
|
||||
|
||||
#### 全局单例模式
|
||||
**文件**: `components/supadb/aksupainstance.uts`
|
||||
|
||||
```typescript
|
||||
import AkSupa from './aksupa.uts'
|
||||
import { SUPA_URL, SUPA_KEY } from '@/ak/config.uts'
|
||||
|
||||
// 创建全局 Supabase 客户端实例
|
||||
const supa = new AkSupa(SUPA_URL, SUPA_KEY)
|
||||
|
||||
// 自动登录 (开发环境)
|
||||
const supaReady: Promise<boolean> = (async () => {
|
||||
try {
|
||||
await supa.signIn('test@example.com', 'password')
|
||||
return true
|
||||
} catch (err) {
|
||||
console.error('Supabase auto sign-in failed', err)
|
||||
return false
|
||||
}
|
||||
})()
|
||||
|
||||
export { supaReady }
|
||||
export default supa
|
||||
```
|
||||
|
||||
#### 在页面中使用
|
||||
|
||||
```typescript
|
||||
// pages/mall/consumer/index.uvue
|
||||
<script setup lang="uts">
|
||||
import supa from '@/components/supadb/aksupainstance.uts'
|
||||
import { ProductType } from '@/types/mall-types.uts'
|
||||
|
||||
const products = ref<Array<ProductType>>([])
|
||||
|
||||
onMounted(async () => {
|
||||
// 等待 Supabase 客户端就绪
|
||||
await supaReady
|
||||
|
||||
// 查询商品列表
|
||||
const res = await supa.select('ml_products', {
|
||||
status: 1 // 只查询已上架商品
|
||||
}, {
|
||||
limit: 20,
|
||||
order: 'created_at.desc'
|
||||
})
|
||||
|
||||
if (res.success && res.data) {
|
||||
products.value = res.data as Array<ProductType>
|
||||
}
|
||||
})
|
||||
</script>
|
||||
```
|
||||
|
||||
### 3.2 API 调用方式
|
||||
|
||||
#### 3.2.1 查询数据 (SELECT)
|
||||
|
||||
```typescript
|
||||
// 简单查询
|
||||
const res = await supa.select('ml_products', null, {
|
||||
limit: 10,
|
||||
order: 'created_at.desc'
|
||||
})
|
||||
|
||||
// 带过滤条件
|
||||
const res = await supa.select('ml_products', {
|
||||
status: 1,
|
||||
category_id: categoryId
|
||||
}, {
|
||||
limit: 20,
|
||||
order: 'sale_count.desc'
|
||||
})
|
||||
|
||||
// 复杂过滤 (PostgREST 操作符)
|
||||
const res = await supa.select('ml_products', {
|
||||
base_price: { gte: 100, lte: 500 },
|
||||
name: { ilike: '%商品%' },
|
||||
category_id: { in: [id1, id2, id3] }
|
||||
}, {
|
||||
limit: 20
|
||||
})
|
||||
|
||||
// 单条记录
|
||||
const res = await supa.select('ml_products', { id: productId }, {
|
||||
single: true
|
||||
})
|
||||
|
||||
// 选择特定字段
|
||||
const res = await supa.select('ml_products', null, {
|
||||
columns: 'id,name,base_price,main_image_url',
|
||||
limit: 20
|
||||
})
|
||||
```
|
||||
|
||||
#### 3.2.2 插入数据 (INSERT)
|
||||
|
||||
```typescript
|
||||
// 插入订单
|
||||
const orderRes = await supa.insert('ml_orders', {
|
||||
user_id: userId,
|
||||
merchant_id: merchantId,
|
||||
total_amount: 100.00,
|
||||
order_status: 1,
|
||||
payment_status: 1,
|
||||
shipping_status: 1,
|
||||
shipping_address: {
|
||||
receiver_name: '张三',
|
||||
receiver_phone: '13800138000',
|
||||
address_detail: '北京市朝阳区xxx'
|
||||
}
|
||||
})
|
||||
|
||||
// 批量插入
|
||||
const items = [
|
||||
{ order_id: orderId, product_id: productId1, quantity: 2 },
|
||||
{ order_id: orderId, product_id: productId2, quantity: 1 }
|
||||
]
|
||||
const itemsRes = await supa.insert('ml_order_items', items)
|
||||
```
|
||||
|
||||
#### 3.2.3 更新数据 (UPDATE)
|
||||
|
||||
```typescript
|
||||
// 更新商品状态
|
||||
await supa.update('ml_products',
|
||||
{ id: productId }, // 过滤条件
|
||||
{
|
||||
status: 2, // 下架
|
||||
updated_at: new Date().toISOString()
|
||||
}
|
||||
)
|
||||
|
||||
// 更新订单状态
|
||||
await supa.update('ml_orders',
|
||||
{ id: orderId },
|
||||
{
|
||||
order_status: 2, // 待发货
|
||||
updated_at: new Date().toISOString()
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
#### 3.2.4 删除数据 (DELETE)
|
||||
|
||||
```typescript
|
||||
// 删除收藏
|
||||
await supa.delete('ml_user_favorites', { id: favoriteId })
|
||||
|
||||
// 删除购物车商品
|
||||
await supa.delete('ml_shopping_cart', {
|
||||
user_id: userId,
|
||||
product_id: productId
|
||||
})
|
||||
```
|
||||
|
||||
#### 3.2.5 调用数据库函数 (RPC)
|
||||
|
||||
```typescript
|
||||
// 计算购物车总金额
|
||||
const totalRes = await supa.rpc('calculate_cart_total', {
|
||||
p_user_id: userId
|
||||
})
|
||||
|
||||
// 生成订单号
|
||||
const orderNoRes = await supa.rpc('generate_order_no')
|
||||
|
||||
// 获取用户默认地址
|
||||
const addressRes = await supa.rpc('get_user_default_address', {
|
||||
p_user_id: userId
|
||||
})
|
||||
```
|
||||
|
||||
### 3.3 链式查询构建器
|
||||
|
||||
```typescript
|
||||
// 使用链式 API
|
||||
const res = await supa
|
||||
.from('ml_products')
|
||||
.eq('status', 1)
|
||||
.gte('base_price', 100)
|
||||
.lte('base_price', 500)
|
||||
.like('name', '%商品%')
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(20)
|
||||
.select()
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、调试工具和方法
|
||||
|
||||
### 4.1 浏览器开发者工具
|
||||
|
||||
#### 网络请求调试
|
||||
1. **打开 Chrome DevTools** (F12)
|
||||
2. **Network 标签页**
|
||||
- 查看所有 HTTP 请求
|
||||
- 检查请求 URL、Headers、Body
|
||||
- 查看响应状态码、数据
|
||||
|
||||
3. **Console 标签页**
|
||||
- 查看 `console.log()` 输出
|
||||
- 查看错误信息
|
||||
- 执行调试代码
|
||||
|
||||
#### 示例: 检查 API 请求
|
||||
|
||||
```typescript
|
||||
// 在代码中添加日志
|
||||
console.log('请求商品列表:', {
|
||||
table: 'ml_products',
|
||||
filter: { status: 1 },
|
||||
options: { limit: 20 }
|
||||
})
|
||||
|
||||
const res = await supa.select('ml_products', { status: 1 }, { limit: 20 })
|
||||
|
||||
console.log('API 响应:', {
|
||||
success: res.success,
|
||||
data: res.data,
|
||||
error: res.error,
|
||||
status: res.status
|
||||
})
|
||||
```
|
||||
|
||||
### 4.2 Supabase Dashboard
|
||||
|
||||
#### 实时查看数据
|
||||
1. **Table Editor**
|
||||
- 查看表数据
|
||||
- 手动编辑数据
|
||||
- 验证数据是否正确
|
||||
|
||||
2. **SQL Editor**
|
||||
- 执行 SQL 查询
|
||||
- 测试数据库函数
|
||||
- 验证 RLS 策略
|
||||
|
||||
3. **API Logs**
|
||||
- 查看 API 请求日志
|
||||
- 检查错误信息
|
||||
- 分析性能问题
|
||||
|
||||
#### 示例: 测试查询
|
||||
|
||||
```sql
|
||||
-- 在 Supabase Dashboard SQL Editor 中执行
|
||||
SELECT * FROM ml_products
|
||||
WHERE status = 1
|
||||
ORDER BY created_at DESC
|
||||
LIMIT 20;
|
||||
|
||||
-- 测试 RLS 策略
|
||||
SET ROLE authenticated;
|
||||
SET request.jwt.claim.sub = 'user-uuid-here';
|
||||
SELECT * FROM ml_user_profiles;
|
||||
```
|
||||
|
||||
### 4.3 Postman / Insomnia
|
||||
|
||||
#### 直接测试 Supabase API
|
||||
|
||||
```http
|
||||
# 获取商品列表
|
||||
GET https://your-project.supabase.co/rest/v1/ml_products?status=eq.1&limit=20
|
||||
Headers:
|
||||
apikey: your-anon-key
|
||||
Authorization: Bearer your-jwt-token
|
||||
Content-Type: application/json
|
||||
|
||||
# 创建订单
|
||||
POST https://your-project.supabase.co/rest/v1/ml_orders
|
||||
Headers:
|
||||
apikey: your-anon-key
|
||||
Authorization: Bearer your-jwt-token
|
||||
Content-Type: application/json
|
||||
Prefer: return=representation
|
||||
Body:
|
||||
{
|
||||
"user_id": "user-uuid",
|
||||
"merchant_id": "merchant-uuid",
|
||||
"total_amount": 100.00,
|
||||
"order_status": 1
|
||||
}
|
||||
|
||||
# 调用 RPC 函数
|
||||
POST https://your-project.supabase.co/rest/v1/rpc/calculate_cart_total
|
||||
Headers:
|
||||
apikey: your-anon-key
|
||||
Authorization: Bearer your-jwt-token
|
||||
Content-Type: application/json
|
||||
Body:
|
||||
{
|
||||
"p_user_id": "user-uuid"
|
||||
}
|
||||
```
|
||||
|
||||
### 4.4 数据库客户端工具
|
||||
|
||||
#### pgAdmin / DBeaver / DataGrip
|
||||
|
||||
```sql
|
||||
-- 直接连接 PostgreSQL 数据库
|
||||
-- Host: localhost (或 192.168.0.150)
|
||||
-- Port: 5432
|
||||
-- Database: postgres
|
||||
-- User: postgres
|
||||
-- Password: (从 supa.env 获取)
|
||||
|
||||
-- 查看表结构
|
||||
SELECT * FROM information_schema.tables
|
||||
WHERE table_schema = 'public' AND table_name LIKE 'ml_%';
|
||||
|
||||
-- 查看数据
|
||||
SELECT * FROM ml_products LIMIT 10;
|
||||
|
||||
-- 查看 RLS 策略
|
||||
SELECT * FROM pg_policies WHERE tablename = 'ml_products';
|
||||
```
|
||||
|
||||
### 4.5 uni-app-x 调试
|
||||
|
||||
#### HBuilderX 调试工具
|
||||
1. **控制台输出**
|
||||
- 查看 `console.log()` 输出
|
||||
- 查看错误堆栈
|
||||
|
||||
2. **网络请求监控**
|
||||
- 查看所有网络请求
|
||||
- 检查请求参数和响应
|
||||
|
||||
3. **断点调试**
|
||||
- 在代码中设置断点
|
||||
- 单步执行
|
||||
- 查看变量值
|
||||
|
||||
---
|
||||
|
||||
## 五、常见联调场景
|
||||
|
||||
### 5.1 场景一: 查询商品列表失败
|
||||
|
||||
#### 问题现象
|
||||
```typescript
|
||||
// 前端代码
|
||||
const res = await supa.select('ml_products', null, { limit: 20 })
|
||||
// res.success = false
|
||||
// res.error = "relation 'ml_products' does not exist"
|
||||
```
|
||||
|
||||
#### 排查步骤
|
||||
1. **检查数据库表是否存在**
|
||||
```sql
|
||||
SELECT table_name FROM information_schema.tables
|
||||
WHERE table_schema = 'public' AND table_name = 'ml_products';
|
||||
```
|
||||
|
||||
2. **检查表是否已创建**
|
||||
- 执行 `complete_mall_database.sql` 脚本
|
||||
- 验证脚本执行成功
|
||||
|
||||
3. **检查连接配置**
|
||||
```typescript
|
||||
console.log('Supabase URL:', SUPA_URL)
|
||||
console.log('Supabase Key:', SUPA_KEY)
|
||||
```
|
||||
|
||||
#### 解决方案
|
||||
```bash
|
||||
# 重新执行数据库脚本
|
||||
psql -h localhost -U postgres -d postgres -f doc_mall/database/complete_mall_database.sql
|
||||
```
|
||||
|
||||
### 5.2 场景二: RLS 策略阻止数据访问
|
||||
|
||||
#### 问题现象
|
||||
```typescript
|
||||
// 查询用户数据返回空
|
||||
const res = await supa.select('ml_user_profiles', { user_id: userId })
|
||||
// res.data = [] 或 null
|
||||
```
|
||||
|
||||
#### 排查步骤
|
||||
1. **检查用户是否已登录**
|
||||
```typescript
|
||||
const session = await supa.getSession()
|
||||
console.log('当前用户:', session.user)
|
||||
```
|
||||
|
||||
2. **检查 RLS 策略**
|
||||
```sql
|
||||
-- 查看表的 RLS 策略
|
||||
SELECT * FROM pg_policies WHERE tablename = 'ml_user_profiles';
|
||||
|
||||
-- 测试 RLS 策略
|
||||
SET ROLE authenticated;
|
||||
SET request.jwt.claim.sub = 'auth-user-id';
|
||||
SELECT * FROM ml_user_profiles;
|
||||
```
|
||||
|
||||
3. **检查 auth_id 关联**
|
||||
```sql
|
||||
-- 验证 ak_users.auth_id 是否正确
|
||||
SELECT id, auth_id FROM ak_users WHERE id = 'user-uuid';
|
||||
```
|
||||
|
||||
#### 解决方案
|
||||
```typescript
|
||||
// 确保用户已登录
|
||||
await supa.signIn('user@example.com', 'password')
|
||||
|
||||
// 或检查 Token
|
||||
const token = AkReq.getToken()
|
||||
console.log('JWT Token:', token)
|
||||
```
|
||||
|
||||
### 5.3 场景三: 插入数据失败
|
||||
|
||||
#### 问题现象
|
||||
```typescript
|
||||
// 插入订单失败
|
||||
const res = await supa.insert('ml_orders', orderData)
|
||||
// res.success = false
|
||||
// res.error = "new row violates row-level security policy"
|
||||
```
|
||||
|
||||
#### 排查步骤
|
||||
1. **检查必填字段**
|
||||
```typescript
|
||||
console.log('订单数据:', JSON.stringify(orderData, null, 2))
|
||||
```
|
||||
|
||||
2. **检查外键约束**
|
||||
```sql
|
||||
-- 验证 user_id 和 merchant_id 是否存在
|
||||
SELECT id FROM ak_users WHERE id IN ('user-id', 'merchant-id');
|
||||
```
|
||||
|
||||
3. **检查 RLS INSERT 策略**
|
||||
```sql
|
||||
SELECT * FROM pg_policies
|
||||
WHERE tablename = 'ml_orders' AND cmd = 'INSERT';
|
||||
```
|
||||
|
||||
#### 解决方案
|
||||
```typescript
|
||||
// 确保数据完整
|
||||
const orderData = {
|
||||
user_id: userId, // 必须存在
|
||||
merchant_id: merchantId, // 必须存在
|
||||
total_amount: 100.00,
|
||||
order_status: 1,
|
||||
payment_status: 1,
|
||||
shipping_status: 1,
|
||||
shipping_address: addressData // 必须提供
|
||||
}
|
||||
|
||||
// 确保用户有权限
|
||||
await supa.signIn('user@example.com', 'password')
|
||||
```
|
||||
|
||||
### 5.4 场景四: 实时数据同步不工作
|
||||
|
||||
#### 问题现象
|
||||
```typescript
|
||||
// 订阅订单状态更新,但没有收到推送
|
||||
supa.realtime.subscribe('ml_orders', {
|
||||
filter: `id=eq.${orderId}`,
|
||||
event: 'UPDATE',
|
||||
callback: (payload) => {
|
||||
console.log('订单更新:', payload) // 没有触发
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
#### 排查步骤
|
||||
1. **检查 WebSocket 连接**
|
||||
```typescript
|
||||
console.log('WebSocket URL:', WS_URL)
|
||||
```
|
||||
|
||||
2. **检查表是否启用 Realtime**
|
||||
```sql
|
||||
-- 在 Supabase Dashboard 中检查
|
||||
-- Database -> Replication -> 确保 ml_orders 表已启用
|
||||
```
|
||||
|
||||
3. **检查网络连接**
|
||||
- 确保 WebSocket 连接没有被防火墙阻止
|
||||
- 检查浏览器控制台是否有 WebSocket 错误
|
||||
|
||||
#### 解决方案
|
||||
```typescript
|
||||
// 确保 WebSocket URL 正确
|
||||
export const WS_URL: string = 'wss://your-project.supabase.co/realtime/v1/websocket'
|
||||
|
||||
// 在 Supabase Dashboard 中启用表的 Realtime
|
||||
// Database -> Replication -> 找到 ml_orders -> 启用
|
||||
```
|
||||
|
||||
### 5.5 场景五: 数据库函数调用失败
|
||||
|
||||
#### 问题现象
|
||||
```typescript
|
||||
// 调用 RPC 函数失败
|
||||
const res = await supa.rpc('calculate_cart_total', { p_user_id: userId })
|
||||
// res.success = false
|
||||
// res.error = "function calculate_cart_total does not exist"
|
||||
```
|
||||
|
||||
#### 排查步骤
|
||||
1. **检查函数是否存在**
|
||||
```sql
|
||||
SELECT routine_name FROM information_schema.routines
|
||||
WHERE routine_schema = 'public' AND routine_name = 'calculate_cart_total';
|
||||
```
|
||||
|
||||
2. **检查函数参数**
|
||||
```sql
|
||||
-- 查看函数定义
|
||||
\df calculate_cart_total
|
||||
```
|
||||
|
||||
3. **测试函数**
|
||||
```sql
|
||||
SELECT calculate_cart_total('user-uuid-here');
|
||||
```
|
||||
|
||||
#### 解决方案
|
||||
```bash
|
||||
# 重新执行数据库脚本,确保函数已创建
|
||||
psql -h localhost -U postgres -d postgres -f doc_mall/database/complete_mall_database.sql
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、问题排查
|
||||
|
||||
### 6.1 排查清单
|
||||
|
||||
#### 连接问题
|
||||
- [ ] Supabase URL 是否正确
|
||||
- [ ] API Key 是否正确
|
||||
- [ ] 网络连接是否正常
|
||||
- [ ] 防火墙是否阻止连接
|
||||
|
||||
#### 认证问题
|
||||
- [ ] 用户是否已登录
|
||||
- [ ] JWT Token 是否有效
|
||||
- [ ] Token 是否过期
|
||||
- [ ] auth_id 是否正确关联
|
||||
|
||||
#### 数据问题
|
||||
- [ ] 表是否存在
|
||||
- [ ] 字段名是否正确
|
||||
- [ ] 数据类型是否匹配
|
||||
- [ ] 外键约束是否满足
|
||||
|
||||
#### 权限问题
|
||||
- [ ] RLS 策略是否正确
|
||||
- [ ] 用户是否有权限
|
||||
- [ ] 策略条件是否满足
|
||||
|
||||
### 6.2 常用调试命令
|
||||
|
||||
#### 前端调试
|
||||
```typescript
|
||||
// 打印完整请求信息
|
||||
console.log('请求详情:', {
|
||||
url: `${SUPA_URL}/rest/v1/ml_products`,
|
||||
headers: {
|
||||
apikey: SUPA_KEY,
|
||||
Authorization: `Bearer ${token}`
|
||||
},
|
||||
filter: filter,
|
||||
options: options
|
||||
})
|
||||
|
||||
// 打印完整响应
|
||||
console.log('响应详情:', {
|
||||
success: res.success,
|
||||
status: res.status,
|
||||
data: res.data,
|
||||
error: res.error,
|
||||
raw: res
|
||||
})
|
||||
```
|
||||
|
||||
#### 数据库调试
|
||||
```sql
|
||||
-- 查看表结构
|
||||
\d ml_products
|
||||
|
||||
-- 查看索引
|
||||
\di ml_products*
|
||||
|
||||
-- 查看触发器
|
||||
\d+ ml_products
|
||||
|
||||
-- 查看 RLS 策略
|
||||
SELECT * FROM pg_policies WHERE tablename = 'ml_products';
|
||||
|
||||
-- 测试查询性能
|
||||
EXPLAIN ANALYZE SELECT * FROM ml_products WHERE status = 1;
|
||||
```
|
||||
|
||||
### 6.3 错误码参考
|
||||
|
||||
| HTTP 状态码 | 含义 | 常见原因 |
|
||||
| ----------- | ---------- | ---------------------- |
|
||||
| 200 | 成功 | - |
|
||||
| 400 | 请求错误 | 参数错误、数据格式错误 |
|
||||
| 401 | 未授权 | Token 无效、未登录 |
|
||||
| 403 | 禁止访问 | RLS 策略阻止 |
|
||||
| 404 | 未找到 | 表不存在、记录不存在 |
|
||||
| 500 | 服务器错误 | 数据库错误、函数错误 |
|
||||
|
||||
### 6.4 日志收集
|
||||
|
||||
#### 前端日志
|
||||
```typescript
|
||||
// 创建日志工具
|
||||
class DebugLogger {
|
||||
static log(module: string, action: string, data: any) {
|
||||
console.log(`[${module}] ${action}:`, data)
|
||||
// 可以发送到日志服务器
|
||||
}
|
||||
}
|
||||
|
||||
// 使用
|
||||
DebugLogger.log('MallAPI', '查询商品', { filter, options })
|
||||
```
|
||||
|
||||
#### 后端日志
|
||||
```sql
|
||||
-- 启用 PostgreSQL 日志
|
||||
-- 在 postgresql.conf 中设置
|
||||
log_statement = 'all'
|
||||
log_duration = on
|
||||
log_line_prefix = '%t [%p]: [%l-1] user=%u,db=%d,app=%a,client=%h '
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、最佳实践
|
||||
|
||||
### 7.1 开发环境配置
|
||||
|
||||
1. **使用环境变量**
|
||||
```typescript
|
||||
// 开发环境
|
||||
const isDev = process.env.NODE_ENV === 'development'
|
||||
export const SUPA_URL = isDev
|
||||
? 'http://192.168.0.150:8080'
|
||||
: 'https://ak3.oulog.com'
|
||||
```
|
||||
|
||||
2. **统一错误处理**
|
||||
```typescript
|
||||
async function safeApiCall<T>(apiCall: () => Promise<AkReqResponse<T>>) {
|
||||
try {
|
||||
const res = await apiCall()
|
||||
if (!res.success) {
|
||||
console.error('API 调用失败:', res.error)
|
||||
uni.showToast({ title: '操作失败', icon: 'error' })
|
||||
}
|
||||
return res
|
||||
} catch (error) {
|
||||
console.error('API 调用异常:', error)
|
||||
uni.showToast({ title: '网络错误', icon: 'error' })
|
||||
throw error
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **请求重试机制**
|
||||
```typescript
|
||||
async function retryApiCall<T>(
|
||||
apiCall: () => Promise<AkReqResponse<T>>,
|
||||
maxRetries = 3
|
||||
) {
|
||||
for (let i = 0; i < maxRetries; i++) {
|
||||
try {
|
||||
const res = await apiCall()
|
||||
if (res.success) return res
|
||||
} catch (error) {
|
||||
if (i === maxRetries - 1) throw error
|
||||
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)))
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 联调流程
|
||||
|
||||
1. **数据库准备**
|
||||
- 执行数据库脚本
|
||||
- 插入测试数据
|
||||
- 验证表结构
|
||||
|
||||
2. **前端配置**
|
||||
- 配置 Supabase URL 和 Key
|
||||
- 测试连接
|
||||
- 验证认证
|
||||
|
||||
3. **功能测试**
|
||||
- 测试 CRUD 操作
|
||||
- 测试 RLS 策略
|
||||
- 测试实时同步
|
||||
|
||||
4. **问题排查**
|
||||
- 查看日志
|
||||
- 检查网络请求
|
||||
- 验证数据库数据
|
||||
|
||||
---
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [模块分析报告](./MODULE_ANALYSIS.md)
|
||||
- [数据库创建报告](./database/database_creation_report.md)
|
||||
- [完整部署指南](./database/complete_deployment_guide.md)
|
||||
- [Supabase 官方文档](https://supabase.com/docs)
|
||||
|
||||
---
|
||||
|
||||
**生成时间**: 2025年1月
|
||||
**版本**: v1.0
|
||||
**状态**: ✅ 完整联调指南
|
||||
Reference in New Issue
Block a user