// apizero 代理路由 (前端不直接调 apizero, 一律走后端, key 不外泄) // // GET /api/apizero/oil/forecast - 油价 + 预测 (实时) // GET /api/apizero/oil/price-all - 32 省油价 // GET /api/apizero/oil/price?province= - 单省油价 // GET /api/apizero/oil/schedule?year= - 某年调价日历 (按年缓存) // // 错误: apizero 错误统一包成 502 (上游错误) 或 400 (参数错误) import { Router } from 'express' import { authRequired } from '../middleware.js' import { ApizeroError, oil, history } from '../apizero/index.js' const router = Router() router.use(authRequired) function handleApizeroError(e, res, next) { if (e instanceof ApizeroError) { // 参数错 -> 400, 上游错 -> 502, QPS 限流 / 额度用完 -> 503 if (e.httpStatus === 400) return res.status(400).json({ error: e.message, apizero_code: e.code }) if (e.code === 4029 || e.code === 4030) return res.status(503).json({ error: e.message, apizero_code: e.code }) return res.status(502).json({ error: e.message, apizero_code: e.code }) } next(e) } // 实时: 油价 + 国际原油 + 下次调价预测 router.get('/apizero/oil/forecast', async (req, res, next) => { try { res.json(await oil.getForecast()) } catch (e) { handleApizeroError(e, res, next) } }) // 32 省油价 router.get('/apizero/oil/price-all', async (req, res, next) => { try { res.json(await oil.getPriceAll()) } catch (e) { handleApizeroError(e, res, next) } }) // 单省油价 router.get('/apizero/oil/price', async (req, res, next) => { try { res.json(await oil.getPrice(req.query.province)) } catch (e) { handleApizeroError(e, res, next) } }) // 调价日历 (按年缓存) router.get('/apizero/oil/schedule', async (req, res, next) => { try { res.json(await oil.getSchedule(req.query.year)) } catch (e) { handleApizeroError(e, res, next) } }) export default router // 浙江省油价历史 (DB) // GET /api/apizero/oil/history?fuel=92&days=180 // - fuel: 92 / 95 / 0 (留空 = 3 个油品都返回) // - days: 默认 180 (半年) router.get('/apizero/oil/history', async (req, res, next) => { try { const fuel = req.query.fuel ? String(req.query.fuel) : undefined const days = Math.max(1, Math.min(Number(req.query.days) || 180, 730)) const items = await history.query({ fuel, days }) res.json({ items, fuel: fuel || 'all', days }) } catch (e) { next(e) } })