Spaces:
Sleeping
Sleeping
File size: 3,823 Bytes
de995c4 | 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 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 | const crypto = require('crypto');
const { runQuery, getQuery, allQuery } = require('../database/database');
class ActivationCode {
// 生成批量激活码
static async generateCodes(count, days = 30) {
try {
const codes = [];
const insertPromises = [];
for (let i = 0; i < count; i++) {
const code = this.generateUniqueCode();
codes.push(code);
const insertPromise = runQuery(
`INSERT INTO activation_codes (code, days) VALUES (?, ?)`,
[code, days]
);
insertPromises.push(insertPromise);
}
await Promise.all(insertPromises);
return codes;
} catch (error) {
throw error;
}
}
// 生成唯一激活码
static generateUniqueCode() {
// 生成16位激活码,格式:XXXX-XXXX-XXXX-XXXX
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
let code = '';
for (let i = 0; i < 16; i++) {
if (i > 0 && i % 4 === 0) {
code += '-';
}
code += chars.charAt(Math.floor(Math.random() * chars.length));
}
return code;
}
// 验证激活码
static async validateCode(code) {
try {
const activationCode = await getQuery(
`SELECT * FROM activation_codes WHERE code = ? AND is_used = 0`,
[code]
);
if (!activationCode) {
throw new Error('激活码无效或已被使用');
}
return activationCode;
} catch (error) {
throw error;
}
}
// 使用激活码
static async useCode(code, userId) {
try {
// 验证激活码
const activationCode = await this.validateCode(code);
// 标记激活码为已使用
await runQuery(
`UPDATE activation_codes SET is_used = 1, used_by = ?, used_at = strftime('%s', 'now') WHERE code = ?`,
[userId, code]
);
return activationCode;
} catch (error) {
throw error;
}
}
// 获取所有激活码
static async getAllCodes(page = 1, pageSize = 50) {
try {
const offset = (page - 1) * pageSize;
const codes = await allQuery(
`SELECT ac.*, u.email as used_by_email
FROM activation_codes ac
LEFT JOIN users u ON ac.used_by = u.id
ORDER BY ac.created_at DESC
LIMIT ? OFFSET ?`,
[pageSize, offset]
);
const totalResult = await getQuery(
`SELECT COUNT(*) as total FROM activation_codes`
);
return {
codes,
total: totalResult.total,
page,
pageSize,
totalPages: Math.ceil(totalResult.total / pageSize)
};
} catch (error) {
throw error;
}
}
// 获取激活码统计
static async getStatistics() {
try {
const totalResult = await getQuery(
`SELECT COUNT(*) as total FROM activation_codes`
);
const usedResult = await getQuery(
`SELECT COUNT(*) as used FROM activation_codes WHERE is_used = 1`
);
const unusedResult = await getQuery(
`SELECT COUNT(*) as unused FROM activation_codes WHERE is_used = 0`
);
const todayResult = await getQuery(
`SELECT COUNT(*) as today FROM activation_codes
WHERE created_at > strftime('%s', 'now', '-1 day')`
);
return {
total: totalResult.total,
used: usedResult.used,
unused: unusedResult.unused,
todayGenerated: todayResult.today
};
} catch (error) {
throw error;
}
}
// 删除激活码
static async deleteCode(codeId) {
try {
const result = await runQuery(
`DELETE FROM activation_codes WHERE id = ? AND is_used = 0`,
[codeId]
);
return result.changes > 0;
} catch (error) {
throw error;
}
}
}
module.exports = ActivationCode;
|