fix: improve reservation cleanup and share popup handling
This commit is contained in:
@@ -2284,8 +2284,12 @@ const DownloadTrafficReservationDB = {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
cleanupFinalizedHistory(keepDays = 7) {
|
cleanupFinalizedHistory(keepDays = 0) {
|
||||||
const days = Math.min(365, Math.max(1, Math.floor(Number(keepDays) || 7)));
|
// keepDays=0 表示立即清理全部已完成历史(confirmed/expired/cancelled)
|
||||||
|
const normalized = Number(keepDays);
|
||||||
|
const days = Number.isFinite(normalized)
|
||||||
|
? Math.min(365, Math.max(0, Math.floor(normalized)))
|
||||||
|
: 0;
|
||||||
return db.prepare(`
|
return db.prepare(`
|
||||||
DELETE FROM user_download_traffic_reservations
|
DELETE FROM user_download_traffic_reservations
|
||||||
WHERE status IN ('confirmed', 'expired', 'cancelled')
|
WHERE status IN ('confirmed', 'expired', 'cancelled')
|
||||||
|
|||||||
@@ -8843,7 +8843,10 @@ app.post('/api/admin/download-reservations/:id/cancel', authMiddleware, adminMid
|
|||||||
// 下载流量预扣运维面板:批量清理(过期 pending + 历史 finalized)
|
// 下载流量预扣运维面板:批量清理(过期 pending + 历史 finalized)
|
||||||
app.post('/api/admin/download-reservations/cleanup', authMiddleware, adminMiddleware, (req, res) => {
|
app.post('/api/admin/download-reservations/cleanup', authMiddleware, adminMiddleware, (req, res) => {
|
||||||
try {
|
try {
|
||||||
const keepDays = Math.min(365, Math.max(1, parseInt(req.body?.keep_days, 10) || 7));
|
// 默认 keep_days=0:立即清理全部已完成历史记录,避免“清理无效果”的感知
|
||||||
|
const rawKeepDays = req.body?.keep_days;
|
||||||
|
const parsedKeepDays = Number.isFinite(Number(rawKeepDays)) ? parseInt(rawKeepDays, 10) : 0;
|
||||||
|
const keepDays = Math.min(365, Math.max(0, Number.isFinite(parsedKeepDays) ? parsedKeepDays : 0));
|
||||||
const expireResult = DownloadTrafficReservationDB.expirePendingReservations();
|
const expireResult = DownloadTrafficReservationDB.expirePendingReservations();
|
||||||
const cleanupResult = DownloadTrafficReservationDB.cleanupFinalizedHistory(keepDays);
|
const cleanupResult = DownloadTrafficReservationDB.cleanupFinalizedHistory(keepDays);
|
||||||
|
|
||||||
@@ -8860,7 +8863,7 @@ app.post('/api/admin/download-reservations/cleanup', authMiddleware, adminMiddle
|
|||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
success: true,
|
success: true,
|
||||||
message: '预扣清理完成',
|
message: `预扣清理完成(过期待确认 ${Number(expireResult?.changes || 0)} 条,删除历史 ${Number(cleanupResult?.changes || 0)} 条)`,
|
||||||
result: {
|
result: {
|
||||||
keep_days: keepDays,
|
keep_days: keepDays,
|
||||||
expired_pending: Number(expireResult?.changes || 0),
|
expired_pending: Number(expireResult?.changes || 0),
|
||||||
|
|||||||
@@ -3181,11 +3181,25 @@ handleDragLeave(e) {
|
|||||||
|
|
||||||
openShare(url) {
|
openShare(url) {
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
const newWindow = window.open(url, '_blank', 'noopener');
|
// 仅在真正被拦截(返回 null/undefined)时提示,避免已打开仍误报
|
||||||
if (!newWindow || newWindow.closed || typeof newWindow.closed === 'undefined') {
|
let newWindow = null;
|
||||||
// 弹窗被拦截时提示用户手动打开,避免当前页跳转
|
try {
|
||||||
this.showToast('info', '提示', '浏览器阻止了新标签页,请允许弹窗或手动打开链接');
|
newWindow = window.open(url, '_blank');
|
||||||
|
} catch (error) {
|
||||||
|
newWindow = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newWindow) {
|
||||||
|
try {
|
||||||
|
// 防止新窗口通过 opener 反向控制当前页面
|
||||||
|
newWindow.opener = null;
|
||||||
|
} catch (e) {
|
||||||
|
// 忽略跨域写 opener 失败
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showToast('info', '提示', '浏览器阻止了新标签页,请允许弹窗或手动打开链接');
|
||||||
},
|
},
|
||||||
|
|
||||||
copyTextToClipboard(text, successMessage = '已复制到剪贴板') {
|
copyTextToClipboard(text, successMessage = '已复制到剪贴板') {
|
||||||
@@ -4559,15 +4573,17 @@ handleDragLeave(e) {
|
|||||||
|
|
||||||
async cleanupReservations() {
|
async cleanupReservations() {
|
||||||
if (this.reservationMonitor.cleaning) return;
|
if (this.reservationMonitor.cleaning) return;
|
||||||
if (!confirm('确认清理过期/历史预扣记录吗?')) return;
|
if (!confirm('确认清理预扣历史吗?将立即删除已完成/已过期/已取消记录。')) return;
|
||||||
|
|
||||||
this.reservationMonitor.cleaning = true;
|
this.reservationMonitor.cleaning = true;
|
||||||
try {
|
try {
|
||||||
const response = await axios.post(`${this.apiBase}/api/admin/download-reservations/cleanup`, {
|
const response = await axios.post(`${this.apiBase}/api/admin/download-reservations/cleanup`, {
|
||||||
keep_days: 7
|
keep_days: 0
|
||||||
});
|
});
|
||||||
if (response.data?.success) {
|
if (response.data?.success) {
|
||||||
this.showToast('success', '成功', response.data.message || '预扣清理完成');
|
const result = response.data?.result || {};
|
||||||
|
const msg = `已清理历史 ${Number(result.deleted_finalized || 0)} 条,过期待确认 ${Number(result.expired_pending || 0)} 条`;
|
||||||
|
this.showToast('success', '成功', msg);
|
||||||
await this.loadDownloadReservationMonitor(1);
|
await this.loadDownloadReservationMonitor(1);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user