Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
appbase-edge-function
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
duanjinfei
appbase-edge-function
Commits
b7d9c775
Commit
b7d9c775
authored
Nov 26, 2024
by
duanjinfei
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix function
parent
6b7c1fbb
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
95 additions
and
86 deletions
+95
-86
index.ts
supabase/functions/cleanup-storage/index.ts
+80
-85
index.ts
supabase/functions/update-app/index.ts
+15
-1
No files found.
supabase/functions/cleanup-storage/index.ts
View file @
b7d9c775
...
@@ -34,78 +34,89 @@ async function deleteDirectory(supabase, bucket: string, directory: string) {
...
@@ -34,78 +34,89 @@ async function deleteDirectory(supabase, bucket: string, directory: string) {
}
}
}
}
// 获取当前整点时间
// 计算特定周期的保留时间戳
function
getCurrentHourTimestamp
():
Date
{
function
calculateRetentionTimestamp
(
cycle
:
'
daily
'
|
'
hourly
'
):
{
const
now
=
new
Date
();
retentionTimestamp
:
number
,
return
new
Date
(
now
.
getFullYear
(),
now
.
getMonth
(),
now
.
getDate
(),
now
.
getHours
());
currentPeriodTimestamp
:
number
}
}
{
const
now
=
new
Date
()
// 获取东八区当天凌晨3点时间
function
getTodayThreeAMTimestamp
():
Date
{
let
currentPeriodTimestamp
:
number
const
now
=
new
Date
();
let
retentionTimestamp
:
number
const
today3AM
=
new
Date
(
now
.
getFullYear
(),
now
.
getMonth
(),
now
.
getDate
(),
3
,
0
,
0
);
if
(
cycle
===
'
daily
'
)
{
// 如果当前时间小于凌晨3点,返回前一天的凌晨3点
// 当前周期的时间戳(每天凌晨3点)
if
(
now
.
getHours
()
<
3
)
{
const
currentPeriod
=
new
Date
(
now
)
today3AM
.
setDate
(
today3AM
.
getDate
()
-
1
);
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
{
async
function
cleanupStorage
(
supabase
:
any
,
bucketName
:
string
,
category
:
'
app-category
'
|
'
user-rank
'
)
{
if
(
type
===
"
app-category
"
)
{
const
cycle
=
category
===
'
app-category
'
?
'
daily
'
:
'
hourly
'
const
currentHour
=
getCurrentHourTimestamp
();
const
{
retentionTimestamp
,
currentPeriodTimestamp
}
=
calculateRetentionTimestamp
(
cycle
)
const
cutoff
=
new
Date
(
currentHour
);
const
deletedDirectories
:
string
[]
=
[]
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
getDirectoriesToDelete
(
supabase
,
bucket
:
string
,
type
:
"
app-category
"
|
"
user-rank
"
):
Promise
<
string
[]
>
{
try
{
try
{
const
{
data
,
error
}
=
await
supabase
.
storage
.
from
(
bucket
).
list
(
`
${
type
}
/`
,
{
// 获取指定目录下的所有子目录
limit
:
1000
,
const
{
data
,
error
}
=
await
supabase
.
storage
.
from
(
bucketName
).
list
(
category
+
'
/
'
,
{
});
limit
:
100
,
offset
:
0
})
if
(
error
)
{
if
(
error
)
throw
error
console
.
error
(
`Failed to list directories in
${
type
}
:`
,
error
.
message
);
return
[];
}
const
cutoffTimestamp
=
getCutoffTimestamp
(
type
);
// 过滤并删除过期目录
for
(
const
item
of
data
)
{
const
dirTimestamp
=
parseInt
(
item
.
name
)
const
dirsToDelete
=
data
// 确保不删除当前周期的目录,且删除早于保留时间的目录
.
filter
(
item
=>
!
item
.
name
.
includes
(
'
.
'
))
// 只处理目录
if
(
dirTimestamp
<
retentionTimestamp
&&
dirTimestamp
!==
currentPeriodTimestamp
)
{
.
filter
(
item
=>
{
await
deleteDirectory
(
supabase
,
bucketName
,
`
${
category
}
/
${
item
.
name
}
`
)
const
dirTimestamp
=
parseInt
(
item
.
name
);
// 转为秒
deletedDirectories
.
push
(
item
.
name
)
if
(
isNaN
(
dirTimestamp
))
{
console
.
log
(
`删除过期目录:
${
category
}
/
${
item
.
name
}
`
)
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
)
{
}
catch
(
err
)
{
console
.
error
(
`Error listing directories in
${
type
}
:`
,
err
);
console
.
error
(
`清理
${
category
}
存储时发生错误:`
,
err
)
return
[];
return
{
category
,
cycle
,
totalDeleted
:
0
,
error
:
err
.
message
}
}
}
}
}
// 主逻辑处理
// 主逻辑处理
Deno
.
serve
(
async
(
req
)
=>
{
Deno
.
serve
(
async
(
req
)
=>
{
if
(
req
.
method
===
"
OPTIONS
"
)
{
if
(
req
.
method
===
"
OPTIONS
"
)
{
...
@@ -127,35 +138,19 @@ Deno.serve(async (req) => {
...
@@ -127,35 +138,19 @@ Deno.serve(async (req) => {
console
.
log
(
"
Starting cleanup process...
"
);
console
.
log
(
"
Starting cleanup process...
"
);
// 处理 app-category(每小时)
// 清理存储并收集结果
const
appCategoryDirsToDelete
=
await
getDirectoriesToDelete
(
supabase
,
"
cache
"
,
"
app-category
"
);
const
appCategoryResult
=
await
cleanupStorage
(
supabase
,
'
cache
'
,
'
app-category
'
)
for
(
const
dir
of
appCategoryDirsToDelete
)
{
const
userRankResult
=
await
cleanupStorage
(
supabase
,
'
cache
'
,
'
user-rank
'
)
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
}
`
);
}
return
new
Response
(
return
new
Response
(
JSON
.
stringify
({
JSON
.
stringify
({
code
:
200
,
message
:
'
存储清理完成
'
,
data
:
{
results
:
[
appCategoryResult
,
userRankResult
]
appCategory
:
{
deletedDirs
:
appCategoryDirsToDelete
,
cutoffTime
:
new
Date
(
getCutoffTimestamp
(
"
app-category
"
)).
toISOString
(),
},
userRank
:
{
deletedDirs
:
userRankDirsToDelete
,
cutoffTime
:
new
Date
(
getCutoffTimestamp
(
"
user-rank
"
)).
toISOString
(),
},
},
message
:
"
success
"
,
}),
}),
{
headers
:
{
...
corsHeaders
,
"
Content-Type
"
:
"
application/json
"
},
status
:
200
}
{
);
headers
:
{
'
Content-Type
'
:
'
application/json
'
}
}
)
}
catch
(
err
)
{
}
catch
(
err
)
{
console
.
error
(
"
Error in cleanup process:
"
,
err
);
console
.
error
(
"
Error in cleanup process:
"
,
err
);
return
new
Response
(
return
new
Response
(
...
...
supabase/functions/update-app/index.ts
View file @
b7d9c775
...
@@ -34,6 +34,20 @@ async function fetchAllData(supabase, table: string, pageSize: number = 1000) {
...
@@ -34,6 +34,20 @@ async function fetchAllData(supabase, table: string, pageSize: number = 1000) {
return
allData
;
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
)
=>
{
Deno
.
serve
(
async
(
req
)
=>
{
if
(
req
.
method
===
'
OPTIONS
'
)
{
if
(
req
.
method
===
'
OPTIONS
'
)
{
return
new
Response
(
'
ok
'
,
{
headers
:
corsHeaders
})
return
new
Response
(
'
ok
'
,
{
headers
:
corsHeaders
})
...
@@ -49,7 +63,7 @@ Deno.serve(async (req) => {
...
@@ -49,7 +63,7 @@ Deno.serve(async (req) => {
// 获取所有 app 数据
// 获取所有 app 数据
const
allApps
=
await
fetchAllData
(
supabase
,
'
app
'
);
const
allApps
=
await
fetchAllData
(
supabase
,
'
app
'
);
// 获取当前时间的整点时间戳
// 获取当前时间的整点时间戳
const
timestamp
=
Math
.
floor
(
Date
.
now
()
/
3600000
)
*
3600
;
const
timestamp
=
getTimestampForMidnight3AM
()
;
// 上传所有 app 数据到 storage
// 上传所有 app 数据到 storage
const
directory
=
`app-category/
${
timestamp
}
`
;
const
directory
=
`app-category/
${
timestamp
}
`
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment