后端迁移91卡券共享模块
This commit is contained in:
+22
-21
@@ -9,10 +9,10 @@ export const OPEN_91_SUCCESS_MESSAGE = '接口调用成功'
|
||||
export const OPEN_91_DEFAULT_FAIL_CODE = 1204
|
||||
export const OPEN_91_COST_EXCEED_FAIL_CODE = 1220
|
||||
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export function getOpen91Config() {
|
||||
const config = /** @type {import('../../types/runtime-config.js').RuntimeConfig['platforms']['ninetyone']} */ (
|
||||
runtimeConfig.platforms?.ninetyone || {}
|
||||
)
|
||||
const config = (runtimeConfig.platforms?.ninetyone || {}) as JsonObject
|
||||
|
||||
return {
|
||||
userId: String(config.userId || '').trim(),
|
||||
@@ -49,7 +49,7 @@ export function normalizeOpen91String(value) {
|
||||
return String(value || '').trim()
|
||||
}
|
||||
|
||||
export function normalizeOpen91CreatePayload(payload = {}) {
|
||||
export function normalizeOpen91CreatePayload(payload: JsonObject = {}) {
|
||||
return {
|
||||
orderNo: normalizeOpen91String(payload.orderNo),
|
||||
productNo: normalizeOpen91String(payload.productNo),
|
||||
@@ -62,7 +62,7 @@ export function normalizeOpen91CreatePayload(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeOpen91QueryPayload(payload = {}) {
|
||||
export function normalizeOpen91QueryPayload(payload: JsonObject = {}) {
|
||||
return {
|
||||
orderNo: normalizeOpen91String(payload.orderNo),
|
||||
timestamp: normalizeOpen91Timestamp(payload.timestamp),
|
||||
@@ -71,7 +71,7 @@ export function normalizeOpen91QueryPayload(payload = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
export function assertOpen91CreatePayload(payload, config = assertOpen91Config()) {
|
||||
export function assertOpen91CreatePayload(payload: JsonObject, config = assertOpen91Config()) {
|
||||
if (!payload.orderNo) {
|
||||
throw createHttpError('缺少 orderNo', {
|
||||
statusCode: 400,
|
||||
@@ -96,7 +96,7 @@ export function assertOpen91CreatePayload(payload, config = assertOpen91Config()
|
||||
assertOpen91CommonPayload(payload, config)
|
||||
}
|
||||
|
||||
export function assertOpen91QueryPayload(payload, config = assertOpen91Config()) {
|
||||
export function assertOpen91QueryPayload(payload: JsonObject, config = assertOpen91Config()) {
|
||||
if (!payload.orderNo) {
|
||||
throw createHttpError('缺少 orderNo', {
|
||||
statusCode: 400,
|
||||
@@ -107,7 +107,7 @@ export function assertOpen91QueryPayload(payload, config = assertOpen91Config())
|
||||
assertOpen91CommonPayload(payload, config)
|
||||
}
|
||||
|
||||
function assertOpen91CommonPayload(payload, config) {
|
||||
function assertOpen91CommonPayload(payload: JsonObject, config: JsonObject) {
|
||||
if (!payload.timestamp) {
|
||||
throw createHttpError('缺少 timestamp', {
|
||||
statusCode: 400,
|
||||
@@ -137,7 +137,7 @@ function assertOpen91CommonPayload(payload, config) {
|
||||
}
|
||||
}
|
||||
|
||||
export function assertOpen91Timestamp(timestamp, toleranceSeconds = assertOpen91Config().timestampToleranceSeconds) {
|
||||
export function assertOpen91Timestamp(timestamp: unknown, toleranceSeconds = assertOpen91Config().timestampToleranceSeconds) {
|
||||
const nowSeconds = Math.floor(Date.now() / 1000)
|
||||
if (Math.abs(nowSeconds - Number(timestamp)) > Math.max(1, Number(toleranceSeconds) || 600)) {
|
||||
throw createHttpError('timestamp 已过期', {
|
||||
@@ -147,7 +147,7 @@ export function assertOpen91Timestamp(timestamp, toleranceSeconds = assertOpen91
|
||||
}
|
||||
}
|
||||
|
||||
export function buildOpen91SignSource(params = {}, { secret } = assertOpen91Config()) {
|
||||
export function buildOpen91SignSource(params: JsonObject = {}, { secret } = assertOpen91Config()) {
|
||||
const entries = Object.entries(params)
|
||||
.filter(([key]) => key !== 'sign')
|
||||
.sort(([left], [right]) => {
|
||||
@@ -164,7 +164,7 @@ export function buildOpen91SignSource(params = {}, { secret } = assertOpen91Conf
|
||||
return `${secret}${queryString}${secret}`
|
||||
}
|
||||
|
||||
export function signOpen91Payload(params = {}, config = assertOpen91Config()) {
|
||||
export function signOpen91Payload(params: JsonObject = {}, config = assertOpen91Config()) {
|
||||
return crypto
|
||||
.createHash('md5')
|
||||
.update(buildOpen91SignSource(params, config), 'utf8')
|
||||
@@ -172,13 +172,13 @@ export function signOpen91Payload(params = {}, config = assertOpen91Config()) {
|
||||
.toUpperCase()
|
||||
}
|
||||
|
||||
export function verifyOpen91Signature(params = {}, config = assertOpen91Config()) {
|
||||
export function verifyOpen91Signature(params: JsonObject = {}, config = assertOpen91Config()) {
|
||||
const expected = signOpen91Payload(params, config)
|
||||
const actual = normalizeOpen91String(params.sign).toUpperCase()
|
||||
return expected === actual
|
||||
}
|
||||
|
||||
export function assertOpen91Signature(params = {}, config = assertOpen91Config()) {
|
||||
export function assertOpen91Signature(params: JsonObject = {}, config = assertOpen91Config()) {
|
||||
if (!verifyOpen91Signature(params, config)) {
|
||||
throw createHttpError('验签失败', {
|
||||
statusCode: 400,
|
||||
@@ -203,7 +203,7 @@ export function encryptOpen91Cards(cards = [], secret = assertOpen91Config().sec
|
||||
return `${cipher.update(plainText, 'utf8', 'base64')}${cipher.final('base64')}`
|
||||
}
|
||||
|
||||
export function buildOpen91Cards(cards = [], config = assertOpen91Config()) {
|
||||
export function buildOpen91Cards(cards: unknown[] = [], config = assertOpen91Config()) {
|
||||
const encoding = normalizeOpen91String(config.cardsEncoding).toLowerCase()
|
||||
if (encoding && encoding !== 'aes-256-ecb-base64') {
|
||||
throw createHttpError(`暂不支持的 cardsEncoding: ${config.cardsEncoding}`, {
|
||||
@@ -215,7 +215,7 @@ export function buildOpen91Cards(cards = [], config = assertOpen91Config()) {
|
||||
return encryptOpen91Cards(cards, config.secret)
|
||||
}
|
||||
|
||||
export function buildOpen91SuccessResponse(data, message = OPEN_91_SUCCESS_MESSAGE) {
|
||||
export function buildOpen91SuccessResponse(data: unknown, message = OPEN_91_SUCCESS_MESSAGE) {
|
||||
return {
|
||||
code: 200,
|
||||
message,
|
||||
@@ -223,7 +223,7 @@ export function buildOpen91SuccessResponse(data, message = OPEN_91_SUCCESS_MESSA
|
||||
}
|
||||
}
|
||||
|
||||
export function buildOpen91ErrorResponse(message, code = 500) {
|
||||
export function buildOpen91ErrorResponse(message: unknown, code = 500) {
|
||||
return {
|
||||
code,
|
||||
message: normalizeOpen91String(message) || '系统错误',
|
||||
@@ -231,7 +231,7 @@ export function buildOpen91ErrorResponse(message, code = 500) {
|
||||
}
|
||||
}
|
||||
|
||||
export function buildOpen91OutTradeNo(order) {
|
||||
export function buildOpen91OutTradeNo(order: JsonObject) {
|
||||
const orderId = Number(order?.id || 0)
|
||||
return orderId > 0 ? `OS${String(orderId).padStart(10, '0')}` : ''
|
||||
}
|
||||
@@ -241,7 +241,7 @@ export function buildOpen91OrderCost(value = 0) {
|
||||
return Number.isFinite(amount) ? amount.toFixed(4) : '0.0000'
|
||||
}
|
||||
|
||||
export function buildOpen91CardItem({ claimUrl = '', expireTime = '' } = {}) {
|
||||
export function buildOpen91CardItem({ claimUrl = '', expireTime = '' }: { claimUrl?: unknown, expireTime?: unknown } = {}) {
|
||||
const normalizedClaimUrl = normalizeOpen91String(claimUrl)
|
||||
return {
|
||||
cardNo: normalizedClaimUrl,
|
||||
@@ -251,8 +251,7 @@ export function buildOpen91CardItem({ claimUrl = '', expireTime = '' } = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {unknown} value */
|
||||
export function formatOpen91ExpireTime(value = '') {
|
||||
export function formatOpen91ExpireTime(value: unknown = '') {
|
||||
const normalized = normalizeOpen91String(value)
|
||||
if (!normalized) {
|
||||
return ''
|
||||
@@ -282,7 +281,9 @@ export function formatOpen91ExpireTime(value = '') {
|
||||
return `${byType.year}-${byType.month}-${byType.day} ${byType.hour}:${byType.minute}:${byType.second}`
|
||||
}
|
||||
|
||||
export function resolveOpen91QueryState({ tasks = [], readyTaskIds = [] } = {}) {
|
||||
export function resolveOpen91QueryState(
|
||||
{ tasks = [], readyTaskIds = [] }: { tasks?: JsonObject[], readyTaskIds?: unknown[] } = {},
|
||||
) {
|
||||
const normalizedTasks = Array.isArray(tasks) ? tasks : []
|
||||
const readyTaskIdSet = new Set((Array.isArray(readyTaskIds) ? readyTaskIds : []).map((item) => Number(item)))
|
||||
|
||||
@@ -545,6 +545,14 @@
|
||||
- `npm run typecheck`
|
||||
- `npm run build`
|
||||
- `npm test` 共 139 个用例通过
|
||||
123. 91卡券 Open API 共享模块迁移到 `.ts`:
|
||||
- `src/services/open-91/shared.ts`
|
||||
124. 91 卡券配置读取、请求归一化、签名 / 验签、cards AES 加密、卡密响应构造与查询状态解析已进入 TS 编译链路;动态配置与请求 payload 补齐对象类型
|
||||
125. Docker 内验证通过:
|
||||
- `src/services/open-91/shared.test.js` 共 6 个用例通过
|
||||
- `npm run typecheck`
|
||||
- `npm run build`
|
||||
- `npm test` 共 139 个用例通过
|
||||
|
||||
## 下一步建议
|
||||
|
||||
|
||||
Reference in New Issue
Block a user