// 用户相关API处理 const { getDatabase } = require('./sql'); const fs = require('fs'); const path = require('path'); const { promisify } = require('util'); const formidable = require('formidable'); const mkdir = promisify(fs.mkdir); const access = promisify(fs.access); // 获取用户点数 async function handleGetUserPoints(req, res) { const parsedUrl = require('url').parse(req.url, true); const { username } = parsedUrl.query; if (!username) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '缺少用户名参数' })); return; } try { const db = await getDatabase(); const points = db.getUserPoints(username); res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: true, points: points || 0 })); } catch (error) { console.error('[User] 获取用户点数失败:', error); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '获取点数失败: ' + error.message })); } } // 获取用户信息 async function handleGetUserInfo(req, res) { const parsedUrl = require('url').parse(req.url, true); const { username } = parsedUrl.query; if (!username) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '缺少用户名参数' })); return; } try { const db = await getDatabase(); const user = db.findUserByUsername(username); if (!user) { res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '用户不存在' })); return; } // 创建用户对象副本,不包含密码 const userInfo = { id: user.id, username: user.username, phone: user.phone, avatar: user.avatar, points: user.points || 0, created_at: user.created_at, updated_at: user.updated_at }; res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: true, user: userInfo })); } catch (error) { console.error('[User] 获取用户信息失败:', error); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '获取用户信息失败: ' + error.message })); } } // 更新用户信息 async function handleUpdateUser(req, res) { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', async () => { try { const data = JSON.parse(body); const { username, phone } = data; if (!username) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '缺少用户名参数' })); return; } const db = await getDatabase(); const user = db.findUserByUsername(username); if (!user) { res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '用户不存在' })); return; } // 更新手机号 if (phone) { db.updateUser(user.id, { phone: phone }); } res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: true, message: '更新成功' })); } catch (error) { console.error('[User] 更新用户信息失败:', error); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '更新失败: ' + error.message })); } }); } // 上传头像 async function handleUploadAvatar(req, res) { const form = formidable({ uploadDir: path.join(__dirname, 'temp'), keepExtensions: true, maxFileSize: 5 * 1024 * 1024 // 5MB }); form.parse(req, async (err, fields, files) => { if (err) { console.error('[User] 解析上传文件失败:', err); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '上传失败: ' + err.message })); return; } const username = Array.isArray(fields.username) ? fields.username[0] : fields.username; const file = Array.isArray(files.avatar) ? files.avatar[0] : files.avatar; if (!username || !file) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '缺少参数' })); return; } try { const db = await getDatabase(); const user = db.findUserByUsername(username); if (!user) { res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '用户不存在' })); return; } // 保存头像到用户目录 const usersDir = path.join(__dirname, 'users'); const userDir = path.join(usersDir, username.toLowerCase()); await mkdir(userDir, { recursive: true }); const avatarPath = path.join(userDir, 'avatar.png'); await fs.promises.copyFile(file.filepath, avatarPath); // 删除临时文件 await fs.promises.unlink(file.filepath); // 更新数据库 const avatarUrl = `/users/${username.toLowerCase()}/avatar.png`; db.updateUser(user.id, { avatar: avatarUrl }); res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: true, avatar: avatarUrl, message: '头像更新成功' })); } catch (error) { console.error('[User] 保存头像失败:', error); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '保存头像失败: ' + error.message })); } }); } // 获取AI生图历史 async function handleGetAIHistory(req, res) { const parsedUrl = require('url').parse(req.url, true); const { username } = parsedUrl.query; if (!username) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '缺少用户名参数' })); return; } try { const { getUserAIHistory } = require('./ai-queue'); const history = await getUserAIHistory(username); res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: true, history: history })); } catch (error) { console.error('[User] 获取AI历史失败:', error); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '获取历史失败: ' + error.message })); } } // 处理充值请求 async function handleRecharge(req, res) { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', async () => { try { const data = JSON.parse(body); const { username, points } = data; if (!username) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '缺少用户名参数' })); return; } if (!points || points <= 0) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '充值点数必须大于0' })); return; } const db = await getDatabase(); const user = db.findUserByUsername(username); if (!user) { res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '用户不存在' })); return; } // 增加用户点数 db.addPoints(username, points); // 获取更新后的点数 const newPoints = db.getUserPoints(username); res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: true, message: '充值成功', points: newPoints })); } catch (error) { console.error('[User] 充值失败:', error); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '充值失败: ' + error.message })); } }); } // 扣除用户点数 async function handleDeductUserPoints(req, res) { let body = ''; req.on('data', chunk => { body += chunk.toString(); }); req.on('end', async () => { try { const data = JSON.parse(body); const { username, points } = data; if (!username) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '缺少用户名参数' })); return; } if (!points || points <= 0) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '扣除点数必须大于0' })); return; } const db = await getDatabase(); const user = db.findUserByUsername(username); if (!user) { res.writeHead(404, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '用户不存在' })); return; } // 检查点数是否足够 const currentPoints = db.getUserPoints(username); if (currentPoints < points) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '点数不足' })); return; } // 扣除用户点数 const deducted = db.deductPoints(username, points); if (!deducted) { res.writeHead(400, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '扣除点数失败' })); return; } // 获取更新后的点数 const newPoints = db.getUserPoints(username); res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: true, message: '扣除点数成功', points: newPoints })); } catch (error) { console.error('[User] 扣除点数失败:', error); res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' }); res.end(JSON.stringify({ success: false, message: '扣除点数失败: ' + error.message })); } }); } module.exports = { handleGetUserPoints, handleGetUserInfo, handleDeductUserPoints, handleUpdateUser, handleUploadAvatar, handleGetAIHistory, handleRecharge };