清理旧消息和历史命名
This commit is contained in:
@@ -1,55 +0,0 @@
|
||||
import { listMessageDeliveries } from '../../repositories/message-delivery-repo.js'
|
||||
import { normalizeDateQuery, normalizePage, normalizePageSize, safeParseJson } from './admin-query-utils.js'
|
||||
|
||||
import type { AdminMessageDeliveryListQueryInput } from '../../types/admin-read-inputs.js'
|
||||
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export async function getAdminMessageDeliveries(query: AdminMessageDeliveryListQueryInput = {}) {
|
||||
const page = normalizePage(query.page)
|
||||
const pageSize = normalizePageSize(query.pageSize)
|
||||
const { items, total } = await listMessageDeliveries({
|
||||
page,
|
||||
pageSize,
|
||||
provider: String(query.provider || '').trim(),
|
||||
platform: String(query.platform || '').trim(),
|
||||
status: String(query.status || '').trim(),
|
||||
shopId: String(query.shopId || '').trim(),
|
||||
platformOrderId: String(query.platformOrderId || '').trim(),
|
||||
taskNo: String(query.taskNo || '').trim(),
|
||||
dateFrom: normalizeDateQuery(query.dateFrom),
|
||||
dateTo: normalizeDateQuery(query.dateTo, true),
|
||||
})
|
||||
|
||||
return {
|
||||
items: items.map(mapAdminMessageDeliveryListItem),
|
||||
pagination: { page, pageSize, total },
|
||||
}
|
||||
}
|
||||
|
||||
function mapAdminMessageDeliveryListItem(item: JsonObject) {
|
||||
return {
|
||||
deliveryId: Number(item.id),
|
||||
provider: String(item.provider || '').trim(),
|
||||
platform: String(item.platform || '').trim(),
|
||||
shopId: String(item.shop_id || '').trim(),
|
||||
shopName: String(item.shop_name || '').trim(),
|
||||
channel: String(item.channel || '').trim(),
|
||||
orderId: item.order_id ? Number(item.order_id) : null,
|
||||
taskId: item.task_id ? Number(item.task_id) : null,
|
||||
taskNo: String(item.task_no || '').trim(),
|
||||
taskStatus: String(item.task_status || '').trim(),
|
||||
platformOrderId: String(item.platform_order_id || '').trim(),
|
||||
recipientKey: String(item.recipient_key || '').trim(),
|
||||
messageContent: String(item.message_content || '').trim(),
|
||||
claimUrl: String(item.claim_url || '').trim(),
|
||||
status: String(item.status || '').trim(),
|
||||
requestUrl: String(item.request_url || '').trim(),
|
||||
responseStatus: Number(item.response_status || 0),
|
||||
response: safeParseJson(item.response_json),
|
||||
errorMessage: String(item.error_message || '').trim(),
|
||||
sentAt: item.sent_at || null,
|
||||
createdAt: item.created_at,
|
||||
updatedAt: item.updated_at,
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,7 @@ export async function mapAdminOrderListItem(item: OrderListRow): Promise<AdminOr
|
||||
|
||||
return {
|
||||
orderId: item.id,
|
||||
provider: item.provider || 'agiso',
|
||||
provider: item.provider || '',
|
||||
platform: item.platform,
|
||||
shopId: item.shop_id || '',
|
||||
shopName: resolveDisplayShopName(item.provider, item.shop_id, item.shop_name),
|
||||
|
||||
@@ -17,12 +17,9 @@ import { normalizeDateQuery, normalizePage, normalizePageSize, safeParseJson } f
|
||||
import {
|
||||
canViewerCloseTask,
|
||||
canRegenerateClaimLinkForViewer,
|
||||
canViewerConfirmAssistedRole,
|
||||
canViewerRedeemAssistedTask,
|
||||
createAdminViewerContext,
|
||||
getTaskPrimaryClaimTokenId,
|
||||
getTaskPrimaryInventoryItemId,
|
||||
isAssistedClaimTask,
|
||||
isManualDispatchTask,
|
||||
mapKuaishouCloudFulfillmentContext,
|
||||
mapManualDispatchContext,
|
||||
@@ -108,7 +105,7 @@ export async function getAdminOrderDetail(orderId: AdminEntityIdInput): Promise<
|
||||
return {
|
||||
order: {
|
||||
orderId: order.id,
|
||||
provider: order.provider || 'agiso',
|
||||
provider: order.provider || '',
|
||||
platform: order.platform,
|
||||
shopId: order.shop_id || '',
|
||||
shopName: resolveDisplayShopName(order.provider, order.shop_id, order.shop_name),
|
||||
@@ -144,7 +141,7 @@ export async function getAdminOrderDetail(orderId: AdminEntityIdInput): Promise<
|
||||
tasks: tasks.map((task) => mapAdminTaskSummary(task, getTaskBindingSummary(taskBindingSummaryMap, task.id))),
|
||||
webhookEvents: webhookEvents.map((event) => ({
|
||||
eventId: event.id,
|
||||
provider: event.provider || 'agiso',
|
||||
provider: event.provider || '',
|
||||
platform: event.platform,
|
||||
shopId: event.shop_id || '',
|
||||
shopName: resolveDisplayShopName(event.provider, event.shop_id, event.shop_name),
|
||||
@@ -230,7 +227,7 @@ export async function getAdminTaskDetail(
|
||||
order: order
|
||||
? {
|
||||
orderId: order.id,
|
||||
provider: order.provider || 'agiso',
|
||||
provider: order.provider || '',
|
||||
platform: order.platform,
|
||||
shopId: order.shop_id || '',
|
||||
shopName: order.shop_name || '',
|
||||
@@ -270,7 +267,7 @@ export async function getAdminTaskDetail(
|
||||
artifacts: viewerContext.canViewSensitiveTaskData ? safeParseJson(task.artifacts_json) : {},
|
||||
screenshotUrl,
|
||||
review: {
|
||||
required: isAssistedClaimTask(task),
|
||||
required: false,
|
||||
screenshotCapturedAt: String(taskState.reviewCapturedAt || '').trim() || null,
|
||||
roleId: String(taskState.reviewRoleId || '').trim() || '',
|
||||
roleName: String(taskState.reviewRoleName || '').trim() || '',
|
||||
@@ -302,8 +299,6 @@ export async function getAdminTaskDetail(
|
||||
canReturnKuaishouCloudFulfillment: viewerContext.canManageTaskLifecycle
|
||||
&& String(task.executor_key || '').trim() === 'kuaishou_ct_assisted'
|
||||
&& ['dispatched_pending_return'].includes(String(task.task_status || '').trim()),
|
||||
canSupportConfirmRole: canViewerConfirmAssistedRole(task, viewerContext),
|
||||
canSupportRedeem: canViewerRedeemAssistedTask(task, viewerContext),
|
||||
canViewSensitiveTaskData: viewerContext.canViewSensitiveTaskData,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import {
|
||||
canViewerConfirmAssistedRole,
|
||||
canViewerCloseTask,
|
||||
createAdminViewerContext,
|
||||
resolveAdminTaskScreenshotUrl,
|
||||
@@ -38,18 +37,3 @@ test('canViewerCloseTask allows support to close active task but not redeemed ta
|
||||
assert.equal(canViewerCloseTask({ task_status: 'link_generated' }, viewerContext), true)
|
||||
assert.equal(canViewerCloseTask({ task_status: 'redeemed' }, viewerContext), false)
|
||||
})
|
||||
|
||||
test('canViewerConfirmAssistedRole blocks support when task inventory group is not bound', () => {
|
||||
const viewerContext = createAdminViewerContext({
|
||||
role: 'support',
|
||||
allowedInventoryGroups: ['A组'],
|
||||
})
|
||||
|
||||
assert.equal(canViewerConfirmAssistedRole({
|
||||
task_status: 'claimed',
|
||||
executor_key: 'tencent_claim_assisted',
|
||||
context_json: {
|
||||
inventoryGroupCode: 'B组',
|
||||
},
|
||||
}, viewerContext), false)
|
||||
})
|
||||
|
||||
@@ -279,10 +279,6 @@ export function isManualDispatchTask(task: TaskLike | null | undefined): boolean
|
||||
return String(task?.executor_key || '').trim() === 'manual_dispatch'
|
||||
}
|
||||
|
||||
export function isAssistedClaimTask(task: TaskLike | null | undefined): boolean {
|
||||
return String(task?.executor_key || '').trim() === 'tencent_claim_assisted'
|
||||
}
|
||||
|
||||
export function canRegenerateClaimLinkForViewer(task: TaskLike, viewerContext: AdminViewerContext): boolean {
|
||||
if (isManualDispatchTask(task)) {
|
||||
return false
|
||||
@@ -298,25 +294,7 @@ export function canRegenerateClaimLinkForViewer(task: TaskLike, viewerContext: A
|
||||
return true
|
||||
}
|
||||
|
||||
return viewerContext.canOperateAssistedTask
|
||||
&& isAssistedClaimTask(task)
|
||||
&& canViewerAccessTaskInventoryGroup(task, viewerContext)
|
||||
}
|
||||
|
||||
export function canViewerConfirmAssistedRole(task: TaskLike, viewerContext: AdminViewerContext): boolean {
|
||||
if (!viewerContext.canOperateAssistedTask || !isAssistedClaimTask(task) || !canViewerAccessTaskInventoryGroup(task, viewerContext)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return String(task?.task_status || '').trim() === 'claimed'
|
||||
}
|
||||
|
||||
export function canViewerRedeemAssistedTask(task: TaskLike, viewerContext: AdminViewerContext): boolean {
|
||||
if (!viewerContext.canOperateAssistedTask || !isAssistedClaimTask(task) || !canViewerAccessTaskInventoryGroup(task, viewerContext)) {
|
||||
return false
|
||||
}
|
||||
|
||||
return ['role_confirmed', 'redeeming'].includes(String(task?.task_status || '').trim())
|
||||
return false
|
||||
}
|
||||
|
||||
export function canViewerAccessTaskInventoryGroup(
|
||||
|
||||
@@ -10,8 +10,8 @@ import {
|
||||
test('mapAdminObservedProductRow normalizes query row fields', () => {
|
||||
assert.deepEqual(
|
||||
mapAdminObservedProductRow({
|
||||
provider: ' agiso ',
|
||||
platform: ' xianyu ',
|
||||
provider: ' 91kaquan ',
|
||||
platform: ' kuaishou ',
|
||||
shop_id: ' shop-1 ',
|
||||
shop_name: ' 店铺A ',
|
||||
external_item_id: ' item-1 ',
|
||||
@@ -21,8 +21,8 @@ test('mapAdminObservedProductRow normalizes query row fields', () => {
|
||||
order_item_count: '3',
|
||||
}),
|
||||
{
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
provider: '91kaquan',
|
||||
platform: 'kuaishou',
|
||||
shopId: 'shop-1',
|
||||
shopName: '店铺A',
|
||||
externalItemId: 'item-1',
|
||||
@@ -40,8 +40,8 @@ test('listAdminObservedProducts queries rows and maps matched binding summary',
|
||||
const result = await listAdminObservedProducts(
|
||||
[
|
||||
{
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
provider: '91kaquan',
|
||||
platform: 'kuaishou',
|
||||
shopId: 'shop-1',
|
||||
skuCode: 'inner-1',
|
||||
skuName: '内部商品A',
|
||||
@@ -57,8 +57,8 @@ test('listAdminObservedProducts queries rows and maps matched binding summary',
|
||||
return {
|
||||
rows: [
|
||||
{
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
provider: '91kaquan',
|
||||
platform: 'kuaishou',
|
||||
shop_id: 'shop-1',
|
||||
shop_name: '店铺A',
|
||||
external_item_id: '',
|
||||
@@ -77,8 +77,8 @@ test('listAdminObservedProducts queries rows and maps matched binding summary',
|
||||
assert.equal(sqlCalls[0], ADMIN_OBSERVED_PRODUCTS_QUERY)
|
||||
assert.deepEqual(result, [
|
||||
{
|
||||
provider: 'agiso',
|
||||
platform: 'xianyu',
|
||||
provider: '91kaquan',
|
||||
platform: 'kuaishou',
|
||||
shopId: 'shop-1',
|
||||
shopName: '店铺A',
|
||||
externalItemId: '',
|
||||
|
||||
@@ -1,21 +1,12 @@
|
||||
import { buildClaimUrl, createTaskClaimToken } from '../../claim/claim-service.js'
|
||||
import { createHttpError } from '../../../utils/http.js'
|
||||
import {
|
||||
maskCode as maskCodeValue,
|
||||
maskPhone as maskPhoneValue,
|
||||
} from '../../../utils/masking.js'
|
||||
import {
|
||||
canViewerConfirmAssistedRole,
|
||||
canViewerRedeemAssistedTask,
|
||||
isAssistedClaimTask,
|
||||
parseTaskContext,
|
||||
} from '../admin-read-shared-helpers.js'
|
||||
import { parseTaskContext } from '../admin-read-shared-helpers.js'
|
||||
|
||||
import type { AdminViewerContext } from '../admin-read-shared-helpers.js'
|
||||
import type { TaskRow } from '../../../types/repository-rows.js'
|
||||
|
||||
type AssistedTaskAction = 'confirm' | 'redeem'
|
||||
|
||||
type TaskClaimLink = {
|
||||
token: string
|
||||
expiredAt: string | null
|
||||
@@ -41,33 +32,6 @@ export function resolveTaskInventoryGroupCodes(task: TaskRow): string[] | null {
|
||||
return inventoryGroupCode ? [inventoryGroupCode] : null
|
||||
}
|
||||
|
||||
export function ensureViewerCanOperateAssistedTask(
|
||||
task: TaskRow,
|
||||
viewerContext: AdminViewerContext,
|
||||
action: AssistedTaskAction,
|
||||
): void {
|
||||
if (!viewerContext.canOperateAssistedTask || !isAssistedClaimTask(task)) {
|
||||
throw createHttpError('当前账号没有此操作权限', {
|
||||
statusCode: 403,
|
||||
errorCode: 'admin_task_assisted_permission_denied',
|
||||
})
|
||||
}
|
||||
|
||||
if (action === 'confirm' && !canViewerConfirmAssistedRole(task, viewerContext)) {
|
||||
throw createHttpError('当前任务状态还不能确认角色', {
|
||||
statusCode: 409,
|
||||
errorCode: 'admin_task_assisted_confirm_not_allowed',
|
||||
})
|
||||
}
|
||||
|
||||
if (action === 'redeem' && !canViewerRedeemAssistedTask(task, viewerContext)) {
|
||||
throw createHttpError('当前任务状态还不能开始兑换', {
|
||||
statusCode: 409,
|
||||
errorCode: 'admin_task_assisted_redeem_not_allowed',
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function isRecoverableTaskSessionCloseError(error: ErrorLike | null | undefined): boolean {
|
||||
const errorCode = String(error?.errorCode || error?.code || '').trim()
|
||||
return errorCode === 'session_not_found' || errorCode === 'session_closed'
|
||||
|
||||
Reference in New Issue
Block a user