wwt-platform 1.1.10 → 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 +1 -1
- package/platform.html +138 -7
- package/tools.json +1 -1
package/package.json
CHANGED
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.
|
|
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.
|
|
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}
|
|
@@ -1616,12 +1685,20 @@ function mergeManifest(m) {
|
|
|
1616
1685
|
|
|
1617
1686
|
// 找出「清单里有、平台界面里还没装」的工具
|
|
1618
1687
|
function refreshNewTools() {
|
|
1688
|
+
const mods = ST.modules || [];
|
|
1689
|
+
// 模块 id 不存在时回退到第一个模块,避免清单里模块名写错导致工具被静默忽略
|
|
1690
|
+
const resolveMod = (id) => mods.find(x => x.id === id) || mods[0] || null;
|
|
1691
|
+
|
|
1619
1692
|
_newTools = UPD_REG.filter(it => {
|
|
1620
1693
|
if (it.key === 'platform' || it.removed) return false;
|
|
1621
|
-
const m = (
|
|
1694
|
+
const m = resolveMod(it.module || 'fin');
|
|
1622
1695
|
if (!m) return false;
|
|
1623
1696
|
return !(m.tools || []).some(t => t.mkey === it.key);
|
|
1624
|
-
}).map(it =>
|
|
1697
|
+
}).map(it => {
|
|
1698
|
+
const m = resolveMod(it.module || 'fin');
|
|
1699
|
+
return { key: it.key, name: it.name, desc: it.desc, module: m.id, ver: it.cur,
|
|
1700
|
+
moduleFixed: it.module && it.module !== m.id };
|
|
1701
|
+
});
|
|
1625
1702
|
return _newTools;
|
|
1626
1703
|
}
|
|
1627
1704
|
|
|
@@ -1790,6 +1867,12 @@ async function openUpdateModal() {
|
|
|
1790
1867
|
}
|
|
1791
1868
|
}
|
|
1792
1869
|
|
|
1870
|
+
// 模块 id → 显示名
|
|
1871
|
+
function modName(id) {
|
|
1872
|
+
const m = (ST.modules || []).find(x => x.id === id);
|
|
1873
|
+
return m ? m.name + '模块' : (id || '财务') + '模块';
|
|
1874
|
+
}
|
|
1875
|
+
|
|
1793
1876
|
function renderUpdList() {
|
|
1794
1877
|
const body = $id('upd-body');
|
|
1795
1878
|
|
|
@@ -1801,7 +1884,8 @@ function renderUpdList() {
|
|
|
1801
1884
|
+ _newTools.map(t =>
|
|
1802
1885
|
'<div style="display:flex;align-items:center;justify-content:space-between;padding:8px 0;border-top:1px solid #dbeafe">'
|
|
1803
1886
|
+ '<div><div style="font-weight:600;font-size:13.5px">' + esc(t.name) + '</div>'
|
|
1804
|
-
+ '<div style="font-size:12px;color:var(--text-3)">' + esc(t.desc || '') + ' · v' + esc(t.ver || '')
|
|
1887
|
+
+ '<div style="font-size:12px;color:var(--text-3)">' + esc(t.desc || '') + ' · v' + esc(t.ver || '')
|
|
1888
|
+
+ ' 安装到:' + esc(modName(t.module)) + '</div></div>'
|
|
1805
1889
|
+ '<button class="btn sm prim" onclick="installTool(\'' + t.key + '\')">⬇ 安装</button></div>').join('')
|
|
1806
1890
|
+ '</div>';
|
|
1807
1891
|
}
|
|
@@ -1981,9 +2065,47 @@ function b64ToBytes(b64) {
|
|
|
1981
2065
|
return bytes;
|
|
1982
2066
|
}
|
|
1983
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
|
+
|
|
1984
2102
|
async function doUpdateOne(key) {
|
|
1985
2103
|
const it = UPD_REG.find(x=>x.key===key);
|
|
1986
2104
|
if (!it) return;
|
|
2105
|
+
|
|
2106
|
+
// exe 模式:交给本地服务处理
|
|
2107
|
+
if (SRV_MODE) return await doUpdateViaServer(key, it);
|
|
2108
|
+
|
|
1987
2109
|
const body = $id('upd-body');
|
|
1988
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>';
|
|
1989
2111
|
// 已有进度条就更新,没有就追加
|
|
@@ -2071,10 +2193,19 @@ function _init(){
|
|
|
2071
2193
|
}
|
|
2072
2194
|
}
|
|
2073
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
|
+
}
|
|
2074
2205
|
if(document.readyState==='loading'){
|
|
2075
|
-
document.addEventListener('DOMContentLoaded',
|
|
2206
|
+
document.addEventListener('DOMContentLoaded',_boot);
|
|
2076
2207
|
}else{
|
|
2077
|
-
|
|
2208
|
+
_boot();
|
|
2078
2209
|
}
|
|
2079
2210
|
</script>
|
|
2080
2211
|
</body>
|