wwt-platform 1.1.11 → 1.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wwt-platform",
3
- "version": "1.1.11",
3
+ "version": "1.1.12",
4
4
  "description": "WWT 工作平台 - 平台本体与工具清单分发",
5
5
  "files": [
6
6
  "platform.html",
package/platform.html CHANGED
@@ -591,6 +591,46 @@ const COLORS=['#1a6fd4','#14915b','#6b46d4','#c47f00','#d92b2b','#0891b2','#7c3a
591
591
  const CAT_ICONS={销售:'💰',入库:'📦',出库:'🚛',维修:'🔧',调拨:'🔄',对账:'📋',往来账:'📒',凭证:'🧾',其他:'📂'};
592
592
  const CAT_COLORS={销售:'#1a6fd4',入库:'#14915b',出库:'#0891b2',维修:'#c47f00',调拨:'#6b46d4',对账:'#7c3aed',往来账:'#b45309',凭证:'#d92b2b',其他:'#5b656f'};
593
593
 
594
+ // ── 免安装 exe 模式 ──────────────────────────────────────────
595
+ // 启动器注入 window.__WWT_SERVER__ 时,平台和工具都由本地服务下发。
596
+ // 关键收益:平台与工具同源(http://127.0.0.1),iframe 里 localStorage /
597
+ // IndexedDB 全部可用;工具也不再依赖写死的本地路径。
598
+ const SRV = (typeof window!=='undefined' && window.__WWT_SERVER__) || null;
599
+ const SRV_MODE = !!(SRV && SRV.base);
600
+
601
+ // 从本地服务同步工具列表(服务端为准,用户自己上传的工具保留)
602
+ async function syncServerTools(){
603
+ if(!SRV_MODE) return false;
604
+ try{
605
+ const r = await fetch(SRV.base + '/api/tools', {cache:'no-store'});
606
+ const j = await r.json();
607
+ if(!j || !Array.isArray(j.tools)) return false;
608
+
609
+ // 保留用户自己上传的工具(有 fileId 且不是服务端下发的)
610
+ const keep = [];
611
+ (ST.modules||[]).forEach(m => (m.tools||[]).forEach(t => {
612
+ if(t.fileId && !t.skey) keep.push({mod:m.id, tool:t});
613
+ }));
614
+
615
+ (ST.modules||[]).forEach(m => {
616
+ m.tools = (m.tools||[]).filter(t => t.fileId && !t.skey);
617
+ });
618
+
619
+ j.tools.forEach(t => {
620
+ const mod = (ST.modules||[]).find(x => x.id === t.module) || ST.modules[0];
621
+ if(!mod) return;
622
+ mod.tools.push({
623
+ id:'srv_'+t.key, name:t.name, desc:t.desc, tag:t.tag||'HTML',
624
+ skey:t.key, local:false, mkey:t.key, installed:!!t.installed, ver:t.ver
625
+ });
626
+ });
627
+
628
+ ST.__srv = {manifestVer:j.manifestVer, manifestSrc:j.manifestSrc, launcher:j.launcher};
629
+ save(); renderNav();
630
+ return true;
631
+ }catch(e){ return false; }
632
+ }
633
+
594
634
  function initST(){return{modules:[
595
635
  {id:'fin',name:'财务',desc:'财务对账、核销、凭证管理等工具集',icon:'💰',color:'#1a6fd4',open:true,tools:[
596
636
  {id:'t1',name:'往来款项两清工具',desc:'自动对账核销,支持 Excel 导入',tag:'HTML',path:'C:/Users/Administrator/Desktop/往来款项两清工具.html',local:true},
@@ -735,6 +775,11 @@ function openTool(tid,mid){
735
775
  openServiceTool(tool,mod);return;
736
776
  }
737
777
 
778
+ // ── exe 模式:工具由本地服务下发(同源 → 存储、Worker、下载全部正常)──
779
+ if(tool.skey && SRV_MODE){
780
+ openServerTool(tool,mod);return;
781
+ }
782
+
738
783
  // ── 本地/上传型工具多重开预警 ──
739
784
  warnIfToolOpenInOtherTab(tool);markToolOpen(tool);
740
785
 
@@ -785,6 +830,30 @@ function markToolOpen(tool){
785
830
  window.addEventListener('pagehide',onUnload);
786
831
  }
787
832
 
833
+ // ── exe 模式:打开由本地服务下发的工具 ──────────────────────────────
834
+ // 平台与工具同源(http://127.0.0.1:端口),因此界面里的一切存储能力都正常,
835
+ // 不再出现 file:// / blob:null 下 localStorage 被禁的问题
836
+ function openServerTool(tool,mod){
837
+ hideAll();curPage='tool-'+tool.id;setTxt('ttag',tool.name);
838
+ const url = SRV.base + '/tool/' + tool.skey;
839
+ let fp=$id('fp-'+tool.id);
840
+ if(!fp){
841
+ fp=mk('div','fpage');fp.id='fp-'+tool.id;
842
+ fp.innerHTML=`
843
+ <div class="frame-hd">
844
+ <button class="back-btn" onclick="showModPage('${mod.id}')">← 返回${esc(mod.name)}模块</button>
845
+ <h3>${esc(tool.name)}</h3>
846
+ <div style="display:flex;gap:8px">
847
+ <button class="btn sm" onclick="(function(){const f=$id('ifr-${tool.id}');if(f){const s=f.src;f.src='';f.src=s;}})()">↻ 刷新</button>
848
+ <button class="btn sm" onclick="window.open('${url}','_blank')">⧉ 新窗口</button>
849
+ </div>
850
+ </div>
851
+ <div class="frame-box"><iframe id="ifr-${tool.id}" src="${url}"></iframe></div>`;
852
+ $id('main').appendChild(fp);
853
+ }
854
+ fp.classList.add('on');renderNav();
855
+ }
856
+
788
857
  // ── 上传型工具:从 IndexedDB 读回文件内容,动态生成 blob 地址 ────────────────
789
858
  async function openUploadedTool(tool,mod){
790
859
  warnIfToolOpenInOtherTab(tool);
@@ -1357,7 +1426,7 @@ function doAddMod(){
1357
1426
  // ═══════════════════════════════════════════════════════════
1358
1427
  // 平台更新(方案B:平台 + 内置工具统一检查)
1359
1428
  // ═══════════════════════════════════════════════════════════
1360
- const PLATFORM_VER = '1.1.11';
1429
+ const PLATFORM_VER = '1.1.12';
1361
1430
  const NPM_PKG = 'wwt-platform'; // NPM 包名(主力分发源)
1362
1431
  const GITEE_TOKEN_KEY = 'wwt_gitee_token';
1363
1432
  const GITEE_TOKEN_DEF = 'e45883b9c89b8d9689746ce42bbc2b0b';
@@ -1382,7 +1451,7 @@ const SOURCES = [
1382
1451
  // 更新清单:每个条目 = 一个可更新对象(平台或工具)
1383
1452
  // 这是「离线兜底种子」——联网时会与远程 tools.json 合并,远程为准
1384
1453
  const UPD_REG_DEF = [
1385
- {key:'platform', name:'WWT 工作平台', cur:'1.1.11', repo:GITEE_PLATFORM_REPO, verFile:'version.js', appFile:'app.js', pat:'__WWT_PLATFORM_VER', kind:'platform'},
1454
+ {key:'platform', name:'WWT 工作平台', cur:'1.1.12', repo:GITEE_PLATFORM_REPO, verFile:'version.js', appFile:'app.js', pat:'__WWT_PLATFORM_VER', kind:'platform'},
1386
1455
  {key:'erp-recon', name:'ERP 对账工具', cur:'V1.0.2',repo:'wwtmrhu/erp-recon', verFile:'version.js', appFile:'app.js', pat:'__ERP_LATEST_VER'},
1387
1456
  {key:'erp-tool', name:'ERP 对账单生成匹配', cur:'1.0.0', repo:'wwtmrhu/erp-tool', verFile:'version.js', appFile:'app.js', pat:'__ERP_LATEST_VER'},
1388
1457
  {key:'voucher', name:'WWT 凭证工具', cur:'P1.2.12',repo:'wwtmrhu/certificate-generation', verFile:'dist/version.json', appFile:'', pat:'ver', appUrl:true}
@@ -1996,9 +2065,47 @@ function b64ToBytes(b64) {
1996
2065
  return bytes;
1997
2066
  }
1998
2067
 
2068
+ // exe 模式下的更新:全部交给本地服务完成
2069
+ // 工具 → 服务下载后写入数据目录,平台界面立即生效,无需手动替换文件
2070
+ // 平台 → 服务下载新版 platform.html 到数据目录,下次启动自动采用
2071
+ async function doUpdateViaServer(key, it) {
2072
+ const body = $id('upd-body');
2073
+ const setMsg = (t, bg, color) => {
2074
+ const html = '<div id="upd-prog" style="margin-top:10px;padding:10px 14px;background:'
2075
+ + (bg || 'var(--bg)') + ';border-radius:8px;font-size:13px;color:' + (color || 'var(--text-2)') + '">' + t + '</div>';
2076
+ const old = $id('upd-prog');
2077
+ if (old) old.outerHTML = html; else body.insertAdjacentHTML('beforeend', html);
2078
+ };
2079
+
2080
+ const isPlat = key === 'platform';
2081
+ setMsg('⏳ 正在由本地服务下载「' + esc(it.name) + '」最新版…');
2082
+ try {
2083
+ const url = SRV.base + (isPlat ? '/api/update-platform' : '/api/install?key=' + encodeURIComponent(key));
2084
+ const r = await fetch(url, {cache:'no-store'});
2085
+ const j = await r.json();
2086
+ if (!j.ok) throw new Error(j.error || '更新失败');
2087
+
2088
+ markUpdatedSilent(key, it.manifestVer || it.cur);
2089
+ if (!isPlat) await syncServerTools(); // 工具装好后重建界面
2090
+ renderUpdList();
2091
+
2092
+ setMsg('✅ 「' + esc(it.name) + '」已更新完成'
2093
+ + (isPlat ? ',<b>重新打开浏览器页面即可生效</b>(数据不受影响)。'
2094
+ : ',本地服务已直接装好,<b>无需手动替换任何文件</b>。'),
2095
+ '#f0fdf4', 'var(--green)');
2096
+ toast('✓ 「' + it.name + '」已更新', 'ok');
2097
+ } catch(e) {
2098
+ setMsg('❌ 更新失败:' + esc(e.message), '#fef2f2', 'var(--red)');
2099
+ }
2100
+ }
2101
+
1999
2102
  async function doUpdateOne(key) {
2000
2103
  const it = UPD_REG.find(x=>x.key===key);
2001
2104
  if (!it) return;
2105
+
2106
+ // exe 模式:交给本地服务处理
2107
+ if (SRV_MODE) return await doUpdateViaServer(key, it);
2108
+
2002
2109
  const body = $id('upd-body');
2003
2110
  const prog = '<div id="upd-prog" style="margin-top:10px;padding:10px 14px;background:var(--bg);border-radius:8px;font-size:13px;color:var(--text-2)">⏳ 正在下载「'+esc(it.name)+'」最新版…</div>';
2004
2111
  // 已有进度条就更新,没有就追加
@@ -2086,10 +2193,19 @@ function _init(){
2086
2193
  }
2087
2194
  }
2088
2195
  }
2196
+ // exe 模式:启动后从本地服务同步工具列表(服务端为准),再重绘界面
2197
+ function _boot(){
2198
+ _init();
2199
+ if(SRV_MODE){
2200
+ syncServerTools().then(ok=>{
2201
+ if(ok){ renderNav(); if(curPage==='home') renderHomeMods(); }
2202
+ });
2203
+ }
2204
+ }
2089
2205
  if(document.readyState==='loading'){
2090
- document.addEventListener('DOMContentLoaded',_init);
2206
+ document.addEventListener('DOMContentLoaded',_boot);
2091
2207
  }else{
2092
- _init();
2208
+ _boot();
2093
2209
  }
2094
2210
  </script>
2095
2211
  </body>
package/tools.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "schema": 1,
3
- "platform": "1.1.11",
3
+ "platform": "1.1.12",
4
4
  "updatedAt": "2026-09-10",
5
5
  "note": "WWT 工作平台工具清单。新增/修改工具只需改这个文件并发布新版本,用户端自动同步,无需重新分发平台。",
6
6
  "tools": [