后端迁移后台管理写侧基础工具

This commit is contained in:
yml
2026-05-21 16:51:32 +08:00
parent 89754802d1
commit a27467bfad
3 changed files with 45 additions and 26 deletions
@@ -1,5 +1,3 @@
// @ts-check
import { buildClaimUrl, createTaskClaimToken } from '../../claim/claim-service.js'
import { createHttpError } from '../../../utils/http.js'
import {
@@ -9,7 +7,27 @@ import {
parseTaskContext,
} from '../admin-read-shared-helpers.js'
export function maskPhone(value) {
import type { TaskRow } from '../../../types/repository-rows.js'
type AssistedTaskAction = 'confirm' | 'redeem'
type AdminViewerContextLike = {
canOperateAssistedTask?: boolean
[key: string]: unknown
}
type TaskClaimLink = {
token: string
expiredAt: string | null
claimUrl: string
}
type ErrorLike = {
errorCode?: string
code?: string
}
export function maskPhone(value: unknown): string {
const text = String(value || '').trim()
if (!text) {
return ''
@@ -22,7 +40,7 @@ export function maskPhone(value) {
return `${text.slice(0, 3)}****${text.slice(-4)}`
}
export function maskCode(value) {
export function maskCode(value: unknown): string {
const text = String(value || '').trim()
if (!text) {
return ''
@@ -35,18 +53,17 @@ export function maskCode(value) {
return `${text.slice(0, 4)}****${text.slice(-4)}`
}
export function resolveTaskInventoryGroupCodes(task) {
export function resolveTaskInventoryGroupCodes(task: TaskRow): string[] | null {
const taskContext = parseTaskContext(task)
const inventoryGroupCode = String(taskContext?.inventoryGroupCode || '').trim()
return inventoryGroupCode ? [inventoryGroupCode] : null
}
/**
* @param {any} task
* @param {any} viewerContext
* @param {'confirm' | 'redeem'} action
*/
export function ensureViewerCanOperateAssistedTask(task, viewerContext, action) {
export function ensureViewerCanOperateAssistedTask(
task: TaskRow,
viewerContext: AdminViewerContextLike,
action: AssistedTaskAction,
): void {
if (!viewerContext.canOperateAssistedTask || !isAssistedClaimTask(task)) {
throw createHttpError('当前账号没有此操作权限', {
statusCode: 403,
@@ -69,12 +86,12 @@ export function ensureViewerCanOperateAssistedTask(task, viewerContext, action)
}
}
export function isRecoverableTaskSessionCloseError(error) {
export function isRecoverableTaskSessionCloseError(error: ErrorLike | null | undefined): boolean {
const errorCode = String(error?.errorCode || error?.code || '').trim()
return errorCode === 'session_not_found' || errorCode === 'session_closed'
}
export function normalizeManualDispatchOutcome(value) {
export function normalizeManualDispatchOutcome(value: unknown): 'delivered' | 'failed' {
const normalized = String(value || '').trim().toLowerCase()
if (normalized === 'failed') {
@@ -84,14 +101,11 @@ export function normalizeManualDispatchOutcome(value) {
return 'delivered'
}
export function getTaskClaimExpiresAt(task) {
export function getTaskClaimExpiresAt(task: Partial<TaskRow> | null | undefined): string | null {
return task?.claim_expires_at || task?.primary_claim_expires_at || null
}
/**
* @param {any} task
*/
export async function ensureTaskClaimLink(task) {
export async function ensureTaskClaimLink(task: TaskRow): Promise<TaskClaimLink> {
const tokenStatus = String(task?.primary_claim_token_status || '').trim()
const token = String(task?.primary_claim_token || task?.claim_token || '').trim()
const expiredAt = getTaskClaimExpiresAt(task)
@@ -112,7 +126,7 @@ export async function ensureTaskClaimLink(task) {
}
}
function isClaimExpired(expiredAt) {
function isClaimExpired(expiredAt: string | null): boolean {
if (!expiredAt) {
return false
}
@@ -1,15 +1,11 @@
// @ts-check
import { getWebhookEventById } from '../../../repositories/webhook-event-repo.js'
import { replayAgisoTradeWebhookEvent } from '../../order/webhook-service.js'
import { createHttpError } from '../../../utils/http.js'
/** @typedef {import('../../../types/admin-read-inputs.js').AdminEntityIdInput} AdminEntityIdInput */
/** @typedef {import('../../../types/admin-write-models.js').AdminWebhookReplayResponse} AdminWebhookReplayResponse */
import type { AdminEntityIdInput } from '../../../types/admin-read-inputs.js'
import type { AdminWebhookReplayResponse } from '../../../types/admin-write-models.js'
/** @returns {Promise<AdminWebhookReplayResponse>} */
/** @param {AdminEntityIdInput} eventId */
export async function replayAdminWebhookEvent(eventId) {
export async function replayAdminWebhookEvent(eventId: AdminEntityIdInput): Promise<AdminWebhookReplayResponse> {
const event = await getWebhookEventById(Number(eventId))
if (!event) {