221 lines
5.8 KiB
Markdown
221 lines
5.8 KiB
Markdown
# Analytics RPC 函数部署脚本
|
||
|
||
## 问题诊断
|
||
错误信息 "Searched for the function public.get_teacher_analytics ... but no matches were found in the schema cache" 表明:
|
||
|
||
1. RPC 函数尚未在 Supabase 数据库中创建
|
||
2. 或函数签名与调用方式不匹配
|
||
3. 或函数权限未正确设置
|
||
|
||
## 解决方案
|
||
|
||
### 步骤 1: 确认数据库连接
|
||
首先确保你能够连接到 Supabase 数据库:
|
||
|
||
```sql
|
||
-- 在 Supabase SQL Editor 中运行,检查连接
|
||
SELECT current_user, current_database(), now();
|
||
```
|
||
|
||
### 步骤 2: 检查现有函数
|
||
```sql
|
||
-- 检查是否已存在相关函数
|
||
SELECT
|
||
routine_name,
|
||
routine_type,
|
||
routine_definition
|
||
FROM information_schema.routines
|
||
WHERE routine_schema = 'public'
|
||
AND (
|
||
routine_name LIKE '%teacher_analytics%' OR
|
||
routine_name LIKE '%top_performers%' OR
|
||
routine_name LIKE '%chart_data%'
|
||
)
|
||
ORDER BY routine_name;
|
||
```
|
||
|
||
### 步骤 3: 创建简化版本的函数(用于测试)
|
||
如果完整的函数创建有问题,先创建一个简化版本:
|
||
|
||
```sql
|
||
-- 简化版 get_teacher_analytics 函数
|
||
CREATE OR REPLACE FUNCTION public.get_teacher_analytics(
|
||
teacher_id uuid DEFAULT NULL,
|
||
start_date text DEFAULT NULL,
|
||
end_date text DEFAULT NULL
|
||
)
|
||
RETURNS jsonb
|
||
LANGUAGE plpgsql
|
||
SECURITY DEFINER
|
||
AS $$
|
||
BEGIN
|
||
-- 返回简单的测试数据
|
||
RETURN jsonb_build_object(
|
||
'total_students', 25,
|
||
'total_assignments', 8,
|
||
'completion_rate', 85.5,
|
||
'average_score', 78.2,
|
||
'active_classes', 3,
|
||
'total_submissions', 180,
|
||
'pending_reviews', 12,
|
||
'graded_submissions', 168
|
||
);
|
||
END;
|
||
$$;
|
||
|
||
-- 简化版 get_top_performers 函数
|
||
CREATE OR REPLACE FUNCTION public.get_top_performers(
|
||
teacher_id uuid DEFAULT NULL,
|
||
start_date text DEFAULT NULL,
|
||
end_date text DEFAULT NULL,
|
||
"limit" integer DEFAULT 10
|
||
)
|
||
RETURNS jsonb
|
||
LANGUAGE plpgsql
|
||
SECURITY DEFINER
|
||
AS $$
|
||
BEGIN
|
||
-- 返回简单的测试数据
|
||
RETURN jsonb_build_array(
|
||
jsonb_build_object(
|
||
'student_id', gen_random_uuid(),
|
||
'name', '张三',
|
||
'username', 'zhangsan',
|
||
'avatar_url', null,
|
||
'score', 95.5,
|
||
'submission_count', 8,
|
||
'completion_rate', 100,
|
||
'class_name', '三年级一班',
|
||
'rank_position', 1
|
||
),
|
||
jsonb_build_object(
|
||
'student_id', gen_random_uuid(),
|
||
'name', '李四',
|
||
'username', 'lisi',
|
||
'avatar_url', null,
|
||
'score', 92.3,
|
||
'submission_count', 7,
|
||
'completion_rate', 87.5,
|
||
'class_name', '三年级一班',
|
||
'rank_position', 2
|
||
)
|
||
);
|
||
END;
|
||
$$;
|
||
|
||
-- 简化版 get_chart_data 函数
|
||
CREATE OR REPLACE FUNCTION public.get_chart_data(
|
||
teacher_id uuid DEFAULT NULL,
|
||
start_date text DEFAULT NULL,
|
||
end_date text DEFAULT NULL,
|
||
"type" text DEFAULT 'completion_rate'
|
||
)
|
||
RETURNS jsonb
|
||
LANGUAGE plpgsql
|
||
SECURITY DEFINER
|
||
AS $$
|
||
BEGIN
|
||
-- 返回简单的测试数据
|
||
RETURN jsonb_build_array(
|
||
jsonb_build_object(
|
||
'date_key', '2024-06-01',
|
||
'value', 75.5,
|
||
'label', '完成率',
|
||
'count', 15
|
||
),
|
||
jsonb_build_object(
|
||
'date_key', '2024-06-02',
|
||
'value', 82.3,
|
||
'label', '完成率',
|
||
'count', 18
|
||
),
|
||
jsonb_build_object(
|
||
'date_key', '2024-06-03',
|
||
'value', 90.1,
|
||
'label', '完成率',
|
||
'count', 22
|
||
)
|
||
);
|
||
END;
|
||
$$;
|
||
|
||
-- 授权函数
|
||
GRANT EXECUTE ON FUNCTION public.get_teacher_analytics TO authenticated;
|
||
GRANT EXECUTE ON FUNCTION public.get_top_performers TO authenticated;
|
||
GRANT EXECUTE ON FUNCTION public.get_chart_data TO authenticated;
|
||
```
|
||
|
||
### 步骤 4: 测试函数调用
|
||
```sql
|
||
-- 测试函数调用
|
||
SELECT public.get_teacher_analytics();
|
||
SELECT public.get_top_performers();
|
||
SELECT public.get_chart_data();
|
||
```
|
||
|
||
### 步骤 5: 验证 Supabase RPC 调用
|
||
在 Supabase 中测试 RPC 调用:
|
||
|
||
```javascript
|
||
// 在 Supabase 控制台的 API 文档中测试
|
||
const { data, error } = await supabase
|
||
.rpc('get_teacher_analytics', {
|
||
teacher_id: null,
|
||
start_date: '2024-06-01',
|
||
end_date: '2024-06-12'
|
||
});
|
||
```
|
||
|
||
## 常见问题解决
|
||
|
||
### 问题 1: 函数参数类型不匹配
|
||
如果遇到参数类型问题,确保:
|
||
- 日期参数使用 `text` 类型而不是 `date`
|
||
- `limit` 参数加引号 `"limit"`(因为是 PostgreSQL 保留字)
|
||
- UUID 参数允许 NULL 值
|
||
|
||
### 问题 2: 权限问题
|
||
```sql
|
||
-- 检查函数权限
|
||
SELECT
|
||
routine_name,
|
||
routine_schema,
|
||
security_type
|
||
FROM information_schema.routines
|
||
WHERE routine_name LIKE '%teacher_analytics%';
|
||
|
||
-- 重新授权
|
||
GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA public TO authenticated;
|
||
```
|
||
|
||
### 问题 3: RLS 策略冲突
|
||
```sql
|
||
-- 临时禁用 RLS(仅用于调试)
|
||
ALTER TABLE public.ak_users DISABLE ROW LEVEL SECURITY;
|
||
-- 记住调试完成后重新启用
|
||
-- ALTER TABLE public.ak_users ENABLE ROW LEVEL SECURITY;
|
||
```
|
||
|
||
## 部署步骤(按顺序执行)
|
||
|
||
1. **创建简化函数**:在 Supabase SQL Editor 中执行上面的简化版函数
|
||
2. **测试调用**:确认 RPC 调用能够工作
|
||
3. **逐步升级**:如果简化版本工作正常,再部署完整版本
|
||
4. **验证数据**:确保返回的数据结构符合前端期望
|
||
|
||
## 前端调试技巧
|
||
|
||
在 analytics.uvue 中添加调试信息:
|
||
|
||
```javascript
|
||
const handleError = (errorData: any) => {
|
||
console.error('Analytics error详细信息:', errorData)
|
||
console.error('错误类型:', typeof errorData)
|
||
console.error('错误内容:', JSON.stringify(errorData, null, 2))
|
||
error.value = '数据加载失败:' + (errorData.message || '未知错误')
|
||
loading.value = false
|
||
}
|
||
```
|
||
|
||
执行这些步骤后,Analytics 页面应该能够正常加载数据。
|