下沉后台 khhao 平台辅助组装逻辑

This commit is contained in:
yml
2026-05-04 15:56:52 +08:00
parent dad646b678
commit 60b84b23b4
3 changed files with 265 additions and 55 deletions
@@ -0,0 +1,83 @@
// @ts-check
import { getKhhaoSourceConfig } from '../../platforms/khhao/source-config-service.js'
import { mapKhhaoOrderPreviewList } from '../../platforms/khhao/order-mapper-service.js'
import { maskSecret } from './mappers.js'
export function resolveAdminKhhaoCredentialPayload(
payload = {},
options = {},
) {
const savedSource = /** @type {Record<string, unknown>} */ (
options.savedSource || getKhhaoSourceConfig()
)
return {
baseUrl: String(payload.baseUrl || savedSource.baseUrl || '').trim(),
username: String(payload.username || savedSource.username || '').trim(),
password: String(payload.password || savedSource.password || '').trim(),
maxCaptchaAttempts: payload.maxCaptchaAttempts || savedSource.maxCaptchaAttempts,
}
}
export function buildAdminKhhaoLoginPayload(
payload = {},
options = {},
) {
const credential = resolveAdminKhhaoCredentialPayload(payload, options)
const requestIdScope = String(options.requestIdScope || 'test-login').trim() || 'test-login'
return {
...credential,
includeImageBase64: payload.includeImageBase64,
requestId: `admin-khhao-${requestIdScope}:${credential.username || 'anonymous'}`,
}
}
export function buildAdminKhhaoSyncPayload(
payload = {},
options = {},
) {
return {
...payload,
...resolveAdminKhhaoCredentialPayload(payload, options),
}
}
export function buildAdminKhhaoLoginResult(session = {}) {
const cookieKeys = Object.keys(session.cookieMap || {})
return {
baseUrl: String(session.baseUrl || '').trim(),
username: String(session.username || '').trim(),
loggedInAt: String(session.loggedInAt || '').trim(),
attempt: Number(session.attempt || 0),
responseMessage: String(session.responseMessage || '').trim(),
captcha: {
recognizedText: String(session.captchaText || '').trim(),
imageBase64: String(session.captchaImageBase64 || '').trim(),
},
session: {
cookieKeys,
cookieCount: cookieKeys.length,
cookieHeaderMasked: maskSecret(session.cookieHeader),
},
}
}
export function buildAdminKhhaoOrderQueryResult(
session = {},
result = {},
) {
const items = Array.isArray(result.items) ? result.items : []
return {
baseUrl: String(session.baseUrl || '').trim(),
page: Number(result.page || 1),
limit: Number(result.limit || 0),
total: Number(result.total || 0),
itemCount: items.length,
items: mapKhhaoOrderPreviewList(items),
rawItems: items,
}
}
@@ -0,0 +1,166 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import {
buildAdminKhhaoLoginPayload,
buildAdminKhhaoLoginResult,
buildAdminKhhaoOrderQueryResult,
buildAdminKhhaoSyncPayload,
resolveAdminKhhaoCredentialPayload,
} from './khhao.js'
test('resolveAdminKhhaoCredentialPayload merges payload and saved source defaults', () => {
assert.deepEqual(
resolveAdminKhhaoCredentialPayload(
{
baseUrl: ' https://override.example.com ',
maxCaptchaAttempts: 5,
},
{
savedSource: {
baseUrl: 'https://saved.example.com',
username: 'saved-user',
password: 'saved-pass',
maxCaptchaAttempts: 3,
},
},
),
{
baseUrl: 'https://override.example.com',
username: 'saved-user',
password: 'saved-pass',
maxCaptchaAttempts: 5,
},
)
})
test('buildAdminKhhaoLoginPayload appends request id and includeImageBase64', () => {
assert.deepEqual(
buildAdminKhhaoLoginPayload(
{
username: ' user ',
includeImageBase64: true,
},
{
requestIdScope: 'query-orders',
savedSource: {
baseUrl: 'https://saved.example.com',
password: 'saved-pass',
maxCaptchaAttempts: 3,
},
},
),
{
baseUrl: 'https://saved.example.com',
username: 'user',
password: 'saved-pass',
maxCaptchaAttempts: 3,
includeImageBase64: true,
requestId: 'admin-khhao-query-orders:user',
},
)
})
test('buildAdminKhhaoSyncPayload merges normalized credential fields into payload', () => {
assert.deepEqual(
buildAdminKhhaoSyncPayload(
{
page: 2,
limit: 20,
username: ' user ',
},
{
savedSource: {
baseUrl: 'https://saved.example.com',
password: 'saved-pass',
maxCaptchaAttempts: 4,
},
},
),
{
page: 2,
limit: 20,
username: 'user',
baseUrl: 'https://saved.example.com',
password: 'saved-pass',
maxCaptchaAttempts: 4,
},
)
})
test('buildAdminKhhaoLoginResult assembles login response payload', () => {
assert.deepEqual(
buildAdminKhhaoLoginResult({
baseUrl: ' https://admin.khhao.com ',
username: ' test-user ',
loggedInAt: ' 2026-05-04T12:00:00.000Z ',
attempt: 2,
responseMessage: ' success ',
captchaText: ' abcd ',
captchaImageBase64: ' image-data ',
cookieMap: {
PHPSESSID: 'a',
foo: 'b',
},
cookieHeader: 'abcdef1234567890',
}),
{
baseUrl: 'https://admin.khhao.com',
username: 'test-user',
loggedInAt: '2026-05-04T12:00:00.000Z',
attempt: 2,
responseMessage: 'success',
captcha: {
recognizedText: 'abcd',
imageBase64: 'image-data',
},
session: {
cookieKeys: ['PHPSESSID', 'foo'],
cookieCount: 2,
cookieHeaderMasked: 'abcdef****567890',
},
},
)
})
test('buildAdminKhhaoOrderQueryResult maps preview list and preserves raw items', () => {
const rawItems = [
{
ordersn: ' A1 ',
pingtai: '3',
pingtaiName: '快手',
shopid: '1001',
shopName: '店铺A',
goodid: 'g1',
goodName: '商品A',
sku: 'sku-1',
num: '2',
fee: '12.34',
status: '2',
statusName: '<span>已支付</span>',
addtime: '2026-05-04 10:00:00',
},
]
const result = buildAdminKhhaoOrderQueryResult(
{
baseUrl: ' https://admin.khhao.com ',
},
{
page: 2,
limit: 20,
total: 50,
items: rawItems,
},
)
assert.equal(result.baseUrl, 'https://admin.khhao.com')
assert.equal(result.page, 2)
assert.equal(result.limit, 20)
assert.equal(result.total, 50)
assert.equal(result.itemCount, 1)
assert.equal(result.rawItems, rawItems)
assert.equal(result.items[0].platformOrderId, 'A1')
assert.equal(result.items[0].platform, 'kuaishou')
assert.equal(result.items[0].itemTitle, '商品A')
})
@@ -9,7 +9,6 @@ import {
saveAgisoMessagingConfig,
} from '../../platforms/agiso/shop-config-service.js'
import { enrichAgisoXianyuTradeOrder } from '../../platforms/agiso/xianyu/order-detail-service.js'
import { mapKhhaoOrderPreviewList } from '../../platforms/khhao/order-mapper-service.js'
import { queryKhhaoOrderList } from '../../platforms/khhao/order-query-service.js'
import { syncKhhaoOrders } from '../../platforms/khhao/order-sync-service.js'
import { getKhhaoSourceConfig, getKhhaoSourcesFilePath, saveKhhaoSourceConfig } from '../../platforms/khhao/source-config-service.js'
@@ -87,6 +86,13 @@ import {
normalizeFulfillmentLookupPayload,
resolveFulfillmentLookupDetail,
} from './fulfillment.js'
import {
buildAdminKhhaoLoginPayload,
buildAdminKhhaoLoginResult,
buildAdminKhhaoOrderQueryResult,
buildAdminKhhaoSyncPayload,
resolveAdminKhhaoCredentialPayload,
} from './khhao.js'
import {
buildAdminCloudtentaclesLoginResult,
buildAdminCloudtentaclesPersistedSessionPayload,
@@ -116,7 +122,6 @@ import {
mapAdminKuaishouCloudFulfillmentSource,
mapAdminKuaishouEticketSourceConfig,
maskPhone,
maskSecret,
} from './mappers.js'
/** @typedef {import('../../../types/admin-write-inputs.js').AdminAgisoShopConfigSaveInput} AdminAgisoShopConfigSaveInput */
@@ -241,74 +246,30 @@ export function updateAdminKhhaoSourceConfig(payload = /** @type {AdminKhhaoSour
/** @param {AdminKhhaoTestLoginInput} [payload] */
export async function testAdminKhhaoLogin(payload = /** @type {AdminKhhaoTestLoginInput} */ ({})) {
const savedSource = getKhhaoSourceConfig()
const session = await loginKhhaoSession({
baseUrl: String(payload.baseUrl || savedSource.baseUrl || '').trim(),
username: String(payload.username || savedSource.username || '').trim(),
password: String(payload.password || savedSource.password || '').trim(),
maxCaptchaAttempts: payload.maxCaptchaAttempts || savedSource.maxCaptchaAttempts,
includeImageBase64: payload.includeImageBase64,
requestId: `admin-khhao-test-login:${String(payload.username || savedSource.username || '').trim() || 'anonymous'}`,
})
return {
baseUrl: session.baseUrl,
username: session.username,
loggedInAt: session.loggedInAt,
attempt: session.attempt,
responseMessage: session.responseMessage,
captcha: {
recognizedText: session.captchaText,
imageBase64: session.captchaImageBase64,
},
session: {
cookieKeys: Object.keys(session.cookieMap),
cookieCount: Object.keys(session.cookieMap).length,
cookieHeaderMasked: maskSecret(session.cookieHeader),
},
}
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload))
return buildAdminKhhaoLoginResult(session)
}
/** @param {AdminKhhaoOrderQueryInput} [payload] */
export async function queryAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
const savedSource = getKhhaoSourceConfig()
const session = await loginKhhaoSession({
baseUrl: String(payload.baseUrl || savedSource.baseUrl || '').trim(),
username: String(payload.username || savedSource.username || '').trim(),
password: String(payload.password || savedSource.password || '').trim(),
maxCaptchaAttempts: payload.maxCaptchaAttempts || savedSource.maxCaptchaAttempts,
requestId: `admin-khhao-query-orders:${String(payload.username || savedSource.username || '').trim() || 'anonymous'}`,
})
const credential = resolveAdminKhhaoCredentialPayload(payload)
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload, {
requestIdScope: 'query-orders',
}))
const result = await queryKhhaoOrderList({
baseUrl: String(payload.baseUrl || savedSource.baseUrl || '').trim(),
baseUrl: credential.baseUrl,
page: payload.page,
limit: payload.limit,
session,
})
const previews = mapKhhaoOrderPreviewList(result.items)
return {
baseUrl: session.baseUrl,
page: result.page,
limit: result.limit,
total: result.total,
itemCount: result.items.length,
items: previews,
rawItems: result.items,
}
return buildAdminKhhaoOrderQueryResult(session, result)
}
/** @param {AdminKhhaoOrderQueryInput} [payload] */
export async function syncAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
const savedSource = getKhhaoSourceConfig()
return syncKhhaoOrders({
...payload,
baseUrl: String(payload.baseUrl || savedSource.baseUrl || '').trim(),
username: String(payload.username || savedSource.username || '').trim(),
password: String(payload.password || savedSource.password || '').trim(),
maxCaptchaAttempts: payload.maxCaptchaAttempts || savedSource.maxCaptchaAttempts,
})
return syncKhhaoOrders(buildAdminKhhaoSyncPayload(payload))
}
/** @param {AdminKuaishouEticketDetailQueryInput} [payload] */