103 lines
6.4 KiB
Python
103 lines
6.4 KiB
Python
from pathlib import Path
|
|
import hashlib,json,shutil,re
|
|
ROOTS=[Path('C:/wechat_rpa'),Path('C:/kefu/wechat_rpa')]
|
|
HELPERS='''const loadingActionLocks = new Set();
|
|
const recentDbSelections = new Map();
|
|
function isLoadingActionPending(method){ return loadingActionLocks.has(method); }
|
|
function callLoadingAction(method, action, label){
|
|
const serverBusy = method === "refreshWeChatDatabase" ? (STATE.wechatDb || {}).loading
|
|
: (((STATE.automation || {}).protocol || {}).status === "checking");
|
|
if (serverBusy || loadingActionLocks.has(method)) return;
|
|
loadingActionLocks.add(method);
|
|
const selector = `[data-action="${action}"]`;
|
|
const button = document.querySelector(selector);
|
|
if (button){ button.disabled = true; button.innerHTML = icon("refresh") + label; }
|
|
if (!callBridge(method)) {
|
|
loadingActionLocks.delete(method);
|
|
if (button) button.disabled = false;
|
|
toast("界面尚未连接后台,请稍后重试。");
|
|
if (STATE.view) render(STATE.view);
|
|
return;
|
|
}
|
|
// Qt owns long-running work. This short local lock covers the bridge round trip.
|
|
setTimeout(()=>{
|
|
loadingActionLocks.delete(method);
|
|
const current = document.querySelector(selector);
|
|
const busy = method === "refreshWeChatDatabase" ? (STATE.wechatDb || {}).loading
|
|
: (((STATE.automation || {}).protocol || {}).status === "checking");
|
|
if (current && !busy){
|
|
current.disabled = false;
|
|
current.innerHTML = icon("refresh") + (method === "refreshWeChatDatabase" ? "刷新消息库" : "检测本机协议");
|
|
}
|
|
}, 800);
|
|
}
|
|
function selectDbItem(method, key, selected){
|
|
const last = recentDbSelections.get(method);
|
|
const recent = last && performance.now() - last.at < 800;
|
|
if ((recent && last.key === key) || (!recent && String(selected || "") === key)) return;
|
|
recentDbSelections.set(method, {key, at:performance.now()});
|
|
callBridge(method, key);
|
|
}
|
|
|
|
'''
|
|
def once(s,old,new):
|
|
assert s.count(old)==1,(old[:100],s.count(old))
|
|
return s.replace(old,new,1)
|
|
manifest=[]
|
|
for root in ROOTS:
|
|
backup=root/'backups/loading-performance-20260917/frontend'
|
|
for rel in ['assets/ui/console-app.js','assets/ui/zhenyang-ai-console.html']:
|
|
src=root/rel;dst=backup/rel
|
|
assert not dst.exists(),dst
|
|
dst.parent.mkdir(parents=True,exist_ok=True);shutil.copy2(src,dst)
|
|
js=root/'assets/ui/console-app.js';s=js.read_text(encoding='utf-8')
|
|
s=once(s,'const _queueList = queueList;',HELPERS+'const _queueList = queueList;')
|
|
s=once(s,'"wechat-db-refresh": () => callBridge("refreshWeChatDatabase") || toast("正在刷新消息库"),','"wechat-db-refresh": () => callLoadingAction("refreshWeChatDatabase", "wechat-db-refresh", "正在读取…"),')
|
|
s=once(s,'"wechat-db-account": () => callBridge("selectWeChatAccount", key),','"wechat-db-account": () => selectDbItem("selectWeChatAccount", key, (STATE.wechatDb || {}).selectedAccount),')
|
|
s=once(s,'"wechat-db-conversation": () => callBridge("selectWeChatConversation", key),','"wechat-db-conversation": () => selectDbItem("selectWeChatConversation", key, (STATE.wechatDb || {}).selectedConversation),')
|
|
s=once(s,'data-action="wechat-db-refresh" ${db.loading ? "disabled" : ""}','data-action="wechat-db-refresh" ${db.loading || isLoadingActionPending("refreshWeChatDatabase") ? "disabled" : ""}')
|
|
s=once(s,'const patientControl = !currentConversation ? "" : !canSearchPatient','const patientControl = !currentConversation ? "" : patientContext.loading\n ? `<span class="badge" data-patient-loading="1">${icon("refresh")} 患者关联加载中</span>`\n : !canSearchPatient')
|
|
if root==ROOTS[0]:
|
|
s=once(s,'const checking = p.status === "checking";', 'const checking = p.status === "checking" || isLoadingActionPending("probeProtocol");')
|
|
s=once(s,'"probe-protocol": () => callBridge("probeProtocol"),','"probe-protocol": () => callLoadingAction("probeProtocol", "probe-protocol", "检测中…"),')
|
|
else:
|
|
s=once(s,'let searchTimer = 0;', '''let searchTimer = 0;
|
|
let dbSearchComposing = false;
|
|
document.addEventListener("compositionstart", event=>{
|
|
if (event.target && event.target.id === "wechat-db-search") {
|
|
dbSearchComposing = true;
|
|
clearTimeout(searchTimer);
|
|
}
|
|
});
|
|
document.addEventListener("compositionend", event=>{
|
|
if (event.target && event.target.id === "wechat-db-search") {
|
|
dbSearchComposing = false;
|
|
event.target.dispatchEvent(new Event("input", {bubbles:true}));
|
|
}
|
|
});''')
|
|
s=once(s,' const value = e.target.value || "";\n if (["ai-name"', ' const value = e.target.value || "";\n if (id === "wechat-db-search" && (e.isComposing || dbSearchComposing)) { clearTimeout(searchTimer); return; }\n if (["ai-name"')
|
|
s=once(s,' const sameView = STATE.view === name;\n STATE.view = name;', ''' const sameView = STATE.view === name;
|
|
const active = document.activeElement;
|
|
const keepSearch = sameView && active && active.id === "wechat-db-search"
|
|
? {element:active, start:active.selectionStart, end:active.selectionEnd} : null;
|
|
STATE.view = name;''')
|
|
s=once(s,' main.innerHTML = html;\n normalizeReferenceView();', ''' main.innerHTML = html;
|
|
if (keepSearch){
|
|
const placeholder=document.getElementById("wechat-db-search");
|
|
if (placeholder){
|
|
placeholder.replaceWith(keepSearch.element);
|
|
keepSearch.element.focus({preventScroll:true});
|
|
if (keepSearch.start != null) keepSearch.element.setSelectionRange(keepSearch.start,keepSearch.end);
|
|
}
|
|
}
|
|
normalizeReferenceView();''')
|
|
s=once(s,' const prev = STATE.view;\n Object.assign(STATE, data);', ' const prev = STATE.view;\n Object.assign(STATE, data);')
|
|
s=once(s,' if (typing && (STATE.view || prev) === prev && ["ai"', ' if (dbSearchComposing && prev === "wechatdb" && (STATE.view || prev) === prev) return;\n if (typing && (STATE.view || prev) === prev && ["ai"')
|
|
js.write_text(s,encoding='utf-8',newline='\n')
|
|
html=root/'assets/ui/zhenyang-ai-console.html';s=html.read_text(encoding='utf-8')
|
|
s,n=re.subn(r'console-app\.js\?v=[^"\s]+','console-app.js?v=loading1',s);assert n==1
|
|
html.write_text(s,encoding='utf-8',newline='\n')
|
|
manifest.append({'root':str(root),'files':[{'path':rel,'sha256':hashlib.sha256((root/rel).read_bytes()).hexdigest()} for rel in ['assets/ui/console-app.js','assets/ui/zhenyang-ai-console.html']]})
|
|
Path('C:/kefu/deploy/loading-performance-20260917/frontend-files.json').write_text(json.dumps(manifest,ensure_ascii=False,indent=2),encoding='utf-8')
|
|
print('Saved JS-only loading improvements and HTML cache keys in both directories.')
|