|
@@ -32,7 +32,7 @@ class SendCount extends API {
|
|
|
await conn.beginTransaction()
|
|
await conn.beginTransaction()
|
|
|
|
|
|
|
|
const [senderRows] = await conn.execute(
|
|
const [senderRows] = await conn.execute(
|
|
|
- "SELECT id, username, lepao_count FROM users WHERE uuid = ?",
|
|
|
|
|
|
|
+ "SELECT id, username, lepao_count, COALESCE(send_count_auto_approve, 0) AS send_count_auto_approve FROM users WHERE uuid = ?",
|
|
|
[uuid]
|
|
[uuid]
|
|
|
)
|
|
)
|
|
|
if (!senderRows || senderRows.length !== 1) {
|
|
if (!senderRows || senderRows.length !== 1) {
|
|
@@ -62,9 +62,96 @@ class SendCount extends API {
|
|
|
return res.json({ ...BaseStdResponse.ERR, msg: "剩余乐跑次数不足,请购买后再赠送!" })
|
|
return res.json({ ...BaseStdResponse.ERR, msg: "剩余乐跑次数不足,请购买后再赠送!" })
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ const senderLepaoBefore = Number(senderRows[0].lepao_count || 0)
|
|
|
|
|
+ const autoApprove = Number(senderRows[0].send_count_auto_approve) === 1
|
|
|
|
|
+
|
|
|
|
|
+ if (autoApprove) {
|
|
|
|
|
+ const [recvRows] = await conn.execute(
|
|
|
|
|
+ "SELECT uuid, lepao_count FROM users WHERE id = ? FOR UPDATE",
|
|
|
|
|
+ [targetRows[0].id]
|
|
|
|
|
+ )
|
|
|
|
|
+ if (!recvRows || recvRows.length !== 1) {
|
|
|
|
|
+ await conn.rollback()
|
|
|
|
|
+ return res.json({ ...BaseStdResponse.ERR, msg: "未找到接收用户,请检查用户名是否正确!" })
|
|
|
|
|
+ }
|
|
|
|
|
+ const receiverUuid = recvRows[0].uuid
|
|
|
|
|
+ const beforeRecv = Number(recvRows[0].lepao_count || 0)
|
|
|
|
|
+
|
|
|
|
|
+ const [incResult] = await conn.execute(
|
|
|
|
|
+ "UPDATE users SET lepao_count = lepao_count + ? WHERE id = ?",
|
|
|
|
|
+ [count, targetRows[0].id]
|
|
|
|
|
+ )
|
|
|
|
|
+ if (!incResult || incResult.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, reviewed_at, reviewer_uuid)
|
|
|
|
|
+ VALUES (?, ?, ?, 'approved', NOW(), NOW(), NULL)`,
|
|
|
|
|
+ [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: senderLepaoBefore,
|
|
|
|
|
+ balanceAfter: senderLepaoBefore - count,
|
|
|
|
|
+ bizType: "gift_send_lock",
|
|
|
|
|
+ bizId: `send_request:${requestId}`,
|
|
|
|
|
+ remark: `向${username}赠送${count}次`
|
|
|
|
|
+ })
|
|
|
|
|
+ await insertLedgerRecord({
|
|
|
|
|
+ executor: conn,
|
|
|
|
|
+ userUuid: receiverUuid,
|
|
|
|
|
+ delta: count,
|
|
|
|
|
+ balanceBefore: beforeRecv,
|
|
|
|
|
+ balanceAfter: beforeRecv + count,
|
|
|
|
|
+ bizType: "gift_receive",
|
|
|
|
|
+ bizId: `send_request:${requestId}`,
|
|
|
|
|
+ operatorUuid: null,
|
|
|
|
|
+ remark: `${senderRows[0].username}赠送${count}次`
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ await conn.commit()
|
|
|
|
|
+ const reviewTime = new Date().getTime()
|
|
|
|
|
+
|
|
|
|
|
+ Promise.resolve().then(async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const infoSql = `
|
|
|
|
|
+ SELECT ru.email AS receiver_email, ru.username AS receiver_username
|
|
|
|
|
+ FROM users ru
|
|
|
|
|
+ WHERE ru.id = ?
|
|
|
|
|
+ `
|
|
|
|
|
+ const infoRows = await db.query(infoSql, [targetRows[0].id])
|
|
|
|
|
+ if (!infoRows || infoRows.length !== 1 || !infoRows[0].receiver_email) {
|
|
|
|
|
+ this.logger.warn(`[SendCountNotify][auto][requestId=${requestId}] 接收人邮箱为空,跳过通知`)
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+ await EmailTemplate.sendCountRequestApproved(infoRows[0].receiver_email, {
|
|
|
|
|
+ requestId,
|
|
|
|
|
+ senderUsername: senderRows[0].username,
|
|
|
|
|
+ count,
|
|
|
|
|
+ reviewTime
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (mailErr) {
|
|
|
|
|
+ this.logger.error(`[SendCountNotify][auto][requestId=${requestId}] 接收人通知发送失败:${mailErr.message || "未知错误"}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ return res.json({ ...BaseStdResponse.OK, msg: "赠送成功,对方已到账" })
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
const [insertResult] = await conn.execute(
|
|
const [insertResult] = await conn.execute(
|
|
|
- `INSERT INTO lepao_send_count_request
|
|
|
|
|
- (sender_uuid, receiver_user_id, count, status, created_at)
|
|
|
|
|
|
|
+ `INSERT INTO lepao_send_count_request
|
|
|
|
|
+ (sender_uuid, receiver_user_id, count, status, created_at)
|
|
|
VALUES (?, ?, ?, 'pending', NOW())`,
|
|
VALUES (?, ?, ?, 'pending', NOW())`,
|
|
|
[uuid, targetRows[0].id, count]
|
|
[uuid, targetRows[0].id, count]
|
|
|
)
|
|
)
|
|
@@ -78,9 +165,9 @@ class SendCount extends API {
|
|
|
executor: conn,
|
|
executor: conn,
|
|
|
userUuid: uuid,
|
|
userUuid: uuid,
|
|
|
delta: -count,
|
|
delta: -count,
|
|
|
- balanceBefore: Number(senderRows[0].lepao_count || 0),
|
|
|
|
|
- balanceAfter: Number(senderRows[0].lepao_count || 0) - count,
|
|
|
|
|
- bizType: 'gift_send_lock',
|
|
|
|
|
|
|
+ balanceBefore: senderLepaoBefore,
|
|
|
|
|
+ balanceAfter: senderLepaoBefore - count,
|
|
|
|
|
+ bizType: "gift_send_lock",
|
|
|
bizId: `send_request:${requestId}`,
|
|
bizId: `send_request:${requestId}`,
|
|
|
remark: `向${username}赠送${count}次`
|
|
remark: `向${username}赠送${count}次`
|
|
|
})
|
|
})
|
|
@@ -93,7 +180,7 @@ class SendCount extends API {
|
|
|
const adminSql = `
|
|
const adminSql = `
|
|
|
SELECT email
|
|
SELECT email
|
|
|
FROM users
|
|
FROM users
|
|
|
- WHERE email IS NOT NULL
|
|
|
|
|
|
|
+ WHERE email IS NOT NULL
|
|
|
AND email <> ''
|
|
AND email <> ''
|
|
|
AND (JSON_CONTAINS(permission, '"admin"') OR JSON_CONTAINS(permission, '"service"'))
|
|
AND (JSON_CONTAINS(permission, '"admin"') OR JSON_CONTAINS(permission, '"service"'))
|
|
|
`
|
|
`
|