下沉后台 khhao 平台辅助组装逻辑
This commit is contained in:
@@ -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,
|
saveAgisoMessagingConfig,
|
||||||
} from '../../platforms/agiso/shop-config-service.js'
|
} from '../../platforms/agiso/shop-config-service.js'
|
||||||
import { enrichAgisoXianyuTradeOrder } from '../../platforms/agiso/xianyu/order-detail-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 { queryKhhaoOrderList } from '../../platforms/khhao/order-query-service.js'
|
||||||
import { syncKhhaoOrders } from '../../platforms/khhao/order-sync-service.js'
|
import { syncKhhaoOrders } from '../../platforms/khhao/order-sync-service.js'
|
||||||
import { getKhhaoSourceConfig, getKhhaoSourcesFilePath, saveKhhaoSourceConfig } from '../../platforms/khhao/source-config-service.js'
|
import { getKhhaoSourceConfig, getKhhaoSourcesFilePath, saveKhhaoSourceConfig } from '../../platforms/khhao/source-config-service.js'
|
||||||
@@ -87,6 +86,13 @@ import {
|
|||||||
normalizeFulfillmentLookupPayload,
|
normalizeFulfillmentLookupPayload,
|
||||||
resolveFulfillmentLookupDetail,
|
resolveFulfillmentLookupDetail,
|
||||||
} from './fulfillment.js'
|
} from './fulfillment.js'
|
||||||
|
import {
|
||||||
|
buildAdminKhhaoLoginPayload,
|
||||||
|
buildAdminKhhaoLoginResult,
|
||||||
|
buildAdminKhhaoOrderQueryResult,
|
||||||
|
buildAdminKhhaoSyncPayload,
|
||||||
|
resolveAdminKhhaoCredentialPayload,
|
||||||
|
} from './khhao.js'
|
||||||
import {
|
import {
|
||||||
buildAdminCloudtentaclesLoginResult,
|
buildAdminCloudtentaclesLoginResult,
|
||||||
buildAdminCloudtentaclesPersistedSessionPayload,
|
buildAdminCloudtentaclesPersistedSessionPayload,
|
||||||
@@ -116,7 +122,6 @@ import {
|
|||||||
mapAdminKuaishouCloudFulfillmentSource,
|
mapAdminKuaishouCloudFulfillmentSource,
|
||||||
mapAdminKuaishouEticketSourceConfig,
|
mapAdminKuaishouEticketSourceConfig,
|
||||||
maskPhone,
|
maskPhone,
|
||||||
maskSecret,
|
|
||||||
} from './mappers.js'
|
} from './mappers.js'
|
||||||
|
|
||||||
/** @typedef {import('../../../types/admin-write-inputs.js').AdminAgisoShopConfigSaveInput} AdminAgisoShopConfigSaveInput */
|
/** @typedef {import('../../../types/admin-write-inputs.js').AdminAgisoShopConfigSaveInput} AdminAgisoShopConfigSaveInput */
|
||||||
@@ -241,74 +246,30 @@ export function updateAdminKhhaoSourceConfig(payload = /** @type {AdminKhhaoSour
|
|||||||
|
|
||||||
/** @param {AdminKhhaoTestLoginInput} [payload] */
|
/** @param {AdminKhhaoTestLoginInput} [payload] */
|
||||||
export async function testAdminKhhaoLogin(payload = /** @type {AdminKhhaoTestLoginInput} */ ({})) {
|
export async function testAdminKhhaoLogin(payload = /** @type {AdminKhhaoTestLoginInput} */ ({})) {
|
||||||
const savedSource = getKhhaoSourceConfig()
|
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload))
|
||||||
const session = await loginKhhaoSession({
|
return buildAdminKhhaoLoginResult(session)
|
||||||
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),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
||||||
export async function queryAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
export async function queryAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
||||||
const savedSource = getKhhaoSourceConfig()
|
const credential = resolveAdminKhhaoCredentialPayload(payload)
|
||||||
const session = await loginKhhaoSession({
|
const session = await loginKhhaoSession(buildAdminKhhaoLoginPayload(payload, {
|
||||||
baseUrl: String(payload.baseUrl || savedSource.baseUrl || '').trim(),
|
requestIdScope: 'query-orders',
|
||||||
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 result = await queryKhhaoOrderList({
|
const result = await queryKhhaoOrderList({
|
||||||
baseUrl: String(payload.baseUrl || savedSource.baseUrl || '').trim(),
|
baseUrl: credential.baseUrl,
|
||||||
page: payload.page,
|
page: payload.page,
|
||||||
limit: payload.limit,
|
limit: payload.limit,
|
||||||
session,
|
session,
|
||||||
})
|
})
|
||||||
const previews = mapKhhaoOrderPreviewList(result.items)
|
|
||||||
|
|
||||||
return {
|
return buildAdminKhhaoOrderQueryResult(session, result)
|
||||||
baseUrl: session.baseUrl,
|
|
||||||
page: result.page,
|
|
||||||
limit: result.limit,
|
|
||||||
total: result.total,
|
|
||||||
itemCount: result.items.length,
|
|
||||||
items: previews,
|
|
||||||
rawItems: result.items,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
/** @param {AdminKhhaoOrderQueryInput} [payload] */
|
||||||
export async function syncAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
export async function syncAdminKhhaoOrders(payload = /** @type {AdminKhhaoOrderQueryInput} */ ({})) {
|
||||||
const savedSource = getKhhaoSourceConfig()
|
return syncKhhaoOrders(buildAdminKhhaoSyncPayload(payload))
|
||||||
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,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @param {AdminKuaishouEticketDetailQueryInput} [payload] */
|
/** @param {AdminKuaishouEticketDetailQueryInput} [payload] */
|
||||||
|
|||||||
Reference in New Issue
Block a user