Repository navigation
Expand file tree
/
Copy pathcron.php
More file actions
76 lines (67 loc) · 3.02 KB
/
Copy pathcron.php
File metadata and controls
76 lines (67 loc) · 3.02 KB
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
<?php
/**
* 坤发卡 - 计划任务入口
* 宝塔计划任务(Shell脚本): php /www/wwwroot/你的站点/cron.php
* 或(访问URL): curl -s "http://你的站点/cron.php?key=YF_KEY的值"(见 data/config.php)
* 建议: 每1分钟执行一次, 负责 1)过期订单处理 2)链上免挂支付(USDT/BTC/ETH/XMR等)轮询到账检测
*/
require __DIR__ . '/app/bootstrap.php';
// Web方式访问需要携带密钥(YF_KEY), 防止外部随意触发; 命令行(宝塔Shell)不受限
if (PHP_SAPI !== 'cli') {
$key = isset($_GET['key']) ? (string)$_GET['key'] : '';
if (!defined('YF_KEY') || $key === '' || !hash_equals(YF_KEY, $key)) {
http_response_code(403);
exit('forbidden');
}
}
// 链上轮询多单多插件时耗时可能超过默认限时(Windows下按墙钟计), 放开执行时限
@set_time_limit(0);
// 单实例锁: 上一轮未跑完时本轮直接退出, 防止重入并发拉链上API触发限频
$lockFp = fopen(YF_DATA . '/cron.lock', 'c');
if ($lockFp && !flock($lockFp, LOCK_EX | LOCK_NB)) {
exit("[cron] previous run still in progress, skipped\n");
}
require YF_ROOT . '/app/lib/Router.php';
// 1. 过期未支付订单
$n = DB::exec('UPDATE orders SET status = 2 WHERE status = 0 AND expired_at > 0 AND expired_at < ?', [now()]);
echo '[expire] ' . $n . " orders expired\n";
// 2. 链上免挂支付轮询(USDT/BTC/ETH/XMR等, 由各插件实现sweep)
// 捕获Throwable: PHP8下插件抛Error(TypeError等)不再中断后续插件与更新预取
foreach (Plugin::scan('payment') as $pname => $pmeta) {
try {
$plugin = Plugin::payment($pname);
if (!$plugin || !$plugin->enabled) continue;
$c = $plugin->sweep();
echo "[{$pname}] checked, {$c} paid\n";
} catch (Throwable $ex) {
echo "[{$pname}] error: " . $ex->getMessage() . "\n";
}
}
// 3. 自动更新: 预取下载更新包(后台应用时零等待)
if (setting('auto_update', '0') === '1') {
try {
$info = Updater::check();
if ($info && Updater::hasUpdate($info)) {
echo Updater::download($info) ? "[update] 包已预取 v{$info['version']}\n" : "[update] 包预取中\n";
}
} catch (Throwable $ex) {
echo '[update] error: ' . $ex->getMessage() . "\n";
}
}
// 4. 每日数据清理(每天首个触发执行一次): 过期OTP已失效即删, 登录失败/注册记录保留30天, 防三表无限膨胀
$today = date('Y-m-d');
if (setting('cleanup_last_date', '') !== $today) {
try {
$c1 = DB::exec('DELETE FROM contact_otps WHERE expires_at < ?', [now() - 3600]);
$c2 = DB::exec('DELETE FROM login_fails WHERE fail_at < ?', [now() - 30 * 86400]);
$c3 = DB::exec('DELETE FROM registers WHERE created_at < ?', [now() - 30 * 86400]);
setting_set('cleanup_last_date', $today);
echo "[cleanup] otp={$c1} login_fails={$c2} registers={$c3}\n";
} catch (Throwable $ex) {
echo '[cleanup] error: ' . $ex->getMessage() . "\n";
}
}
if ($lockFp) {
flock($lockFp, LOCK_UN);
fclose($lockFp);
}