# -*- coding: utf-8 -*- """票 09:验证 fat jar 含 D-16 收尾字节码(detail 引用 describeStages/stageStayDays), 并复跑票 06 四判据确认无回退。""" import io, sys, os, time, zipfile sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') jar = r'e:\code\crm-backend-matt\crm-app\target\crm-app-1.0.0-SNAPSHOT.jar' print('fat jar mtime =', time.strftime('%m-%d %H:%M:%S', time.localtime(os.stat(jar).st_mtime))) z = zipfile.ZipFile(jar) nested = [n for n in z.namelist() if n.startswith('BOOT-INF/lib/crm-opportunity-')] print('[nested]', nested) inner = zipfile.ZipFile(z.open(nested[0])) # 票 06 四判据复跑 has_filter = any(n.endswith('query/OpportunityViewFilter.class') for n in inner.namelist()) ti = [n for n in inner.namelist() if n.endswith('state/impl/OpportunityTransitionImpl.class')] oplog_msg = '商机状态:'.encode('utf-8') in inner.read(ti[0]) sc = [n for n in inner.namelist() if n.endswith('controller/OpportunitySubController.class')] biz_const = b'ATTACHMENT_BIZ_TYPES' in inner.read(sc[0]) ent = [n for n in inner.namelist() if n.endswith('domain/entity/Opportunity.class')] snap_field = b'schemeCardStatus' in inner.read(ent[0]) print('[T06] filter/oplog/bizconst/snapshot =', has_filter, oplog_msg, biz_const, snap_field) # 票 09 新判据:OpportunityDetailServiceImpl 引用 describeStages(D-16 收尾) ds = [n for n in inner.namelist() if n.endswith('service/impl/OpportunityDetailServiceImpl.class')] detail_bytes = inner.read(ds[0]) d16_stage = b'describeStages' in detail_bytes d16_stay = b'setStageStayDays' in detail_bytes # setter 调用在常量池是 setStageStayDays print('[T09-D16] detail describeStages/stageStayDays =', d16_stage, d16_stay) ok = has_filter and oplog_msg and biz_const and snap_field and d16_stage and d16_stay print('VERDICT:', 'NEW-JAR-WITH-T09' if ok else 'OLD-JAR-T09-MISSING')