Browse Source

✨ feat: 限制mcp单日解绑次数

Pchen0 1 week ago
parent
commit
6e9d62361d
1 changed files with 25 additions and 0 deletions
  1. 25 0
      lib/Lepao/WorkOrderMcp.js

+ 25 - 0
lib/Lepao/WorkOrderMcp.js

@@ -3,6 +3,7 @@ const path = require('path')
 const Logger = require('../Logger')
 const mq = require('../../plugin/mq')
 const { mq: mqName } = require('../../plugin/mq/mqPrefix')
+const Redis = require('../../plugin/DataBase/Redis')
 const EmailTemplate = require('../../plugin/Email/emailTemplate')
 
 class WorkOrderMcp {
@@ -43,6 +44,7 @@ class WorkOrderMcp {
 
         this.emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
         this.banEmailList = ['icloud.com']
+        this.dailyUnbindLimit = 5
     }
 
 
@@ -115,12 +117,30 @@ class WorkOrderMcp {
         return [(now >= feb1ThisYear && now < aug31ThisYear) ? feb1ThisYear.getTime() : new Date(now < feb1ThisYear ? year - 1 : year, 7, 31, 0, 0, 0, 0).getTime(), now.getTime() + 86400000]
       }
 
+    getDailyUnbindRedisKey(sender) {
+        const now = new Date()
+        const year = now.getFullYear()
+        const month = `${now.getMonth() + 1}`.padStart(2, '0')
+        const day = `${now.getDate()}`.padStart(2, '0')
+        return `mcp:unbind:daily:${sender}:${year}${month}${day}`
+    }
+
+    getSecondsToDayEnd() {
+        const now = new Date()
+        const tomorrow = new Date(now.getFullYear(), now.getMonth(), now.getDate() + 1, 0, 0, 0, 0)
+        return Math.max(1, Math.floor((tomorrow.getTime() - now.getTime()) / 1000))
+    }
+
     async unbind_account({ sender, student_num }) {
         try {
             if ([sender, student_num].some(value => value === '' || value === null || value === undefined))
                 return '缺少参数'
 
             this.logger.info(`工单MCP接收解绑账号请求:${sender}`)
+            const dailyUnbindKey = this.getDailyUnbindRedisKey(sender)
+            const dailyUnbindCount = Number(await Redis.get(dailyUnbindKey) || 0)
+            if (dailyUnbindCount >= this.dailyUnbindLimit) return '今日通过MCP解绑次数已超过限制,只能人工处理'
+
             let selectSql = `SELECT create_user, auto_run, update_time FROM lepao_account WHERE student_num = ? AND create_user IS NOT NULL`
             let selectRows = await db.query(selectSql, [student_num])
             if (!selectRows || selectRows.length === 0 || !selectRows[0]?.create_user) return '该账号未绑定,无需解绑'
@@ -131,6 +151,11 @@ class WorkOrderMcp {
             let updateRows = await db.query(updateSql, [Date.now(), student_num])
             if (!updateRows || updateRows.affectedRows !== 1)
                 return '系统出错,请稍后再试'
+
+            const latestUnbindCount = await Redis.incr(dailyUnbindKey)
+            if (latestUnbindCount === 1) {
+                await Redis.expire(dailyUnbindKey, this.getSecondsToDayEnd())
+            }
             return `解绑成功,您现在可绑定该账号`
         } catch (error) {
             this.logger.error(`工单MCP解绑账号出错:${error.stack}`)