You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
3.1 KiB

19 hours ago
# -*- coding: utf-8 -*-
"""clean-residue-defix.py — customer-defectfix 终态残留清理 + 复扫
终态目标任务书 §.6 seed 活跃 e2c-* = 0活跃=archive_status=0
seed 17 样例白名单外清理走正门 POST /api/customer/archive?id=
落盘.scratch/customer-defectfix/residue-final.json
"""
import io, sys, json, time
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
import requests
import pymysql
BASE = 'http://localhost:8080'
ADMIN = '739564171091247104'
OUT = '.scratch/customer-defectfix/residue-final.json'
ids = json.load(open('.scratch/customer-e2e/seed-ids.json', encoding='utf-8'))
SEED = {str(v['id']) for v in ids.get('customers', {}).values()}
print(f'seed 白名单 {len(SEED)}')
def db():
return pymysql.connect(host='8.129.84.155', port=3306, user='root', password='Itc@123456',
database='crm', charset='utf8mb4', autocommit=True,
connect_timeout=10, cursorclass=pymysql.cursors.DictCursor)
def dbq(sql, args=None):
with db() as conn, conn.cursor() as cur:
cur.execute(sql, args)
return cur.fetchall()
def scan():
# 口径:archive_status 1=有效 2=已归档(Customer.java L135-137);有效且非 seed = 残留
rows = dbq("SELECT id, customer_no, customer_name, archive_status, create_time "
"FROM customer WHERE customer_name LIKE 'e2c-%' ORDER BY create_time")
active = [r for r in rows if str(r['id']) not in SEED and int(r['archive_status'] or 0) == 1]
return rows, active
rows, active = scan()
print(f'e2c-* 总数={len(rows)},非 seed 活跃残留={len(active)}')
for r in active:
print(f" 待清理: {r['id']} {r['customer_name']} no={r['customer_no']} created={r['create_time']}")
# archive 正门清理
r = requests.get(f'{BASE}/api/auth/debug/token', params={'userId': ADMIN}, timeout=30)
tok = r.json().get('data')
tok = tok if isinstance(tok, str) else (tok or {}).get('token')
S = requests.Session()
S.headers['Authorization'] = f'Bearer {tok}'
results = []
for r_ in active:
resp = S.post(f'{BASE}/api/customer/archive', params={'id': str(r_['id'])}, timeout=30)
body = resp.json() if resp.status_code == 200 else {}
ok = resp.status_code == 200 and body.get('code') == 0
results.append({'id': str(r_['id']), 'name': r_['customer_name'],
'archive': ok, 'msg': str(body.get('message'))[:60]})
print(f" archive {r_['customer_name']}: {'OK' if ok else 'FAIL ' + str(body)[:80]}")
time.sleep(0.2)
# 复扫
rows2, active2 = scan()
print(f'\n复扫:非 seed 活跃 e2c-* = {len(active2)}')
for r_ in active2:
print(f" 仍活跃: {r_['id']} {r_['customer_name']} arch={r_['archive_status']}")
report = {'before_active': len(active), 'archived': results, 'after_active': len(active2),
'CLEAN_OK': len(active2) == 0}
json.dump(report, open(OUT, 'w', encoding='utf-8'), ensure_ascii=False, indent=2)
print('\n== 残留终态', 'CLEAN_OK ✅(非 seed 活跃=0)' if report['CLEAN_OK'] else '仍有残留 ❌',
',证据落盘', OUT, '==')