1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Follow this setup guide to integrate the Deno language server with your editor:
// https://deno.land/manual/getting_started/setup_your_environment
// This enables autocomplete, go to definition, etc.
// Setup type definitions for built-in Supabase Runtime APIs
import "jsr:@supabase/functions-js/edge-runtime.d.ts"
import { createClient } from 'jsr:@supabase/supabase-js@2'
async function count_holders(supabase) {
let { data, count, error } = await supabase
.from("user")
.select("*", { count: "exact" })
.or('invite_points.gt.0,earn_points.gt.0,task_points.gt.0');
if (error) {
throw error;
}
return count
}
async function cacheUserRank(supabase) {
const { data: userData, error: userError } = await supabase.from('user').select('*').order('rank', { ascending: true }).limit(100);
const updatesUserData = userData.map((user, index) => ({
...user,
rank: index + 1,
}));
if (userError) {
console.error('Error fetching top 100 users:', error);
return new Response(JSON.stringify({ error: 'Failed to fetch users' }), { status: 500 });
}
// 2. 将数据 JSON 序列化
const jsonData = JSON.stringify(updatesUserData);
// 3. 生成文件名
const timestamp = Math.floor(Date.now() / 3600000) * 3600; // 计算整点的时间戳
const directory = `user-rank/${timestamp}`;
const fileName = `${directory}/user_top_100.json`;
const bucketName = 'cache'; // 替换为你的存储桶名称
const { error: uploadError } = await supabase.storage
.from(bucketName)
.upload(fileName, new Blob([jsonData]), {
contentType: 'application/json',
upsert: true, // 如果文件已存在则覆盖
});
if (uploadError) {
console.error('Error uploading file to storage:', uploadError);
const { error } = await supabase.storage
.from(bucketName)
.upload(fileName, new Blob([jsonData]), {
contentType: 'application/json',
upsert: true, // 如果文件已存在则覆盖
});
if (error) {
console.error('Twice Error uploading file to storage:', error);
}
}
const holdersCountFileName = `${directory}/user_holders.json`;
let holdersCount = await count_holders(supabase);
const holdersJson = JSON.stringify({
holders_count: holdersCount
});
const { error: uploadHolderError } = await supabase.storage
.from(bucketName)
.upload(holdersCountFileName, new Blob([holdersJson]), {
contentType: 'application/json',
upsert: true, // 如果文件已存在则覆盖
});
if (uploadHolderError) {
console.error('Error uploading file to storage:', uploadHolderError);
}
}
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response('ok', { headers: corsHeaders })
}
try {
// const { name } = await req.json()
const supabase = createClient(
Deno.env.get('SUPABASE_URL') ?? '',
Deno.env.get('SUPABASE_ANON_KEY') ?? '',
{ global: { headers: { Authorization: req.headers.get('Authorization')! } } }
)
EdgeRuntime.waitUntil(cacheUserRank(supabase));
return new Response(JSON.stringify({
code: 200,
data: null,
message: 'success'
}), {
headers: { 'Content-Type': 'application/json' },
status: 200,
})
} catch (err) {
return new Response(String(err?.message ?? err), { status: 500 })
}
})