feat(work-order): 新增一次性补资料链接
This commit is contained in:
@@ -17,6 +17,7 @@ export * from './work-order-deposit-query-repo.js'
|
||||
export * from './work-order-deposit-repo.js'
|
||||
export * from './work-order-event-repo.js'
|
||||
export * from './work-order-share-repo.js'
|
||||
export * from './work-order-material-link-repo.js'
|
||||
export * from './work-category-repo.js'
|
||||
export * from './work-product-rule-repo.js'
|
||||
export * from './worker-order-note-repo.js'
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
import type { PoolClient } from 'pg'
|
||||
|
||||
import { query } from '../../db/client.js'
|
||||
import type { WorkOrderRow } from './types.js'
|
||||
|
||||
export type WorkOrderMaterialLinkStatus = 'active' | 'used' | 'expired' | 'revoked'
|
||||
|
||||
export type WorkOrderMaterialLinkRow = {
|
||||
id: number
|
||||
work_order_id: number
|
||||
token: string
|
||||
status: WorkOrderMaterialLinkStatus
|
||||
expires_at: string
|
||||
used_at: string | null
|
||||
created_by: string
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
|
||||
export async function findWorkOrderMaterialLinkByToken(
|
||||
token: string,
|
||||
): Promise<WorkOrderMaterialLinkRow | null> {
|
||||
const result = await query<WorkOrderMaterialLinkRow>(
|
||||
'SELECT * FROM work_order_material_links WHERE token = $1 LIMIT 1',
|
||||
[String(token || '').trim()],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
}
|
||||
|
||||
export async function findActiveWorkOrderMaterialLink(
|
||||
workOrderId: number | string,
|
||||
now: string,
|
||||
): Promise<WorkOrderMaterialLinkRow | null> {
|
||||
const result = await query<WorkOrderMaterialLinkRow>(
|
||||
`SELECT * FROM work_order_material_links
|
||||
WHERE work_order_id = $1 AND status = 'active' AND expires_at > $2
|
||||
ORDER BY id DESC
|
||||
LIMIT 1`,
|
||||
[Number(workOrderId), now],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
}
|
||||
|
||||
export async function getWorkOrderForUpdateWithClient(
|
||||
client: PoolClient,
|
||||
workOrderId: number | string,
|
||||
): Promise<WorkOrderRow | null> {
|
||||
const result = await client.query<WorkOrderRow>(
|
||||
'SELECT * FROM work_orders WHERE id = $1 FOR UPDATE',
|
||||
[Number(workOrderId)],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
}
|
||||
|
||||
export async function getWorkOrderMaterialLinkForUpdateWithClient(
|
||||
client: PoolClient,
|
||||
linkId: number | string,
|
||||
): Promise<WorkOrderMaterialLinkRow | null> {
|
||||
const result = await client.query<WorkOrderMaterialLinkRow>(
|
||||
'SELECT * FROM work_order_material_links WHERE id = $1 FOR UPDATE',
|
||||
[Number(linkId)],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
}
|
||||
|
||||
export async function findActiveWorkOrderMaterialLinkWithClient(
|
||||
client: PoolClient,
|
||||
workOrderId: number | string,
|
||||
now: string,
|
||||
): Promise<WorkOrderMaterialLinkRow | null> {
|
||||
const result = await client.query<WorkOrderMaterialLinkRow>(
|
||||
`SELECT * FROM work_order_material_links
|
||||
WHERE work_order_id = $1 AND status = 'active' AND expires_at > $2
|
||||
ORDER BY id DESC
|
||||
LIMIT 1`,
|
||||
[Number(workOrderId), now],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
}
|
||||
|
||||
/** 重新生成前清掉旧 active:已过期标 expired,未过期标 revoked。 */
|
||||
export async function revokeActiveWorkOrderMaterialLinksWithClient(
|
||||
client: PoolClient,
|
||||
workOrderId: number | string,
|
||||
now: string,
|
||||
): Promise<number> {
|
||||
const result = await client.query(
|
||||
`UPDATE work_order_material_links
|
||||
SET status = CASE WHEN expires_at <= $2 THEN 'expired' ELSE 'revoked' END,
|
||||
updated_at = $2
|
||||
WHERE work_order_id = $1 AND status = 'active'`,
|
||||
[Number(workOrderId), now],
|
||||
)
|
||||
return result.rowCount || 0
|
||||
}
|
||||
|
||||
export async function createWorkOrderMaterialLinkWithClient(
|
||||
client: PoolClient,
|
||||
input: {
|
||||
workOrderId: number | string
|
||||
token: string
|
||||
expiresAt: string
|
||||
createdBy: string
|
||||
now: string
|
||||
},
|
||||
): Promise<WorkOrderMaterialLinkRow> {
|
||||
const result = await client.query<WorkOrderMaterialLinkRow>(
|
||||
`INSERT INTO work_order_material_links (
|
||||
work_order_id, token, status, expires_at, created_by, created_at, updated_at
|
||||
) VALUES ($1, $2, 'active', $3, $4, $5, $5)
|
||||
RETURNING *`,
|
||||
[
|
||||
Number(input.workOrderId),
|
||||
input.token,
|
||||
input.expiresAt,
|
||||
String(input.createdBy || '').trim(),
|
||||
input.now,
|
||||
],
|
||||
)
|
||||
return result.rows[0]!
|
||||
}
|
||||
|
||||
export async function markWorkOrderMaterialLinkUsedWithClient(
|
||||
client: PoolClient,
|
||||
linkId: number | string,
|
||||
now: string,
|
||||
): Promise<WorkOrderMaterialLinkRow | null> {
|
||||
const result = await client.query<WorkOrderMaterialLinkRow>(
|
||||
`UPDATE work_order_material_links
|
||||
SET status = 'used', used_at = $2, updated_at = $2
|
||||
WHERE id = $1 AND status = 'active'
|
||||
RETURNING *`,
|
||||
[Number(linkId), now],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
}
|
||||
|
||||
export async function markWorkOrderMaterialLinkExpired(
|
||||
linkId: number | string,
|
||||
now: string,
|
||||
): Promise<void> {
|
||||
await query(
|
||||
`UPDATE work_order_material_links
|
||||
SET status = 'expired', updated_at = $2
|
||||
WHERE id = $1 AND status = 'active'`,
|
||||
[Number(linkId), now],
|
||||
)
|
||||
}
|
||||
|
||||
export async function updateWorkOrderMaterialWithClient(
|
||||
client: PoolClient,
|
||||
input: {
|
||||
workOrderId: number | string
|
||||
status: string
|
||||
materialJson: string
|
||||
now: string
|
||||
},
|
||||
): Promise<WorkOrderRow | null> {
|
||||
const result = await client.query<WorkOrderRow>(
|
||||
`UPDATE work_orders
|
||||
SET status = $2, material_json = $3::jsonb, updated_at = $4
|
||||
WHERE id = $1
|
||||
RETURNING *`,
|
||||
[Number(input.workOrderId), input.status, input.materialJson, input.now],
|
||||
)
|
||||
return result.rows[0] || null
|
||||
}
|
||||
Reference in New Issue
Block a user