彻底重构-2
This commit is contained in:
@@ -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',
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user