feat(quota): add downloadable traffic quota with local/OSS/share metering

This commit is contained in:
2026-02-17 16:52:26 +08:00
parent b0e89df5c4
commit 2629237f9e
5 changed files with 750 additions and 84 deletions

View File

@@ -528,7 +528,9 @@ const UserDB = {
'is_verified': 'number',
'local_storage_quota': 'number',
'local_storage_used': 'number',
'oss_storage_quota': 'number'
'oss_storage_quota': 'number',
'download_traffic_quota': 'number',
'download_traffic_used': 'number'
};
const expectedType = FIELD_TYPES[fieldName];
@@ -589,6 +591,8 @@ const UserDB = {
'local_storage_quota': 'local_storage_quota',
'local_storage_used': 'local_storage_used',
'oss_storage_quota': 'oss_storage_quota',
'download_traffic_quota': 'download_traffic_quota',
'download_traffic_used': 'download_traffic_used',
// 偏好设置
'theme_preference': 'theme_preference'
@@ -670,6 +674,8 @@ const UserDB = {
'local_storage_quota': 'local_storage_quota',
'local_storage_used': 'local_storage_used',
'oss_storage_quota': 'oss_storage_quota',
'download_traffic_quota': 'download_traffic_quota',
'download_traffic_used': 'download_traffic_used',
// 偏好设置
'theme_preference': 'theme_preference'
@@ -723,7 +729,8 @@ const UserDB = {
'is_admin': 'number', 'is_active': 'number', 'is_banned': 'number',
'has_oss_config': 'number', 'is_verified': 'number',
'local_storage_quota': 'number', 'local_storage_used': 'number',
'oss_storage_quota': 'number'
'oss_storage_quota': 'number', 'download_traffic_quota': 'number',
'download_traffic_used': 'number'
}[key];
console.warn(`[类型检查] 字段 ${key} 值类型不符: 期望 ${expectedType}, 实际 ${typeof value}, 值: ${JSON.stringify(value)}`);
@@ -1285,6 +1292,60 @@ function migrateOssQuotaField() {
}
}
// 数据库迁移 - 下载流量配额字段
function migrateDownloadTrafficFields() {
try {
const columns = db.prepare("PRAGMA table_info(users)").all();
const hasDownloadTrafficQuota = columns.some(col => col.name === 'download_traffic_quota');
const hasDownloadTrafficUsed = columns.some(col => col.name === 'download_traffic_used');
if (!hasDownloadTrafficQuota) {
console.log('[数据库迁移] 添加 download_traffic_quota 字段...');
db.exec('ALTER TABLE users ADD COLUMN download_traffic_quota INTEGER DEFAULT 0');
console.log('[数据库迁移] ✓ download_traffic_quota 字段已添加');
}
if (!hasDownloadTrafficUsed) {
console.log('[数据库迁移] 添加 download_traffic_used 字段...');
db.exec('ALTER TABLE users ADD COLUMN download_traffic_used INTEGER DEFAULT 0');
console.log('[数据库迁移] ✓ download_traffic_used 字段已添加');
}
// 统一策略download_traffic_quota <= 0 表示不限流量
const quotaBackfillResult = db.prepare(`
UPDATE users
SET download_traffic_quota = 0
WHERE download_traffic_quota IS NULL OR download_traffic_quota < 0
`).run();
if (quotaBackfillResult.changes > 0) {
console.log(`[数据库迁移] ✓ 下载流量配额默认值已回填: ${quotaBackfillResult.changes} 条记录`);
}
const usedBackfillResult = db.prepare(`
UPDATE users
SET download_traffic_used = 0
WHERE download_traffic_used IS NULL OR download_traffic_used < 0
`).run();
if (usedBackfillResult.changes > 0) {
console.log(`[数据库迁移] ✓ 下载流量已用值已回填: ${usedBackfillResult.changes} 条记录`);
}
const usedCapResult = db.prepare(`
UPDATE users
SET download_traffic_used = download_traffic_quota
WHERE download_traffic_quota > 0 AND download_traffic_used > download_traffic_quota
`).run();
if (usedCapResult.changes > 0) {
console.log(`[数据库迁移] ✓ 下载流量已用值已按配额校准: ${usedCapResult.changes} 条记录`);
}
} catch (error) {
console.error('[数据库迁移] 下载流量字段迁移失败:', error);
}
}
// 系统日志操作
const SystemLogDB = {
// 日志级别常量
@@ -1471,6 +1532,7 @@ migrateToV2(); // 执行数据库迁移
migrateThemePreference(); // 主题偏好迁移
migrateToOss(); // SFTP → OSS 迁移
migrateOssQuotaField(); // OSS 配额字段迁移
migrateDownloadTrafficFields(); // 下载流量字段迁移
module.exports = {
db,