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;