抽离后台平台配置共享映射逻辑
This commit is contained in:
@@ -0,0 +1,151 @@
|
|||||||
|
// @ts-check
|
||||||
|
|
||||||
|
export 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)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export 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)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapAdminKhhaoSourceConfig(config = {}) {
|
||||||
|
return {
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapAdminKhhaoSyncState(syncState = {}) {
|
||||||
|
return {
|
||||||
|
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(),
|
||||||
|
}))
|
||||||
|
: [],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapAdminKuaishouEticketSourceConfig(config = {}, shops = []) {
|
||||||
|
return {
|
||||||
|
enabled: config.enabled !== false,
|
||||||
|
baseUrl: String(config.baseUrl || '').trim(),
|
||||||
|
shops: shops.map((item) => mapAdminKuaishouEticketShopItem(item)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapAdminCloudtentaclesSourceConfig(config = {}) {
|
||||||
|
return {
|
||||||
|
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),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export 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()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapAdminKuaishouCloudFulfillmentItem(item = {}) {
|
||||||
|
return {
|
||||||
|
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(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapAdminKuaishouCloudFulfillmentSource(config = {}) {
|
||||||
|
return {
|
||||||
|
enabled: config.enabled !== false,
|
||||||
|
items: (Array.isArray(config.items) ? config.items : []).map((item) =>
|
||||||
|
mapAdminKuaishouCloudFulfillmentItem(item),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
import test from 'node:test'
|
||||||
|
import assert from 'node:assert/strict'
|
||||||
|
|
||||||
|
import {
|
||||||
|
mapAdminCloudtentaclesSession,
|
||||||
|
mapAdminKhhaoSourceConfig,
|
||||||
|
mapAdminKhhaoSyncState,
|
||||||
|
mapAdminKuaishouCloudFulfillmentSource,
|
||||||
|
mapAdminKuaishouEticketSourceConfig,
|
||||||
|
maskPhone,
|
||||||
|
maskSecret,
|
||||||
|
} from './admin-platform-config-mappers.js'
|
||||||
|
|
||||||
|
test('maskSecret preserves edges while hiding middle characters', () => {
|
||||||
|
assert.equal(maskSecret('abcdef1234567890'), 'abcdef****567890')
|
||||||
|
assert.equal(maskSecret('12345678'), '12****78')
|
||||||
|
assert.equal(maskSecret(''), '')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('maskPhone hides middle digits for mobile numbers', () => {
|
||||||
|
assert.equal(maskPhone('13812345678'), '138****5678')
|
||||||
|
assert.equal(maskPhone('123456'), '123456')
|
||||||
|
assert.equal(maskPhone(''), '')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mapAdminKhhaoSourceConfig normalizes defaults and nested auto sync values', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
mapAdminKhhaoSourceConfig({
|
||||||
|
enabled: true,
|
||||||
|
baseUrl: ' https://admin.khhao.com ',
|
||||||
|
username: ' user ',
|
||||||
|
password: ' pass ',
|
||||||
|
maxCaptchaAttempts: '0',
|
||||||
|
autoSync: {
|
||||||
|
enabled: true,
|
||||||
|
intervalMinutes: '',
|
||||||
|
pages: '0',
|
||||||
|
pageSize: '50',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
baseUrl: 'https://admin.khhao.com',
|
||||||
|
username: 'user',
|
||||||
|
password: 'pass',
|
||||||
|
maxCaptchaAttempts: 3,
|
||||||
|
autoSync: {
|
||||||
|
enabled: true,
|
||||||
|
intervalMinutes: 3,
|
||||||
|
pages: 2,
|
||||||
|
pageSize: 50,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mapAdminKhhaoSyncState normalizes watch orders and fallback values', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
mapAdminKhhaoSyncState({
|
||||||
|
watchMode: '',
|
||||||
|
fetchedCount: '8',
|
||||||
|
watchOrders: [
|
||||||
|
{
|
||||||
|
platformOrderId: ' A1 ',
|
||||||
|
shopId: ' S1 ',
|
||||||
|
shopName: ' 店铺 ',
|
||||||
|
itemTitle: ' 商品 ',
|
||||||
|
payStatus: ' unpaid ',
|
||||||
|
detectedAt: ' t1 ',
|
||||||
|
lastSeenAt: ' t2 ',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
syncFromCreatedAt: '',
|
||||||
|
lastRunStartedAt: '',
|
||||||
|
lastRunFinishedAt: '',
|
||||||
|
lastRunStatus: '',
|
||||||
|
lastErrorMessage: '',
|
||||||
|
fetchedCount: 8,
|
||||||
|
syncedCount: 0,
|
||||||
|
ignoredCount: 0,
|
||||||
|
watchMode: 'normal',
|
||||||
|
watchOrders: [
|
||||||
|
{
|
||||||
|
platformOrderId: 'A1',
|
||||||
|
shopId: 'S1',
|
||||||
|
shopName: '店铺',
|
||||||
|
itemTitle: '商品',
|
||||||
|
payStatus: 'unpaid',
|
||||||
|
detectedAt: 't1',
|
||||||
|
lastSeenAt: 't2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mapAdminKuaishouEticketSourceConfig maps shops and masks cookies', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
mapAdminKuaishouEticketSourceConfig(
|
||||||
|
{ enabled: true, baseUrl: ' https://s.kwaixiaodian.com ' },
|
||||||
|
[{ shopId: ' 1 ', kshopName: ' A店 ', cookie: 'cookie-abcdef123456', enabled: true }],
|
||||||
|
),
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
baseUrl: 'https://s.kwaixiaodian.com',
|
||||||
|
shops: [
|
||||||
|
{
|
||||||
|
shopId: '1',
|
||||||
|
kshopName: 'A店',
|
||||||
|
cookie: 'cookie-abcdef123456',
|
||||||
|
cookieMasked: 'cookie****123456',
|
||||||
|
hasCookie: true,
|
||||||
|
userAvatar: '',
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mapAdminCloudtentaclesSession derives masked fields and token presence', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
mapAdminCloudtentaclesSession({
|
||||||
|
token: 'abcdef1234567890',
|
||||||
|
baseUrl: ' https://123.207.217.176 ',
|
||||||
|
username: ' admin ',
|
||||||
|
phone: '13812345678',
|
||||||
|
loggedInAt: ' 2026-05-04T10:00:00.000Z ',
|
||||||
|
deviceId: ' dev-1 ',
|
||||||
|
deviceType: '2',
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
token: 'abcdef1234567890',
|
||||||
|
tokenMasked: 'abcdef****567890',
|
||||||
|
baseUrl: 'https://123.207.217.176',
|
||||||
|
username: 'admin',
|
||||||
|
phoneMasked: '138****5678',
|
||||||
|
loggedInAt: '2026-05-04T10:00:00.000Z',
|
||||||
|
deviceId: 'dev-1',
|
||||||
|
deviceType: 2,
|
||||||
|
hasToken: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('mapAdminKuaishouCloudFulfillmentSource normalizes items and defaults', () => {
|
||||||
|
assert.deepEqual(
|
||||||
|
mapAdminKuaishouCloudFulfillmentSource({
|
||||||
|
enabled: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: ' item-1 ',
|
||||||
|
provider: '',
|
||||||
|
platform: '',
|
||||||
|
cloudSourceKey: '',
|
||||||
|
cloudSkuId: '0',
|
||||||
|
autoConsumeAfterDispatch: true,
|
||||||
|
kuaishouConsumeShopId: ' ks1 ',
|
||||||
|
notes: ' note ',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
enabled: true,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
id: 'item-1',
|
||||||
|
enabled: true,
|
||||||
|
priority: 100,
|
||||||
|
provider: 'khhao',
|
||||||
|
platform: 'kuaishou',
|
||||||
|
shopId: '',
|
||||||
|
internalSkuCode: '',
|
||||||
|
internalSkuName: '',
|
||||||
|
externalSkuCode: '',
|
||||||
|
externalItemId: '',
|
||||||
|
externalSkuName: '',
|
||||||
|
resolvedSkuName: '',
|
||||||
|
cloudSourceKey: 'default',
|
||||||
|
cloudSkuId: 0,
|
||||||
|
cloudSkuName: '',
|
||||||
|
vnKey: '',
|
||||||
|
autoBuyEnabled: true,
|
||||||
|
minAssetReserve: 0,
|
||||||
|
autoReturnNumberAfterDispatch: false,
|
||||||
|
autoConsumeAfterDispatch: true,
|
||||||
|
kuaishouConsumeShopId: 'ks1',
|
||||||
|
kuaishouConsumeShopName: '',
|
||||||
|
notes: 'note',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
})
|
||||||
@@ -80,6 +80,16 @@ import { formatFenToAmount } from '../../utils/money.js'
|
|||||||
import { syncConfiguredFulfillmentBindings } from '../bootstrap/fulfillment-bootstrap-service.js'
|
import { syncConfiguredFulfillmentBindings } from '../bootstrap/fulfillment-bootstrap-service.js'
|
||||||
import { normalizeProductName } from '../order/product-match-service.js'
|
import { normalizeProductName } from '../order/product-match-service.js'
|
||||||
import { resolveDisplayShopName } from './admin-read-shared-helpers.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').AdminAgisoShopConfigSaveInput} AdminAgisoShopConfigSaveInput */
|
||||||
/** @typedef {import('../../types/admin-write-inputs.js').AdminKhhaoSourceConfigInput} AdminKhhaoSourceConfigInput */
|
/** @typedef {import('../../types/admin-write-inputs.js').AdminKhhaoSourceConfigInput} AdminKhhaoSourceConfigInput */
|
||||||
@@ -259,39 +269,8 @@ export function getAdminKhhaoSourceConfig() {
|
|||||||
return {
|
return {
|
||||||
filePath: getKhhaoSourcesFilePath(),
|
filePath: getKhhaoSourcesFilePath(),
|
||||||
stateFilePath: getKhhaoSyncStateFilePath(),
|
stateFilePath: getKhhaoSyncStateFilePath(),
|
||||||
source: {
|
source: mapAdminKhhaoSourceConfig(config),
|
||||||
enabled: config.enabled !== false,
|
syncState: mapAdminKhhaoSyncState(syncState),
|
||||||
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(),
|
|
||||||
})) : [],
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,11 +279,7 @@ export function getAdminKuaishouEticketSourceConfig() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
filePath: getKuaishouEticketSourceFilePath(),
|
filePath: getKuaishouEticketSourceFilePath(),
|
||||||
source: {
|
source: mapAdminKuaishouEticketSourceConfig(config, listKuaishouEticketShopConfigs(config)),
|
||||||
enabled: config.enabled !== false,
|
|
||||||
baseUrl: String(config.baseUrl || '').trim(),
|
|
||||||
shops: listKuaishouEticketShopConfigs(config).map((item) => mapAdminKuaishouEticketShopItem(item)),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,11 +293,7 @@ export function updateAdminKuaishouEticketSourceConfig(payload = /** @type {Admi
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
filePath: getKuaishouEticketSourceFilePath(),
|
filePath: getKuaishouEticketSourceFilePath(),
|
||||||
source: {
|
source: mapAdminKuaishouEticketSourceConfig(saved, listKuaishouEticketShopConfigs(saved)),
|
||||||
enabled: saved.enabled !== false,
|
|
||||||
baseUrl: String(saved.baseUrl || '').trim(),
|
|
||||||
shops: listKuaishouEticketShopConfigs(saved).map((item) => mapAdminKuaishouEticketShopItem(item)),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,39 +317,8 @@ export function updateAdminKhhaoSourceConfig(payload = /** @type {AdminKhhaoSour
|
|||||||
return {
|
return {
|
||||||
filePath: getKhhaoSourcesFilePath(),
|
filePath: getKhhaoSourcesFilePath(),
|
||||||
stateFilePath: getKhhaoSyncStateFilePath(),
|
stateFilePath: getKhhaoSyncStateFilePath(),
|
||||||
source: {
|
source: mapAdminKhhaoSourceConfig(saved),
|
||||||
enabled: saved.enabled !== false,
|
syncState: mapAdminKhhaoSyncState(syncState),
|
||||||
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(),
|
|
||||||
})) : [],
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,15 +436,7 @@ export function getAdminCloudtentaclesSourceConfig() {
|
|||||||
return {
|
return {
|
||||||
filePath: getCloudtentaclesSourcesFilePath(),
|
filePath: getCloudtentaclesSourcesFilePath(),
|
||||||
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
||||||
source: {
|
source: mapAdminCloudtentaclesSourceConfig(config),
|
||||||
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),
|
|
||||||
},
|
|
||||||
session: mapAdminCloudtentaclesSession(session),
|
session: mapAdminCloudtentaclesSession(session),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -527,15 +459,7 @@ export function updateAdminCloudtentaclesSourceConfig(payload = /** @type {Admin
|
|||||||
return {
|
return {
|
||||||
filePath: getCloudtentaclesSourcesFilePath(),
|
filePath: getCloudtentaclesSourcesFilePath(),
|
||||||
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
sessionFilePath: getCloudtentaclesSessionFilePath(),
|
||||||
source: {
|
source: mapAdminCloudtentaclesSourceConfig(saved),
|
||||||
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),
|
|
||||||
},
|
|
||||||
session: mapAdminCloudtentaclesSession(session),
|
session: mapAdminCloudtentaclesSession(session),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -810,34 +734,7 @@ export function getAdminKuaishouCloudFulfillmentConfig() {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
filePath: getKuaishouCloudFulfillmentFilePath(),
|
filePath: getKuaishouCloudFulfillmentFilePath(),
|
||||||
source: {
|
source: mapAdminKuaishouCloudFulfillmentSource(config),
|
||||||
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(),
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -854,34 +751,7 @@ export async function updateAdminKuaishouCloudFulfillmentConfig(
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
filePath: getKuaishouCloudFulfillmentFilePath(),
|
filePath: getKuaishouCloudFulfillmentFilePath(),
|
||||||
source: {
|
source: mapAdminKuaishouCloudFulfillmentSource(saved),
|
||||||
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(),
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1256,44 +1126,6 @@ function findMatchingObservedBinding(bindings, observed) {
|
|||||||
return (Array.isArray(bindings) ? bindings : []).find((binding) => matchesObservedProduct(binding, observed)) || null
|
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 = {}) {
|
function resolveKuaishouEticketAdminContext(payload = {}) {
|
||||||
const savedSource = getKuaishouEticketSourceConfig()
|
const savedSource = getKuaishouEticketSourceConfig()
|
||||||
const requestedShopId = String(payload.shopId || '').trim()
|
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) {
|
function isPlainObject(value) {
|
||||||
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
return Boolean(value) && typeof value === 'object' && !Array.isArray(value)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user