"""生成本地双版本导航与真人素材审看页,不依赖网络。""" import csv import html import io import json from pathlib import Path ROOT=Path(__file__).resolve().parent.parent LIVE=ROOT/'08_真人AI短剧' assets=json.loads((LIVE/'02_资产/全部资产任务.json').read_text(encoding='utf8')) receipts={} notes_path=LIVE/'05_检查与交付/图像审看提示.json' notes=json.loads(notes_path.read_text(encoding='utf8')) if notes_path.exists() else {} for p in (LIVE/'02_资产/生成回执').glob('*.json'): r=json.loads(p.read_text(encoding='utf8'));receipts[r['id']]=r cards=[];rows=[] for a in assets: r=receipts.get(a['id']);exists=bool(r and (LIVE/r['path']).is_file()) status='REVIEW' if exists else '待生成' kind='角色' if a['kind']=='character' else '场景' picpath=r['path'] if exists else '' note=notes.get(a['id'],'') row={'资产ID':a['id'],'名称':a['name'],'类别':kind,'状态':status,'图片':picpath, '提示词':'04_生成与后期/逐项出图提示词/'+a['id']+'.txt','原生尺寸':'×'.join(map(str,r['size'])) if exists and r.get('size') else '', '身份':a.get('identity',''),'审看提示':note,'角色批准':'未批准','动作验证':'未测试'} rows.append(row) title=html.escape(a['name']);aid=html.escape(a['id']) picture=f'{title}' if exists else '
待生成
' note_html=f'

{html.escape(note)}

' if note else '' identity_html=f'

{html.escape(a.get("identity",""))}

' if a.get('identity') else '' cards.append(f'
{picture}

{title}

{aid}

{identity_html}

{kind} · {status}

{note_html}查看完整提示词
') done=sum(r['状态']=='REVIEW' for r in rows) page='''真人AI短剧素材审看

真人AI奇幻短剧素材审看

COUNT · 每项可查看原图与实际出图提示词。REVIEW表示已出候选,尚未作者批准或动作验证。

CARDS
''' page=page.replace('COUNT',f'已生成 {done} / {len(assets)} 项').replace('CARDS','\n'.join(cards)) (LIVE/'素材审看.html').write_text(page,encoding='utf8') out=io.StringIO(newline='');w=csv.DictWriter(out,list(rows[0]),delimiter='\t',lineterminator='\n');w.writeheader();w.writerows(rows) (LIVE/'02_资产/资产制作总表.tsv').write_text(out.getvalue(),encoding='utf8') report={'total':len(assets),'generated':done,'remaining':len(assets)-done,'characters':sum(a['kind']=='character' for a in assets),'environments':sum(a['kind']=='environment' for a in assets),'missing':[a['id'] for a in assets if not (receipts.get(a['id']) and (LIVE/receipts[a['id']]['path']).is_file())]} (LIVE/'05_检查与交付/图像生成进度.json').write_text(json.dumps(report,ensure_ascii=False,indent=2)+'\n',encoding='utf8') print(json.dumps({k:v for k,v in report.items() if k!='missing'},ensure_ascii=False))