{ "properties" : { }, "id" : "a1b2c3d4e5f6478990abcdef12345678", "script" : null, "groupId" : "f8e3d2c1b0a94e5f8a7b6c5d4e3f2a1", "name" : "牦牛供应实时信息", "createTime" : 1780882000000, "updateTime" : null, "lock" : null, "createBy" : "admin", "updateBy" : "admin", "path" : "/yak-supply-realtime-info", "method" : "GET", "parameters" : [ { "name" : "pageNo", "value" : "1", "description" : "页码,从 1 开始(勿用 page,与 magic-api 内置分页参数冲突)", "required" : false, "dataType" : "Integer", "type" : null, "defaultValue" : "1", "validateType" : null, "error" : null, "expression" : null, "children" : null }, { "name" : "pageSize", "value" : "5", "description" : "每页条数", "required" : false, "dataType" : "Integer", "type" : null, "defaultValue" : "5", "validateType" : null, "error" : null, "expression" : null, "children" : null } ], "options" : [ ], "requestBody" : "", "headers" : [ ], "paths" : [ ], "responseBody" : null, "description" : "牦牛供应实时信息:卖家进场登记列表与汇总,数据源 yak_trade_entry_record + 耳标库存(只读)。", "requestBodyDefinition" : null, "responseBodyDefinition" : null } ================================ // 只读查询,不修改任何数据 // page 为 magic-api 内置分页变量,页码参数使用 pageNo var pageNum = 1 var sizeNum = 5 if (pageNo) { pageNum = pageNo } if (pageSize) { sizeNum = pageSize } if (pageNum < 1) { pageNum = 1 } if (sizeNum < 1) { sizeNum = 5 } if (sizeNum > 50) { sizeNum = 50 } var offset = (pageNum - 1) * sizeNum var summarySql = """ SELECT COUNT(*) FILTER (WHERE entered_at >= CURRENT_DATE) AS today_entries, COALESCE(SUM(yak_count), 0) AS total_yaks, COUNT(*) FILTER (WHERE sold_count > 0 AND sold_count < yak_count) AS trading_count, COUNT(*) AS total_records FROM ( SELECT e.entered_at, COALESCE(NULLIF(inv.yak_count, 0), et.yak_count, 0) AS yak_count, COALESCE(inv.sold_count, 0) AS sold_count FROM yak_trade_entry_record e LEFT JOIN ( SELECT seller_entry_record_id, COUNT(*) AS yak_count, COUNT(*) FILTER (WHERE status = 'SOLD') AS sold_count FROM yak_trade_ear_tag_inventory GROUP BY seller_entry_record_id ) inv ON inv.seller_entry_record_id = e.id LEFT JOIN ( SELECT entry_record_id, COUNT(*) AS yak_count FROM yak_trade_entry_record_ear_tag GROUP BY entry_record_id ) et ON et.entry_record_id = e.id WHERE e.entry_type = 'SELLER' ) t """ var listSql = """ SELECT e.id, e.name, e.vehicle_no, e.phone, COALESCE(c.region_name, c.address, '') AS origin, COALESCE(e.quarantine_certificate_no, '') AS quarantine_no, to_char(e.entered_at, 'YYYY-MM-DD HH24:MI') AS entry_time, COALESCE(NULLIF(inv.yak_count, 0), et.yak_count, 0) AS yak_count, COALESCE(inv.sold_count, 0) AS sold_count, CASE WHEN COALESCE(NULLIF(inv.yak_count, 0), et.yak_count, 0) = 0 THEN 0 ELSE ROUND( COALESCE(inv.sold_count, 0) * 100.0 / COALESCE(NULLIF(inv.yak_count, 0), et.yak_count, 0) )::int END AS progress FROM yak_trade_entry_record e LEFT JOIN ( SELECT seller_entry_record_id, COUNT(*) AS yak_count, COUNT(*) FILTER (WHERE status = 'SOLD') AS sold_count FROM yak_trade_ear_tag_inventory GROUP BY seller_entry_record_id ) inv ON inv.seller_entry_record_id = e.id LEFT JOIN ( SELECT entry_record_id, COUNT(*) AS yak_count FROM yak_trade_entry_record_ear_tag GROUP BY entry_record_id ) et ON et.entry_record_id = e.id LEFT JOIN yak_sn_customer c ON c.id = e.party_id AND c.del_flag = '0' WHERE e.entry_type = 'SELLER' ORDER BY e.entered_at DESC LIMIT #{sizeNum} OFFSET #{offset} """ var summaryRows = db.select(summarySql) var summaryRow = summaryRows && summaryRows.length > 0 ? summaryRows[0] : null var rows = db.select(listSql) var list = [] for (row in rows) { var yakCount = row.yakCount ? row.yakCount : (row.yak_count ? row.yak_count : 0) var soldCount = row.soldCount ? row.soldCount : (row.sold_count ? row.sold_count : 0) var progress = row.progress ? row.progress : 0 list.push({ id: row.id, name: row.name ? row.name : '', licensePlate: row.vehicleNo ? row.vehicleNo : (row.vehicle_no ? row.vehicle_no : ''), yakCount: yakCount, contact: row.phone ? row.phone : '', origin: row.origin ? row.origin : '', quarantineNo: row.quarantineNo ? row.quarantineNo : (row.quarantine_no ? row.quarantine_no : ''), entryTime: row.entryTime ? row.entryTime : (row.entry_time ? row.entry_time : ''), progress: progress, tradedCount: soldCount, pendingCount: yakCount - soldCount }) } return { summary: { todayEntries: summaryRow && summaryRow.todayEntries ? summaryRow.todayEntries : (summaryRow && summaryRow.today_entries ? summaryRow.today_entries : 0), totalYaks: summaryRow && summaryRow.totalYaks ? summaryRow.totalYaks : (summaryRow && summaryRow.total_yaks ? summaryRow.total_yaks : 0), tradingCount: summaryRow && summaryRow.tradingCount ? summaryRow.tradingCount : (summaryRow && summaryRow.trading_count ? summaryRow.trading_count : 0) }, total: summaryRow && summaryRow.totalRecords ? summaryRow.totalRecords : (summaryRow && summaryRow.total_records ? summaryRow.total_records : 0), list: list }