修复无法兑换bug
This commit is contained in:
@@ -0,0 +1,43 @@
|
|||||||
|
import assert from 'node:assert/strict'
|
||||||
|
import test from 'node:test'
|
||||||
|
|
||||||
|
import { syncKuaishouCloudTaskStateForTask } from './kuaishou-cloud-task-state-repo.js'
|
||||||
|
|
||||||
|
test('syncKuaishouCloudTaskStateForTask 将 Date 更新时间规范化为 ISO 字符串', async () => {
|
||||||
|
const calls: Array<{ text: string; params?: unknown[] }> = []
|
||||||
|
const executor = async (text: string, params?: unknown[]) => {
|
||||||
|
calls.push({ text, params })
|
||||||
|
return { rows: [] }
|
||||||
|
}
|
||||||
|
|
||||||
|
await syncKuaishouCloudTaskStateForTask({
|
||||||
|
taskId: 9,
|
||||||
|
executorKey: 'kuaishou_ct_assisted',
|
||||||
|
contextJson: {
|
||||||
|
kuaishouCloudFulfillment: {
|
||||||
|
ticket: {
|
||||||
|
status: 'verified',
|
||||||
|
code: '597172E91CF18417',
|
||||||
|
},
|
||||||
|
binding: {
|
||||||
|
bindUrl: 'https://example.test/bind',
|
||||||
|
vnPhone: '14062706492',
|
||||||
|
roleName: '测试角色',
|
||||||
|
roleId: '4212063544',
|
||||||
|
resolvedSourceKey: 'account_test',
|
||||||
|
},
|
||||||
|
dispatch: {
|
||||||
|
status: 'pending',
|
||||||
|
},
|
||||||
|
consume: {
|
||||||
|
status: 'pending',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
updatedAt: new Date('2026-05-29T09:05:46.658Z'),
|
||||||
|
}, executor)
|
||||||
|
|
||||||
|
assert.equal(calls.length, 1)
|
||||||
|
assert.match(calls[0].text, /INSERT INTO kuaishou_cloud_task_states/)
|
||||||
|
assert.equal(calls[0].params?.[10], '2026-05-29T09:05:46.658Z')
|
||||||
|
})
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { query } from '../db/client.js'
|
import { query } from '../db/client.js'
|
||||||
import { maskCode } from '../utils/masking.js'
|
import { maskCode } from '../utils/masking.js'
|
||||||
import { parseTaskContext } from '../utils/task-json.js'
|
import { parseTaskContext } from '../utils/task-json.js'
|
||||||
|
import { normalizeTimestampIso } from '../utils/time.js'
|
||||||
|
|
||||||
type QueryExecutor = (text: string, params?: unknown[]) => Promise<{ rows: unknown[] }>
|
type QueryExecutor = (text: string, params?: unknown[]) => Promise<{ rows: unknown[] }>
|
||||||
type JsonRecord = Record<string, any>
|
type JsonRecord = Record<string, any>
|
||||||
@@ -39,7 +40,7 @@ export async function syncKuaishouCloudTaskStateForTask(
|
|||||||
const consume = asRecord(flow.consume)
|
const consume = asRecord(flow.consume)
|
||||||
const roleName = pickFirstNonEmpty([role.name, binding.roleName])
|
const roleName = pickFirstNonEmpty([role.name, binding.roleName])
|
||||||
const roleId = pickFirstNonEmpty([role.rid, binding.roleId])
|
const roleId = pickFirstNonEmpty([role.rid, binding.roleId])
|
||||||
const updatedAt = String(input.updatedAt || '').trim() || new Date().toISOString()
|
const updatedAt = normalizeTimestampIso(input.updatedAt)
|
||||||
|
|
||||||
await executor(
|
await executor(
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import { query, withTransaction } from '../db/client.js'
|
|||||||
import type { PoolClient } from 'pg'
|
import type { PoolClient } from 'pg'
|
||||||
|
|
||||||
import { syncKuaishouCloudTaskStateForTask } from './kuaishou-cloud-task-state-repo.js'
|
import { syncKuaishouCloudTaskStateForTask } from './kuaishou-cloud-task-state-repo.js'
|
||||||
|
import { normalizeTimestampIso } from '../utils/time.js'
|
||||||
import type {
|
import type {
|
||||||
TaskCreateInput,
|
TaskCreateInput,
|
||||||
TaskListQueryInput,
|
TaskListQueryInput,
|
||||||
@@ -245,7 +246,7 @@ export async function updateTaskStatusIfCurrent(
|
|||||||
currentStatus: string,
|
currentStatus: string,
|
||||||
patch: TaskUpdatePatch,
|
patch: TaskUpdatePatch,
|
||||||
): Promise<TaskRow | null> {
|
): Promise<TaskRow | null> {
|
||||||
const now = String(patch.updated_at || '').trim()
|
const now = normalizeTimestampIso(patch.updated_at, '')
|
||||||
return withTransaction(async (client) => {
|
return withTransaction(async (client) => {
|
||||||
const result = await client.query<{
|
const result = await client.query<{
|
||||||
id: number
|
id: number
|
||||||
|
|||||||
@@ -6,3 +6,18 @@ export function addHours(baseIso: string | null | undefined, hours: number): str
|
|||||||
const baseTime = baseIso ? new Date(baseIso).getTime() : Date.now()
|
const baseTime = baseIso ? new Date(baseIso).getTime() : Date.now()
|
||||||
return new Date(baseTime + hours * 60 * 60 * 1000).toISOString()
|
return new Date(baseTime + hours * 60 * 60 * 1000).toISOString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function normalizeTimestampIso(value: unknown, fallbackIso = nowIso()): string {
|
||||||
|
if (value instanceof Date) {
|
||||||
|
const timestamp = value.getTime()
|
||||||
|
return Number.isFinite(timestamp) ? value.toISOString() : fallbackIso
|
||||||
|
}
|
||||||
|
|
||||||
|
const normalized = String(value || '').trim()
|
||||||
|
if (!normalized) {
|
||||||
|
return fallbackIso
|
||||||
|
}
|
||||||
|
|
||||||
|
const timestamp = Date.parse(normalized)
|
||||||
|
return Number.isFinite(timestamp) ? new Date(timestamp).toISOString() : fallbackIso
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user