Commit b7d9c775 authored by duanjinfei's avatar duanjinfei

fix function

parent 6b7c1fbb
......@@ -34,78 +34,89 @@ async function deleteDirectory(supabase, bucket: string, directory: string) {
}
}
// 获取当前整点时间
function getCurrentHourTimestamp(): Date {
const now = new Date();
return new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours());
}
// 获取东八区当天凌晨3点时间
function getTodayThreeAMTimestamp(): Date {
const now = new Date();
const today3AM = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 3, 0, 0);
// 如果当前时间小于凌晨3点,返回前一天的凌晨3点
if (now.getHours() < 3) {
today3AM.setDate(today3AM.getDate() - 1);
// 计算特定周期的保留时间戳
function calculateRetentionTimestamp(cycle: 'daily' | 'hourly'): {
retentionTimestamp: number,
currentPeriodTimestamp: number
} {
const now = new Date()
let currentPeriodTimestamp: number
let retentionTimestamp: number
if (cycle === 'daily') {
// 当前周期的时间戳(每天凌晨3点)
const currentPeriod = new Date(now)
currentPeriod.setHours(3, 0, 0, 0)
currentPeriodTimestamp = currentPeriod.getTime() / 1000
// 保留最近7天的数据,即7个凌晨3点周期
const retentionPeriod = new Date(now)
retentionPeriod.setDate(retentionPeriod.getDate() - 7)
retentionPeriod.setHours(3, 0, 0, 0)
retentionTimestamp = retentionPeriod.getTime() / 1000
} else {
// 当前周期的时间戳(每小时整点)
const currentPeriod = new Date(now)
currentPeriod.setMinutes(0, 0, 0)
currentPeriodTimestamp = currentPeriod.getTime() / 1000
// 保留最近7个小时的数据
const retentionPeriod = new Date(now)
retentionPeriod.setHours(retentionPeriod.getHours() - 7, 0, 0, 0)
retentionTimestamp = retentionPeriod.getTime() / 1000
}
return today3AM;
return { retentionTimestamp, currentPeriodTimestamp }
}
// 计算截止时间(7个周期之前的时间戳)
function getCutoffTimestamp(type: "app-category" | "user-rank"): number {
if (type === "app-category") {
const currentHour = getCurrentHourTimestamp();
const cutoff = new Date(currentHour);
cutoff.setHours(cutoff.getHours() - 7);
return cutoff.getTime();
} else {
const today3AM = getTodayThreeAMTimestamp();
const cutoff = new Date(today3AM);
cutoff.setDate(cutoff.getDate() - 7);
return cutoff.getTime();
}
}
// 清理存储桶中过期数据
async function cleanupStorage(supabase: any, bucketName: string, category: 'app-category' | 'user-rank') {
const cycle = category === 'app-category' ? 'daily' : 'hourly'
const { retentionTimestamp, currentPeriodTimestamp } = calculateRetentionTimestamp(cycle)
const deletedDirectories: string[] = []
// 获取需要删除的目录
async function getDirectoriesToDelete(supabase, bucket: string, type: "app-category" | "user-rank"): Promise<string[]> {
try {
const { data, error } = await supabase.storage.from(bucket).list(`${type}/`, {
limit: 1000,
});
if (error) {
console.error(`Failed to list directories in ${type}:`, error.message);
return [];
// 获取指定目录下的所有子目录
const { data, error } = await supabase.storage.from(bucketName).list(category + '/', {
limit: 100,
offset: 0
})
if (error) throw error
// 过滤并删除过期目录
for (const item of data) {
const dirTimestamp = parseInt(item.name)
// 确保不删除当前周期的目录,且删除早于保留时间的目录
if (dirTimestamp < retentionTimestamp && dirTimestamp !== currentPeriodTimestamp) {
await deleteDirectory(supabase, bucketName, `${category}/${item.name}`)
deletedDirectories.push(item.name)
console.log(`删除过期目录: ${category}/${item.name}`)
}
}
const cutoffTimestamp = getCutoffTimestamp(type);
const dirsToDelete = data
.filter(item => !item.name.includes('.')) // 只处理目录
.filter(item => {
const dirTimestamp = parseInt(item.name); // 转为秒
if (isNaN(dirTimestamp)) {
console.log(`Invalid timestamp directory: ${item.name}`);
return false;
}
const dirDate = new Date(dirTimestamp * 1000); // 转为日期
const shouldDelete = dirTimestamp * 1000 < cutoffTimestamp; // 确保单位统一为毫秒
console.log(`Directory "${item.name}" date: ${dirDate.toISOString()}, should delete: ${shouldDelete}`);
return shouldDelete;
})
.map(item => item.name);
console.log(`Found ${dirsToDelete.length} directories to delete for ${type}`);
return dirsToDelete;
return {
category,
cycle,
totalDeleted: deletedDirectories.length,
deletedDirectories,
currentPeriodTimestamp: currentPeriodTimestamp.toString()
}
} catch (err) {
console.error(`Error listing directories in ${type}:`, err);
return [];
console.error(`清理 ${category} 存储时发生错误:`, err)
return {
category,
cycle,
totalDeleted: 0,
error: err.message
}
}
}
// 主逻辑处理
Deno.serve(async (req) => {
if (req.method === "OPTIONS") {
......@@ -127,35 +138,19 @@ Deno.serve(async (req) => {
console.log("Starting cleanup process...");
// 处理 app-category(每小时)
const appCategoryDirsToDelete = await getDirectoriesToDelete(supabase, "cache", "app-category");
for (const dir of appCategoryDirsToDelete) {
await deleteDirectory(supabase, "cache", `app-category/${dir}`);
}
// 处理 user-rank(每天凌晨3点)
const userRankDirsToDelete = await getDirectoriesToDelete(supabase, "cache", "user-rank");
for (const dir of userRankDirsToDelete) {
await deleteDirectory(supabase, "cache", `user-rank/${dir}`);
}
// 清理存储并收集结果
const appCategoryResult = await cleanupStorage(supabase, 'cache', 'app-category')
const userRankResult = await cleanupStorage(supabase, 'cache', 'user-rank')
return new Response(
JSON.stringify({
code: 200,
data: {
appCategory: {
deletedDirs: appCategoryDirsToDelete,
cutoffTime: new Date(getCutoffTimestamp("app-category")).toISOString(),
},
userRank: {
deletedDirs: userRankDirsToDelete,
cutoffTime: new Date(getCutoffTimestamp("user-rank")).toISOString(),
},
},
message: "success",
message: '存储清理完成',
results: [appCategoryResult, userRankResult]
}),
{ headers: { ...corsHeaders, "Content-Type": "application/json" }, status: 200 }
);
{
headers: { 'Content-Type': 'application/json' }
}
)
} catch (err) {
console.error("Error in cleanup process:", err);
return new Response(
......
......@@ -34,6 +34,20 @@ async function fetchAllData(supabase, table: string, pageSize: number = 1000) {
return allData;
}
const getTimestampForMidnight3AM = () => {
// 获取当前时间
const now = new Date();
// 将当前时间转换为东八区时间
const utc8Time = new Date(now.toLocaleString("en-US", { timeZone: "Asia/Shanghai" }));
// 设置时间为东八区凌晨3点
utc8Time.setHours(3, 0, 0, 0);
// 返回东八区凌晨三点的时间戳(单位:秒)
return Math.floor(utc8Time.getTime() / 1000);
}
Deno.serve(async (req) => {
if (req.method === 'OPTIONS') {
return new Response('ok', { headers: corsHeaders })
......@@ -49,7 +63,7 @@ Deno.serve(async (req) => {
// 获取所有 app 数据
const allApps = await fetchAllData(supabase, 'app');
// 获取当前时间的整点时间戳
const timestamp = Math.floor(Date.now() / 3600000) * 3600;
const timestamp = getTimestampForMidnight3AM();
// 上传所有 app 数据到 storage
const directory = `app-category/${timestamp}`;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment