抽离后台履约观察商品查询逻辑

This commit is contained in:
yml
2026-05-04 15:14:51 +08:00
parent ace3c7b477
commit 9b4a3039fa
3 changed files with 153 additions and 41 deletions
@@ -0,0 +1,54 @@
// @ts-check
import { query } from '../../db/client.js'
import { mapAdminObservedProductItem } from './admin-platform-config-domain.js'
export const ADMIN_OBSERVED_PRODUCTS_QUERY = `
SELECT
o.provider,
o.platform,
o.shop_id,
MAX(CASE WHEN trim(o.shop_name) != '' THEN o.shop_name ELSE '' END) AS shop_name,
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalItemId', ''), '') AS external_item_id,
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuCode', ''), '') AS external_sku_code,
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuName', ''), '') AS external_sku_name,
MAX(oi.created_at) AS latest_seen_at,
COUNT(*)::int AS order_item_count
FROM order_items oi
JOIN orders o ON o.id = oi.order_id
WHERE
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalItemId', ''), '') != ''
OR COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuCode', ''), '') != ''
OR COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuName', ''), '') != ''
GROUP BY
o.provider,
o.platform,
o.shop_id,
external_item_id,
external_sku_code,
external_sku_name
ORDER BY latest_seen_at DESC, o.platform ASC, o.shop_id ASC, external_sku_code ASC
LIMIT 200
`
export function mapAdminObservedProductRow(row = {}) {
return {
provider: String(row.provider || '').trim(),
platform: String(row.platform || '').trim(),
shopId: String(row.shop_id || '').trim(),
shopName: String(row.shop_name || '').trim(),
externalItemId: String(row.external_item_id || '').trim(),
externalSkuCode: String(row.external_sku_code || '').trim(),
externalSkuName: String(row.external_sku_name || '').trim(),
latestSeenAt: row.latest_seen_at || null,
orderItemCount: Number(row.order_item_count || 0),
}
}
export async function listAdminObservedProducts(bindings = [], options = {}) {
const queryImpl = /** @type {(sql: string) => Promise<{ rows: Array<Record<string, unknown>> }>} */ (
options.query || query
)
const rowsResult = await queryImpl(ADMIN_OBSERVED_PRODUCTS_QUERY)
return rowsResult.rows.map((row) => mapAdminObservedProductItem(mapAdminObservedProductRow(row), bindings))
}
@@ -0,0 +1,97 @@
import test from 'node:test'
import assert from 'node:assert/strict'
import {
ADMIN_OBSERVED_PRODUCTS_QUERY,
listAdminObservedProducts,
mapAdminObservedProductRow,
} from './admin-platform-config-observed-products.js'
test('mapAdminObservedProductRow normalizes query row fields', () => {
assert.deepEqual(
mapAdminObservedProductRow({
provider: ' agiso ',
platform: ' xianyu ',
shop_id: ' shop-1 ',
shop_name: ' 店铺A ',
external_item_id: ' item-1 ',
external_sku_code: ' sku-1 ',
external_sku_name: ' 商品A ',
latest_seen_at: '2026-05-04T12:00:00.000Z',
order_item_count: '3',
}),
{
provider: 'agiso',
platform: 'xianyu',
shopId: 'shop-1',
shopName: '店铺A',
externalItemId: 'item-1',
externalSkuCode: 'sku-1',
externalSkuName: '商品A',
latestSeenAt: '2026-05-04T12:00:00.000Z',
orderItemCount: 3,
},
)
})
test('listAdminObservedProducts queries rows and maps matched binding summary', async () => {
/** @type {string[]} */
const sqlCalls = []
const result = await listAdminObservedProducts(
[
{
provider: 'agiso',
platform: 'xianyu',
shopId: 'shop-1',
skuCode: 'inner-1',
skuName: '内部商品A',
profileKey: 'manual_review',
match: {
externalSkuCode: 'sku-1',
},
},
],
{
async query(sql) {
sqlCalls.push(sql)
return {
rows: [
{
provider: 'agiso',
platform: 'xianyu',
shop_id: 'shop-1',
shop_name: '店铺A',
external_item_id: '',
external_sku_code: 'sku-1',
external_sku_name: '商品A',
latest_seen_at: '2026-05-04T12:00:00.000Z',
order_item_count: 2,
},
],
}
},
},
)
assert.equal(sqlCalls.length, 1)
assert.equal(sqlCalls[0], ADMIN_OBSERVED_PRODUCTS_QUERY)
assert.deepEqual(result, [
{
provider: 'agiso',
platform: 'xianyu',
shopId: 'shop-1',
shopName: '店铺A',
externalItemId: '',
externalSkuCode: 'sku-1',
externalSkuName: '商品A',
latestSeenAt: '2026-05-04T12:00:00.000Z',
orderItemCount: 2,
configured: true,
matchedBinding: {
skuCode: 'inner-1',
skuName: '内部商品A',
profileKey: 'manual_review',
},
},
])
})
@@ -89,6 +89,7 @@ import {
normalizeFulfillmentLookupPayload, normalizeFulfillmentLookupPayload,
resolveFulfillmentLookupDetail, resolveFulfillmentLookupDetail,
} from './admin-platform-config-fulfillment.js' } from './admin-platform-config-fulfillment.js'
import { listAdminObservedProducts } from './admin-platform-config-observed-products.js'
import { import {
assertAdminFulfillmentBindingsInput, assertAdminFulfillmentBindingsInput,
buildAdminFulfillmentBindingUniqueKey, buildAdminFulfillmentBindingUniqueKey,
@@ -99,7 +100,6 @@ import {
mapAdminAgisoMessagingDefaults, mapAdminAgisoMessagingDefaults,
mapAdminAgisoShopConfigItem, mapAdminAgisoShopConfigItem,
mapAdminFulfillmentBindingConfigItem, mapAdminFulfillmentBindingConfigItem,
mapAdminObservedProductItem,
} from './admin-platform-config-domain.js' } from './admin-platform-config-domain.js'
import { import {
mapAdminCloudtentaclesSession, mapAdminCloudtentaclesSession,
@@ -721,50 +721,11 @@ export async function runAdminCloudtentaclesFullFlow(payload = /** @type {AdminC
export async function getAdminFulfillmentBindingConfigs() { export async function getAdminFulfillmentBindingConfigs() {
const bindings = getOrderFulfillmentBindingConfigs() const bindings = getOrderFulfillmentBindingConfigs()
const rowsResult = await query(
`
SELECT
o.provider,
o.platform,
o.shop_id,
MAX(CASE WHEN trim(o.shop_name) != '' THEN o.shop_name ELSE '' END) AS shop_name,
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalItemId', ''), '') AS external_item_id,
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuCode', ''), '') AS external_sku_code,
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuName', ''), '') AS external_sku_name,
MAX(oi.created_at) AS latest_seen_at,
COUNT(*)::int AS order_item_count
FROM order_items oi
JOIN orders o ON o.id = oi.order_id
WHERE
COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalItemId', ''), '') != ''
OR COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuCode', ''), '') != ''
OR COALESCE(NULLIF(oi.item_snapshot_json ->> 'externalSkuName', ''), '') != ''
GROUP BY
o.provider,
o.platform,
o.shop_id,
external_item_id,
external_sku_code,
external_sku_name
ORDER BY latest_seen_at DESC, o.platform ASC, o.shop_id ASC, external_sku_code ASC
LIMIT 200
`,
)
return { return {
filePath: getOrderFulfillmentBindingsFilePath(), filePath: getOrderFulfillmentBindingsFilePath(),
bindings: bindings.map(mapAdminFulfillmentBindingConfigItem), bindings: bindings.map(mapAdminFulfillmentBindingConfigItem),
observedProducts: rowsResult.rows.map((row) => mapAdminObservedProductItem({ observedProducts: await listAdminObservedProducts(bindings),
provider: String(row.provider || '').trim(),
platform: String(row.platform || '').trim(),
shopId: String(row.shop_id || '').trim(),
shopName: String(row.shop_name || '').trim(),
externalItemId: String(row.external_item_id || '').trim(),
externalSkuCode: String(row.external_sku_code || '').trim(),
externalSkuName: String(row.external_sku_name || '').trim(),
latestSeenAt: row.latest_seen_at || null,
orderItemCount: Number(row.order_item_count || 0),
}, bindings)),
} }
} }