后端迁移平台配置读写辅助
This commit is contained in:
+15
-6
@@ -1,11 +1,11 @@
|
|||||||
// @ts-check
|
|
||||||
|
|
||||||
import { createHttpError } from '../../../utils/http.js'
|
import { createHttpError } from '../../../utils/http.js'
|
||||||
import { formatFenToAmount } from '../../../utils/money.js'
|
import { formatFenToAmount } from '../../../utils/money.js'
|
||||||
import { isPlainObject, pickFirstNonEmpty } from './context.js'
|
import { isPlainObject, pickFirstNonEmpty } from './context.js'
|
||||||
import { mapAdminObservedProductItem } from './domain.js'
|
import { mapAdminObservedProductItem } from './domain.js'
|
||||||
|
|
||||||
export function normalizeFulfillmentLookupPayload(payload = {}) {
|
type JsonObject = Record<string, any>
|
||||||
|
|
||||||
|
export function normalizeFulfillmentLookupPayload(payload: JsonObject = {}) {
|
||||||
const provider = String(payload.provider || 'agiso').trim() || 'agiso'
|
const provider = String(payload.provider || 'agiso').trim() || 'agiso'
|
||||||
const platform = String(payload.platform || 'xianyu').trim() || 'xianyu'
|
const platform = String(payload.platform || 'xianyu').trim() || 'xianyu'
|
||||||
const shopId = String(payload.shopId || '').trim()
|
const shopId = String(payload.shopId || '').trim()
|
||||||
@@ -35,7 +35,7 @@ export function normalizeFulfillmentLookupPayload(payload = {}) {
|
|||||||
return { provider, platform, shopId, platformOrderId }
|
return { provider, platform, shopId, platformOrderId }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function resolveFulfillmentLookupDetail(detailResult, platformOrderId) {
|
export function resolveFulfillmentLookupDetail(detailResult: JsonObject, platformOrderId: unknown) {
|
||||||
const detail = isPlainObject(detailResult?.parsed) ? detailResult.parsed : {}
|
const detail = isPlainObject(detailResult?.parsed) ? detailResult.parsed : {}
|
||||||
const items = Array.isArray(detail.items) ? detail.items : []
|
const items = Array.isArray(detail.items) ? detail.items : []
|
||||||
|
|
||||||
@@ -66,10 +66,19 @@ export function buildFulfillmentLookupResult({
|
|||||||
platform = '',
|
platform = '',
|
||||||
shopId = '',
|
shopId = '',
|
||||||
platformOrderId = '',
|
platformOrderId = '',
|
||||||
detail = /** @type {Record<string, unknown>} */ ({}),
|
detail = {},
|
||||||
detailResult = /** @type {Record<string, unknown>} */ ({}),
|
detailResult = {},
|
||||||
bindings = [],
|
bindings = [],
|
||||||
fallbackShopName = '',
|
fallbackShopName = '',
|
||||||
|
}: {
|
||||||
|
provider?: string
|
||||||
|
platform?: string
|
||||||
|
shopId?: string
|
||||||
|
platformOrderId?: string
|
||||||
|
detail?: JsonObject
|
||||||
|
detailResult?: JsonObject
|
||||||
|
bindings?: JsonObject[]
|
||||||
|
fallbackShopName?: string
|
||||||
} = {}) {
|
} = {}) {
|
||||||
const resolvedShopName = pickFirstNonEmpty([detail.shopName, fallbackShopName])
|
const resolvedShopName = pickFirstNonEmpty([detail.shopName, fallbackShopName])
|
||||||
const items = Array.isArray(detail.items) ? detail.items : []
|
const items = Array.isArray(detail.items) ? detail.items : []
|
||||||
+5
-7
@@ -1,8 +1,8 @@
|
|||||||
// @ts-check
|
|
||||||
|
|
||||||
import { query } from '../../../db/client.js'
|
import { query } from '../../../db/client.js'
|
||||||
import { mapAdminObservedProductItem } from './domain.js'
|
import { mapAdminObservedProductItem } from './domain.js'
|
||||||
|
|
||||||
|
type JsonObject = Record<string, any>
|
||||||
|
|
||||||
export const ADMIN_OBSERVED_PRODUCTS_QUERY = `
|
export const ADMIN_OBSERVED_PRODUCTS_QUERY = `
|
||||||
SELECT
|
SELECT
|
||||||
o.provider,
|
o.provider,
|
||||||
@@ -31,7 +31,7 @@ export const ADMIN_OBSERVED_PRODUCTS_QUERY = `
|
|||||||
LIMIT 200
|
LIMIT 200
|
||||||
`
|
`
|
||||||
|
|
||||||
export function mapAdminObservedProductRow(row = {}) {
|
export function mapAdminObservedProductRow(row: JsonObject = {}) {
|
||||||
return {
|
return {
|
||||||
provider: String(row.provider || '').trim(),
|
provider: String(row.provider || '').trim(),
|
||||||
platform: String(row.platform || '').trim(),
|
platform: String(row.platform || '').trim(),
|
||||||
@@ -45,10 +45,8 @@ export function mapAdminObservedProductRow(row = {}) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function listAdminObservedProducts(bindings = [], options = {}) {
|
export async function listAdminObservedProducts(bindings: JsonObject[] = [], options: JsonObject = {}) {
|
||||||
const queryImpl = /** @type {(sql: string) => Promise<{ rows: Array<Record<string, unknown>> }>} */ (
|
const queryImpl = (options.query || query) as (sql: string) => Promise<{ rows: JsonObject[] }>
|
||||||
options.query || query
|
|
||||||
)
|
|
||||||
const rowsResult = await queryImpl(ADMIN_OBSERVED_PRODUCTS_QUERY)
|
const rowsResult = await queryImpl(ADMIN_OBSERVED_PRODUCTS_QUERY)
|
||||||
return rowsResult.rows.map((row) => mapAdminObservedProductItem(mapAdminObservedProductRow(row), bindings))
|
return rowsResult.rows.map((row) => mapAdminObservedProductItem(mapAdminObservedProductRow(row), bindings))
|
||||||
}
|
}
|
||||||
+12
-16
@@ -1,14 +1,14 @@
|
|||||||
// @ts-check
|
|
||||||
|
|
||||||
import { applyOptionalStringField } from "./domain.js";
|
import { applyOptionalStringField } from "./domain.js";
|
||||||
|
|
||||||
export function buildAdminAgisoShopConfigUpdate(item, current = {}) {
|
type JsonObject = Record<string, any>
|
||||||
|
|
||||||
|
export function buildAdminAgisoShopConfigUpdate(item: JsonObject, current: JsonObject = {}) {
|
||||||
const shopId = String(item?.shopId || "").trim();
|
const shopId = String(item?.shopId || "").trim();
|
||||||
if (!shopId) {
|
if (!shopId) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const next = /** @type {Record<string, unknown>} */ ({ ...current });
|
const next: JsonObject = { ...current };
|
||||||
const shopName = String(item?.shopName || "").trim();
|
const shopName = String(item?.shopName || "").trim();
|
||||||
const accessToken = String(item?.accessToken || "").trim();
|
const accessToken = String(item?.accessToken || "").trim();
|
||||||
const messageTemplate = String(item?.messageTemplate || "").trim();
|
const messageTemplate = String(item?.messageTemplate || "").trim();
|
||||||
@@ -58,20 +58,16 @@ export function buildAdminAgisoShopConfigUpdate(item, current = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function buildAdminAgisoMessagingSavePayload(
|
export function buildAdminAgisoMessagingSavePayload(
|
||||||
payload = {},
|
payload: JsonObject = {},
|
||||||
options = {}
|
options: JsonObject = {}
|
||||||
) {
|
) {
|
||||||
const rawItems = Array.isArray(payload.shops) ? payload.shops : [];
|
const rawItems = Array.isArray(payload.shops) ? payload.shops : [];
|
||||||
const currentDefaults = /** @type {Record<string, unknown>} */ (
|
const currentDefaults: JsonObject = options.currentDefaults || {};
|
||||||
options.currentDefaults || {}
|
const currentMap: Record<string, JsonObject> = options.currentMap || {};
|
||||||
);
|
const nextDefaults: JsonObject = {
|
||||||
const currentMap = /** @type {Record<string, Record<string, unknown>>} */ (
|
|
||||||
options.currentMap || {}
|
|
||||||
);
|
|
||||||
const nextDefaults = /** @type {Record<string, unknown>} */ ({
|
|
||||||
...currentDefaults,
|
...currentDefaults,
|
||||||
});
|
};
|
||||||
const nextMap = /** @type {Record<string, Record<string, unknown>>} */ ({});
|
const nextMap: Record<string, JsonObject> = {};
|
||||||
|
|
||||||
applyOptionalStringField(nextDefaults, "messageTemplate", payload.defaults);
|
applyOptionalStringField(nextDefaults, "messageTemplate", payload.defaults);
|
||||||
applyOptionalStringField(
|
applyOptionalStringField(
|
||||||
@@ -103,7 +99,7 @@ export function buildAdminAgisoMessagingSavePayload(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function normalizeAdminCloudtentaclesSourceConfigPayload(payload = {}) {
|
export function normalizeAdminCloudtentaclesSourceConfigPayload(payload: JsonObject = {}) {
|
||||||
const sourceKey =
|
const sourceKey =
|
||||||
String(payload.sourceKey || payload.key || "").trim() || "default";
|
String(payload.sourceKey || payload.key || "").trim() || "default";
|
||||||
return {
|
return {
|
||||||
@@ -589,6 +589,16 @@
|
|||||||
- `npm run typecheck`
|
- `npm run typecheck`
|
||||||
- `npm run build`
|
- `npm run build`
|
||||||
- `npm test` 共 139 个用例通过
|
- `npm test` 共 139 个用例通过
|
||||||
|
138. 后台平台配置观察 / 查询 / 写入辅助模块迁移到 `.ts`:
|
||||||
|
- `src/services/admin/platform-config/observed-products.ts`
|
||||||
|
- `src/services/admin/platform-config/fulfillment.ts`
|
||||||
|
- `src/services/admin/platform-config/writes.ts`
|
||||||
|
139. 后台观察商品列表、履约手动查询结果组装、Agiso 店铺消息配置写入与 Cloudtentacles 来源配置归一化已进入 TS 编译链路;查询依赖、payload 与配置 map 补齐动态对象类型
|
||||||
|
140. Docker 内验证通过:
|
||||||
|
- `src/services/admin/platform-config/observed-products.test.js`、`fulfillment.test.js`、`writes.test.js` 共 8 个用例通过
|
||||||
|
- `npm run typecheck`
|
||||||
|
- `npm run build`
|
||||||
|
- `npm test` 共 139 个用例通过
|
||||||
|
|
||||||
## 下一步建议
|
## 下一步建议
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user