|
@@ -0,0 +1,106 @@
|
|
|
|
|
+const API = require("../../lib/API.js")
|
|
|
|
|
+const db = require('../../plugin/DataBase/db.js')
|
|
|
|
|
+const axios = require("axios")
|
|
|
|
|
+const EmailTemplate = require('../../plugin/Email/emailTemplate')
|
|
|
|
|
+const { BaseStdResponse } = require("../../BaseStdResponse.js")
|
|
|
|
|
+
|
|
|
|
|
+class StartPowerCheck extends API {
|
|
|
|
|
+ constructor() {
|
|
|
|
|
+ super()
|
|
|
|
|
+ this.noEncrypt()
|
|
|
|
|
+ this.setPath('/Corn/StartPowerCheck')
|
|
|
|
|
+ this.setMethod('GET')
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ async onRequest(req, res) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ res.json({ ...BaseStdResponse.OK })
|
|
|
|
|
+
|
|
|
|
|
+ this.logger.info('开始执行电费提醒任务')
|
|
|
|
|
+
|
|
|
|
|
+ const sql = 'SELECT id, email, balance, lowest, area, building, room, is_notice FROM power_task'
|
|
|
|
|
+ const tasks = await db.query(sql)
|
|
|
|
|
+
|
|
|
|
|
+ if (!tasks) {
|
|
|
|
|
+ this.logger.error('获取电费提醒任务失败!')
|
|
|
|
|
+ return
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for (const item of tasks) {
|
|
|
|
|
+ const { id, email, balance, lowest, area, building, room, is_notice } = item
|
|
|
|
|
+ this.logger.info(`${building}-${room} 开始电费查询余额`)
|
|
|
|
|
+
|
|
|
|
|
+ try {
|
|
|
|
|
+ const endpoint = `https://hqpay.ctbu.edu.cn/weixin/ashx/frmuser.ashx?test=lastlist&pid=${room}&dyid=${building}`
|
|
|
|
|
+ const response = await axios.get(endpoint, { proxy: false, timeout: 8000 })
|
|
|
|
|
+
|
|
|
|
|
+ if (!response || !response.data || !response.data[0]) {
|
|
|
|
|
+ this.logger.error('获取电费信息失败!返回数据:' + (response && response.data ? JSON.stringify(response.data) : 'no-response'))
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const now_balance_raw = response.data[0][1]
|
|
|
|
|
+ const now_change_time = response.data[0][2]
|
|
|
|
|
+
|
|
|
|
|
+ this.logger.info(`${building}-${room} 电费余额:${now_balance_raw},扣费时间:${now_change_time}`)
|
|
|
|
|
+ const time = Date.now()
|
|
|
|
|
+
|
|
|
|
|
+ const nowBalanceNum = parseFloat(String(now_balance_raw).replace(/[^0-9.-]/g, ''))
|
|
|
|
|
+ const balanceNum = parseFloat(String(balance).replace(/[^0-9.-]/g, '')) || 0
|
|
|
|
|
+ const lowestNum = parseFloat(String(lowest).replace(/[^0-9.-]/g, '')) || 0
|
|
|
|
|
+
|
|
|
|
|
+ if (Number.isNaN(nowBalanceNum)) {
|
|
|
|
|
+ this.logger.error(`${building}-${room}:解析当前余额失败,原值:${now_balance_raw}`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 如果余额未变,跳过当前任务
|
|
|
|
|
+ if (nowBalanceNum === balanceNum) {
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 记录变更并更新任务表余额
|
|
|
|
|
+ const insertSql = 'INSERT INTO power_chang_record (time, balance, old_balance, change_time, task_id) VALUES (?, ?, ?, ?, ?)'
|
|
|
|
|
+ const insertRows = await db.query(insertSql, [time, nowBalanceNum, balanceNum, now_change_time, id])
|
|
|
|
|
+
|
|
|
|
|
+ const updateSql = 'UPDATE power_task SET update_time = ?, balance = ?, koufei_date = ? WHERE id = ?'
|
|
|
|
|
+ const updateRows = await db.query(updateSql, [time, nowBalanceNum, now_change_time, id])
|
|
|
|
|
+
|
|
|
|
|
+ if (!insertRows || insertRows.affectedRows !== 1 || !updateRows || updateRows.affectedRows !== 1) {
|
|
|
|
|
+ this.logger.error(`${building}-${room}:更新电费信息失败! 数据库错误`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 余额低于阈值且尚未通知 -> 发邮件并置 is_notice = 1
|
|
|
|
|
+ if (nowBalanceNum < balanceNum && nowBalanceNum <= lowestNum && Number(is_notice) === 0) {
|
|
|
|
|
+ const data = { now_balance: nowBalanceNum, now_change_time, lowest: lowestNum, area, building, room }
|
|
|
|
|
+ try {
|
|
|
|
|
+ await EmailTemplate.powerCheck(email, data)
|
|
|
|
|
+ const upd = await db.query('UPDATE power_task SET is_notice = 1 WHERE id = ?', [id])
|
|
|
|
|
+ if (!upd || upd.affectedRows !== 1) {
|
|
|
|
|
+ this.logger.error(`${building}-${room}:更新 is_notice=1 失败`)
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ this.logger.error(`${building}-${room}:发送邮件失败:${err.stack || err}`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 充值后恢复未提醒状态
|
|
|
|
|
+ if (nowBalanceNum > balanceNum && nowBalanceNum > lowestNum) {
|
|
|
|
|
+ const upd = await db.query('UPDATE power_task SET is_notice = 0 WHERE id = ?', [id])
|
|
|
|
|
+ if (!upd || upd.affectedRows !== 1) {
|
|
|
|
|
+ this.logger.error(`${building}-${room}:更新 is_notice=0 失败`)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ this.logger.error(`获取电费信息失败!${error.stack || error}`)
|
|
|
|
|
+ continue
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ this.logger.error(error)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+module.exports.StartPowerCheck = StartPowerCheck
|