import * as ConfigStore from "@/activityConfig/store"; import { timingSafeEqual } from "crypto"; import { TABLES as T, validateConfig, failure, reject, periodDates } from "@/goldMiner/config"; import { collection, controlId, periodById } from "@/goldMiner/service"; import { setupIndexes } from "@/goldMiner/jobs"; import { publishTestPeriod } from "@/goldMiner/testPeriods"; export default async function (ctx: FunctionContext) { const body = ctx.body || {}; try { const expected = process.env.ADMIN_TOKEN; if (!expected || typeof body.adminToken !== "string") reject("UNAUTHORIZED"); const supplied = Buffer.from(body.adminToken), secret = Buffer.from(expected); if (supplied.length !== secret.length || !timingSafeEqual(supplied, secret)) reject("UNAUTHORIZED"); if (body.action === "setup_indexes") { await setupIndexes(); return { code: 1, msg: "索引已准备" }; } if (body.action === "publish_test_period") { return { code: 1, data: await publishTestPeriod(body), msg: "测试临时期已发布" }; } if (body.action === "publish") { if (!body.config || typeof body.config !== "object" || Array.isArray(body.config)) reject("CONFIG_UNAVAILABLE", "config 必须为 JSON 对象,请把活动参数放在请求的 config 字段内"); const snapshot = validateConfig({ ...body.config, publishedAt: Date.now() }); if (periodDates(snapshot.effectiveFromPeriodId).startsAt <= Date.now()) reject("CONFIG_UNAVAILABLE", "只能发布未来期配置"); const { configVersion, publishedAt, ...config } = snapshot; try { const stored = await ConfigStore.publish("goldMiner", configVersion, periodDates(config.effectiveFromPeriodId).startsAt, config, body.enabled); snapshot.publishedAt = stored.publishedAt; } catch (error: any) { reject("CONFIG_UNAVAILABLE", error.message); } return { code: 1, data: { ...snapshot, enabled: body.enabled === undefined ? true : body.enabled }, msg: "后续期配置已发布" }; } if (body.action === "set_purchasable") { if (typeof body.purchaseEnabled !== "boolean") reject("INVALID_INPUT", "purchaseEnabled 必须为 JSON 布尔值 true 或 false,不能使用字符串"); if (typeof body.periodId !== "string") reject("INVALID_INPUT", "periodId 必须为字符串,请传入要调整购买开关的活动期 ID"); if (!await periodById(body.periodId)) reject("NOT_FOUND"); await collection(T.configs).updateOne({ _id: controlId(body.periodId) }, { $set: { activityId: "goldMiner", recordType: "control", periodId: body.periodId, purchaseEnabled: body.purchaseEnabled, updatedAt: Date.now() } }, { upsert: true }); return { code: 1, msg: "购买开关已更新,已有权益不受影响" }; } reject("INVALID_ACTION"); } catch (error) { return failure(error); } }