gaoluyang
13 小时以前 e40a608ef9bf51db294d8eefada6a8e2e80cebca
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import sys,json
from pathlib import Path
from collections import defaultdict
sys.stdout.reconfigure(encoding='utf-8')
sys.path.insert(0,str(Path(__file__).parent/'iqc-import-20261012/deps'))
import pymysql
out=Path(__file__).parent/'schedule-diagnosis-20261015'
before=json.loads(sorted(out.glob('complete-route-before-*.json'))[-1].read_text(encoding='utf-8'))
data={}
with pymysql.connect(host='36.213.150.237',port=10000,user='root',password=sys.stdin.readline().strip(),database='mom-hm',charset='utf8mb4',connect_timeout=15,cursorclass=pymysql.cursors.DictCursor) as c:
 with c.cursor() as q:
  for t in before:
   q.execute('SELECT * FROM '+t+' WHERE deleted=0 ORDER BY id');data[t]=q.fetchall()
  q.execute('SELECT * FROM mes_pro_work_order_process WHERE deleted=0 ORDER BY id');data['mes_pro_work_order_process']=q.fetchall()
  q.execute('SELECT id,status FROM mes_dv_machinery WHERE deleted=0');machines={m['id']:m['status'] for m in q.fetchall()}
  q.execute('SELECT * FROM mes_pro_task WHERE deleted=0 AND status NOT IN (4,5)');active=q.fetchall()
  q.execute('SELECT * FROM mes_md_workstation WHERE deleted=0 AND status=0');stations=q.fetchall()
  q.execute('SELECT * FROM mes_md_workstation_machine WHERE deleted=0');links=q.fetchall()
normalize=lambda rows:json.loads(json.dumps(rows,default=str))
assert normalize(data['mes_pro_work_order'])==before['mes_pro_work_order'],'工单被改动'
for table,allowed in [('mes_pro_route',{'status','update_time'}),('mes_pro_route_process',{'output_item_id','update_time'})]:
 now={r['id']:r for r in normalize(data[table])}
 for row in before[table]:
  unexpected={k:{'before':v,'after':now[row['id']].get(k)} for k,v in row.items() if k not in allowed and v!=now[row['id']].get(k)}
  if unexpected:print(json.dumps({'concurrentChange':table,'id':row['id'],'fields':unexpected},ensure_ascii=False))
for table in ['mes_md_product_bom','mes_pro_route_product_bom']:
 now={r['id']:r for r in normalize(data[table])}
 assert all(now[r['id']]==r for r in before[table]),'原有BOM被改动'
assert all(r['status']==0 for r in data['mes_pro_route'])
alloc={(b['route_id'],b['product_id']) for b in data['mes_pro_route_product_bom']}
assert all((p['route_id'],p['item_id']) in alloc for p in data['mes_pro_route_product'])
station_machines=defaultdict(set)
for rel in links:station_machines[rel['workstation_id']].add(rel['machinery_id'])
occupied=set().union(*(station_machines[t['workstation_id']] for t in active)) if active else set()
station_available={s['id']:bool(station_machines[s['id']]) and all(machines.get(i)==1 or (machines.get(i)==2 and i in occupied) for i in station_machines[s['id']]) for s in stations}
order_checks=[]
for o in data['mes_pro_work_order']:
 if o['status']!=1:continue
 qps=[p for p in data['mes_pro_work_order_process'] if p['work_order_id']==o['id']]
 blocked=[p['process_id'] for p in qps if not any(s['process_id']==p['process_id'] and station_available[s['id']] for s in stations)]
 order_checks.append({'id':o['id'],'code':o['code'],'blockedEquipmentProcesses':blocked})
report={'allRoutesEnabled':len(data['mes_pro_route']),'boundProductsWithInput':len(data['mes_pro_route_product']),'explicitOutputProcesses':sum(bool(p['output_item_id']) for p in data['mes_pro_route_process']),'nativeDefaultOutputProcesses':sum(not p['output_item_id'] for p in data['mes_pro_route_process']),'existingBomAndWorkOrdersPreserved':True,'equipmentChecks':order_checks,'scope':'数据库读回及资源前置条件核验,未执行实际排产或线上HTTP预览'}
(out/'verification.json').write_text(json.dumps(report,ensure_ascii=False,indent=2),encoding='utf-8')
print(json.dumps(report,ensure_ascii=False))