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.
 
 
 
 
 

95 lines
3.0 KiB

import json, os
from collections import Counter
base = r'.scratch/opportunity-e2e/env-raw'
out_path = r'.scratch/opportunity-e2e/env-analysis.txt'
_buf = []
def out(s=''):
_buf.append(str(s))
def load(name):
with open(os.path.join(base, name + '.json'), encoding='utf-8-sig') as f:
return json.load(f)
def fix(s):
"""PS5.1 把 UTF-8 响应按 Latin-1 解码的 mojibake,可逆还原"""
if not isinstance(s, str):
return s
try:
t = s.encode('latin-1').decode('utf-8')
return t
except (UnicodeEncodeError, UnicodeDecodeError):
return s
def deepfix(x):
if isinstance(x, str):
return fix(x)
if isinstance(x, list):
return [deepfix(i) for i in x]
if isinstance(x, dict):
return {k: deepfix(v) for k, v in x.items()}
return x
def content(payload):
d = payload.get('data')
if isinstance(d, list):
return d, len(d)
d = d or {}
for k in ('content', 'list', 'records', 'rows'):
if isinstance(d.get(k), list):
return d.get(k), d.get('total')
return [], d.get('total')
# 1. 部门树(只打前 3 层,全量在 json 里)
depts = load('depts')
rows = depts.get('data') or []
out('=== DEPTS TREE (top3 levels) ===')
def walk(nodes, depth=0):
for n in nodes:
if not isinstance(n, dict):
continue
out(' ' * depth + '- id=%s name=%s parent=%s' % (n.get('id'), fix(n.get('deptName') or n.get('name')), n.get('parentId')))
if depth < 2:
walk(n.get('children') or [], depth + 1)
walk(rows)
# 2. 用户
users = load('users')
ul, utotal = content(users)
out('=== USERS total=%s n_page1=%s ===' % (utotal, len(ul)))
if ul:
out('sample-fields: ' + json.dumps(deepfix(ul[0]), ensure_ascii=False)[:700])
me = [u for u in ul if str(u.get('id')) == '739564171091247104']
out('me row: ' + (json.dumps(deepfix(me[0]), ensure_ascii=False)[:700] if me else 'not-in-page1'))
cnt = Counter(fix(u.get('deptName')) or 'dept-null' for u in ul)
out('dept dist top12: ' + repr(cnt.most_common(12)))
# 3. 商机
opp = load('opp-page-MINE')
ol, ot = content(opp)
out('=== OPP MINE total=%s n=%s ===' % (ot, len(ol)))
if ol:
out('fields: ' + repr(sorted(ol[0].keys())))
for k in ol[0].keys():
if 'status' in k.lower():
out('dist(%s): %s' % (k, Counter(str(o.get(k)) for o in ol).most_common()))
out('sample row: ' + json.dumps(deepfix(ol[0]), ensure_ascii=False)[:900])
# 4. 规则三族
for f in ['rule-opp-stage-template', 'rule-opp-scheme-template', 'rule-opp-pool-rule']:
r = load(f)
rl, rt = content(r)
out('=== %s total=%s ===' % (f, rt))
for x in rl:
out(json.dumps(deepfix(x), ensure_ascii=False)[:900])
# 5. 字典 22 组
g = load('dict-groups')
gl, gt = content(g)
out('=== DICT GROUPS (enabled) total=%s ===' % gt)
for x in gl:
out('%s | %s | sort=%s' % (x.get('code'), fix(x.get('name')), x.get('sortNo')))
with open(out_path, 'w', encoding='utf-8') as f:
f.write('\n'.join(_buf))
print('written', out_path, len(_buf), 'lines')