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 RejectSendCountRequest extends API { constructor() { super() this.setPath("/Admin/Goods/SendCountRequest/Reject") this.setMethod("POST") } async onRequest(req, res) { let { uuid, session, id, reject_reason } = req.body id = Number(id) reject_reason = typeof reject_reason === "string" ? reject_reason.trim() : "" if ([uuid, session, id].some(value => value === "" || value === null || value === undefined || Number.isNaN(id))) return res.json({ ...BaseStdResponse.MISSING_PARAMETER }) if (!Number.isInteger(id) || id <= 0) return res.json({ ...BaseStdResponse.ERR, msg: "参数错误" }) if (reject_reason.length > 255) return res.json({ ...BaseStdResponse.ERR, msg: "拒绝原因过长,请控制在255字以内!" }) if (!await AccessControl.checkSession(uuid, session)) return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED }) let permission = await AccessControl.getPermission(uuid) if (!permission.includes("admin") && !permission.includes("service")) return res.json({ ...BaseStdResponse.PERMISSION_DENIED }) const conn = await db.connect() try { await conn.beginTransaction() const [requestRows] = await conn.execute( `SELECT id, sender_uuid, receiver_user_id, count, status FROM lepao_send_count_request WHERE id = ? FOR UPDATE`, [id] ) if (!requestRows || requestRows.length !== 1) { await conn.rollback() return res.json({ ...BaseStdResponse.MISSING_FILE, msg: "未找到赠送申请记录!" }) } const request = requestRows[0] if (request.status !== "pending") { await conn.rollback() return res.json({ ...BaseStdResponse.ERR, msg: "该申请已审核,请刷新后重试!" }) } const [senderRows] = await conn.execute( "SELECT lepao_count FROM users WHERE uuid = ? FOR UPDATE", [request.sender_uuid] ) if (!senderRows || senderRows.length !== 1) { await conn.rollback() return res.json({ ...BaseStdResponse.ERR, msg: "赠送人不存在,退回次数失败!" }) } const beforeCount = Number(senderRows[0].lepao_count || 0) const [refundResult] = await conn.execute( "UPDATE users SET lepao_count = lepao_count + ? WHERE uuid = ?", [request.count, request.sender_uuid] ) if (!refundResult || refundResult.affectedRows !== 1) { await conn.rollback() return res.json({ ...BaseStdResponse.ERR, msg: "赠送人不存在,退回次数失败!" }) } const [updateResult] = await conn.execute( `UPDATE lepao_send_count_request SET status = 'rejected', reviewer_uuid = ?, reviewed_at = NOW(), reject_reason = ? WHERE id = ?`, [uuid, reject_reason || null, id] ) if (!updateResult || updateResult.affectedRows !== 1) { await conn.rollback() return res.json({ ...BaseStdResponse.ERR, msg: "更新审核状态失败,请稍后再试!" }) } await insertLedgerRecord({ executor: conn, userUuid: request.sender_uuid, delta: Number(request.count || 0), balanceBefore: beforeCount, balanceAfter: beforeCount + Number(request.count || 0), bizType: 'gift_send_refund', bizId: `send_request:${id}`, operatorUuid: uuid, remark: reject_reason || '' }) await conn.commit() const requestId = request.id const reviewTime = new Date().getTime() // 非阻塞通知赠送人,不影响审核结果 Promise.resolve().then(async () => { try { const infoSql = ` SELECT su.email AS sender_email, su.username AS sender_username, ru.username AS receiver_username FROM users su LEFT JOIN users ru ON ru.id = ? WHERE su.uuid = ? ` const infoRows = await db.query(infoSql, [request.receiver_user_id, request.sender_uuid]) if (!infoRows || infoRows.length !== 1 || !infoRows[0].sender_email) { this.logger.warn(`[SendCountNotify][reject][requestId=${requestId}] 赠送人邮箱为空或用户不存在,跳过通知`) return } await EmailTemplate.sendCountRequestRejected(infoRows[0].sender_email, { requestId, receiverUsername: infoRows[0].receiver_username || "未知用户", count: request.count, reviewTime, rejectReason: reject_reason || "无" }) } catch (mailErr) { this.logger.error(`[SendCountNotify][reject][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 { conn.release() } } } module.exports.RejectSendCountRequest = RejectSendCountRequest