| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- // SQLite 数据库操作模块
- const Database = require('better-sqlite3');
- const path = require('path');
- const fs = require('fs');
- const { promisify } = require('util');
- const mkdir = promisify(fs.mkdir);
- const access = promisify(fs.access);
- class DatabaseManager {
- constructor() {
- this.dbPath = path.join(__dirname, 'data.db');
- this.db = null;
- }
- // 初始化数据库连接
- async init() {
- try {
- this.db = new Database(this.dbPath);
- console.log('[SQL] 数据库连接成功');
- this.createTables();
- } catch (err) {
- console.error('[SQL] 数据库连接失败:', err);
- throw err;
- }
- }
- // 创建表
- createTables() {
- try {
- const createUsersTable = `
- CREATE TABLE IF NOT EXISTS users (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- username TEXT UNIQUE NOT NULL,
- phone TEXT UNIQUE NOT NULL,
- password TEXT NOT NULL,
- avatar TEXT,
- points INTEGER DEFAULT 0,
- created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
- updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
- )
- `;
-
- // 如果表已存在但没有 points 字段,添加该字段
- try {
- this.db.exec('ALTER TABLE users ADD COLUMN points INTEGER DEFAULT 0');
- console.log('[SQL] 已添加 points 字段到 users 表');
- } catch (err) {
- // 字段已存在,忽略错误
- }
- this.db.exec(createUsersTable);
- console.log('[SQL] users表已创建或已存在');
- } catch (err) {
- console.error('[SQL] 创建表失败:', err);
- throw err;
- }
- }
- // 根据用户名查找用户(不区分大小写)
- findUserByUsername(username) {
- // 将输入转换为小写进行查询,但返回原始数据
- const normalizedUsername = username.toLowerCase();
- const sql = 'SELECT * FROM users WHERE LOWER(username) = ?';
- return this.db.prepare(sql).get(normalizedUsername) || null;
- }
- // 根据手机号查找用户
- findUserByPhone(phone) {
- const sql = 'SELECT * FROM users WHERE phone = ?';
- return this.db.prepare(sql).get(phone) || null;
- }
- // 根据ID查找用户
- findUserById(id) {
- const sql = 'SELECT * FROM users WHERE id = ?';
- return this.db.prepare(sql).get(id) || null;
- }
- // 获取所有用户
- getAllUsers() {
- const sql = 'SELECT id, username, phone, points, avatar, created_at, updated_at FROM users ORDER BY id DESC';
- return this.db.prepare(sql).all() || [];
- }
- // 创建新用户
- createUser(userData) {
- const { username, phone, password, avatar, points } = userData;
- const sql = `
- INSERT INTO users (username, phone, password, avatar, points)
- VALUES (?, ?, ?, ?, ?)
- `;
- const stmt = this.db.prepare(sql);
- const result = stmt.run(username, phone, password, avatar || null, points || 0);
- return { id: result.lastInsertRowid, ...userData };
- }
-
- // 获取用户点数
- getUserPoints(username) {
- const normalizedUsername = username.toLowerCase();
- const sql = 'SELECT points FROM users WHERE LOWER(username) = ?';
- const result = this.db.prepare(sql).get(normalizedUsername);
- return result ? result.points : 0;
- }
-
- // 扣除用户点数
- deductPoints(username, points) {
- const normalizedUsername = username.toLowerCase();
- const sql = 'UPDATE users SET points = points - ?, updated_at = CURRENT_TIMESTAMP WHERE LOWER(username) = ? AND points >= ?';
- const stmt = this.db.prepare(sql);
- const result = stmt.run(points, normalizedUsername, points);
- return result.changes > 0;
- }
-
- // 增加用户点数
- addPoints(username, points) {
- const normalizedUsername = username.toLowerCase();
- const sql = 'UPDATE users SET points = points + ?, updated_at = CURRENT_TIMESTAMP WHERE LOWER(username) = ?';
- const stmt = this.db.prepare(sql);
- const result = stmt.run(points, normalizedUsername);
- return result.changes > 0;
- }
- // 更新用户信息
- updateUser(id, updates) {
- const fields = [];
- const values = [];
-
- if (updates.username !== undefined) {
- fields.push('username = ?');
- values.push(updates.username);
- }
- if (updates.phone !== undefined) {
- fields.push('phone = ?');
- values.push(updates.phone);
- }
- if (updates.password !== undefined) {
- fields.push('password = ?');
- values.push(updates.password);
- }
- if (updates.avatar !== undefined) {
- fields.push('avatar = ?');
- values.push(updates.avatar);
- }
-
- fields.push('updated_at = CURRENT_TIMESTAMP');
- values.push(id);
- const sql = `UPDATE users SET ${fields.join(', ')} WHERE id = ?`;
- const stmt = this.db.prepare(sql);
- const result = stmt.run(...values);
- return { changes: result.changes };
- }
- // ============ AI 历史记录操作(保存到用户目录) ============
-
- // 获取用户历史文件路径
- _getHistoryFilePath(username) {
- const userDir = path.join(__dirname, 'users', username.toLowerCase(), 'generate-history');
- if (!fs.existsSync(userDir)) {
- fs.mkdirSync(userDir, { recursive: true });
- }
- return path.join(userDir, 'history.json');
- }
-
- // 加载用户历史
- _loadUserHistory(username) {
- const filePath = this._getHistoryFilePath(username);
- try {
- if (fs.existsSync(filePath)) {
- return JSON.parse(fs.readFileSync(filePath, 'utf-8'));
- }
- } catch (err) {
- console.error('[SQL] 加载用户历史失败:', err);
- }
- return [];
- }
-
- // 保存用户历史
- _saveUserHistory(username, history) {
- const filePath = this._getHistoryFilePath(username);
- try {
- fs.writeFileSync(filePath, JSON.stringify(history, null, 2), 'utf-8');
- } catch (err) {
- console.error('[SQL] 保存用户历史失败:', err);
- }
- }
-
- // 添加 AI 历史记录
- addAIHistory(taskId, username, status, previewUrl, retryData = null, createdAt = null) {
- const history = this._loadUserHistory(username);
- const timestamp = createdAt || new Date().toISOString();
-
- history.unshift({
- id: taskId,
- status: status,
- imageUrl: null,
- previewUrl: previewUrl,
- error: null,
- isRetry: false,
- retryData: retryData,
- createdAt: timestamp,
- completedAt: null
- });
-
- this._saveUserHistory(username, history);
- return history.length;
- }
-
- // 获取用户 AI 历史记录
- getAIHistory(username) {
- return this._loadUserHistory(username);
- }
-
- // 更新 AI 任务状态
- updateAITaskStatus(taskId, status, imageUrl = null, error = null) {
- // 需要找到任务所属用户
- const usersDir = path.join(__dirname, 'users');
- if (!fs.existsSync(usersDir)) return false;
-
- const users = fs.readdirSync(usersDir);
- for (const username of users) {
- const history = this._loadUserHistory(username);
- const task = history.find(t => t.id === taskId);
- if (task) {
- task.status = status;
- if (imageUrl) task.imageUrl = imageUrl;
- if (error) task.error = error;
- task.completedAt = new Date().toISOString();
- this._saveUserHistory(username, history);
- return true;
- }
- }
- return false;
- }
-
- // 获取 AI 任务
- getAITask(taskId) {
- const usersDir = path.join(__dirname, 'users');
- if (!fs.existsSync(usersDir)) return null;
-
- const users = fs.readdirSync(usersDir);
- for (const username of users) {
- const history = this._loadUserHistory(username);
- const task = history.find(t => t.id === taskId);
- if (task) {
- return { ...task, username };
- }
- }
- return null;
- }
-
- // 删除 AI 任务
- deleteAITask(taskId) {
- const usersDir = path.join(__dirname, 'users');
- if (!fs.existsSync(usersDir)) return false;
-
- const users = fs.readdirSync(usersDir);
- for (const username of users) {
- const history = this._loadUserHistory(username);
- const index = history.findIndex(t => t.id === taskId);
- if (index !== -1) {
- history.splice(index, 1);
- this._saveUserHistory(username, history);
- return true;
- }
- }
- return false;
- }
-
- // 更新 AI 任务重试数据
- updateAITaskRetryData(taskId, retryData) {
- const usersDir = path.join(__dirname, 'users');
- if (!fs.existsSync(usersDir)) return false;
-
- const users = fs.readdirSync(usersDir);
- for (const username of users) {
- const history = this._loadUserHistory(username);
- const task = history.find(t => t.id === taskId);
- if (task) {
- task.retryData = retryData;
- this._saveUserHistory(username, history);
- return true;
- }
- }
- return false;
- }
- // 关闭数据库连接
- close() {
- if (this.db) {
- this.db.close();
- console.log('[SQL] 数据库连接已关闭');
- }
- }
- }
- // 创建单例
- let dbInstance = null;
- async function getDatabase() {
- if (!dbInstance) {
- dbInstance = new DatabaseManager();
- await dbInstance.init();
- }
- return dbInstance;
- }
- module.exports = {
- Database: DatabaseManager,
- getDatabase
- };
|