Browse Source

✨ feat: 增加电费、趣选书管理

Pchen. 4 days ago
parent
commit
08d7adc7e4

+ 42 - 0
apis/Power/Admin/GetChangeRecord.js

@@ -0,0 +1,42 @@
+const API = require("../../../lib/API.js")
+const db = require("../../../plugin/DataBase/db.js")
+const { BaseStdResponse } = require("../../../BaseStdResponse.js")
+const AccessControl = require("../../../lib/AccessControl.js")
+
+class AdminPowerGetChangeRecord extends API {
+    constructor() {
+        super()
+        this.setPath('/Admin/Power/Task/GetChangeRecord')
+        this.setMethod('GET')
+    }
+
+    async onRequest(req, res) {
+        let { uuid, session, id } = req.query
+
+        if ([uuid, session, id].some(v => v === '' || v === null || v === undefined))
+            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
+
+        if (!await AccessControl.checkSession(uuid, session))
+            return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
+
+        const permission = await AccessControl.getPermission(uuid)
+        if (!permission.includes('admin') && !permission.includes('server') && !permission.includes('service'))
+            return res.json({ ...BaseStdResponse.PERMISSION_DENIED })
+
+        const sql = `
+            SELECT *
+            FROM power_change_record
+            WHERE task_id = ?
+            ORDER BY id DESC
+        `
+        const rows = await db.query(sql, [id])
+        if (!rows) return res.json({ ...BaseStdResponse.DATABASE_ERR })
+
+        return res.json({
+            ...BaseStdResponse.OK,
+            data: rows
+        })
+    }
+}
+
+module.exports.AdminPowerGetChangeRecord = AdminPowerGetChangeRecord

+ 129 - 0
apis/Power/Admin/List.js

