| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- const API = require("../../lib/API")
- const db = require("../../plugin/DataBase/db")
- const AccessControl = require("../../lib/AccessControl")
- const { BaseStdResponse } = require("../../BaseStdResponse")
- const EmailTemplate = require("../../plugin/Email/emailTemplate")
- const { insertLedgerRecord } = require("../../lib/Lepao/CountLedger")
- class SendCount extends API {
- constructor() {
- super()
- this.setPath("/Goods/SendCount")
- this.setMethod("POST")
- }
- async onRequest(req, res) {
- let { uuid, session, username, count } = req.body
- username = typeof username === "string" ? username.trim() : username
- count = Number(count)
- if ([uuid, session, username, count].some(v => v == null || v === "" || Number.isNaN(count)))
- return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
- if (!Number.isInteger(count) || count < 1 || count > 9999)
- return res.json({ ...BaseStdResponse.ERR, msg: "超出赠送的次数范围,请重新选择赠送次数" })
- if (!(await AccessControl.checkSession(uuid, session)))
- return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
- const conn = await db.connect() // 这里直接拿 connection
- try {
- await conn.beginTransaction()
- const [senderRows] = await conn.execute(
- "SELECT id, username, lepao_count FROM users WHERE uuid = ?",
- [uuid]
- )
- if (!senderRows || senderRows.length !== 1) {
- await conn.rollback()
- return res.json({ ...BaseStdResponse.MISSING_FILE, msg: "获取用户信息失败!" })
- }
- const [targetRows] = await conn.execute(
- "SELECT id, uuid FROM users WHERE username = ?",
- [username]
- )
- if (!targetRows || targetRows.length !== 1) {
- await conn.rollback()
- return res.json({ ...BaseStdResponse.ERR, msg: "未找到接收用户,请检查用户名是否正确!" })
- }
- if (targetRows[0].uuid === uuid) {
- await conn.rollback()
- return res.json({ ...BaseStdResponse.ERR, msg: "不能给自己赠送次数!" })
- }
- const [decResult] = await conn.execute(
- "UPDATE users SET lepao_count = lepao_count - ? WHERE uuid = ? AND lepao_count >= ?",
- [count, uuid, count]
- )
- if (decResult.affectedRows !== 1) {
- await conn.rollback()
- return res.json({ ...BaseStdResponse.ERR, msg: "剩余乐跑次数不足,请购买后再赠送!" })
- }
- const [insertResult] = await conn.execute(
- `INSERT INTO lepao_send_count_request
- (sender_uuid, receiver_user_id, count, status, created_at)
- VALUES (?, ?, ?, 'pending', NOW())`,
- [uuid, targetRows[0].id, count]
- )
- if (!insertResult || insertResult.affectedRows !== 1) {
- await conn.rollback()
- return res.json({ ...BaseStdResponse.ERR, msg: "提交赠送审核失败,请稍后再试!" })
- }
- const requestId = insertResult.insertId
- await insertLedgerRecord({
- executor: conn,
- userUuid: uuid,
- delta: -count,
- balanceBefore: Number(senderRows[0].lepao_count || 0),
- balanceAfter: Number(senderRows[0].lepao_count || 0) - count,
- bizType: 'gift_send_lock',
- bizId: `send_request:${requestId}`,
- remark: `向${username}赠送${count}次`
- })
- await conn.commit()
- const createTime = new Date().getTime()
- // 非阻塞通知管理员,不影响主业务流程
- Promise.resolve().then(async () => {
- try {
- const adminSql = `
- SELECT email
- FROM users
- WHERE email IS NOT NULL
- AND email <> ''
- AND (JSON_CONTAINS(permission, '"admin"') OR JSON_CONTAINS(permission, '"service"'))
- `
- const adminRows = await db.query(adminSql)
- if (!adminRows || adminRows.length === 0) {
- this.logger.warn(`[SendCountNotify][submit][requestId=${requestId}] 未找到可通知的管理员邮箱`)
- return
- }
- const emails = [...new Set(adminRows.map(row => row.email).filter(Boolean))]
- for (const email of emails) {
- await EmailTemplate.sendCountRequestNotifyAdmins(email, {
- requestId,
- senderUsername: senderRows[0].username,
- receiverUsername: username,
- count,
- createTime
- })
- }
- } catch (mailErr) {
- this.logger.error(`[SendCountNotify][submit][requestId=${requestId}] 管理员通知发送失败:${mailErr.message || "未知错误"}`)
- }
- })
- return res.json({ ...BaseStdResponse.OK, msg: "已提交审核,审核通过后接收方将到账" })
- } catch (err) {
- try { await conn.rollback() } catch (_) { }
- this.logger.error(`赠送乐跑次数失败!${err.message || "未知错误"}`)
- return res.json({
- ...BaseStdResponse.ERR,
- msg: `赠送次数失败,请稍后再试!`
- })
- } finally {
- if (conn?.connection && typeof conn.connection.release === 'function' && typeof conn?.release === 'function') {
- conn.release()
- }
- }
- }
- }
- module.exports.SendCount = SendCount
|