增强工单游戏资料搜索

This commit is contained in:
yml2213
2026-08-17 19:26:31 +08:00
parent 2aa8769661
commit 1b4bdec56d
5 changed files with 45 additions and 8 deletions
@@ -0,0 +1,22 @@
-- 031_work_order_search.sql —— 扩展接单工单搜索字段并建立模糊检索索引。
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX IF NOT EXISTS idx_work_orders_search_text_trgm
ON work_orders USING gin (
LOWER(
COALESCE(work_order_no, '') || ' ' ||
COALESCE(platform_order_id, '') || ' ' ||
COALESCE(product_name, '') || ' ' ||
COALESCE(material_json->'collect'->'fields'->>'gameId', '') || ' ' ||
COALESCE(material_json->'collect'->'fields'->>'gameNickname', '') || ' ' ||
COALESCE(material_json->'collect'->'fields'->>'gameAccount', '') || ' ' ||
COALESCE(material_json->'collect'->'fields'->>'roleName', '') || ' ' ||
COALESCE(material_json->'fields'->>'gameId', '') || ' ' ||
COALESCE(material_json->'fields'->>'gameNickname', '') || ' ' ||
COALESCE(material_json->>'gameId', '') || ' ' ||
COALESCE(material_json->>'gameNickname', '')
) gin_trgm_ops
);
COMMENT ON INDEX idx_work_orders_search_text_trgm IS '接单工单模糊搜索:订单号、商品名、游戏 ID/昵称及历史字段';
@@ -65,6 +65,23 @@ type WorkOrderStatisticsRow = {
refund_amount: number | string refund_amount: number | string
} }
/** 工单统一搜索字段,兼容当前资料结构和历史资料字段。 */
function workOrderSearchExpression(alias = 'wo') {
return `LOWER(
COALESCE(${alias}.work_order_no, '') || ' ' ||
COALESCE(${alias}.platform_order_id, '') || ' ' ||
COALESCE(${alias}.product_name, '') || ' ' ||
COALESCE(${alias}.material_json->'collect'->'fields'->>'gameId', '') || ' ' ||
COALESCE(${alias}.material_json->'collect'->'fields'->>'gameNickname', '') || ' ' ||
COALESCE(${alias}.material_json->'collect'->'fields'->>'gameAccount', '') || ' ' ||
COALESCE(${alias}.material_json->'collect'->'fields'->>'roleName', '') || ' ' ||
COALESCE(${alias}.material_json->'fields'->>'gameId', '') || ' ' ||
COALESCE(${alias}.material_json->'fields'->>'gameNickname', '') || ' ' ||
COALESCE(${alias}.material_json->>'gameId', '') || ' ' ||
COALESCE(${alias}.material_json->>'gameNickname', '')
)`
}
export async function listWorkOrderShares( export async function listWorkOrderShares(
workOrderId: number | string, workOrderId: number | string,
): Promise<WorkOrderShareRow[]> { ): Promise<WorkOrderShareRow[]> {
@@ -2821,9 +2838,7 @@ function buildWorkOrderWhere({
} }
if (keyword) { if (keyword) {
params.push(`%${keyword}%`) params.push(`%${keyword}%`)
filters.push( filters.push(`${workOrderSearchExpression()} LIKE LOWER($${params.length})`)
`(wo.work_order_no ILIKE $${params.length} OR wo.platform_order_id ILIKE $${params.length} OR wo.product_name ILIKE $${params.length})`,
)
} }
if (workerId) { if (workerId) {
params.push(workerId) params.push(workerId)
@@ -912,7 +912,7 @@ export default function WorkOrdersPanel() {
<Input <Input
allowClear allowClear
value={keywordInput} value={keywordInput}
placeholder="订单号或商品名" placeholder="订单号 / 商品名 / 游戏ID / 游戏昵称"
style={{ width: 280 }} style={{ width: 280 }}
onChange={(event) => setKeywordInput(event.target.value)} onChange={(event) => setKeywordInput(event.target.value)}
onPressEnter={searchOrders} onPressEnter={searchOrders}
@@ -327,7 +327,7 @@ export default function WorkerHallPage() {
<Input <Input
allowClear allowClear
value={keywordInput} value={keywordInput}
placeholder="搜索商品 / 订单号" placeholder="搜索商品 / 订单号 / 游戏ID / 游戏昵称"
prefix={<SearchOutlined />} prefix={<SearchOutlined />}
className="worker-hall-mobile-search-input" className="worker-hall-mobile-search-input"
onChange={(event) => { onChange={(event) => {
@@ -524,7 +524,7 @@ export default function WorkerHallPage() {
<Input <Input
allowClear allowClear
value={keywordInput} value={keywordInput}
placeholder="搜索商品名称 / 订单号" placeholder="搜索商品名称 / 订单号 / 游戏ID / 游戏昵称"
prefix={<SearchOutlined />} prefix={<SearchOutlined />}
onChange={(event) => { onChange={(event) => {
const nextKeyword = event.target.value const nextKeyword = event.target.value
@@ -659,7 +659,7 @@ export default function WorkerOrdersPage() {
<Input <Input
allowClear allowClear
value={keywordInput} value={keywordInput}
placeholder="搜索订单号 / 商品名" placeholder="搜索订单号 / 商品名 / 游戏ID / 游戏昵称"
prefix={<SearchOutlined />} prefix={<SearchOutlined />}
className="worker-orders-mobile-search-input" className="worker-orders-mobile-search-input"
onChange={(event) => { onChange={(event) => {
@@ -986,7 +986,7 @@ export default function WorkerOrdersPage() {
<Input <Input
allowClear allowClear
value={keywordInput} value={keywordInput}
placeholder="搜索订单号 / 商品名" placeholder="搜索订单号 / 商品名 / 游戏ID / 游戏昵称"
prefix={<SearchOutlined />} prefix={<SearchOutlined />}
onChange={(event) => { onChange={(event) => {
const nextValue = event.target.value const nextValue = event.target.value