200 lines
5.8 KiB
TypeScript
200 lines
5.8 KiB
TypeScript
import process from 'node:process'
|
|
import { Router } from 'express'
|
|
import type { JsonObject } from '../types/json.js'
|
|
|
|
import { createRateLimitMiddleware } from '../middleware/rate-limit.js'
|
|
import { handleSendCode } from '../services/platforms/kuaishou-industry/send-code-service.js'
|
|
import { handleDestroyCode } from '../services/platforms/kuaishou-industry/destroy-code-service.js'
|
|
import { handleQueryCode } from '../services/platforms/kuaishou-industry/query-code-service.js'
|
|
import { handleConsumeCode } from '../services/platforms/kuaishou-industry/consume-code-service.js'
|
|
import { buildIndustryErrorResponse } from '../services/platforms/kuaishou-industry/response.js'
|
|
import { createRequestId, logIntegration } from '../utils/logger.js'
|
|
|
|
const router = Router()
|
|
|
|
const industryRateLimit = createRateLimitMiddleware({
|
|
scope: 'kuaishouIndustry',
|
|
windowMs: 60_000,
|
|
max: normalizeRateLimitMax(process.env.KUASHOU_INDUSTRY_RATE_LIMIT_MAX, 120),
|
|
onLimit: (_req, res) => {
|
|
res.status(200).json(buildIndustryErrorResponse(4010003, '请求过于频繁,请稍后再试'))
|
|
},
|
|
})
|
|
|
|
router.post('/send-code', industryRateLimit, async (req, res) => {
|
|
const requestId = createRequestId('ksind')
|
|
const startedAt = Date.now()
|
|
|
|
logIntegration('[kuaishou-industry/send-code]', '收到快手行业电子凭证发码请求', {
|
|
requestId,
|
|
method: req.method,
|
|
originalUrl: req.originalUrl,
|
|
ip: req.ip,
|
|
query: req.query,
|
|
body: req.body,
|
|
})
|
|
|
|
try {
|
|
const params = mergeRequestParams(req)
|
|
const result = await handleSendCode(params)
|
|
logIntegration('[kuaishou-industry/send-code]', '发码处理完成', {
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
result,
|
|
})
|
|
res.status(200).json(result)
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : '系统异常'
|
|
logIntegration(
|
|
'[kuaishou-industry/send-code]',
|
|
'发码处理失败',
|
|
{
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
error,
|
|
},
|
|
{ level: 'error' },
|
|
)
|
|
res.status(200).json(buildIndustryErrorResponse(4010003, message))
|
|
}
|
|
})
|
|
|
|
router.post('/destroy-code', industryRateLimit, async (req, res) => {
|
|
const requestId = createRequestId('ksind')
|
|
const startedAt = Date.now()
|
|
|
|
logIntegration('[kuaishou-industry/destroy-code]', '收到快手行业电子凭证销毁请求', {
|
|
requestId,
|
|
method: req.method,
|
|
originalUrl: req.originalUrl,
|
|
ip: req.ip,
|
|
query: req.query,
|
|
body: req.body,
|
|
})
|
|
|
|
try {
|
|
const params = mergeRequestParams(req)
|
|
const result = await handleDestroyCode(params)
|
|
logIntegration('[kuaishou-industry/destroy-code]', '销毁处理完成', {
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
result,
|
|
})
|
|
res.status(200).json(result)
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : '系统异常'
|
|
logIntegration(
|
|
'[kuaishou-industry/destroy-code]',
|
|
'销毁处理失败',
|
|
{
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
error,
|
|
},
|
|
{ level: 'error' },
|
|
)
|
|
res.status(200).json(buildIndustryErrorResponse(4010003, message))
|
|
}
|
|
})
|
|
|
|
router.post('/query-code', industryRateLimit, async (req, res) => {
|
|
const requestId = createRequestId('ksind')
|
|
const startedAt = Date.now()
|
|
|
|
logIntegration('[kuaishou-industry/query-code]', '收到快手行业电子凭证查询请求', {
|
|
requestId,
|
|
method: req.method,
|
|
originalUrl: req.originalUrl,
|
|
ip: req.ip,
|
|
query: req.query,
|
|
body: req.body,
|
|
})
|
|
|
|
try {
|
|
const params = mergeRequestParams(req)
|
|
const result = await handleQueryCode(params)
|
|
logIntegration('[kuaishou-industry/query-code]', '查询处理完成', {
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
result,
|
|
})
|
|
res.status(200).json(result)
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : '系统异常'
|
|
logIntegration(
|
|
'[kuaishou-industry/query-code]',
|
|
'查询处理失败',
|
|
{
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
error,
|
|
},
|
|
{ level: 'error' },
|
|
)
|
|
res.status(200).json(buildIndustryErrorResponse(4010003, message))
|
|
}
|
|
})
|
|
|
|
router.post('/consume-code', industryRateLimit, async (req, res) => {
|
|
const requestId = createRequestId('ksind')
|
|
const startedAt = Date.now()
|
|
|
|
logIntegration('[kuaishou-industry/consume-code]', '收到快手行业电子凭证核销回调', {
|
|
requestId,
|
|
method: req.method,
|
|
originalUrl: req.originalUrl,
|
|
ip: req.ip,
|
|
query: req.query,
|
|
body: req.body,
|
|
})
|
|
|
|
try {
|
|
const params = mergeRequestParams(req)
|
|
const result = await handleConsumeCode(params)
|
|
logIntegration('[kuaishou-industry/consume-code]', '核销处理完成', {
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
result,
|
|
})
|
|
res.status(200).json(result)
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message : '系统异常'
|
|
logIntegration(
|
|
'[kuaishou-industry/consume-code]',
|
|
'核销处理失败',
|
|
{
|
|
requestId,
|
|
durationMs: Date.now() - startedAt,
|
|
error,
|
|
},
|
|
{ level: 'error' },
|
|
)
|
|
res.status(200).json(buildIndustryErrorResponse(4010003, message))
|
|
}
|
|
})
|
|
|
|
function mergeRequestParams(req: any): JsonObject {
|
|
const query = req.query || {}
|
|
const body = req.body || {}
|
|
const params: JsonObject = { ...query }
|
|
|
|
for (const [key, value] of Object.entries(body)) {
|
|
if (params[key] === undefined && key !== 'param') {
|
|
params[key] = value
|
|
}
|
|
}
|
|
|
|
if (body.param && !params.param) {
|
|
params.param = body.param
|
|
}
|
|
|
|
return params
|
|
}
|
|
|
|
function normalizeRateLimitMax(raw: string | undefined, fallback: number): number {
|
|
const parsed = Number(raw)
|
|
return Number.isFinite(parsed) && parsed >= 1 ? parsed : fallback
|
|
}
|
|
|
|
export default router
|