彻底重构-2

This commit is contained in:
yml
2026-04-09 10:17:50 +08:00
parent df2eb34478
commit 606ef875e2
4 changed files with 155 additions and 12 deletions
@@ -1,7 +1,7 @@
import { createAdminAuditLog, listAdminAuditLogs } from '../../repositories/admin-audit-log-repo.js'
import { nowIso } from '../../utils/time.js'
export function writeAdminAuditLog(session, payload = {}) {
export async function writeAdminAuditLog(session, payload = {}) {
if (!session?.userId) {
return null
}
@@ -18,10 +18,10 @@ export function writeAdminAuditLog(session, payload = {}) {
})
}
export function getAdminAuditLogs(query = {}) {
export async function getAdminAuditLogs(query = {}) {
const page = normalizePage(query.page)
const pageSize = normalizePageSize(query.pageSize)
const { items, total } = listAdminAuditLogs({
const { items, total } = await listAdminAuditLogs({
page,
pageSize,
actorUsername: String(query.actorUsername || '').trim(),
@@ -33,8 +33,8 @@ export function getAdminAuditLogs(query = {}) {
return {
items: items.map((item) => ({
logId: item.id,
actorUserId: item.actor_user_id,
logId: Number(item.id),
actorUserId: Number(item.actor_user_id || 0),
actorUsername: item.actor_username,
actorRole: item.actor_role,
action: item.action,
@@ -76,7 +76,7 @@ function normalizeDateQuery(rawValue, endOfDay = false) {
function safeParseJson(value) {
try {
return JSON.parse(String(value || '{}'))
return typeof value === 'string' ? JSON.parse(value) : value || {}
} catch {
return {}
}
@@ -0,0 +1,126 @@
import { runtimeConfig } from '../../config/runtime.js'
import {
getFulfillmentProfileByKey,
listFulfillmentProfileRequirements,
replaceFulfillmentProfileRequirements,
upsertFulfillmentProfile,
upsertSkuFulfillmentBinding,
} from '../../repositories/fulfillment-profile-repo.js'
import { nowIso } from '../../utils/time.js'
const CORE_PROFILES = [
{
profileKey: 'manual_review',
name: '人工发货',
executorKey: 'manual_dispatch',
requiresClaim: false,
autoDispatch: false,
inventoryStrategy: 'static_pool',
requirements: [],
},
{
profileKey: 'tencent_claim_redeem',
name: '腾讯领取兑换',
executorKey: 'tencent_claim_redeem',
requiresClaim: true,
autoDispatch: false,
inventoryStrategy: 'static_pool',
requirements: [
{
roleKey: 'primary_code',
credentialType: 'tencent_code',
quantityPerUnit: 1,
isRequired: true,
},
],
},
]
export async function ensureFulfillmentCatalogBootstrapped() {
const timestamp = nowIso()
const profileMap = {}
for (const profile of CORE_PROFILES) {
const saved = await upsertFulfillmentProfile({
profileKey: profile.profileKey,
name: profile.name,
executorKey: profile.executorKey,
requiresClaim: profile.requiresClaim,
autoDispatch: profile.autoDispatch,
inventoryStrategy: profile.inventoryStrategy,
configJson: '{}',
createdAt: timestamp,
updatedAt: timestamp,
})
if (!saved) {
continue
}
profileMap[profile.profileKey] = saved
const currentRequirements = await listFulfillmentProfileRequirements(saved.id)
if (currentRequirements.length !== profile.requirements.length) {
await replaceFulfillmentProfileRequirements(saved.id, profile.requirements, timestamp)
}
}
const configuredBindings = normalizeConfiguredBindings(runtimeConfig.orders?.fulfillmentBindings)
const bindingsToApply = configuredBindings.length > 0
? configuredBindings
: inferDefaultBindingsFromSkuMappings(runtimeConfig.orders?.skuMappings)
for (const binding of bindingsToApply) {
const profile = profileMap[binding.profileKey] || await getFulfillmentProfileByKey(binding.profileKey)
if (!profile) {
continue
}
await upsertSkuFulfillmentBinding({
skuCode: binding.skuCode,
provider: binding.provider,
platform: binding.platform,
shopId: binding.shopId,
profileId: profile.id,
enabled: binding.enabled,
priority: binding.priority,
configJson: JSON.stringify(binding.config || {}),
createdAt: timestamp,
updatedAt: timestamp,
})
}
}
function normalizeConfiguredBindings(bindings) {
if (!Array.isArray(bindings)) {
return []
}
return bindings
.map((binding) => ({
skuCode: String(binding?.skuCode || '').trim(),
provider: String(binding?.provider || '').trim(),
platform: String(binding?.platform || '').trim(),
shopId: String(binding?.shopId || '').trim(),
profileKey: String(binding?.profileKey || '').trim() || 'manual_review',
enabled: binding?.enabled !== false,
priority: Number(binding?.priority || 100),
config: binding?.config || {},
}))
.filter((binding) => binding.skuCode)
}
function inferDefaultBindingsFromSkuMappings(skuMappings) {
const values = Object.values(skuMappings || {})
const uniqueSkuCodes = [...new Set(values.map((value) => String(value || '').trim()).filter(Boolean))]
return uniqueSkuCodes.map((skuCode) => ({
skuCode,
provider: '',
platform: '',
shopId: '',
profileKey: 'tencent_claim_redeem',
enabled: true,
priority: 100,
config: {},
}))
}
@@ -3,10 +3,10 @@ import { createClaimToken } from '../../repositories/claim-token-repo.js'
import { addHours, nowIso } from '../../utils/time.js'
import { randomToken } from '../../utils/random.js'
export function createTaskClaimToken(taskId) {
export async function createTaskClaimToken(taskId) {
const createdAt = nowIso()
const expiredAt = addHours(createdAt, Number(runtimeConfig.orders.tokenTtlHours || 24))
const token = createClaimToken({
const token = await createClaimToken({
taskId,
token: randomToken(24),
status: 'active',
+21 -4
View File
@@ -1,16 +1,33 @@
import { assignReservedCdk, findFirstAvailableCdkBySkuCode } from '../../repositories/cdk-repo.js'
import { assignReservedCdk, findFirstAvailableCdkBySkuCode, releaseReservedCdk } from '../../repositories/cdk-repo.js'
import { nowIso } from '../../utils/time.js'
export function reserveCdkForTask(skuCode, taskId) {
export async function reserveCdkForTask({ skuCode, taskId, credentialType = 'tencent_code', roleKey = 'primary_code' }) {
if (!skuCode) {
return null
}
const available = findFirstAvailableCdkBySkuCode(skuCode)
const available = await findFirstAvailableCdkBySkuCode(skuCode, credentialType)
if (!available) {
return null
}
return assignReservedCdk(available.id, taskId, nowIso())
return assignReservedCdk(available.id, taskId, nowIso(), roleKey)
}
export async function releaseReservedCdks(cdkIds = [], updatedAt = nowIso()) {
const released = []
for (const cdkId of cdkIds) {
if (!cdkId) {
continue
}
const item = await releaseReservedCdk(cdkId, updatedAt)
if (item) {
released.push(item)
}
}
return released
}