const API = require('../../../../lib/API') const db = require('../../../../plugin/DataBase/db') const AccessControl = require('../../../../lib/AccessControl') const { BaseStdResponse } = require('../../../../BaseStdResponse') const path = require('path') const ipSearcher = require('../../../../plugin/ip2region') let searcher = null function getSearcher() { if (searcher) return searcher searcher = ipSearcher.newWithFileOnly(path.join(__dirname, '../../../../plugin/ip2region/ip2region.xdb')) return searcher } function isIpv4(host) { return /^(\d{1,3}\.){3}\d{1,3}$/.test(String(host || '').trim()) } class List extends API { constructor() { super() this.setPath('/Admin/Lepao/Proxy/List') this.setMethod('get') } async onRequest(req, res) { let { uuid, session, pagesize, current, is_active, host } = 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 || Number(pagesize) > 100) { return res.json({ ...BaseStdResponse.ERR, msg: '参数错误' }) } if (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('service')) { return res.json({ ...BaseStdResponse.PERMISSION_DENIED }) } const offset = (Number(current) - 1) * Number(pagesize) const where = ['1 = 1'] const params = [] const countParams = [] if (is_active !== undefined && is_active !== null && String(is_active) !== '') { where.push('p.is_active = ?') params.push(Number(is_active) === 1 ? 1 : 0) countParams.push(Number(is_active) === 1 ? 1 : 0) } if (host) { where.push('p.host LIKE ?') params.push(`%${host}%`) countParams.push(`%${host}%`) } const whereSql = where.join(' AND ') const listSql = ` SELECT p.*, (SELECT COUNT(*) FROM lepao_account a WHERE a.assigned_proxy_id = p.id) AS account_count FROM lepao_proxy_pool p WHERE ${whereSql} ORDER BY p.id DESC LIMIT ? OFFSET ? ` params.push(String(pagesize), String(offset)) const countSql = ` SELECT COUNT(*) AS total FROM lepao_proxy_pool p WHERE ${whereSql} ` const rows = await db.query(listSql, params) const countResult = await db.query(countSql, countParams) if (!rows || !countResult) { return res.json({ ...BaseStdResponse.DATABASE_ERR, msg: '查询失败' }) } const s = getSearcher() for (const row of rows) { row.ip_location = '未知' if (!isIpv4(row.host)) { row.ip_location = '非IPv4/域名' continue } try { const info = await s.search(row.host) row.ip_location = info?.region || '未知' } catch { row.ip_location = '未知' } } return res.json({ ...BaseStdResponse.OK, data: rows, pagination: { current: Number(current), pagesize: Number(pagesize), total: countResult[0].total } }) } } module.exports.List = List