抽离后台平台配置共享映射逻辑

This commit is contained in:
yml
2026-05-04 14:29:05 +08:00
parent 1aac738739
commit 5c44184de0
3 changed files with 367 additions and 202 deletions
@@ -80,6 +80,16 @@ import { formatFenToAmount } from '../../utils/money.js'
import { syncConfiguredFulfillmentBindings } from '../bootstrap/fulfillment-bootstrap-service.js'
import { normalizeProductName } from '../order/product-match-service.js'
import { resolveDisplayShopName } from './admin-read-shared-helpers.js'
import {
mapAdminCloudtentaclesSession,
mapAdminCloudtentaclesSourceConfig,
mapAdminKhhaoSourceConfig,
mapAdminKhhaoSyncState,
mapAdminKuaishouCloudFulfillmentSource,
mapAdminKuaishouEticketSourceConfig,
maskPhone,
maskSecret,
} from './admin-platform-config-mappers.js'
/** @typedef {import('../../types/admin-write-inputs.js').AdminAgisoShopConfigSaveInput} AdminAgisoShopConfigSaveInput */
/** @typedef {import('../../types/admin-write-inputs.js').AdminKhhaoSourceConfigInput} AdminKhhaoSourceConfigInput */
@@ -259,39 +269,8 @@ export function getAdminKhhaoSourceConfig() {
return {
filePath: getKhhaoSourcesFilePath(),
stateFilePath: getKhhaoSyncStateFilePath(),
source: {
enabled: config.enabled !== false,
baseUrl: String(config.baseUrl || '').trim(),
username: String(config.username || '').trim(),
password: String(config.password || '').trim(),
maxCaptchaAttempts: Number(config.maxCaptchaAttempts || 3) || 3,
autoSync: {
enabled: config.autoSync?.enabled === true,
intervalMinutes: Number(config.autoSync?.intervalMinutes || 3) || 3,
pages: Number(config.autoSync?.pages || 2) || 2,
pageSize: Number(config.autoSync?.pageSize || 20) || 20,
},
},
syncState: {
syncFromCreatedAt: String(syncState.syncFromCreatedAt || '').trim(),
lastRunStartedAt: String(syncState.lastRunStartedAt || '').trim(),
lastRunFinishedAt: String(syncState.lastRunFinishedAt || '').trim(),
lastRunStatus: String(syncState.lastRunStatus || '').trim(),
lastErrorMessage: String(syncState.lastErrorMessage || '').trim(),
fetchedCount: Number(syncState.fetchedCount || 0),
syncedCount: Number(syncState.syncedCount || 0),
ignoredCount: Number(syncState.ignoredCount || 0),
watchMode: String(syncState.watchMode || 'normal').trim() || 'normal',
watchOrders: Array.isArray(syncState.watchOrders) ? syncState.watchOrders.map((item) => ({
platformOrderId: String(item?.platformOrderId || '').trim(),
shopId: String(item?.shopId || '').trim(),
shopName: String(item?.shopName || '').trim(),
itemTitle: String(item?.itemTitle || '').trim(),
payStatus: String(item?.payStatus || '').trim(),
detectedAt: String(item?.detectedAt || '').trim(),
lastSeenAt: String(item?.lastSeenAt || '').trim(),
})) : [],
},
source: mapAdminKhhaoSourceConfig(config),
syncState: mapAdminKhhaoSyncState(syncState),
}
}
@@ -300,11 +279,7 @@ export function getAdminKuaishouEticketSourceConfig() {
return {
filePath: getKuaishouEticketSourceFilePath(),
source: {
enabled: config.enabled !== false,
baseUrl: String(config.baseUrl || '').trim(),
shops: listKuaishouEticketShopConfigs(config).map((item) => mapAdminKuaishouEticketShopItem(item)),
},
source: mapAdminKuaishouEticketSourceConfig(config, listKuaishouEticketShopConfigs(config)),
}
}
@@ -318,11 +293,7 @@ export function updateAdminKuaishouEticketSourceConfig(payload = /** @type {Admi
return {
filePath: getKuaishouEticketSourceFilePath(),
source: {
enabled: saved.enabled !== false,
baseUrl: String(saved.baseUrl || '').trim(),
shops: listKuaishouEticketShopConfigs(saved).map((item) => mapAdminKuaishouEticketShopItem(item)),
},
source: mapAdminKuaishouEticketSourceConfig(saved, listKuaishouEticketShopConfigs(saved)),
}
}
@@ -346,39 +317,8 @@ export function updateAdminKhhaoSourceConfig(payload = /** @type {AdminKhhaoSour
return {
filePath: getKhhaoSourcesFilePath(),
stateFilePath: getKhhaoSyncStateFilePath(),
source: {
enabled: saved.enabled !== false,
baseUrl: String(saved.baseUrl || '').trim(),
username: String(saved.username || '').trim(),
password: String(saved.password || '').trim(),
maxCaptchaAttempts: Number(saved.maxCaptchaAttempts || 3) || 3,
autoSync: {
enabled: saved.autoSync?.enabled === true,
intervalMinutes: Number(saved.autoSync?.intervalMinutes || 3) || 3,
pages: Number(saved.autoSync?.pages || 2) || 2,
pageSize: Number(saved.autoSync?.pageSize || 20) || 20,
},
},
syncState: {
syncFromCreatedAt: String(syncState.syncFromCreatedAt || '').trim(),
lastRunStartedAt: String(syncState.lastRunStartedAt || '').trim(),
lastRunFinishedAt: String(syncState.lastRunFinishedAt || '').trim(),
lastRunStatus: String(syncState.lastRunStatus || '').trim(),
lastErrorMessage: String(syncState.lastErrorMessage || '').trim(),
fetchedCount: Number(syncState.fetchedCount || 0),
syncedCount: Number(syncState.syncedCount || 0),
ignoredCount: Number(syncState.ignoredCount || 0),
watchMode: String(syncState.watchMode || 'normal').trim() || 'normal',
watchOrders: Array.isArray(syncState.watchOrders) ? syncState.watchOrders.map((item) => ({
platformOrderId: String(item?.platformOrderId || '').trim(),
shopId: String(item?.shopId || '').trim(),
shopName: String(item?.shopName || '').trim(),
itemTitle: String(item?.itemTitle || '').trim(),
payStatus: String(item?.payStatus || '').trim(),
detectedAt: String(item?.detectedAt || '').trim(),
lastSeenAt: String(item?.lastSeenAt || '').trim(),
})) : [],
},
source: mapAdminKhhaoSourceConfig(saved),
syncState: mapAdminKhhaoSyncState(syncState),
}
}
@@ -496,15 +436,7 @@ export function getAdminCloudtentaclesSourceConfig() {
return {
filePath: getCloudtentaclesSourcesFilePath(),
sessionFilePath: getCloudtentaclesSessionFilePath(),
source: {
enabled: config.enabled !== false,
baseUrl: String(config.baseUrl || '').trim(),
username: String(config.username || '').trim(),
password: String(config.password || '').trim(),
phone: String(config.phone || '').trim(),
deviceId: String(config.deviceId || '-').trim() || '-',
deviceType: Number(config.deviceType || 0),
},
source: mapAdminCloudtentaclesSourceConfig(config),
session: mapAdminCloudtentaclesSession(session),
}
}
@@ -527,15 +459,7 @@ export function updateAdminCloudtentaclesSourceConfig(payload = /** @type {Admin
return {
filePath: getCloudtentaclesSourcesFilePath(),
sessionFilePath: getCloudtentaclesSessionFilePath(),
source: {
enabled: saved.enabled !== false,
baseUrl: String(saved.baseUrl || '').trim(),
username: String(saved.username || '').trim(),
password: String(saved.password || '').trim(),
phone: String(saved.phone || '').trim(),
deviceId: String(saved.deviceId || '-').trim() || '-',
deviceType: Number(saved.deviceType || 0),
},
source: mapAdminCloudtentaclesSourceConfig(saved),
session: mapAdminCloudtentaclesSession(session),
}
}
@@ -810,34 +734,7 @@ export function getAdminKuaishouCloudFulfillmentConfig() {
return {
filePath: getKuaishouCloudFulfillmentFilePath(),
source: {
enabled: config.enabled !== false,
items: (Array.isArray(config.items) ? config.items : []).map((item) => ({
id: String(item.id || '').trim(),
enabled: item.enabled !== false,
priority: Number(item.priority || 100) || 100,
provider: String(item.provider || 'khhao').trim() || 'khhao',
platform: String(item.platform || 'kuaishou').trim() || 'kuaishou',
shopId: String(item.shopId || '').trim(),
internalSkuCode: String(item.internalSkuCode || '').trim(),
internalSkuName: String(item.internalSkuName || '').trim(),
externalSkuCode: String(item.externalSkuCode || '').trim(),
externalItemId: String(item.externalItemId || '').trim(),
externalSkuName: String(item.externalSkuName || '').trim(),
resolvedSkuName: String(item.resolvedSkuName || '').trim(),
cloudSourceKey: String(item.cloudSourceKey || 'default').trim() || 'default',
cloudSkuId: Number(item.cloudSkuId || 0) || 0,
cloudSkuName: String(item.cloudSkuName || '').trim(),
vnKey: String(item.vnKey || '').trim(),
autoBuyEnabled: item.autoBuyEnabled !== false,
minAssetReserve: Number(item.minAssetReserve || 0) || 0,
autoReturnNumberAfterDispatch: item.autoReturnNumberAfterDispatch === true,
autoConsumeAfterDispatch: item.autoConsumeAfterDispatch === true,
kuaishouConsumeShopId: String(item.kuaishouConsumeShopId || '').trim(),
kuaishouConsumeShopName: String(item.kuaishouConsumeShopName || '').trim(),
notes: String(item.notes || '').trim(),
})),
},
source: mapAdminKuaishouCloudFulfillmentSource(config),
}
}
@@ -854,34 +751,7 @@ export async function updateAdminKuaishouCloudFulfillmentConfig(
return {
filePath: getKuaishouCloudFulfillmentFilePath(),
source: {
enabled: saved.enabled !== false,
items: (Array.isArray(saved.items) ? saved.items : []).map((item) => ({
id: String(item.id || '').trim(),
enabled: item.enabled !== false,
priority: Number(item.priority || 100) || 100,
provider: String(item.provider || 'khhao').trim() || 'khhao',
platform: String(item.platform || 'kuaishou').trim() || 'kuaishou',
shopId: String(item.shopId || '').trim(),
internalSkuCode: String(item.internalSkuCode || '').trim(),
internalSkuName: String(item.internalSkuName || '').trim(),
externalSkuCode: String(item.externalSkuCode || '').trim(),
externalItemId: String(item.externalItemId || '').trim(),
externalSkuName: String(item.externalSkuName || '').trim(),
resolvedSkuName: String(item.resolvedSkuName || '').trim(),
cloudSourceKey: String(item.cloudSourceKey || 'default').trim() || 'default',
cloudSkuId: Number(item.cloudSkuId || 0) || 0,
cloudSkuName: String(item.cloudSkuName || '').trim(),
vnKey: String(item.vnKey || '').trim(),
autoBuyEnabled: item.autoBuyEnabled !== false,
minAssetReserve: Number(item.minAssetReserve || 0) || 0,
autoReturnNumberAfterDispatch: item.autoReturnNumberAfterDispatch === true,
autoConsumeAfterDispatch: item.autoConsumeAfterDispatch === true,
kuaishouConsumeShopId: String(item.kuaishouConsumeShopId || '').trim(),
kuaishouConsumeShopName: String(item.kuaishouConsumeShopName || '').trim(),
notes: String(item.notes || '').trim(),
})),
},
source: mapAdminKuaishouCloudFulfillmentSource(saved),
}
}
@@ -1256,44 +1126,6 @@ function findMatchingObservedBinding(bindings, observed) {
return (Array.isArray(bindings) ? bindings : []).find((binding) => matchesObservedProduct(binding, observed)) || null
}
function maskSecret(value) {
const normalized = String(value || '').trim()
if (!normalized) {
return ''
}
if (normalized.length <= 10) {
return `${normalized.slice(0, 2)}****${normalized.slice(-2)}`
}
return `${normalized.slice(0, 6)}****${normalized.slice(-6)}`
}
function maskPhone(value) {
const normalized = String(value || '').trim()
if (!normalized) {
return ''
}
if (normalized.length < 7) {
return normalized
}
return `${normalized.slice(0, 3)}****${normalized.slice(-4)}`
}
function mapAdminKuaishouEticketShopItem(item = {}) {
return {
shopId: String(item.shopId || '').trim(),
kshopName: String(item.kshopName || '').trim(),
cookie: String(item.cookie || '').trim(),
cookieMasked: maskSecret(item.cookie),
hasCookie: Boolean(String(item.cookie || '').trim()),
userAvatar: String(item.userAvatar || '').trim(),
enabled: item.enabled !== false,
}
}
function resolveKuaishouEticketAdminContext(payload = {}) {
const savedSource = getKuaishouEticketSourceConfig()
const requestedShopId = String(payload.shopId || '').trim()
@@ -1331,20 +1163,6 @@ function hasCloudtentaclesCredentialContextChanged(current, next) {
)
}
function mapAdminCloudtentaclesSession(session = {}) {
return {
token: String(session.token || '').trim(),
tokenMasked: maskSecret(session.token),
baseUrl: String(session.baseUrl || '').trim(),
username: String(session.username || '').trim(),
phoneMasked: maskPhone(session.phone),
loggedInAt: String(session.loggedInAt || '').trim(),
deviceId: String(session.deviceId || '-').trim() || '-',
deviceType: Number(session.deviceType || 0),
hasToken: Boolean(String(session.token || '').trim()),
}
}
function isPlainObject(value) {
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
}