优化订单流程与数据库关闭

This commit is contained in:
yml2213
2026-08-30 13:15:47 +08:00
parent 04dc363320
commit dcb0fa4c76
5 changed files with 243 additions and 113 deletions
@@ -4,7 +4,7 @@ import { query, withTransaction } from '../db/client.js'
import type { OrderItemReplaceInput } from '../types/repository/inputs.js'
import type { OrderItemRow } from '../types/repository/rows.js'
type QueryExecutor = (text: string, params?: unknown[]) => Promise<QueryResult<any>>
export type QueryExecutor = (text: string, params?: unknown[]) => Promise<QueryResult<any>>
type OrderItemSyncPlan = {
updates: Array<{
@@ -25,14 +25,22 @@ export async function replaceOrderItems(
orderId: number | string,
items: OrderItemReplaceInput[],
): Promise<OrderItemRow[]> {
return withTransaction(async (client: PoolClient) => {
const executor: QueryExecutor = client.query.bind(client)
const existingItems = await listOrderItemsByOrderIdWithExecutor(executor, orderId)
const plan = resolveOrderItemSyncPlan(existingItems, items)
return withTransaction((client: PoolClient) =>
replaceOrderItemsWithExecutor(client.query.bind(client), orderId, items),
)
}
for (const update of plan.updates) {
await executor(
`
export async function replaceOrderItemsWithExecutor(
executor: QueryExecutor,
orderId: number | string,
items: OrderItemReplaceInput[],
): Promise<OrderItemRow[]> {
const existingItems = await listOrderItemsByOrderIdWithExecutor(executor, orderId)
const plan = resolveOrderItemSyncPlan(existingItems, items)
for (const update of plan.updates) {
await executor(
`
UPDATE order_items
SET
sku_code = $1,
@@ -43,21 +51,21 @@ export async function replaceOrderItems(
updated_at = $6
WHERE id = $7
`,
[
update.item.skuCode,
update.item.skuName,
update.item.quantity,
update.item.specJson || '{}',
update.item.itemSnapshotJson || update.item.specJson || '{}',
update.item.updatedAt,
update.orderItemId,
],
)
}
[
update.item.skuCode,
update.item.skuName,
update.item.quantity,
update.item.specJson || '{}',
update.item.itemSnapshotJson || update.item.specJson || '{}',
update.item.updatedAt,
update.orderItemId,
],
)
}
for (const create of plan.creates) {
await executor(
`
for (const create of plan.creates) {
await executor(
`
INSERT INTO order_items (
order_id,
sku_code,
@@ -69,29 +77,28 @@ export async function replaceOrderItems(
updated_at
) VALUES ($1, $2, $3, $4, $5::jsonb, $6::jsonb, $7, $8)
`,
[
Number(orderId),
create.skuCode,
create.skuName,
create.quantity,
create.specJson || '{}',
create.itemSnapshotJson || create.specJson || '{}',
create.createdAt,
create.updatedAt,
],
)
[
Number(orderId),
create.skuCode,
create.skuName,
create.quantity,
create.specJson || '{}',
create.itemSnapshotJson || create.specJson || '{}',
create.createdAt,
create.updatedAt,
],
)
}
if (plan.deletes.length > 0) {
const deletableIds = await listDeletableOrderItemIdsWithExecutor(executor, plan.deletes)
if (deletableIds.length > 0) {
await executor('DELETE FROM order_items WHERE id = ANY($1::bigint[])', [deletableIds])
}
}
if (plan.deletes.length > 0) {
const deletableIds = await listDeletableOrderItemIdsWithExecutor(executor, plan.deletes)
if (deletableIds.length > 0) {
await executor('DELETE FROM order_items WHERE id = ANY($1::bigint[])', [deletableIds])
}
}
return listOrderItemsByOrderIdWithExecutor(executor, orderId)
})
return listOrderItemsByOrderIdWithExecutor(executor, orderId)
}
export function resolveOrderItemSyncPlan(
+36 -3
View File
@@ -1,3 +1,5 @@
import type { QueryResult, QueryResultRow } from 'pg'
import { query } from '../db/client.js'
import type {
OrderCreateInput,
@@ -6,6 +8,11 @@ import type {
} from '../types/repository/inputs.js'
import type { OrderListQueryResult, OrderListRow, OrderRow } from '../types/repository/rows.js'
export type OrderQueryExecutor = <T extends QueryResultRow = QueryResultRow>(
text: string,
params?: unknown[],
) => Promise<QueryResult<T>>
type OrderPlatformLookupInput = {
provider?: string
platform: string
@@ -37,7 +44,18 @@ export async function findLatestOrderByPlatformOrderId({
platform,
platformOrderId,
}: Omit<OrderPlatformLookupInput, 'shopId'>): Promise<OrderRow | null> {
const result = await query<OrderRow>(
return findLatestOrderByPlatformOrderIdWithExecutor(query, {
provider,
platform,
platformOrderId,
})
}
export async function findLatestOrderByPlatformOrderIdWithExecutor(
executor: OrderQueryExecutor,
{ provider = '91kaquan', platform, platformOrderId }: Omit<OrderPlatformLookupInput, 'shopId'>,
): Promise<OrderRow | null> {
const result = await executor<OrderRow>(
`
SELECT *
FROM orders
@@ -69,7 +87,14 @@ export async function findLatestOrderByAnyPlatformOrderId(
}
export async function createOrder(input: OrderCreateInput): Promise<OrderRow | null> {
const result = await query<OrderRow>(
return createOrderWithExecutor(query, input)
}
export async function createOrderWithExecutor(
executor: OrderQueryExecutor,
input: OrderCreateInput,
): Promise<OrderRow | null> {
const result = await executor<OrderRow>(
`
INSERT INTO orders (
provider,
@@ -118,7 +143,15 @@ export async function updateOrder(
orderId: number | string,
input: OrderUpdateInput,
): Promise<OrderRow | null> {
const result = await query<OrderRow>(
return updateOrderWithExecutor(query, orderId, input)
}
export async function updateOrderWithExecutor(
executor: OrderQueryExecutor,
orderId: number | string,
input: OrderUpdateInput,
): Promise<OrderRow | null> {
const result = await executor<OrderRow>(
`
UPDATE orders
SET