
    j[                         d dl mZ d dlmZmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ dd	lmZmZ g d
ZdedefdZdedefdZdefdZdefdZddedefdZddedefdZdS )    )logger)execute	query_all   )calc_case_score)calc_behavior_score)calc_family_score)calc_education_score)calc_social_score)upsert_scoreappend_history))P   extreme)<   high)(   medium)   low)r   normalscorereturnc                 4    t           D ]\  }}| |k    r|c S dS )Nr   )RISK_LEVELS)r   	thresholdlevels      E/home/longshao/multi-rider-rag/modules/score/services/score_engine.py_map_risk_levelr      s4    '  	5ILLL 8    zjhmc                    t          |           \  }}t          |           \  }}t          |           \  }}t          |           \  }}t	          |           \  }	}
t          ||z   |z   |z   |	z   d          }t          |          }|||||
d}t          | |||||||	|	  	         t          | ||           | |||||||	|d	S )Nd   )casebehaviorfamily	educationsocial)	r    total_score
risk_leveldim_casedim_behavior
dim_familydim_education
dim_socialdetail)	r   r   r	   r
   r   minr   r   r   )r    r*   case_detailr+   behavior_detailr,   family_detailr-   education_detailr.   social_detailtotalr)   detail_jsons                 r   calculate_scorer8      s   +D11Hk$7$=$=!L/ 1$ 7 7J&:4&@&@#M# 1$ 7 7J<'*4}DzQSVWWE ''J #% K uj(L]JE E E4
+++  $ & 
 
 
r   c                  L   d} t          |           }t          |          }d}d}|D ]a}|                    d          }|s	 t          |           |dz  }0# t          $ r%}|dz  }t          j        d||           Y d }~Zd }~ww xY wt          j        d|||           |||dS )Nz4SELECT zjhm FROM "jcgkzx_monitor"."wcnr_target_pool"r   r    r   z#Score calculation failed for %s: %sz9Batch recalculate complete: total=%d success=%d failed=%d)r6   successfailed)r   lengetr8   	Exceptionr   warninginfo)sqlrowsr6   r:   r;   rowr    es           r   batch_recalculaterE   >   s    
@CS>>DIIEGF 	K 	Kwwv 		KD!!!qLGG 	K 	K 	KaKFN@$JJJJJJJJ	K KKUT[]cdddw&AAAs   A
B!BBc                     | dS |dS 	 | |k     S # t           $ r# t          |           t          |          k     cY S w xY w)NT)	TypeErrorstr)	calc_timelast_event_times     r   _score_is_stalerK   U   sb    tt5?** 5 5 59~~O 4 444445s    *==   window_minutesc                    	 t          dt          | pd                    }n# t          t          f$ r d}Y nw xY wd}	 t	          |d|i          }n1# t
          $ r$}t          j        d|           dddcY d }~S d }~ww xY wt          |          }d}|D ]}|	                    d          }|st          |	                    d	          |	                    d
                    sQ	 t          |           |dz  }g# t
          $ r }t          j        d||           Y d }~d }~ww xY wt          j        d||           ||dS )Nr   rL   a  
        WITH candidate_events AS (
            SELECT x."xyrxx_sfzh" AS zjhm,
                   MAX(a."ajxx_fasj") AS last_event_time
            FROM "ywdata"."zq_zfba_xyrxx" x
            JOIN "ywdata"."zq_zfba_ajxx" a
              ON a."ajxx_ajbh" = x."ajxx_join_ajxx_ajbh"
            WHERE a."ajxx_fasj" >= CURRENT_TIMESTAMP - make_interval(mins => %(window_minutes)s)
              AND x."xyrxx_sfzh" IS NOT NULL
            GROUP BY x."xyrxx_sfzh"

            UNION ALL

            SELECT b."sfzhm" AS zjhm,
                   MAX(b."wf_sj") AS last_event_time
            FROM "ywdata"."t_wcnrxwjl_xx" b
            WHERE b."wf_sj" >= CURRENT_TIMESTAMP - make_interval(mins => %(window_minutes)s)
              AND b."sfzhm" IS NOT NULL
            GROUP BY b."sfzhm"
        ),
        latest_events AS (
            SELECT zjhm, MAX(last_event_time) AS last_event_time
            FROM candidate_events
            WHERE zjhm IS NOT NULL
            GROUP BY zjhm
        )
        SELECT e.zjhm, e.last_event_time, s.calc_time
        FROM latest_events e
        LEFT JOIN "jcgkzx_monitor"."wcnr_score" s
          ON s.zjhm = e.zjhm
        ORDER BY e.last_event_time DESC
        LIMIT 500
    rM   z!Incremental score scan failed: %sr   )scannedrecalculatedr    rI   rJ   z/Incremental score calculation failed for %s: %sz<Incremental recalculate complete: scanned=%d recalculated=%d)maxintrG   
ValueErrorr   r>   r   r?   r<   r=   rK   r8   r@   )	rM   safe_windowrA   rB   excrO   rP   rC   r    s	            r   incremental_recalculaterV   `   s   !S!526677z"    CB1/=>> 1 1 1:C@@@a000000001 $iiGL 
Y 
Ywwv 	sww{33SWW=N5O5OPP 		YD!!!ALL 	Y 	Y 	YNLdTWXXXXXXXX	Y KNPWYefff===sA   " 88A 
A?A:4A?:A?'C<<
D&D!!D&   	decrementc                     	 t          dt          |                     } n# t          t          f$ r d} Y nw xY wd}t	          |d| i          }t          j        d| |           d|iS )z?Decay scores by `decrement` for all rows whose total_score > 0.r   rW   aO  
        UPDATE "jcgkzx_monitor"."wcnr_score"
        SET total_score = GREATEST(total_score - %(decrement)s, 0),
            risk_level = CASE
                WHEN GREATEST(total_score - %(decrement)s, 0) >= 80 THEN 'extreme'
                WHEN GREATEST(total_score - %(decrement)s, 0) >= 60 THEN 'high'
                WHEN GREATEST(total_score - %(decrement)s, 0) >= 40 THEN 'medium'
                WHEN GREATEST(total_score - %(decrement)s, 0) >= 20 THEN 'low'
                ELSE 'normal'
            END,
            calc_time = CURRENT_TIMESTAMP
        WHERE total_score > 0
    rX   z5Monthly score decay complete: decrement=%s updated=%supdated)rQ   rR   rG   rS   r   r   r@   )rX   rA   rZ   s      r   monthly_decayr[      s    3y>>**		z"   			C cK344G
KGT[\\\ws     66N)rL   )rW   )shared.config.configr   shared.db.kingbaser   r   r*   r   r+   r   r,   r	   r-   r
   r.   r   score_storer   r   r   rR   rH   r   dictr8   rE   boolrK   rV   r[    r   r   <module>rb      s   ' ' ' ' ' ' 1 1 1 1 1 1 1 1 % % % % % % - - - - - - ) ) ) ) ) ) / / / / / / ) ) ) ) ) ) 5 5 5 5 5 5 5 5  3 3     #  $        FB4 B B B B.54 5 5 5 5<> <>C <> <> <> <> <>~   S              r   