From d56388dd299375d9ce33e6bcfc1ee9ebb9dfb65f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=96=BB=E5=8B=87=E7=A5=A5?= <237899745@qq.com> Date: Fri, 14 Nov 2025 16:25:31 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=88=86=E4=BA=AB?= =?UTF-8?q?=E8=BF=87=E6=9C=9F=E6=97=B6=E9=97=B4=E6=A0=BC=E5=BC=8F=E5=AF=BC?= =?UTF-8?q?=E8=87=B4=E7=9A=84=E8=BF=87=E6=BB=A4=E5=A4=B1=E8=B4=A5=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 问题分析 通过调试日志发现,过期分享仍能访问的根本原因是: - expires_at 存储格式: `2025-11-14T07:31:31.922Z` (ISO 8601) - datetime('now') 返回格式: `2025-11-14 08:19:52` (SQLite格式) - SQLite进行字符串比较时: 'T' (ASCII 84) > ' ' (ASCII 32) - 导致条件 `expires_at > datetime('now')` 对已过期分享仍返回true ## 修复内容 1. database.js: 修改create方法,将expires_at转换为SQLite datetime格式 - 旧格式: 2025-11-14T07:31:31.922Z - 新格式: 2025-11-14 07:31:31 2. fix_expires_at_format.js: 数据库修复脚本 - 将已存在的ISO格式时间转换为SQLite格式 - 确保历史数据也能正确过滤 ## 部署步骤 ```bash cd /var/www/wanwanyun git pull cd backend node fix_expires_at_format.js # 修复历史数据 pm2 restart wanwanyun-backend # 重启服务 ``` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- backend/database.js | 4 +++- backend/fix_expires_at_format.js | 34 ++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 backend/fix_expires_at_format.js diff --git a/backend/database.js b/backend/database.js index 6667532..10c88b0 100644 --- a/backend/database.js +++ b/backend/database.js @@ -303,7 +303,9 @@ const ShareDB = { if (expiry_days) { const expireDate = new Date(); expireDate.setDate(expireDate.getDate() + parseInt(expiry_days)); - expiresAt = expireDate.toISOString(); + // 转换为SQLite datetime格式 (YYYY-MM-DD HH:MM:SS),而不是ISO格式 + // 这样才能正确与 datetime('now') 进行比较 + expiresAt = expireDate.toISOString().replace('T', ' ').replace(/\.\d+Z$/, ''); } const stmt = db.prepare(` diff --git a/backend/fix_expires_at_format.js b/backend/fix_expires_at_format.js new file mode 100644 index 0000000..c039db7 --- /dev/null +++ b/backend/fix_expires_at_format.js @@ -0,0 +1,34 @@ +const { db } = require('./database'); + +console.log('开始修复 expires_at 格式...\n'); + +// 查找所有有过期时间的分享 +const shares = db.prepare(` + SELECT id, share_code, expires_at + FROM shares + WHERE expires_at IS NOT NULL +`).all(); + +console.log(`找到 ${shares.length} 条需要修复的记录\n`); + +let fixed = 0; +const updateStmt = db.prepare('UPDATE shares SET expires_at = ? WHERE id = ?'); + +shares.forEach(share => { + const oldFormat = share.expires_at; + + // 如果是ISO格式(包含T和Z),需要转换 + if (oldFormat.includes('T') || oldFormat.includes('Z')) { + // 转换为 SQLite datetime 格式: YYYY-MM-DD HH:MM:SS + const newFormat = oldFormat.replace('T', ' ').replace(/\.\d+Z$/, ''); + + updateStmt.run(newFormat, share.id); + fixed++; + + console.log(`✓ 修复分享 ${share.share_code}:`); + console.log(` 旧格式: ${oldFormat}`); + console.log(` 新格式: ${newFormat}\n`); + } +}); + +console.log(`\n修复完成! 共修复 ${fixed} 条记录`);