拆分feifei配置并修复商品查询
This commit is contained in:
@@ -2,7 +2,10 @@ import crypto from 'node:crypto'
|
||||
import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
|
||||
import { signKuaishouFeifeiPayload } from './http-client.js'
|
||||
import {
|
||||
isKuaishouFeifeiSuccessResponse,
|
||||
signKuaishouFeifeiPayload,
|
||||
} from './http-client.js'
|
||||
|
||||
test('signKuaishouFeifeiPayload signs app key, timestamp and raw body with HMAC SHA256', () => {
|
||||
const input = {
|
||||
@@ -19,3 +22,10 @@ test('signKuaishouFeifeiPayload signs app key, timestamp and raw body with HMAC
|
||||
|
||||
assert.equal(signKuaishouFeifeiPayload(input), expected)
|
||||
})
|
||||
|
||||
test('isKuaishouFeifeiSuccessResponse accepts documented and actual success codes', () => {
|
||||
assert.equal(isKuaishouFeifeiSuccessResponse({ code: 0, message: 'success' }), true)
|
||||
assert.equal(isKuaishouFeifeiSuccessResponse({ code: 10000, message: 'success' }), true)
|
||||
assert.equal(isKuaishouFeifeiSuccessResponse({ code: 10000, message: '商品不存在' }), false)
|
||||
assert.equal(isKuaishouFeifeiSuccessResponse({ code: 1, message: 'success' }), false)
|
||||
})
|
||||
|
||||
@@ -44,7 +44,7 @@ export async function kuaishouFeifeiRequest(pathname: string, payload: JsonObjec
|
||||
})
|
||||
}
|
||||
|
||||
if (Number(json.code || 0) !== 0) {
|
||||
if (!isKuaishouFeifeiSuccessResponse(json)) {
|
||||
throw createHttpError(String(json.message || 'kuaishou-feifei 业务失败'), {
|
||||
statusCode: 502,
|
||||
errorCode: 'kuaishou_feifei_business_failed',
|
||||
@@ -85,6 +85,13 @@ export function signKuaishouFeifeiPayload({
|
||||
.toLowerCase()
|
||||
}
|
||||
|
||||
export function isKuaishouFeifeiSuccessResponse(json: JsonObject) {
|
||||
const code = Number(json.code ?? 0)
|
||||
const message = String(json.message || json.msg || '').trim().toLowerCase()
|
||||
|
||||
return code === 0 || (code === 10000 && message === 'success')
|
||||
}
|
||||
|
||||
function parseJsonObject(text: string): JsonObject {
|
||||
try {
|
||||
const parsed = JSON.parse(text || '{}')
|
||||
|
||||
@@ -3,6 +3,30 @@ import { kuaishouFeifeiRequest } from './http-client.js'
|
||||
|
||||
type JsonObject = Record<string, any>
|
||||
|
||||
export async function listKuaishouFeifeiProducts(input: {
|
||||
page?: number
|
||||
perPage?: number
|
||||
status?: string
|
||||
supplyProductName?: string
|
||||
} = {}) {
|
||||
const page = Math.max(1, Number(input.page || 1) || 1)
|
||||
const perPage = Math.min(100, Math.max(1, Number(input.perPage || 20) || 20))
|
||||
const filters: JsonObject = {}
|
||||
const status = String(input.status || 'on_sale').trim()
|
||||
const supplyProductName = String(input.supplyProductName || '').trim()
|
||||
|
||||
if (status) filters.status = status
|
||||
if (supplyProductName) filters.supply_product_name = supplyProductName
|
||||
|
||||
const response = await kuaishouFeifeiRequest('/api/open/v1/products/index', {
|
||||
page,
|
||||
per_page: perPage,
|
||||
filters,
|
||||
})
|
||||
|
||||
return mapKuaishouFeifeiProductList(response.data)
|
||||
}
|
||||
|
||||
export async function createKuaishouFeifeiOrder(input: {
|
||||
platformOrderNo: string
|
||||
productCode: string
|
||||
@@ -73,3 +97,40 @@ export function mapKuaishouFeifeiOrder(value: unknown) {
|
||||
raw: source,
|
||||
}
|
||||
}
|
||||
|
||||
export function mapKuaishouFeifeiProductList(value: unknown) {
|
||||
const source = value && typeof value === 'object' && !Array.isArray(value)
|
||||
? value as JsonObject
|
||||
: {}
|
||||
const list = Array.isArray(source.list) ? source.list : []
|
||||
|
||||
return {
|
||||
items: list.map((item) => mapKuaishouFeifeiProduct(item)),
|
||||
total: Number(source.total || list.length) || 0,
|
||||
page: Number(source.page || 1) || 1,
|
||||
perPage: Number(source.per_page || source.perPage || list.length || 20) || 20,
|
||||
raw: source,
|
||||
}
|
||||
}
|
||||
|
||||
export function mapKuaishouFeifeiProduct(value: unknown) {
|
||||
const source = value && typeof value === 'object' && !Array.isArray(value)
|
||||
? value as JsonObject
|
||||
: {}
|
||||
|
||||
return {
|
||||
productCode: String(source.product_code || '').trim(),
|
||||
name: String(source.name || '').trim(),
|
||||
channel: String(source.channel || '').trim(),
|
||||
externalProductId: String(source.external_product_id || '').trim(),
|
||||
imageUrl: String(source.image_url || '').trim(),
|
||||
status: String(source.status || '').trim(),
|
||||
supplyStatus: String(source.supply_status || '').trim(),
|
||||
supplyPricePoints: Number(source.supply_price_points || 0) || 0,
|
||||
feePoints: Number(source.fee_points || 0) || 0,
|
||||
unitCostPoints: Number(source.unit_cost_points || 0) || 0,
|
||||
maxOrderQuantity: Number(source.max_order_quantity || 0) || 0,
|
||||
salePricePoints: source.sale_price_points == null ? null : Number(source.sale_price_points || 0) || 0,
|
||||
raw: source,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user