优化订单流程与数据库关闭
This commit is contained in:
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user