const baseModel = require("../../middleware/baseModel"); const tokenLogic = require("./biz_token_logic"); const usageSvc = require("./biz_usage_service"); function featureAllowed(plan, feature) { if (!feature) return true; const feats = plan.enabled_features; if (feats == null) return true; if (Array.isArray(feats)) return feats.includes(feature); if (typeof feats === "object") { return feats[feature] === true || feats[feature] === 1 || feats[feature] === "1"; } return false; } function normalizeUsageDelta(raw) { if (!raw || typeof raw !== "object") return {}; return { msg: usageSvc.num(raw.msg ?? raw.msg_count), mass: usageSvc.num(raw.mass ?? raw.mass_count), friend: usageSvc.num(raw.friend ?? raw.friend_count), sns: usageSvc.num(raw.sns ?? raw.sns_count), active_user: usageSvc.num(raw.active_user ?? raw.active_user_count), }; } function hasPositiveDelta(delta) { return Object.values(delta).some((v) => usageSvc.num(v) > 0); } /** * 对外鉴权:Token + 用户 + 有效订阅 + 功能点 + 接口权限 + API调用量 + 可选用量上报 * body: { token, feature?, api_path?, usage_delta?: { msg?, mass?, ... } } */ async function verifyRequest(body) { const { token, feature, api_path } = body || {}; if (!token) { return { ok: false, error_code: "TOKEN_INVALID", message: "缺少 token" }; } const hash = tokenLogic.hashPlainToken(token); const row = await baseModel.biz_api_token.findOne({ where: { token_hash: hash } }); if (!row) { return { ok: false, error_code: "TOKEN_INVALID", message: "Token 不存在" }; } if (row.status === "revoked") { return { ok: false, error_code: "TOKEN_REVOKED", message: "Token 已吊销" }; } const now = new Date(); if (new Date(row.expire_at) < now) { return { ok: false, error_code: "TOKEN_EXPIRED", message: "Token 已过期" }; } const user = await baseModel.biz_user.findByPk(row.user_id); if (!user || user.status !== "active") { return { ok: false, error_code: "SUBSCRIPTION_INACTIVE", message: "用户不可用" }; } const sub = await tokenLogic.findActiveSubscriptionForUser(row.user_id); if (!sub) { return { ok: false, error_code: "SUBSCRIPTION_INACTIVE", message: "无有效订阅" }; } const plan = await baseModel.biz_plan.findByPk(sub.plan_id); if (!plan || plan.status !== "active") { return { ok: false, error_code: "SUBSCRIPTION_INACTIVE", message: "套餐不可用" }; } if (feature && !featureAllowed(plan, feature)) { return { ok: false, error_code: "FEATURE_NOT_ALLOWED", message: "功能未在套餐内" }; } // 接口路径级权限校验 if (api_path) { const apiCheck = usageSvc.checkApiPathAllowed(plan, api_path); if (!apiCheck.ok) { return { ok: false, error_code: apiCheck.error_code, message: apiCheck.message }; } } const statMonth = usageSvc.currentStatMonth(); let usageRow = await usageSvc.getOrCreateUsage(row.user_id, sub.plan_id, statMonth); // API 调用次数配额校验 if (api_path) { const callCheck = usageSvc.checkApiCallQuota(plan, usageRow); if (!callCheck.ok) { return { ok: false, error_code: callCheck.error_code, message: callCheck.message }; } usageRow = await usageSvc.incrementApiCallCount(row.user_id, sub.plan_id, statMonth); } const delta = normalizeUsageDelta(body.usage_delta || body.usage_report); if (hasPositiveDelta(delta)) { const q = usageSvc.checkQuotaAfterDelta(plan, usageRow, delta); if (!q.ok) { return { ok: false, error_code: q.error_code || "QUOTA_EXCEEDED", message: q.message || "额度不足" }; } usageRow = await usageSvc.applyDelta(row.user_id, sub.plan_id, statMonth, delta); } await row.update({ last_used_at: now }); return { ok: true, context: { user_id: row.user_id, plan_id: sub.plan_id, subscription_id: sub.id, token_id: row.id, token_key: row.key || "", stat_month: statMonth, usage_snapshot: { msg_count: usageSvc.num(usageRow.msg_count), mass_count: usageSvc.num(usageRow.mass_count), friend_count: usageSvc.num(usageRow.friend_count), sns_count: usageSvc.num(usageRow.sns_count), active_user_count: usageSvc.num(usageRow.active_user_count), api_call_count: usageSvc.num(usageRow.api_call_count), }, }, }; } module.exports = { verifyRequest };