import type { Context } from '@netlify/functions' import { guardMethod } from '../utils/method.js' import { fail, ok } from '../utils/http.js' import { readJson } from '../utils/request.js' import { prisma } from '../utils/prisma.js' import { createBridgeSignature } from '../utils/crypto.js' import { withErrorBoundary } from '../utils/handler.js' type SupplierTokenRequest = { userId?: string supplierIdentification?: string } type BridgeTokenResponse = { resultCode?: number message?: string accessToken?: string refreshToken?: string expire?: number refreshExpire?: number time?: string } const normalizeBase = (base: string) => base.replace(/\/$/, '') export default withErrorBoundary(async (request: Request, _context: Context) => { const methodResponse = guardMethod(request, ['POST']) if (methodResponse) return methodResponse const body = await readJson(request) const userId = String(body.userId || '').trim() const supplierIdentification = String(body.supplierIdentification || '').trim().toLowerCase() if (!userId || !supplierIdentification) { return fail('用户信息和供应商唯一标识不能为空') } const supplier = await prisma.supplierInfo.findUnique({ where: { supplierIdentification } }) if (!supplier || supplier.deleted === 1) { return fail('供应商信息未配置或已停用', 404, 'SUPPLIER_NOT_CONFIGURED') } const timestamp = String(Date.now()) const signature = createBridgeSignature(supplier.clientId, supplier.clientSecret, timestamp) const apiBase = normalizeBase(process.env.POINTS_MALL_OPEN_API_BASE || '') if (!apiBase) { return fail('平台积分商城接口地址未配置', 500, 'OPEN_API_BASE_MISSING') } const response = await fetch(`${apiBase}/connect/token`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ supplierId: supplier.supplierId, clientId: supplier.clientId, clientSecret: supplier.clientSecret, sendSha256: signature, code: '', timestamp }) }) const tokenPayload = (await response.json().catch(() => ({}))) as BridgeTokenResponse if (!response.ok || tokenPayload.resultCode !== 0) { return fail(tokenPayload.message || '获取平台授权令牌失败', 502, 'BRIDGE_TOKEN_FAILED') } return ok({ supplierIdentification, supplierId: supplier.supplierId, supplierName: supplier.supplierName, userId, token: tokenPayload.accessToken, accessToken: tokenPayload.accessToken, refreshToken: tokenPayload.refreshToken, expiresIn: tokenPayload.expire, refreshExpiresIn: tokenPayload.refreshExpire, issuedAt: tokenPayload.time }) })