feat(energy): 嘉燃经开站存在 JQ 单时全局过滤 GF_HECRI_BILL 历史订单
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
业务背景:旧系统加氢账单使用 GF_HECRI_BILL 前缀,新系统统一改用 JQ 前缀。 切换期间两套数据共存,会重复计入加氢量。约定:当嘉兴嘉燃经开站出现 JQ 订单(视为切到新单号体系),全局过滤掉 GF_HECRI_BILL 前缀的历史订单。 实现: - shouldFilterGfBills() 探测嘉兴嘉燃经开站是否有 JQ 单,结果缓存 5 分钟 - GF_EXCLUDE_CLAUSE = b.bill_code NOT LIKE 'GF\_HECRI\_BILL%' ESCAPE '\\' - 应用到 4 处氢能查询:KPI、Top5、区域占比、daily 站点聚合 实测:当前嘉燃经开 4508 JQ + 665 GF,嘉锦 11783 JQ + 1 GF,全部 GF 已隐藏。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -22,6 +22,31 @@ function customerClause(field: string, customer: CustomerKind): string {
|
||||
|
||||
type Range = 'today' | 'thisWeek' | 'thisMonth' | 'thisQuarter' | 'last7' | 'last30';
|
||||
|
||||
// 是否应过滤 GF_HECRI_BILL 前缀的加氢订单:
|
||||
// 当嘉兴嘉燃经开站存在 JQ 前缀订单时(说明业务已切到新单号体系),
|
||||
// 把 GF_HECRI_BILL 历史/重复订单过滤掉;否则不过滤。
|
||||
// 结果缓存 5 分钟,避免每次请求都跑探测查询。
|
||||
let gfFilterCache: { value: boolean; expiresAt: number } | null = null;
|
||||
const GF_FILTER_TTL_MS = 5 * 60 * 1000;
|
||||
async function shouldFilterGfBills(): Promise<boolean> {
|
||||
const now = Date.now();
|
||||
if (gfFilterCache && gfFilterCache.expiresAt > now) return gfFilterCache.value;
|
||||
const [rows] = await pool.query<RowDataPacket[]>(
|
||||
`SELECT 1 FROM tab_energy_hydrogen_bill b
|
||||
LEFT JOIN tab_hydrogen_site s ON s.id = b.hydrogen_station_id
|
||||
LEFT JOIN tab_outside_hydrogen_site os ON os.inner_site_id = b.hydrogen_station_id
|
||||
WHERE b.is_deleted = 0
|
||||
AND b.bill_code LIKE 'JQ%'
|
||||
AND (s.short_name LIKE '%嘉燃经开%' OR s.name LIKE '%嘉燃经开%'
|
||||
OR os.station_name LIKE '%嘉燃经开%' OR os.fixed_station_name LIKE '%嘉燃经开%')
|
||||
LIMIT 1`,
|
||||
);
|
||||
const value = rows.length > 0;
|
||||
gfFilterCache = { value, expiresAt: now + GF_FILTER_TTL_MS };
|
||||
return value;
|
||||
}
|
||||
const GF_EXCLUDE_CLAUSE = `b.bill_code NOT LIKE 'GF\\_HECRI\\_BILL%' ESCAPE '\\\\'`;
|
||||
|
||||
function rangeClause(localExpr: string, range: Range): string {
|
||||
switch (range) {
|
||||
case 'today': return `DATE(${localExpr}) = CURDATE()`;
|
||||
@@ -38,6 +63,9 @@ function rangeClause(localExpr: string, range: Range): string {
|
||||
// =========================================================
|
||||
app.get('/hydrogen/overview', async (c) => {
|
||||
const data = await cached('hydrogen/overview', async () => {
|
||||
const filterGf = await shouldFilterGfBills();
|
||||
const gfClauseKpi = filterGf ? `AND bill_code NOT LIKE 'GF\\_HECRI\\_BILL%' ESCAPE '\\\\'` : '';
|
||||
const gfClause = filterGf ? `AND ${GF_EXCLUDE_CLAUSE}` : '';
|
||||
// KPI(年/月/日 + 我方/客户分解 + 累计羚牛承担)
|
||||
const [kpiRows] = await pool.query<RowDataPacket[]>(
|
||||
`SELECT
|
||||
@@ -64,7 +92,7 @@ app.get('/hydrogen/overview', async (c) => {
|
||||
SUM(CASE WHEN truck_id IS NOT NULL
|
||||
THEN cost_expense ELSE 0 END) AS lingniuBornFee
|
||||
FROM tab_energy_hydrogen_bill
|
||||
WHERE is_deleted = 0 AND hydrogen_time >= ?`,
|
||||
WHERE is_deleted = 0 AND hydrogen_time >= ? ${gfClauseKpi}`,
|
||||
[HYDROGEN_MIN_DATE],
|
||||
);
|
||||
const k = kpiRows[0] ?? {};
|
||||
@@ -99,6 +127,7 @@ app.get('/hydrogen/overview', async (c) => {
|
||||
WHERE b.is_deleted = 0
|
||||
AND b.hydrogen_time >= ?
|
||||
AND YEAR(DATE_ADD(b.hydrogen_time, INTERVAL 8 HOUR)) = YEAR(CURDATE())
|
||||
${gfClause}
|
||||
GROUP BY b.hydrogen_station_id
|
||||
ORDER BY kg DESC
|
||||
LIMIT 5`,
|
||||
@@ -123,7 +152,8 @@ app.get('/hydrogen/overview', async (c) => {
|
||||
LEFT JOIN tab_outside_hydrogen_site os ON os.inner_site_id = b.hydrogen_station_id
|
||||
WHERE b.is_deleted = 0
|
||||
AND b.hydrogen_time >= ?
|
||||
AND YEAR(${HYDROGEN_LOCAL}) = YEAR(CURDATE())
|
||||
AND YEAR(DATE_ADD(b.hydrogen_time, INTERVAL 8 HOUR)) = YEAR(CURDATE())
|
||||
${gfClause}
|
||||
) r
|
||||
GROUP BY region
|
||||
ORDER BY kg DESC`,
|
||||
@@ -156,11 +186,13 @@ app.get('/hydrogen/daily', async (c) => {
|
||||
|
||||
const data = await cached(`hydrogen/daily?range=${range}&customer=${customer}`, async () => {
|
||||
|
||||
const filterGf = await shouldFilterGfBills();
|
||||
const where = [
|
||||
'b.is_deleted = 0',
|
||||
`b.hydrogen_time >= '${HYDROGEN_MIN_DATE}'`,
|
||||
rangeClause(`b.hydrogen_time + INTERVAL 8 HOUR`, range),
|
||||
customerClause('b.truck_id', customer),
|
||||
filterGf ? GF_EXCLUDE_CLAUSE : '1=1',
|
||||
].join(' AND ');
|
||||
|
||||
// 站点级聚合(每日 × 每站)。前端组装成 day → stations
|
||||
|
||||
Reference in New Issue
Block a user