feat(order-service): 重构分类资料收集与订单状态链路
This commit is contained in:
@@ -0,0 +1,281 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import process from 'node:process'
|
||||
|
||||
import { closeDb, query } from '../src/db/client.js'
|
||||
import { WORK_ORDER_STATUS } from '../src/domain/work-order-status.js'
|
||||
import { createWorkOrder } from '../src/repositories/worker-platform/work-order-management-repo.js'
|
||||
import type { WorkOrderRow } from '../src/repositories/worker-platform/types.js'
|
||||
import {
|
||||
publishAdminOrderServiceProfile,
|
||||
saveAdminOrderServiceProfile,
|
||||
type OrderServiceProfileConfig,
|
||||
} from '../src/services/worker-platform/order-service-profile-service.js'
|
||||
import {
|
||||
getOrderServiceByPlatformOrderId,
|
||||
submitOrderServiceMaterial,
|
||||
} from '../src/services/worker-platform/order-service-public-service.js'
|
||||
import { processDueOrderServiceAutoPublishJobs } from '../src/services/worker-platform/order-service-auto-publish-service.js'
|
||||
import { randomId } from '../src/utils/random.js'
|
||||
import { nowIso } from '../src/utils/time.js'
|
||||
|
||||
if (process.env.ORDER_SERVICE_SMOKE !== '1') {
|
||||
throw new Error('请显式设置 ORDER_SERVICE_SMOKE=1 后运行;该脚本只用于本地测试库')
|
||||
}
|
||||
|
||||
const categoryId = Number(process.env.ORDER_SERVICE_SMOKE_CATEGORY_ID || 1)
|
||||
const platformOrderId = `SMOKE-${Date.now()}`
|
||||
let workOrder: WorkOrderRow | null = null
|
||||
let originalProfile: {
|
||||
id: number
|
||||
name: string
|
||||
title: string
|
||||
description: string
|
||||
guideImage: Record<string, unknown>
|
||||
fields: OrderServiceProfileConfig['fields']
|
||||
screenshots: OrderServiceProfileConfig['screenshots']
|
||||
autoPublish: OrderServiceProfileConfig['autoPublish']
|
||||
submitText: string
|
||||
successText: string
|
||||
} | null = null
|
||||
|
||||
try {
|
||||
const profileResult = await query<{
|
||||
id: number
|
||||
name: string
|
||||
title: string
|
||||
description: string
|
||||
guide_image_json: Record<string, unknown>
|
||||
fields_json: OrderServiceProfileConfig['fields']
|
||||
screenshots_json: Record<string, unknown>
|
||||
auto_publish_json: Record<string, unknown>
|
||||
submit_text: string
|
||||
success_text: string
|
||||
current_version_id: number
|
||||
}>(
|
||||
`
|
||||
SELECT p.*
|
||||
FROM order_service_profiles p
|
||||
WHERE p.category_id = $1
|
||||
AND p.current_version_id IS NOT NULL
|
||||
LIMIT 1
|
||||
`,
|
||||
[categoryId],
|
||||
)
|
||||
const profile = profileResult.rows[0]
|
||||
assert.ok(profile, '测试分类缺少已发布订单服务配置')
|
||||
originalProfile = {
|
||||
id: Number(profile.id),
|
||||
name: profile.name,
|
||||
title: profile.title,
|
||||
description: profile.description,
|
||||
guideImage: profile.guide_image_json,
|
||||
fields: profile.fields_json,
|
||||
screenshots: profile.screenshots_json as OrderServiceProfileConfig['screenshots'],
|
||||
autoPublish: profile.auto_publish_json as OrderServiceProfileConfig['autoPublish'],
|
||||
submitText: profile.submit_text,
|
||||
successText: profile.success_text,
|
||||
}
|
||||
|
||||
const smokeFields: OrderServiceProfileConfig['fields'] = [
|
||||
{
|
||||
key: 'account',
|
||||
label: '游戏账号',
|
||||
type: 'text',
|
||||
required: true,
|
||||
placeholder: '请输入账号',
|
||||
helpText: '',
|
||||
options: [],
|
||||
sortOrder: 10,
|
||||
},
|
||||
]
|
||||
const saved = await saveAdminOrderServiceProfile({
|
||||
categoryId,
|
||||
name: '本地订单服务烟测',
|
||||
title: '本地订单服务烟测',
|
||||
description: '测试完成后自动恢复',
|
||||
guideImage: {},
|
||||
fields: smokeFields,
|
||||
screenshots: {
|
||||
enabled: false,
|
||||
required: false,
|
||||
minCount: 0,
|
||||
maxCount: 3,
|
||||
label: '截图',
|
||||
helpText: '',
|
||||
},
|
||||
autoPublish: {
|
||||
enabled: true,
|
||||
requireVoucherConsume: true,
|
||||
retryMax: 1,
|
||||
},
|
||||
submitText: '提交烟测资料',
|
||||
successText: '烟测资料已提交',
|
||||
})
|
||||
const draftStatus = await query<{ status: string }>(
|
||||
`SELECT status FROM order_service_profiles WHERE id = $1`,
|
||||
[saved.profile.id],
|
||||
)
|
||||
assert.equal(draftStatus.rows[0]?.status, 'draft')
|
||||
const stillPublished = await getPublishedProfile(categoryId)
|
||||
assert.equal(stillPublished.title, originalProfile.title)
|
||||
|
||||
const published = await publishAdminOrderServiceProfile(saved.profile.id)
|
||||
const publishedConfig = await getPublishedProfile(categoryId)
|
||||
assert.equal(publishedConfig.title, '本地订单服务烟测')
|
||||
|
||||
workOrder = await createWorkOrder({
|
||||
workOrderNo: `WKSMOKE${Date.now()}`,
|
||||
platformOrderId,
|
||||
productName: '订单服务烟测商品',
|
||||
categoryId,
|
||||
status: WORK_ORDER_STATUS.PENDING_MATERIAL,
|
||||
rewardAmount: 100,
|
||||
requiredDepositAmount: 0,
|
||||
depositThresholdAmount: 0,
|
||||
sharingEnabled: false,
|
||||
sharingTotalQuantity: 1,
|
||||
sharingUnitReward: 0,
|
||||
timeoutMinutes: 30,
|
||||
timeoutPolicy: 'reopen',
|
||||
acceptanceMode: 'standard',
|
||||
materialJson: JSON.stringify({ source: { smoke: true } }),
|
||||
requirementJson: JSON.stringify({ fields: smokeFields }),
|
||||
serviceProfileId: saved.profile.id,
|
||||
serviceProfileVersionId: published.versionId,
|
||||
serviceProfileSnapshotJson: JSON.stringify({
|
||||
profileId: saved.profile.id,
|
||||
categoryId,
|
||||
versionId: published.versionId,
|
||||
versionNo: published.versionNo,
|
||||
config: publishedConfig,
|
||||
}),
|
||||
now: nowIso(),
|
||||
})
|
||||
assert.ok(workOrder, '创建烟测工单失败')
|
||||
|
||||
const publicInfo = await getOrderServiceByPlatformOrderId(platformOrderId)
|
||||
assert.equal(publicInfo.items[0]?.title, '本地订单服务烟测')
|
||||
assert.equal(publicInfo.items[0]?.canSubmit, true)
|
||||
|
||||
await saveAdminOrderServiceProfile({
|
||||
categoryId,
|
||||
name: '未发布修改',
|
||||
title: '未发布修改不应泄漏',
|
||||
description: 'draft-only',
|
||||
guideImage: {},
|
||||
fields: smokeFields,
|
||||
screenshots: {
|
||||
enabled: false,
|
||||
required: false,
|
||||
minCount: 0,
|
||||
maxCount: 3,
|
||||
label: '截图',
|
||||
helpText: '',
|
||||
},
|
||||
autoPublish: {
|
||||
enabled: true,
|
||||
requireVoucherConsume: true,
|
||||
retryMax: 1,
|
||||
},
|
||||
submitText: '不应泄漏',
|
||||
successText: '不应泄漏',
|
||||
})
|
||||
const afterDraftEdit = await getOrderServiceByPlatformOrderId(platformOrderId)
|
||||
assert.equal(afterDraftEdit.items[0]?.title, '本地订单服务烟测')
|
||||
|
||||
await submitOrderServiceMaterial(platformOrderId, {
|
||||
workOrderId: workOrder.id,
|
||||
fields: { account: 'smoke-account' },
|
||||
screenshots: [],
|
||||
})
|
||||
await assert.rejects(() =>
|
||||
submitOrderServiceMaterial(platformOrderId, {
|
||||
workOrderId: workOrder?.id,
|
||||
fields: { account: 'changed' },
|
||||
screenshots: [],
|
||||
}),
|
||||
)
|
||||
|
||||
await waitForAutoPublishJob(workOrder.id)
|
||||
const afterPublish = await getOrderServiceByPlatformOrderId(platformOrderId)
|
||||
assert.equal(afterPublish.items[0]?.state, WORK_ORDER_STATUS.OPEN)
|
||||
assert.match(afterPublish.items[0]?.message || '', /高峰期/)
|
||||
|
||||
const job = await query<{ status: string; attempt_count: number }>(
|
||||
`SELECT status, attempt_count FROM order_service_auto_publish_jobs WHERE work_order_id = $1`,
|
||||
[workOrder.id],
|
||||
)
|
||||
assert.equal(job.rows[0]?.status, 'succeeded')
|
||||
|
||||
console.log(
|
||||
JSON.stringify(
|
||||
{
|
||||
ok: true,
|
||||
categoryId,
|
||||
profileId: saved.profile.id,
|
||||
versionNo: published.versionNo,
|
||||
platformOrderId,
|
||||
finalStatus: afterPublish.items[0]?.state,
|
||||
finalMessage: afterPublish.items[0]?.message,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
),
|
||||
)
|
||||
} finally {
|
||||
if (workOrder) {
|
||||
await query('DELETE FROM work_orders WHERE id = $1', [workOrder.id]).catch(() => undefined)
|
||||
}
|
||||
if (originalProfile) {
|
||||
const restored = await saveAdminOrderServiceProfile({
|
||||
categoryId,
|
||||
name: originalProfile.name,
|
||||
title: originalProfile.title,
|
||||
description: originalProfile.description,
|
||||
guideImage: originalProfile.guideImage,
|
||||
fields: originalProfile.fields,
|
||||
screenshots: originalProfile.screenshots,
|
||||
autoPublish: originalProfile.autoPublish,
|
||||
submitText: originalProfile.submitText,
|
||||
successText: originalProfile.successText,
|
||||
}).catch(() => null)
|
||||
if (restored) {
|
||||
await publishAdminOrderServiceProfile(restored.profile.id).catch(() => undefined)
|
||||
}
|
||||
}
|
||||
await closeDb()
|
||||
}
|
||||
|
||||
async function getPublishedProfile(categoryIdValue: number) {
|
||||
const result = await query<{ config_json: OrderServiceProfileConfig }>(
|
||||
`
|
||||
SELECT v.config_json
|
||||
FROM order_service_profiles p
|
||||
JOIN order_service_profile_versions v ON v.id = p.current_version_id
|
||||
WHERE p.category_id = $1
|
||||
LIMIT 1
|
||||
`,
|
||||
[categoryIdValue],
|
||||
)
|
||||
const config = result.rows[0]?.config_json
|
||||
assert.ok(config, '未找到已发布订单服务配置')
|
||||
return config
|
||||
}
|
||||
|
||||
async function waitForAutoPublishJob(workOrderId: number) {
|
||||
const deadline = Date.now() + 5_000
|
||||
while (Date.now() < deadline) {
|
||||
await Promise.all([
|
||||
processDueOrderServiceAutoPublishJobs(10),
|
||||
processDueOrderServiceAutoPublishJobs(10),
|
||||
])
|
||||
const result = await query<{ status: string }>(
|
||||
`SELECT status FROM order_service_auto_publish_jobs WHERE work_order_id = $1`,
|
||||
[workOrderId],
|
||||
)
|
||||
const status = result.rows[0]?.status
|
||||
if (status === 'succeeded' || status === 'failed' || status === 'skipped') return
|
||||
await new Promise((resolve) => setTimeout(resolve, 100))
|
||||
}
|
||||
throw new Error('自动发布任务在 5 秒内未结束')
|
||||
}
|
||||
Reference in New Issue
Block a user