@@ -0,0 +1,129 @@
+const API = require("../../../lib/API.js")
+const db = require("../../../plugin/DataBase/db.js")
+const { BaseStdResponse } = require("../../../BaseStdResponse.js")
+const AccessControl = require("../../../lib/AccessControl.js")
+
+class AdminPowerTaskList extends API {
+    constructor() {
+        super()
+        this.setPath('/Admin/Power/Task/List')
+        this.setMethod('GET')
+    }
+
+    async onRequest(req, res) {
+        let {
+            uuid,
+            session,
+            create_user,
+            username,
+            email,
+            area,
+            building,
+            room,
+            queryTime,
+            pagesize,
+            current
+        } = req.query
+
+        if ([uuid, session, pagesize, current].some(v => v === '' || v === null || v === undefined))
+            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
+        if (isNaN(pagesize) || Number(pagesize) <= 0 || isNaN(current) || Number(current) <= 0)
+            return res.json({ ...BaseStdResponse.ERR, msg: '参数错误' })
+
+        if (!await AccessControl.checkSession(uuid, session))
+            return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
+
+        const permission = await AccessControl.getPermission(uuid)
+        if (!permission.includes('admin') && !permission.includes('server') && !permission.includes('service'))
+            return res.json({ ...BaseStdResponse.PERMISSION_DENIED })
+
+        const offset = (Number(current) - 1) * Number(pagesize)
+        const where = ['1 = 1']
+        const params = []
+        const countParams = []
+
+        if (create_user) {
+            where.push('pt.create_user COLLATE utf8mb4_general_ci = (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(create_user)
+            countParams.push(create_user)
+        }
+        if (username) {
+            where.push('u.username COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${username}%`)
+            countParams.push(`%${username}%`)
+        }
+        if (email) {
+            where.push('pt.email COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${email}%`)
+            countParams.push(`%${email}%`)
+        }
+        if (area) {
+            where.push('pt.area COLLATE utf8mb4_general_ci = (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(area)
+            countParams.push(area)
+        }
+        if (building) {
+            where.push('pt.building COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${building}%`)
+            countParams.push(`%${building}%`)
+        }
+        if (room) {
+            where.push('pt.room COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${room}%`)
+            countParams.push(`%${room}%`)
+        }
+        if (Array.isArray(queryTime) && queryTime.length === 2) {
+            where.push('pt.update_time >= ? AND pt.update_time < ?')
+            params.push(queryTime[0], queryTime[1])
+            countParams.push(queryTime[0], queryTime[1])
+        }
+
+        const whereSql = where.join(' AND ')
+        const listSql = `
+            SELECT
+                pt.id,
+                pt.create_user,
+                pt.create_time,
+                pt.update_time,
+                pt.area,
+                pt.building,
+                pt.room,
+                pt.email,
+                pt.lowest,
+                pt.notes,
+                pt.balance,
+                pt.koufei_date,
+                pt.is_notice,
+                u.username,
+                u.avatar
+            FROM power_task pt
+            LEFT JOIN users u ON u.uuid COLLATE utf8mb4_general_ci = pt.create_user COLLATE utf8mb4_general_ci
+            WHERE ${whereSql}
+            ORDER BY pt.id DESC
+            LIMIT ? OFFSET ?
+        `
+        const countSql = `
+            SELECT COUNT(*) AS total
+            FROM power_task pt
+            LEFT JOIN users u ON u.uuid COLLATE utf8mb4_general_ci = pt.create_user COLLATE utf8mb4_general_ci
+            WHERE ${whereSql}
+        `
+        params.push(String(pagesize), String(offset))
+
+        const rows = await db.query(listSql, params)
+        const countRows = await db.query(countSql, countParams)
+        if (!rows || !countRows) return res.json({ ...BaseStdResponse.DATABASE_ERR })
+
+        return res.json({
+            ...BaseStdResponse.OK,
+            data: rows,
+            pagination: {
+                current: Number(current),
+                pagesize: Number(pagesize),
+                total: countRows[0]?.total || 0
+            }
+        })
+    }
+}
+
+module.exports.AdminPowerTaskList = AdminPowerTaskList

+ 72 - 0
apis/QuXuanShu/Admin/Detail.js

@@ -0,0 +1,72 @@
+const API = require("../../../lib/API.js")
+const db = require("../../../plugin/DataBase/db.js")
+const { BaseStdResponse } = require("../../../BaseStdResponse.js")
+const AccessControl = require("../../../lib/AccessControl.js")
+
+function parseBookList(value) {
+    if (value === null || value === undefined || value === '') return []
+    if (Array.isArray(value)) return value
+    try {
+        const parsed = JSON.parse(value)
+        return Array.isArray(parsed) ? parsed : []
+    } catch {
+        return []
+    }
+}
+
+function extractClassName(bookList) {
+    if (!Array.isArray(bookList) || bookList.length === 0) return ''
+    const book = bookList.find(b => b && b.className)
+    return book?.className ?? ''
+}
+
+class AdminQxsAccountDetail extends API {
+    constructor() {
+        super()
+        this.setPath('/Admin/QXS/Account/Detail')
+        this.setMethod('GET')
+    }
+
+    async onRequest(req, res) {
+        let { uuid, session, id } = req.query
+
+        if ([uuid, session, id].some(v => v === '' || v === null || v === undefined))
+            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
+
+        if (!await AccessControl.checkSession(uuid, session))
+            return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
+
+        const permission = await AccessControl.getPermission(uuid)
+        if (!permission.includes('admin') && !permission.includes('server') && !permission.includes('service'))
+            return res.json({ ...BaseStdResponse.PERMISSION_DENIED })
+
+        const sql = `
+            SELECT id, username, create_time, realname, email, mobile, termName, book_list
+            FROM qsx_account
+            WHERE id = ?
+            LIMIT 1
+        `
+        const rows = await db.query(sql, [id])
+        if (!rows) return res.json({ ...BaseStdResponse.DATABASE_ERR })
+        if (!rows.length) return res.json({ ...BaseStdResponse.ERR, msg: '记录不存在' })
+
+        const row = rows[0]
+        const bookList = parseBookList(row.book_list)
+        return res.json({
+            ...BaseStdResponse.OK,
+            data: {
+                id: row.id,
+                username: row.username,
+                create_time: row.create_time,
+                realname: row.realname,
+                email: row.email,
+                mobile: row.mobile,
+                termName: row.termName,
+                className: extractClassName(bookList),
+                bookList
+            }
+        })
+    }
+}
+
+module.exports.AdminQxsAccountDetail = AdminQxsAccountDetail

+ 148 - 0
apis/QuXuanShu/Admin/List.js

@@ -0,0 +1,148 @@
+const API = require("../../../lib/API.js")
+const db = require("../../../plugin/DataBase/db.js")
+const { BaseStdResponse } = require("../../../BaseStdResponse.js")
+const AccessControl = require("../../../lib/AccessControl.js")
+
+function parseBookList(value) {
+    if (value === null || value === undefined || value === '') return []
+    if (Array.isArray(value)) return value
+    try {
+        const parsed = JSON.parse(value)
+        return Array.isArray(parsed) ? parsed : []
+    } catch {
+        return []
+    }
+}
+
+function extractClassName(bookList) {
+    if (!Array.isArray(bookList) || bookList.length === 0) return ''
+    const book = bookList.find(b => b && b.className)
+    return book?.className ?? ''
+}
+
+class AdminQxsAccountList extends API {
+    constructor() {
+        super()
+        this.setPath('/Admin/QXS/Account/List')
+        this.setMethod('GET')
+    }
+
+    async onRequest(req, res) {
+        let {
+            uuid,
+            session,
+            username,
+            realname,
+            email,
+            mobile,
+            termName,
+            className,
+            queryTime,
+            pagesize,
+            current
+        } = req.query
+
+        if ([uuid, session, pagesize, current].some(v => v === '' || v === null || v === undefined))
+            return res.json({ ...BaseStdResponse.MISSING_PARAMETER })
+        if (isNaN(pagesize) || Number(pagesize) <= 0 || isNaN(current) || Number(current) <= 0)
+            return res.json({ ...BaseStdResponse.ERR, msg: '参数错误' })
+
+        if (!await AccessControl.checkSession(uuid, session))
+            return res.status(401).json({ ...BaseStdResponse.ACCESS_DENIED })
+
+        const permission = await AccessControl.getPermission(uuid)
+        if (!permission.includes('admin') && !permission.includes('server') && !permission.includes('service'))
+            return res.json({ ...BaseStdResponse.PERMISSION_DENIED })
+
+        const offset = (Number(current) - 1) * Number(pagesize)
+        const where = ['1 = 1']
+        const params = []
+        const countParams = []
+
+        if (username) {
+            where.push('qa.username COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${username}%`)
+            countParams.push(`%${username}%`)
+        }
+        if (realname) {
+            where.push('qa.realname COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${realname}%`)
+            countParams.push(`%${realname}%`)
+        }
+        if (email) {
+            where.push('qa.email COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${email}%`)
+            countParams.push(`%${email}%`)
+        }
+        if (mobile) {
+            where.push('qa.mobile COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${mobile}%`)
+            countParams.push(`%${mobile}%`)
+        }
+        if (termName) {
+            where.push('qa.termName COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%${termName}%`)
+            countParams.push(`%${termName}%`)
+        }
+        if (className) {
+            where.push('qa.book_list COLLATE utf8mb4_general_ci LIKE (CONVERT(? USING utf8mb4) COLLATE utf8mb4_general_ci)')
+            params.push(`%"className"%${className}%`)
+            countParams.push(`%"className"%${className}%`)
+        }
+        if (Array.isArray(queryTime) && queryTime.length === 2) {
+            where.push('qa.create_time >= ? AND qa.create_time < ?')
+            params.push(queryTime[0], queryTime[1])
+            countParams.push(queryTime[0], queryTime[1])
+        }
+
+        const whereSql = where.join(' AND ')
+        const listSql = `
+            SELECT
+                qa.id,
+                qa.username,
+                qa.create_time,
+                qa.realname,
+                qa.email,
+                qa.mobile,
+                qa.termName,
+                qa.book_list
+            FROM qsx_account qa
+            WHERE ${whereSql}
+            ORDER BY qa.id DESC
+            LIMIT ? OFFSET ?
+        `
+        const countSql = `SELECT COUNT(*) AS total FROM qsx_account qa WHERE ${whereSql}`
+        params.push(String(pagesize), String(offset))
+
+        const rows = await db.query(listSql, params)
+        const countRows = await db.query(countSql, countParams)
+        if (!rows || !countRows) return res.json({ ...BaseStdResponse.DATABASE_ERR })
+
+        const data = rows.map(item => {
+            const bookList = parseBookList(item.book_list)
+            return {
+                id: item.id,
+                username: item.username,
+                create_time: item.create_time,
+                realname: item.realname,
+                email: item.email,
+                mobile: item.mobile,
+                termName: item.termName,
+                className: extractClassName(bookList),
+                book_count: bookList.length
+            }
+        })
+
+        return res.json({
+            ...BaseStdResponse.OK,
+            data,
+            pagination: {
+                current: Number(current),
+                pagesize: Number(pagesize),
+                total: countRows[0]?.total || 0
+            }
+        })
+    }
+}
+
+module.exports.AdminQxsAccountList = AdminQxsAccountList