@agile-team/mach-report 2.1.0 → 2.2.0
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/README.md +97 -12
- package/dist/ReportPreview-BWrQCj9M.js +1643 -0
- package/dist/ReportPreview-DY0PGGqF.cjs +6 -0
- package/dist/grid-geometry-DBH9ExuY.cjs +1 -0
- package/dist/grid-geometry-DONcjshk.js +130 -0
- package/dist/index.cjs +5 -5
- package/dist/index.d.cts +79 -11
- package/dist/index.d.ts +79 -11
- package/dist/index.js +1039 -712
- package/dist/page-window-index-CIuT4BAv.js +43 -0
- package/dist/page-window-index-DEjnM6IB.cjs +1 -0
- package/dist/pdf.cjs +46 -46
- package/dist/pdf.d.cts +4 -0
- package/dist/pdf.d.ts +4 -0
- package/dist/pdf.js +6 -6
- package/dist/{plugin-Bl00j_CP.cjs → plugin-BMoMUxrw.cjs} +1 -1
- package/dist/{plugin-DVScnZ4C.js → plugin-CAcNe0FT.js} +2 -2
- package/dist/report-params-B3Fia6JO.js +10 -0
- package/dist/report-params-D1gZ1DME.cjs +1 -0
- package/dist/style.css +1 -1
- package/dist/textwrap-DdaewxAd.js +117 -0
- package/dist/textwrap-DqiFwAV3.cjs +3 -0
- package/dist/vue/async.d.cts +53 -2
- package/dist/vue/async.d.ts +53 -2
- package/dist/vue/index.d.cts +65 -12
- package/dist/vue/index.d.ts +65 -12
- package/dist/vue-async.cjs +1 -1
- package/dist/vue-async.js +3 -3
- package/dist/vue.cjs +1 -1
- package/dist/vue.js +4 -4
- package/dist/xlsx.cjs +14 -14
- package/dist/xlsx.d.cts +8 -0
- package/dist/xlsx.d.ts +8 -0
- package/dist/xlsx.js +1087 -1053
- package/package.json +3 -2
- package/dist/ReportPreview-Dwdsyk9b.js +0 -1558
- package/dist/ReportPreview-VHAIfsz1.cjs +0 -6
- package/dist/grid-geometry-BXpOxznT.cjs +0 -1
- package/dist/grid-geometry-Bs8QXz1X.js +0 -65
- package/dist/report-params-BB85g7mg.js +0 -10
- package/dist/report-params-D1NeY-eR.cjs +0 -1
- package/dist/style-CFZ-HE2s.cjs +0 -3
- package/dist/style-DnmtG7Gl.js +0 -180
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";var Mt=Object.create;var Ge=Object.defineProperty;var Tt=Object.getOwnPropertyDescriptor;var Dt=Object.getOwnPropertyNames;var Nt=Object.getPrototypeOf,Vt=Object.prototype.hasOwnProperty;var Ot=(t,n,a,l)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of Dt(n))!Vt.call(t,r)&&r!==a&&Ge(t,r,{get:()=>n[r],enumerable:!(l=Tt(n,r))||l.enumerable});return t};var Ze=(t,n,a)=>(a=t!=null?Mt(Nt(t)):{},Ot(n||!t||!t.__esModule?Ge(a,"default",{value:t,enumerable:!0}):a,t));const e=require("vue"),ie=require("@agile-team/mach-report"),Qe=require("./page-window-index-DEjnM6IB.cjs"),ce=require("./plugin-BMoMUxrw.cjs");function Oe(t){return t==null?[]:Array.isArray(t)?t.map(String).filter(n=>n!==""):String(t).split(",").map(n=>n.trim()).filter(n=>n!=="")}function zt(t){return Oe(t).join(",")}class ye extends Error{constructor(n){super(n),this.name="PlanLoadError"}}function It(t={}){const{baseUrl:n="",headers:a,credentials:l,timeoutMs:r=3e4}=t,o=n.replace(/\/+$/,"");return async({url:s,method:f,params:p,signal:g})=>{let d=`${o}${s}`;if(p&&Object.keys(p).length>0){const w=d.indexOf("#"),$=w>=0?d.slice(w):"",x=w>=0?d.slice(0,w):d,P=x.indexOf("?"),N=P>=0?x.slice(0,P):x,B=new URLSearchParams(P>=0?x.slice(P+1):"");for(const[V,O]of Object.entries(p))B.set(V,O);d=`${N}?${B}${$}`}const u=(w,$)=>{const x=new ye(w);return Object.defineProperty(x,"cause",{value:$,configurable:!0,writable:!0}),x};if(g?.aborted)throw u(`请求已取消: ${s}`,g.reason);const h=new AbortController;let v;const R=()=>{h.signal.aborted||(v="external",h.abort(g?.reason))};g?.addEventListener("abort",R,{once:!0});const F=setTimeout(()=>{h.signal.aborted||(v="timeout",h.abort())},r);try{const w=await fetch(d,{method:f.toUpperCase(),headers:{Accept:"application/json",...a},credentials:l,signal:h.signal});if(!w.ok)throw new ye(`HTTP ${w.status} ${s}`);return await w.json()}catch(w){throw v==="timeout"?u(`请求超时(${r}ms): ${s}`,w):v==="external"?u(`请求已取消: ${s}`,w):w instanceof ye?w:u(`请求失败(${s}): ${w instanceof Error?w.message:String(w)}`,w)}finally{clearTimeout(F),g?.removeEventListener("abort",R)}}}function _e(t,n,a={}){const l=a.pxPerMm??3.7795275590551185,r=e.computed(()=>Math.max(0,e.unref(a.gapPx)??18)),o=e.ref(0),s=e.ref(800),f=e.computed(()=>{const w=t.value?.pages??[];return Qe.createPageWindowIndex(w.map($=>$.pageHeightMm*l),r.value)}),p=e.computed(()=>{let w=0;for(const $ of t.value?.pages??[])w=Math.max(w,$.pageWidthMm*l);return{w,h:f.value.totalHeightPx}}),g=e.computed(()=>f.value.window(s.value/n.value,o.value/n.value,e.unref(a.overscan)??1)),d=e.computed(()=>{const w=t.value;if(!w)return[];const{start:$,end:x}=g.value;return w.pages.slice($,x+1).map((P,N)=>({page:P,index:$+N}))});let u=0,h=!1;function v(w){w&&(o.value=w.scrollTop,s.value=w.clientHeight||800)}function R(w,$){return x=>{u||h||(u=requestAnimationFrame(()=>{if(u=0,h||(v(x),$.value<=0))return;const P=Math.max(0,x.scrollTop+32)/n.value;w.value=Math.min($.value,f.value.pageAt(P)+1)}))}}function F(){h=!0,u&&cancelAnimationFrame(u),u=0}return e.onScopeDispose(F),{contentSize:p,windowRange:g,visiblePages:d,makeScrollHandler:R,refreshViewport:v,pageOffsetPx:w=>f.value.offsetAt(w),destroy:F}}function et(t){const n=e.ref(1),a=e.ref("fit");function l(){requestAnimationFrame(()=>{const o=t();!o||!o.viewport||(n.value=Math.min(1,Math.max(.3,(o.viewport.clientWidth-48)/Math.max(1,o.pageWidthPx))))})}function r(o){o==="fit"?(a.value="fit",l()):(a.value="raw",n.value=o/100)}return{zoom:n,zoomMode:a,applyFitZoom:l,setZoom:r}}const xe=8;function Pe(){return new Promise(t=>setTimeout(t,0))}function be(t){return`p${Math.round(t.pageWidthMm)}x${Math.round(t.pageHeightMm)}`}function ze(t){const n=new Map;return t.pages.forEach(r=>{n.has(be(r))||n.set(be(r),r)}),`<!doctype html><html><head><meta charset="utf-8"><style>${`.mr-page{margin:0 auto;page-break-after:always;}
|
|
2
|
+
.mr-page tr{break-inside:avoid;page-break-inside:avoid;}
|
|
3
|
+
.mr-comp{break-inside:avoid;page-break-inside:avoid;}
|
|
4
|
+
${[...n.values()].map(r=>`@page ${be(r)}{size:${Math.round(r.pageWidthMm)}mm ${Math.round(r.pageHeightMm)}mm;margin:0;}`).join(`
|
|
5
|
+
`)}
|
|
6
|
+
body{margin:0;background:#fff;}`}</style></head><body>`}function Ie(t){const n=ie.renderPage(t,96,{},document);return n.style.page=be(t),n.outerHTML}function Le(t){return{head:ze(t),pageChunks:t.pages.map(Ie)}}async function Lt(t,n={}){const a={schemaVersion:"mach-report-batch-print",pages:t.flatMap(s=>s.pages)};if(a.pages.length===0)return;const l=ze(a),r=document.createElement("iframe");r.style.cssText="position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;",document.body.appendChild(r);let o=!1;try{const s=r.contentDocument;s.open(),s.write(l);for(let f=0;f<a.pages.length;f++)s.write(Ie(a.pages[f])),f%xe===xe-1&&(n.onProgress?.(f+1,a.pages.length),await Pe());s.write("</body></html>"),s.close(),await Pe(),n.onProgress?.(a.pages.length,a.pages.length),o=!0,r.contentWindow?.focus(),r.contentWindow?.print()}catch(s){n.onError?.(s instanceof Error?`批量打印失败: ${s.message}`:"批量打印失败")}finally{o?setTimeout(()=>r.remove(),6e4):r.remove()}}function tt(t){const{head:n,pageChunks:a}=Le(t);return{html:`${`<!doctype html><html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns="http://www.w3.org/TR/REC-html40"><head><meta charset="utf-8"><!--[if gte mso 9]><xml><w:WordDocument><w:View>Print</w:View><w:Zoom>100</w:Zoom></w:WordDocument></xml><![endif]-->${n.replace(/^<!doctype html><html><head>/,"")}`}${a.join("")}</body></html>`,filename:"mach-report.doc"}}function nt(t,n){let a=null,l=!1,r=!1,o=0;const s=new Map,f=new Map;let p=null,g=null,d=null,u=null,h=null;function v(i,m){return!r&&t.value===i&&o===m}function R(){if(r)return;const i=[...s.values()].reverse().find(m=>v(m.plan,m.epoch))?.format??null;i!==p&&(p=i,n.onBusy?.(i))}function F(i,m,b){const k={};return s.set(k,{plan:i,epoch:m,format:b}),R(),k}function w(i){s.delete(i),R()}function $(){for(const[i,m]of f)v(m.plan,m.epoch)||(i.close(),f.delete(i))}const x=e.watch(t,()=>{o++,R(),$()},{flush:"sync"});function P(){a?.remove(),a=null}function N(){r=!0,o++,x(),P(),$(),s.clear(),n.onPrinting?.(!1)}function B(i,m){const b=URL.createObjectURL(i);setTimeout(()=>URL.revokeObjectURL(b),1e4);const k=document.createElement("a");k.href=b,k.download=m,k.click()}async function V(){if(l)return;const i=t.value;if(r||!i||i.pages.length===0)return;const m=o;l=!0,n.onPrinting?.(!0),P();const b=ze(i);a=document.createElement("iframe"),a.style.cssText="position:fixed;right:0;bottom:0;width:0;height:0;border:0;visibility:hidden;",document.body.appendChild(a);const k=a;try{const C=k.contentDocument;C.open(),C.write(b);for(let I=0;I<i.pages.length;I++)if(C.write(Ie(i.pages[I])),I%xe===xe-1&&await Pe(),k!==a)return;if(C.write("</body></html>"),C.close(),await Pe(),!v(i,m)||k!==a)return;k.contentWindow?.focus(),k.contentWindow?.print()}catch{k===a&&P(),v(i,m)&&n.onError("调用打印失败,请改用导出 PDF","print")}finally{l=!1,r||n.onPrinting?.(!1)}}function O(i,m){if(g?.plan===i&&g.epoch===m)return g.promise;const b=Promise.resolve().then(()=>{if(!v(i,m))throw new Error("报表已切换或卸载");return n.getPdfExporter()(i,k=>{v(i,m)&&n.onWarning?.(k)})}).finally(()=>{g?.promise===b&&(g=null)});return g={plan:i,epoch:m,promise:b},b}async function S(){const i=t.value;if(r||!i||i.pages.length===0)return;const m=o;if(d?.plan===i&&d.epoch===m)return d.promise;const b=F(i,m,"PDF"),k=(async()=>{try{const C=await O(i,m);if(!v(i,m))return;B(new Blob([C],{type:"application/pdf"}),"mach-report.pdf")}catch(C){v(i,m)&&n.onError(C instanceof Error?`PDF 导出失败: ${C.message}`:"PDF 导出失败","pdf")}finally{w(b),d?.token===b&&(d=null)}})();return d={plan:i,epoch:m,promise:k,token:b},k}async function A(){const i=t.value;if(r||!i||i.pages.length===0)return;const m=o;if(u?.plan===i&&u.epoch===m)return u.promise;const b={...n.getXlsxOptions?.()},k=F(i,m,"Excel"),C=(async()=>{try{const{renderPlanToXlsx:I}=await import("@agile-team/mach-report/xlsx");if(!v(i,m))return;const{buffer:H,warnings:j}=await I(i,b);if(!v(i,m)||(j.length>0&&n.onWarning?.(`Excel 导出有 ${j.length} 条提示:${j.slice(0,2).join(";")}`),!v(i,m)))return;B(new Blob([H],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}),"mach-report.xlsx")}catch(I){v(i,m)&&n.onError(I instanceof Error?`Excel 导出失败: ${I.message}`:"Excel 导出失败","export")}finally{w(k),u?.token===k&&(u=null)}})();return u={plan:i,epoch:m,promise:C,token:k},C}async function z(){const i=t.value;if(r||!i||i.pages.length===0)return;const m=o;if(h?.plan===i&&h.epoch===m)return h.promise;const b=F(i,m,"图片"),k=(async()=>{try{const{blobs:C}=await ie.renderPlanToImages(i,{dpr:Math.min(2,typeof devicePixelRatio=="number"?devicePixelRatio:1)});if(!v(i,m))return;C.forEach((I,H)=>{B(I,C.length>1?`mach-report-page-${H+1}.png`:"mach-report.png")})}catch(C){v(i,m)&&n.onError(C instanceof Error?`图片导出失败: ${C.message}`:"图片导出失败","export")}finally{w(b),h?.token===b&&(h=null)}})();return h={plan:i,epoch:m,promise:k,token:b},k}function re(){const i=t.value;if(!(r||!i||i.pages.length===0))try{const{html:m,filename:b}=tt(i);B(new Blob([m],{type:"application/msword;charset=utf-8"}),b)}catch(m){n.onError(m instanceof Error?`Word 导出失败: ${m.message}`:"Word 导出失败","export")}}async function M(i){const m=t.value;if(!(r||!m||m.pages.length===0)){if(i==="pdf"){await S();return}if(i==="xlsx"||i==="excel"){await A();return}if(i==="png"||i==="image"){await z();return}if(i==="word"||i==="doc"){re();return}if(i!=="html"){n.onError(`不支持的导出格式:${i}`,"export");return}try{const{head:b,pageChunks:k}=Le(m),C=`${b}${k.join("")}</body></html>`;B(new Blob([C],{type:"text/html;charset=utf-8"}),"mach-report.html")}catch(b){n.onError(b instanceof Error?`HTML 导出失败: ${b.message}`:"HTML 导出失败","export")}}}function W(){const i=t.value;if(r||!i||i.pages.length===0)return;const m=o,b=window.open("","_blank");if(!b){n.onError("浏览器拦截了弹窗,请允许弹窗后重试","pdf");return}f.set(b,{plan:i,epoch:m});const k=F(i,m,"PDF");O(i,m).then(C=>{if(!v(i,m)||b.closed){f.delete(b)&&b.close();return}const I=URL.createObjectURL(new Blob([C],{type:"application/pdf"}));setTimeout(()=>URL.revokeObjectURL(I),6e4);const H=b.document;H.title="PDF 预览",H.documentElement.style.height="100%",H.body.style.cssText="margin:0;height:100%;";const j=H.createElement("iframe");j.title="PDF 预览",j.style.cssText="display:block;width:100%;height:100%;border:0;",j.src=I,H.body.replaceChildren(j),f.delete(b)}).catch(C=>{b.close(),f.delete(b),v(i,m)&&n.onError(C instanceof Error?`PDF 预览失败: ${C.message}`:"PDF 预览失败","pdf")}).finally(()=>w(k))}return{print:V,exportAs:M,exportImages:z,exportWord:re,openPdfWindow:W,releasePrintFrame:P,dispose:N}}const rt="mrp-hit";function Wt(t){t.querySelectorAll(`mark.${rt}`).forEach(a=>{const l=a.parentNode;if(l){for(;a.firstChild;)l.insertBefore(a.firstChild,a);a.remove(),l.normalize()}})}function At(t,n){const a=n.trim();if(!a)return 0;const l=a.toLowerCase(),r=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode(f){const p=f.parentElement;return!p||p.closest("mark")||/^(SCRIPT|STYLE)$/.test(p.tagName)?NodeFilter.FILTER_REJECT:(f.nodeValue??"").toLowerCase().includes(l)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}}),o=[];for(let f=r.nextNode();f;f=r.nextNode())o.push(f);let s=0;for(const f of o){const p=f.nodeValue??"",g=p.toLowerCase(),d=f.parentElement;if(!d)continue;const u=document.createDocumentFragment();let h=0,v=g.indexOf(l);for(;v>=0;){v>h&&u.appendChild(document.createTextNode(p.slice(h,v)));const R=document.createElement("mark");R.className=rt,R.textContent=p.slice(v,v+a.length),u.appendChild(R),s++,h=v+a.length,v=g.indexOf(l,h)}h<p.length&&u.appendChild(document.createTextNode(p.slice(h))),d.replaceChild(u,f)}return s}function Ht(t,n){const a=t.toLowerCase();let l=0;for(let r=a.indexOf(n);r>=0;r=a.indexOf(n,r+n.length))l++;return l}function*qt(t){const n=[...t].reverse();for(;n.length>0;){const a=n.pop();if(a.grid){for(const l of a.grid.cells??[])for(const r of l??[])if(yield r?.text??"",r?.children)for(let o=r.children.length-1;o>=0;o--)n.push(r.children[o])}else if(a.kind==="text")if(a.richParagraphs?.length)for(const l of a.richParagraphs)for(const r of l.segments??[])yield(r.kind==="field"?r.field:r.text)??"";else a.lines?.length?yield*a.lines:yield a.text??"";yield""}}function*jt(t){for(let n=0;n<t.pages.length;n++){for(const a of qt(t.pages[n].components))yield{text:a,pageIndex:n};yield{text:"",pageIndex:n}}}function Ut(t){const{plan:n,gotoPage:a,highlight:l,clearHighlights:r}=t,o=e.ref(!1),s=e.ref(""),f=e.ref(0),p=e.ref(0),g=e.ref(!1);let d=[],u=null,h=null,v=0;function R(){v++,u&&clearTimeout(u),h&&clearTimeout(h),u=h=null,g.value=!1}function F(P){s.value=P,f.value=0,p.value=0,d=[],g.value=!1;const N=P.trim().toLowerCase(),B=n.value;if(!N||!B)return;g.value=!0;const V=v,O=jt(B),S=[];let A=0;function z(){if(h=null,V!==v||B!==n.value)return;const re=performance.now();let M=0;for(;M<500&&performance.now()-re<4;){const W=O.next();if(W.done){d=S,p.value=A,g.value=!1,d[0]&&a(d[0].pageIndex+1);return}const i=Ht(W.value.text,N);if(i>0){A+=i;const m=S[S.length-1];m?.pageIndex===W.value.pageIndex?m.cumulative=A:S.push({pageIndex:W.value.pageIndex,cumulative:A})}M++}h=setTimeout(z,0)}z()}function w(P){if(R(),s.value=P,f.value=p.value=0,d=[],!P.trim()){F("");return}g.value=!0,u=setTimeout(()=>{u=null,F(P)},Math.max(0,e.unref(t.debounceMs)??200))}function $(P){const N=p.value;if(N===0||g.value)return;f.value=(f.value+P+N)%N;let B=0,V=d.length-1;for(;B<V;){const O=B+V>>>1;d[O].cumulative<=f.value?B=O+1:V=O}a(d[B].pageIndex+1)}function x(){R(),s.value="",f.value=p.value=0,d=[]}return e.watch(n,x,{flush:"sync"}),e.onScopeDispose(x),{visible:o,query:s,matchIndex:f,matchCount:p,searching:g,toggle:()=>{o.value=!o.value},onInput:w,onNav:$,apply:P=>{s.value.trim()&&l(P,s.value.trim())},clear:P=>{r(P)},reset:x}}function Kt(t,n){const a=e.computed(()=>{if(t.value)return!0;if(typeof location>"u")return!1;try{return new URLSearchParams(location.search).get("mrp-debug")==="1"}catch{return!1}}),l=e.computed(()=>!a.value||!n.plan.value?0:Math.round(JSON.stringify(n.plan.value).length/1024)),r=e.computed(()=>!a.value||!n.plan.value?null:{pages:n.pageCount.value,window:`${n.windowRange.value.start}-${n.windowRange.value.end}`,zoom:`${Math.round(n.zoom.value*100)}%`,loadMs:`${n.loadMs.value}ms`,planKB:l.value});return{enabled:a,debugStats:r}}function Gt(t,n){const{thumbsRoot:a,visible:l,renderThumbCanvas:r}=n,o=e.ref(0),s=e.ref(800),f=e.computed(()=>(t.value?.pages??[]).map(x=>Math.round(x.pageHeightMm/x.pageWidthMm*116))),p=e.computed(()=>Qe.createPageWindowIndex(f.value.map(x=>x+20),8)),g=e.computed(()=>p.value.window(s.value,o.value,1)),d=e.computed(()=>{if(!l.value)return[];const{start:x,end:P}=g.value;return f.value.slice(x,P+1).map((N,B)=>({index:x+B,height:N}))});let u=0,h=0,v=!1;function R(){const x=a.value;x&&(o.value=x.scrollTop,s.value=x.clientHeight||800)}function F(){v||h||(h=requestAnimationFrame(()=>{h=0,R()}))}function w(){if(d.value,u&&cancelAnimationFrame(u),u=0,v||!l.value||!t.value||!a.value)return;R();const x=d.value,P=t.value,N=a.value;let B=0;function V(){if(u=0,!(v||!l.value||t.value!==P||a.value!==N)){for(let O=0;B<x.length&&O<2;O++,B++){const S=x[B].index,A=N.querySelector(`[data-thumb="${S+1}"]`);if(!A||A.childElementCount>0)continue;const z=r(S);z&&(z.style.width="100%",z.style.height="100%",z.style.display="block",A.appendChild(z))}B<x.length&&(u=requestAnimationFrame(V))}}u=requestAnimationFrame(V)}function $(){v=!0,u&&cancelAnimationFrame(u),h&&cancelAnimationFrame(h),u=h=0}return e.onScopeDispose($),{schedule:w,destroy:$,onScroll:F,windowRange:g,visibleThumbs:d}}function Zt(){const t=e.shallowRef(0);return{loadMs:t,start(){return typeof performance<"u"?performance.now():0},end(n){t.value=n?Math.round(performance.now()-n):0}}}const Yt={class:"mrp-toolbar"},Jt={class:"mrp-title"},Xt=["disabled"],Qt={class:"mrp-pageinfo"},_t=["disabled"],en={key:1,class:"mrp-search"},tn=["placeholder","value"],nn={key:0,class:"mrp-search-count",role:"status"},rn=["disabled"],on=["disabled"],an=e.defineComponent({__name:"ReportToolbar",props:{pageCount:{},currentPage:{},zoomMode:{},zoom:{},showExport:{type:Boolean},showPrint:{type:Boolean},showPdfWindow:{type:Boolean},messages:{},search:{},thumbsVisible:{type:Boolean}},emits:["goto","zoom","export","print","pdf-window","search-input","search-nav","search-toggle","thumbs-toggle"],setup(t){const n=t,a=e.ref(null);e.watch(()=>n.search.visible,r=>{r&&e.nextTick(()=>a.value?.focus())});function l(r,o,s){return r.replace("{cur}",String(o)).replace("{total}",String(s))}return(r,o)=>(e.openBlock(),e.createElementBlock("div",Yt,[e.createElementVNode("span",Jt,e.toDisplayString(t.messages.title),1),t.pageCount>0?(e.openBlock(),e.createElementBlock(e.Fragment,{key:0},[e.createElementVNode("button",{class:"mrp-nav",type:"button",disabled:t.currentPage<=1,onClick:o[0]||(o[0]=s=>r.$emit("goto",t.currentPage-1))},e.toDisplayString(t.messages.prevPage),9,Xt),e.createElementVNode("span",Qt,e.toDisplayString(l(t.messages.pageInfo,t.currentPage,t.pageCount)),1),e.createElementVNode("button",{class:"mrp-nav",type:"button",disabled:t.currentPage>=t.pageCount,onClick:o[1]||(o[1]=s=>r.$emit("goto",t.currentPage+1))},e.toDisplayString(t.messages.nextPage),9,_t)],64)):e.createCommentVNode("",!0),o[17]||(o[17]=e.createElementVNode("span",{class:"mrp-spacer"},null,-1)),t.search.visible?(e.openBlock(),e.createElementBlock("div",en,[e.createElementVNode("input",{ref_key:"searchInputRef",ref:a,class:"mrp-search-input",type:"text",placeholder:t.messages.searchPlaceholder,value:t.search.query,onInput:o[2]||(o[2]=s=>r.$emit("search-input",s.target.value))},null,40,tn),t.search.query?(e.openBlock(),e.createElementBlock("span",nn,e.toDisplayString(t.search.searching?t.messages.searching??"搜索中…":l(t.messages.matchInfo,t.search.matchCount>0?t.search.matchIndex+1:0,t.search.matchCount)),1)):e.createCommentVNode("",!0),e.createElementVNode("button",{class:"mrp-nav",type:"button",disabled:t.search.matchCount===0,onClick:o[3]||(o[3]=s=>r.$emit("search-nav",-1))},e.toDisplayString(t.messages.prevMatch),9,rn),e.createElementVNode("button",{class:"mrp-nav",type:"button",disabled:t.search.matchCount===0,onClick:o[4]||(o[4]=s=>r.$emit("search-nav",1))},e.toDisplayString(t.messages.nextMatch),9,on)])):e.createCommentVNode("",!0),e.createElementVNode("button",{class:e.normalizeClass(["mrp-nav",{"mrp-active":t.search.visible}]),type:"button",title:"Ctrl+F",onClick:o[5]||(o[5]=s=>r.$emit("search-toggle"))}," 🔍 ",2),e.createElementVNode("button",{class:e.normalizeClass(["mrp-nav",{"mrp-active":t.thumbsVisible}]),type:"button",onClick:o[6]||(o[6]=s=>r.$emit("thumbs-toggle"))}," ▦ "+e.toDisplayString(t.messages.thumbnails),3),e.createElementVNode("button",{class:e.normalizeClass(["mrp-nav",{"mrp-active":t.zoomMode==="fit"}]),type:"button",onClick:o[7]||(o[7]=s=>r.$emit("zoom","fit"))},e.toDisplayString(t.messages.fitWidth),3),e.createElementVNode("button",{class:e.normalizeClass(["mrp-nav",{"mrp-active":t.zoomMode==="raw"&&Math.round(t.zoom*100)===100}]),type:"button",onClick:o[8]||(o[8]=s=>r.$emit("zoom",100))}," 100% ",2),e.createElementVNode("button",{class:e.normalizeClass(["mrp-nav",{"mrp-active":t.zoomMode==="raw"&&Math.round(t.zoom*100)===150}]),type:"button",onClick:o[9]||(o[9]=s=>r.$emit("zoom",150))}," 150% ",2),t.showExport?(e.openBlock(),e.createElementBlock("button",{key:2,class:"mrp-nav",type:"button",onClick:o[10]||(o[10]=s=>r.$emit("export","html"))},e.toDisplayString(t.messages.exportHtml),1)):e.createCommentVNode("",!0),t.showExport?(e.openBlock(),e.createElementBlock("button",{key:3,class:"mrp-nav",type:"button",onClick:o[11]||(o[11]=s=>r.$emit("export","pdf"))},e.toDisplayString(t.messages.exportPdf),1)):e.createCommentVNode("",!0),t.showExport?(e.openBlock(),e.createElementBlock("button",{key:4,class:"mrp-nav",type:"button",onClick:o[12]||(o[12]=s=>r.$emit("export","xlsx"))},e.toDisplayString(t.messages.exportExcel),1)):e.createCommentVNode("",!0),t.showExport?(e.openBlock(),e.createElementBlock("button",{key:5,class:"mrp-nav",type:"button",onClick:o[13]||(o[13]=s=>r.$emit("export","png"))},e.toDisplayString(t.messages.exportImage),1)):e.createCommentVNode("",!0),t.showExport?(e.openBlock(),e.createElementBlock("button",{key:6,class:"mrp-nav",type:"button",onClick:o[14]||(o[14]=s=>r.$emit("export","word"))},e.toDisplayString(t.messages.exportWord),1)):e.createCommentVNode("",!0),t.showPrint?(e.openBlock(),e.createElementBlock("button",{key:7,class:"mrp-nav",type:"button",onClick:o[15]||(o[15]=s=>r.$emit("print"))},e.toDisplayString(t.messages.print),1)):e.createCommentVNode("",!0),t.showPdfWindow?(e.openBlock(),e.createElementBlock("button",{key:8,class:"mrp-nav",type:"button",onClick:o[16]||(o[16]=s=>r.$emit("pdf-window"))},e.toDisplayString(t.messages.pdfWindow),1)):e.createCommentVNode("",!0)]))}}),We=(t,n)=>{const a=t.__vccOpts||t;for(const[l,r]of n)a[l]=r;return a},ot=We(an,[["__scopeId","data-v-601f8fa8"]]),ln={class:"mrp-params"},sn={class:"mrp-params-title"},cn={class:"mrp-params-grid"},un={class:"mrp-param-label"},dn={key:0,class:"mrp-param-star"},fn=["value","onChange"],mn={value:"",disabled:"",hidden:""},pn=["value"],gn=["type","placeholder","value","onInput"],hn={class:"mrp-params-actions"},vn=e.defineComponent({__name:"ReportParamPanel",props:{defs:{},modelValue:{},messages:{},attempted:{type:Boolean}},emits:["update:modelValue","query","reset"],setup(t,{emit:n}){const a=t,l=n,r=e.ref({...a.modelValue});e.watch(()=>a.modelValue,p=>{r.value={...p}});const o=e.computed(()=>a.defs.map(p=>({def:p,label:p.label??p.field,value:r.value[p.field]??""})));function s(p,g){r.value={...r.value,[p]:g},l("update:modelValue",{...r.value})}function f(p){const g=a.defs.find(d=>d.field===p);return a.attempted&&g?.required===!0&&!(r.value[p]??"").trim()}return(p,g)=>(e.openBlock(),e.createElementBlock("div",ln,[e.createElementVNode("span",sn,e.toDisplayString(t.messages.paramsTitle),1),e.createElementVNode("div",cn,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.value,d=>(e.openBlock(),e.createElementBlock("label",{key:d.def.field,class:e.normalizeClass(["mrp-param",{"mrp-param-missing":f(d.def.field)}])},[e.createElementVNode("span",un,[e.createTextVNode(e.toDisplayString(d.label),1),d.def.required?(e.openBlock(),e.createElementBlock("i",dn,"*")):e.createCommentVNode("",!0)]),(d.def.type??"text")==="select"?(e.openBlock(),e.createElementBlock("select",{key:0,class:"mrp-param-input",value:d.value,onChange:u=>s(d.def.field,u.target.value),onKeydown:g[0]||(g[0]=e.withKeys(u=>p.$emit("query"),["enter"]))},[e.createElementVNode("option",mn,e.toDisplayString(d.def.placeholder??`请选择${d.label}`),1),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(d.def.options??[],u=>(e.openBlock(),e.createElementBlock("option",{key:u.value,value:u.value},e.toDisplayString(u.label),9,pn))),128))],40,fn)):(e.openBlock(),e.createElementBlock("input",{key:1,class:"mrp-param-input",type:d.def.type==="number"?"number":d.def.type==="date"?"date":"text",placeholder:d.def.placeholder??`请输入${d.label}`,value:d.value,onInput:u=>s(d.def.field,u.target.value),onKeydown:g[1]||(g[1]=e.withKeys(u=>p.$emit("query"),["enter"]))},null,40,gn))],2))),128))]),e.createElementVNode("div",hn,[e.createElementVNode("button",{class:"mrp-nav mrp-param-query",type:"button",onClick:g[2]||(g[2]=d=>p.$emit("query"))},e.toDisplayString(t.messages.query),1),e.createElementVNode("button",{class:"mrp-nav",type:"button",onClick:g[3]||(g[3]=d=>p.$emit("reset"))},e.toDisplayString(t.messages.reset),1)])]))}}),at=We(vn,[["__scopeId","data-v-aafce92d"]]),lt={title:"报表预览",prevPage:"‹ 上一页",nextPage:"下一页 ›",pageInfo:"{cur} / {total}",fitWidth:"适宽",exportHtml:"导出 HTML",exportPdf:"导出 PDF",exportExcel:"导出 Excel",exportImage:"导出图片",exportWord:"导出 Word",exporting:"正在生成 {format}…",print:"打印",pdfWindow:"PDF 窗口",loading:"报表渲染中…",empty:"暂无预览数据",errorPrefix:"",retry:"重试",pdfFontUnavailable:"PDF 字体尚未就绪,请联系管理员检查字体配置;预览及其它导出仍可使用。",searchPlaceholder:"搜索报表内容",matchInfo:"{cur}/{total}",prevMatch:"‹",nextMatch:"›",thumbnails:"缩略图",paramsTitle:"查询条件",query:"查 询",reset:"重 置",paramRequired:"请填写{label}",searching:"搜索中…"},st={shellBg:"#525659",shellFg:"#e8e8e8",toolbarBg:"#323639",toolbarBorder:"#22252a",toolbarFg:"#e8e8e8",btnFg:"#cfcfcf",btnBorder:"#4a4d52",btnHoverBg:"#414549",btnHoverFg:"#ffffff",btnActiveBg:"#2d5fb8"};function it(t={}){return{...t,defaults:t.defaults??{},presets:t.presets??{}}}function wn(t){return t}const te={showExport:!0,showPrint:!0,showPdfWindow:!0,showParams:!0,gapPx:18,pdfFontUrl:"/simhei.ttf",logger:console},yn={warn:()=>{},info:()=>{}};function Ee(t,n){return{...t,...n,theme:{...t?.theme,...n?.theme},messages:{...t?.messages,...n?.messages},preview:{...t?.preview,...n?.preview},xlsx:{...t?.xlsx,...n?.xlsx}}}function ct(t,n){const a=n?t?.presets?.[n]:t?.defaultPreset?t?.presets?.[t.defaultPreset]:void 0,l=Ee(t?.defaults,a);return{showExport:l.showExport??te.showExport,showPrint:l.showPrint??te.showPrint,showPdfWindow:l.showPdfWindow??te.showPdfWindow,showParams:l.showParams??te.showParams,gapPx:l.gapPx??te.gapPx,pdfFontUrl:l.pdfFontUrl??te.pdfFontUrl,theme:{...st,...l.theme},messages:{...lt,...l.messages},logger:l.logger??te.logger,preview:{overscanPages:Ye(l.preview?.overscanPages,1,10,!0),searchDebounceMs:Ye(l.preview?.searchDebounceMs,200,2e3)},xlsx:{...l.xlsx}}}function Ye(t,n,a,l=!1){if(t==null||!Number.isFinite(t))return n;const r=Math.max(0,Math.min(a,t));return l?Math.floor(r):r}function ut(t){const n={};return t.shellBg!=null&&(n["--mrp-shell-bg"]=t.shellBg),t.shellFg!=null&&(n["--mrp-shell-fg"]=t.shellFg),t.toolbarBg!=null&&(n["--mrp-toolbar-bg"]=t.toolbarBg),t.toolbarBorder!=null&&(n["--mrp-toolbar-border"]=t.toolbarBorder),t.toolbarFg!=null&&(n["--mrp-toolbar-fg"]=t.toolbarFg),t.btnFg!=null&&(n["--mrp-btn-fg"]=t.btnFg),t.btnBorder!=null&&(n["--mrp-btn-border"]=t.btnBorder),t.btnHoverBg!=null&&(n["--mrp-btn-hover-bg"]=t.btnHoverBg),t.btnHoverFg!=null&&(n["--mrp-btn-hover-fg"]=t.btnHoverFg),t.btnActiveBg!=null&&(n["--mrp-btn-active-bg"]=t.btnActiveBg),n}function bn(t){const n=e.inject(ce.MACH_REPORT_CONFIG_KEY,null),a=e.computed(()=>{const l=n?.value??null,r="defaults"in t||"presets"in t||"defaultPreset"in t?it(t):{defaults:t,presets:{}};if(!l)return r;const o={...l.presets,...r.presets};for(const s of Object.keys(o))o[s]=Ee(Ee(l.presets[s],r.defaults),r.presets[s]);return{defaults:Ee(l.defaults,r.defaults),presets:o,defaultPreset:r.defaultPreset??l.defaultPreset}});e.provide(ce.MACH_REPORT_CONFIG_KEY,a)}function dt(){return e.inject(ce.MACH_REPORT_CONFIG_KEY,e.computed(()=>null))}const Je=new Map,se=new Map,En=15e3;function Ve(t,n){return Object.assign(new Error(t),{cause:n})}function pe(t,n){return`PDF 字体 ${JSON.stringify(t)}:${n}。请部署支持报表文字的字体文件,并将 pdfFontUrl 配置为可访问的字体 URL;西文报表可设为空串`}function ke(t){if(t?.reason instanceof Error&&t.reason.name==="AbortError")return t.reason;const n=Ve("PDF 字体检查已取消",t?.reason);return n.name="AbortError",n}async function xn(t,n){let a=!1;const l=setTimeout(()=>{a=!0,n.abort()},En);try{const r=await fetch(t,{method:"HEAD",signal:n.signal});if(n.signal.aborted)throw ke(n.signal);if(r.status===405||r.status===501||r.type==="opaque")return{status:"unverified",fontUrl:t,message:`PDF 字体 ${JSON.stringify(t)} 无法通过 HEAD 检查验证;仍可尝试导出,届时会加载并校验字体`};if(!r.ok){const s=new Error(`字体请求返回 HTTP ${r.status}`);return{status:"error",fontUrl:t,message:pe(t,s.message),cause:s}}const o=r.headers.get("content-type")??"";if(/text\/html|application\/xhtml\+xml/i.test(o)){const s=new Error("字体 URL 返回 HTML 页面(可能是 SPA 路由回退),不是字体文件");return{status:"error",fontUrl:t,message:pe(t,s.message),cause:s}}if(/^text\//i.test(o)||/(?:\/|\+)json(?:\s*;|$)/i.test(o)){const s=new Error(`字体 URL 返回 ${o} 文本响应,不是字体文件`);return{status:"error",fontUrl:t,message:pe(t,s.message),cause:s}}return{status:"available",fontUrl:t,message:"PDF 字体资源可达;文字覆盖范围将在实际导出时校验"}}catch(r){if(n.signal.aborted&&!a)throw ke(n.signal);return{status:"error",fontUrl:t,message:pe(t,a?"字体检查超时,请检查网络或字体服务":"字体检查失败,请检查网络、字体服务或跨域访问配置"),cause:r}}finally{clearTimeout(l)}}function Pn(t,n){if(n?.aborted)return Promise.reject(ke(n));if(!t)return Promise.resolve({status:"disabled",fontUrl:t,message:"已停用自定义 PDF 字体;内置字体用于西文,其他文字会在导出时校验"});const a=Je.get(t);if(a)return Promise.resolve(a);let l=se.get(t);if(!l){const o=new AbortController;l={controller:o,promise:xn(t,o),subscribers:0};const s=l;se.set(t,s),s.promise=s.promise.then(f=>(!o.signal.aborted&&f.status==="available"&&Je.set(t,f),f)).finally(()=>{se.get(t)===s&&se.delete(t)})}const r=l;return r.subscribers++,new Promise((o,s)=>{let f=!1;const p=()=>f?!1:(f=!0,r.subscribers--,n?.removeEventListener("abort",g),!0),g=()=>{p()&&(r.subscribers===0&&(se.get(t)===r&&se.delete(t),r.controller.abort()),s(ke(n)))};n?.addEventListener("abort",g,{once:!0}),r.promise.then(d=>{p()&&o(d)},d=>{p()&&s(d)}),n?.aborted&&g()})}function ft(t={fontUrl:"/simhei.ttf"}){let n=null;const a=async(l,r)=>{n||(n=await import("@agile-team/mach-report/pdf"));let o=null;if(t.fontUrl)try{if(o=await n.loadFontWithCache(t.fontUrl,{strict:!0}),!o?.byteLength)throw new Error("字体文件为空或加载失败")}catch(u){const h=u instanceof Error?u.message:String(u);throw Ve(pe(t.fontUrl,h),u)}let s;try{s=await n.renderPlanToPdf(l,o?{customFontBytes:o}:{})}catch(u){if(!o)throw u;const h=u instanceof Error?u.message:String(u);throw Ve(`PDF 生成失败:${h}。当前字体 URL 为 ${JSON.stringify(t.fontUrl)};请确认该文件是有效字体,或重新配置 pdfFontUrl`,u)}const{bytes:f,unsupportedTextCount:p,pageErrors:g,fidelityWarnings:d}=s;if(p>0)throw new Error(`PDF 中有 ${p} 行文字无法编码;请部署支持所用文字的字体并配置 pdfFontUrl`);if(g.length>0)throw new Error(`PDF 有 ${g.length} 页渲染失败:${g[0]}`);return d.length>0&&r?.(`PDF 有 ${d.length} 处版式降级:${d.slice(0,2).join(";")}`),f};return a.checkFont=l=>Pn(t.fontUrl,l),a}class ne extends Error{constructor(n,a,l){super(a),this.name="MachReportError",this.code=n,this.cause=l}}function mt(t){return t instanceof ne?{code:t.code,cause:t.cause}:{code:"render",cause:t}}const kn={key:2,class:"mrp-export-notice mrp-export-warning",role:"status"},Cn={class:"mrp-main"},$n={key:0,class:"mrp-state"},Bn={key:1,class:"mrp-state mrp-error"},Sn={key:2,class:"mrp-state"},Rn=["data-page"],Fn=["onClick"],Mn=["data-thumb"],Tn={class:"mrp-thumb-no"},Dn={class:"mrp-overlay"},Nn={key:3,class:"mrp-debug","aria-hidden":"true"},Ne=96/25.4,Xe="mach-report:ui",Vn=e.defineComponent({__name:"ReportPreview",props:{reportId:{type:[String,Array],default:null},params:{type:Object,default:()=>({})},height:{type:String,default:"100vh"},autoLoad:{type:Boolean,default:!0},showExport:{type:Boolean,default:void 0},showPrint:{type:Boolean,default:void 0},showPdfWindow:{type:Boolean,default:void 0},gapPx:{type:Number,default:void 0},messages:{type:Object,default:void 0},preset:{type:String,default:void 0},debug:{type:Boolean,default:!1},paramDefs:{type:Array,default:void 0},showParams:{type:Boolean,default:void 0},fetcher:{type:Function,default:null}},emits:["loaded","error","warning"],setup(t,{expose:n,emit:a}){e.useCssVars(c=>({v4c81cc3e:P.value+"px"}));const l=t,r=a,o=e.shallowRef(null),s=e.ref(!1),f=e.ref(""),p=e.shallowRef(null),g=e.ref(null),d=e.ref(!1),u=e.shallowRef(Object.freeze({status:"unchecked",fontUrl:""})),h=e.ref(null),v=e.ref(1),R=e.ref(null),F=e.ref(null),w=e.ref(null),$=e.ref(!1),x=Zt(),P=e.computed(()=>Math.max(0,k.value)),N=e.inject(ce.MACH_REPORT_FETCHER_KEY,null),B=e.inject(ce.MACH_REPORT_PDF_EXPORTER_KEY,null),V=e.computed(()=>Oe(l.reportId)),O=e.computed(()=>l.fetcher??N),S=e.computed(()=>o.value?.pages.length??0),A=e.computed(()=>Object.freeze({loading:s.value,hasPlan:S.value>0,pageCount:S.value,currentPage:v.value,exporting:g.value,printing:d.value,canExport:!s.value&&S.value>0&&g.value===null,canPrint:!s.value&&S.value>0&&!d.value,error:p.value,pdfFont:u.value}));function z(c,y,E){p.value=Object.freeze({message:c,code:y,cause:E}),r("error",c,{code:y,cause:E})}const re=dt(),M=e.computed(()=>ct(re.value,l.preset)),W=e.computed(()=>({...M.value.messages,...l.messages})),i=e.computed(()=>l.showExport??M.value.showExport),m=e.computed(()=>l.showPrint??M.value.showPrint),b=e.computed(()=>l.showPdfWindow??M.value.showPdfWindow),k=e.computed(()=>l.gapPx??M.value.gapPx),C=e.computed(()=>l.showParams??M.value.showParams);let I=null,H=null;function j(){if(B)return B;const c=M.value.pdfFontUrl;return(!H||I!==c)&&(I=c,H=ft({fontUrl:c})),H}let ge=0,ue=null,de=!1;function Ce(){ge++,ue?.abort(),ue=null}async function he(){if(de)throw new ne("config","报表预览已卸载");Ce();const c=ge,y=new AbortController;ue=y;const E=M.value.pdfFontUrl;u.value=Object.freeze({status:"checking",fontUrl:E});try{const T=j(),G=T.checkFont?await T.checkFont(y.signal):{status:"unverified",fontUrl:"",message:"自定义 PDF 导出器未提供字体预检查;字体由宿主确认"};return!de&&c===ge&&!y.signal.aborted&&(u.value=Object.freeze({...G})),G}catch(T){if(y.signal.aborted)throw T;const G={status:"error",fontUrl:E,message:T instanceof Error?T.message:"PDF 字体检查失败",cause:T};return!de&&c===ge&&(u.value=Object.freeze(G)),G}finally{ue===y&&(ue=null)}}function gt(){he().catch(()=>{})}e.watch([o,()=>M.value.pdfFontUrl,i,b],()=>{const c=u.value.fontUrl===M.value.pdfFontUrl;Ce(),(!c||u.value.status==="checking")&&(u.value=Object.freeze({status:"unchecked",fontUrl:M.value.pdfFontUrl})),!de&&S.value>0&&(i.value||b.value)&&he().catch(()=>{})},{immediate:!0});const J=e.computed(()=>l.paramDefs??O.value?.getParamDefs?.(V.value)??[]),Q=e.ref({}),$e=e.ref(!1);function fe(c){const y={};for(const E of c)y[E.field]=l.params[E.field]??E.defaultValue??"";Q.value=y,$e.value=!1}fe(J.value),e.watch(J,c=>fe(c)),e.watch(V,()=>fe(J.value)),e.watch(()=>JSON.stringify(l.params),()=>fe(J.value));const ht=e.computed(()=>{const c={...l.params};for(const[y,E]of Object.entries(Q.value))E===""?delete c[y]:c[y]=E;return c});function vt(){return J.value.filter(c=>c.required===!0&&!(Q.value[c.field]??"").trim())}function wt(){$e.value=!0;const c=vt();if(c.length>0){const y=c[0].label??c[0].field,E=W.value.paramRequired.replace("{label}",y);f.value=E,z(E,"param");return}_()}function yt(){fe(J.value)}const bt=e.computed(()=>({height:l.height,...ut(M.value.theme)})),{zoom:q,zoomMode:oe,applyFitZoom:Ae,setZoom:Be}=et(()=>({viewport:F.value,pageWidthPx:(o.value?.pages[0]?.pageWidthMm??210)*Ne})),He=_e(o,q,{pxPerMm:Ne,gapPx:k,overscan:e.computed(()=>M.value.preview.overscanPages)}),{contentSize:Se,windowRange:me,visiblePages:qe,makeScrollHandler:Et,refreshViewport:Re}=He,xt=Et(v,S);function Fe(c){oe.value="raw",q.value=Math.min(3,Math.max(.3,c))}function ve(){Pt(),o.value=null,v.value=1,L.reset()}let X=0,Z=null;async function _(){const c=++X;Z?.abort(),Z=null;const y=O.value;if(s.value=!1,p.value=null,V.value.length===0){f.value="缺少报表 ID",ve(),z(f.value,"param");return}if(!y){f.value="未提供渲染数据源 fetcher",ve(),z(f.value,"config");return}s.value=!0,f.value="",h.value=null,ve();const E=x.start(),T=new AbortController;Z=T;const G=new Set;function le(D){c!==X||T.signal.aborted||G.has(D)||(G.add(D),M.value.logger.warn("[mach-report] 报表告警:",D),r("warning",D))}try{const D=await y({reportIds:V.value,params:{...ht.value},signal:T.signal,onWarning:le});if(c!==X)return;const U=ie.validateRenderPlan(D);if(!U.ok){const ee=U.errors.slice(0,3).map(Ke=>`${Ke.path}: ${Ke.message}`).join("; ");throw new ne("validate",`渲染计划校验失败(${U.errors.length} 处): ${ee}`)}if(U.warnings.forEach(ee=>le(`${ee.path}: ${ee.message}`)),c!==X||T.signal.aborted)return;o.value=D,v.value=1,x.end(E),F.value&&(F.value.scrollTop=0),oe.value==="fit"&&Ae(),r("loaded",D.pages.length)}catch(D){if(c!==X)return;const U=D instanceof ne?D:D instanceof ie.ReportSourceError?new ne(D.code,D.message,D.cause):new ne("fetch",D instanceof Error?D.message:"预览加载失败",D);f.value=U.message;const ee=mt(U);z(U.message,ee.code,ee.cause)}finally{c===X&&(s.value=!1),Z===T&&(Z=null)}}function Y(c){if(S.value<=0)return;const y=Math.max(1,Math.min(S.value,c));v.value=y;const E=F.value;E&&(E.scrollTop=He.pageOffsetPx(y-1)*q.value,Re(E))}const we=nt(o,{getPdfExporter:j,getXlsxOptions:()=>M.value.xlsx,onError:(c,y)=>{h.value={kind:"error",message:c},z(c,y??"print")},onWarning:c=>{h.value={kind:"warning",message:c},r("warning",c)},onBusy:c=>{g.value=c,c?h.value={kind:"progress",message:W.value.exporting.replace("{format}",c)}:h.value?.kind==="progress"&&(h.value=null)},onPrinting:c=>{d.value=c}}),{releasePrintFrame:Pt,dispose:kt}=we;async function Me(){p.value=null,await we.print()}async function Te(c){p.value=null,await we.exportAs(c)}function De(){p.value=null,we.openPdfWindow()}async function je(c,y={}){Q.value={...Q.value,...c},y.reload!==!1&&await _()}const Ct={reload:_,print:Me,exportAs:Te,openPdfWindow:De,gotoPage:Y,setParams:je,checkPdfFont:he,get state(){return A.value}};e.provide(ce.MACH_REPORT_CONTROLLER_KEY,Ct);const L=Ut({plan:o,gotoPage:Y,debounceMs:e.computed(()=>M.value.preview.searchDebounceMs),highlight:At,clearHighlights:Wt});function $t(c){c.ctrlKey&&(c.preventDefault(),Fe(q.value*(c.deltaY<0?1.1:1/1.1)))}function Bt(c){if((c.ctrlKey||c.metaKey)&&c.key.toLowerCase()==="f"){c.preventDefault(),L.visible.value||L.toggle();return}switch(c.key){case"PageDown":c.preventDefault(),Y(v.value+1);break;case"PageUp":c.preventDefault(),Y(v.value-1);break;case"Home":c.preventDefault(),Y(1);break;case"End":c.preventDefault(),Y(S.value);break;case"+":case"=":c.preventDefault(),Fe(q.value*1.1);break;case"-":c.preventDefault(),Fe(q.value/1.1);break}}function St(){try{localStorage.setItem(Xe,JSON.stringify({zoomMode:oe.value==="fit"?"fit":Math.round(q.value*100)}))}catch{}}e.watch([oe,q],St),e.watchEffect(()=>{const c=o.value;if(!c)return;qe.value;const y=R.value;if(!y)return;y.querySelectorAll(".mrp-page-holder").forEach(T=>{const G=Number(T.dataset.page??0)-1,le=c.pages[G];if(!le||T.childElementCount>0){if(T.firstElementChild){const U=T.firstElementChild;L.clear(U),L.apply(U)}return}T.style.width=`${le.pageWidthMm*Ne}px`;const D=ie.renderPage(le,96,{},document);L.apply(D),T.appendChild(D)})},{flush:"post"}),e.watch(()=>L.query.value,c=>{c||R.value?.querySelectorAll(".mrp-page-holder").forEach(y=>{L.clear(y)})});const K=Gt(o,{thumbsRoot:w,visible:$,renderThumbCanvas:c=>{try{const{canvases:y}=ie.renderPlanToCanvas(o.value,{start:c,end:c,dpr:.2});return y[0]??null}catch{return null}}});e.watchEffect(()=>{K.schedule()},{flush:"post"});const Rt=e.computed(()=>l.debug),{debugStats:ae}=Kt(Rt,{plan:o,pageCount:S,windowRange:me,zoom:q,loadMs:x.loadMs});function Ue(){Re(F.value),K.schedule(),oe.value==="fit"&&Ae()}function Ft(){try{const c=JSON.parse(localStorage.getItem(Xe)??"{}");c.zoomMode==="fit"?Be("fit"):typeof c.zoomMode=="number"&&Be(c.zoomMode)}catch{}}return e.onMounted(()=>{window.addEventListener("resize",Ue),Re(F.value),Ft(),l.autoLoad&&_()}),e.onUnmounted(()=>{de=!0,Ce(),X++,Z?.abort(),Z=null,window.removeEventListener("resize",Ue),K.destroy(),L.reset(),kt()}),e.watch(()=>[JSON.stringify(V.value),JSON.stringify(l.params),O.value],()=>{if(l.autoLoad){_();return}X++,Z?.abort(),Z=null,s.value=!1,f.value="",p.value=null,h.value=null,ve()}),n({reload:_,print:Me,exportAs:Te,openPdfWindow:De,gotoPage:Y,setParams:je,checkPdfFont:he,state:A}),(c,y)=>(e.openBlock(),e.createElementBlock("div",{class:"mach-report-preview",style:e.normalizeStyle(bt.value)},[C.value&&J.value.length>0?(e.openBlock(),e.createBlock(at,{key:0,defs:J.value,modelValue:Q.value,"onUpdate:modelValue":y[0]||(y[0]=E=>Q.value=E),messages:W.value,attempted:$e.value,onQuery:wt,onReset:yt},null,8,["defs","modelValue","messages","attempted"])):e.createCommentVNode("",!0),e.createVNode(ot,{"page-count":S.value,"current-page":v.value,"zoom-mode":e.unref(oe),zoom:e.unref(q),"show-export":i.value,"show-print":m.value,"show-pdf-window":b.value,messages:W.value,search:{visible:e.unref(L).visible.value,query:e.unref(L).query.value,matchIndex:e.unref(L).matchIndex.value,matchCount:e.unref(L).matchCount.value,searching:e.unref(L).searching.value},"thumbs-visible":$.value,onGoto:Y,onZoom:e.unref(Be),onExport:y[1]||(y[1]=E=>Te(E)),onPrint:Me,onPdfWindow:De,onSearchInput:e.unref(L).onInput,onSearchNav:e.unref(L).onNav,onSearchToggle:e.unref(L).toggle,onThumbsToggle:y[2]||(y[2]=E=>$.value=!$.value)},null,8,["page-count","current-page","zoom-mode","zoom","show-export","show-print","show-pdf-window","messages","search","thumbs-visible","onZoom","onSearchInput","onSearchNav","onSearchToggle"]),h.value?(e.openBlock(),e.createElementBlock("div",{key:1,class:e.normalizeClass(["mrp-export-notice",`mrp-export-${h.value.kind}`]),role:"alert"},e.toDisplayString(h.value.message),3)):e.createCommentVNode("",!0),u.value.status==="error"&&(i.value||b.value)?(e.openBlock(),e.createElementBlock("div",kn,[e.createTextVNode(e.toDisplayString(W.value.pdfFontUnavailable)+" ",1),e.createElementVNode("button",{type:"button",onClick:gt},e.toDisplayString(W.value.retry),1)])):e.createCommentVNode("",!0),e.createElementVNode("div",Cn,[e.createElementVNode("div",{ref_key:"viewportRef",ref:F,class:"mrp-body",tabindex:"0",onWheel:$t,onKeydown:Bt,onScrollPassive:y[3]||(y[3]=E=>e.unref(xt)(E.target))},[s.value?(e.openBlock(),e.createElementBlock("div",$n,e.toDisplayString(W.value.loading),1)):f.value?(e.openBlock(),e.createElementBlock("div",Bn,[e.createTextVNode(e.toDisplayString(f.value)+" ",1),e.createElementVNode("button",{class:"mrp-retry",type:"button",onClick:_},e.toDisplayString(W.value.retry),1)])):!o.value||S.value===0?(e.openBlock(),e.createElementBlock("div",Sn,e.toDisplayString(W.value.empty),1)):(e.openBlock(),e.createElementBlock("div",{key:3,class:"mrp-scale",style:e.normalizeStyle({width:`${e.unref(Se).w*e.unref(q)}px`,height:`${e.unref(Se).h*e.unref(q)}px`})},[e.createElementVNode("div",{ref_key:"containerRef",ref:R,class:"mrp-scale-inner",style:e.normalizeStyle({transform:`scale(${e.unref(q)})`,transformOrigin:"top left",width:`${e.unref(Se).w}px`})},[e.unref(me).padTopPx>0?(e.openBlock(),e.createElementBlock("div",{key:0,class:"mrp-spacer-top",style:e.normalizeStyle({height:`${e.unref(me).padTopPx}px`}),"aria-hidden":"true"},null,4)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(qe),E=>(e.openBlock(),e.createElementBlock("div",{key:E.index,class:"mrp-page-holder","data-page":E.index+1},null,8,Rn))),128)),e.unref(me).padBottomPx>0?(e.openBlock(),e.createElementBlock("div",{key:1,class:"mrp-spacer-bottom",style:e.normalizeStyle({height:`${e.unref(me).padBottomPx}px`}),"aria-hidden":"true"},null,4)):e.createCommentVNode("",!0)],4)],4))],544),$.value&&S.value>0?(e.openBlock(),e.createElementBlock("aside",{key:0,ref_key:"thumbsRef",ref:w,class:"mrp-thumbs",onScrollPassive:y[4]||(y[4]=(...E)=>e.unref(K).onScroll&&e.unref(K).onScroll(...E))},[e.unref(K).windowRange.value.padTopPx>0?(e.openBlock(),e.createElementBlock("div",{key:0,class:"mrp-thumb-spacer",style:e.normalizeStyle({height:`${e.unref(K).windowRange.value.padTopPx}px`}),"aria-hidden":"true"},null,4)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(K).visibleThumbs.value,E=>(e.openBlock(),e.createElementBlock("div",{key:E.index,class:e.normalizeClass(["mrp-thumb",{"mrp-thumb-active":E.index+1===v.value}]),style:e.normalizeStyle({height:`${E.height+20}px`}),onClick:T=>Y(E.index+1)},[e.createElementVNode("div",{class:"mrp-thumb-box","data-thumb":E.index+1,style:e.normalizeStyle({height:`${E.height}px`})},null,12,Mn),e.createElementVNode("span",Tn,e.toDisplayString(E.index+1),1)],14,Fn))),128)),e.unref(K).windowRange.value.padBottomPx>0?(e.openBlock(),e.createElementBlock("div",{key:1,class:"mrp-thumb-spacer",style:e.normalizeStyle({height:`${e.unref(K).windowRange.value.padBottomPx}px`}),"aria-hidden":"true"},null,4)):e.createCommentVNode("",!0)],544)):e.createCommentVNode("",!0)]),e.createElementVNode("div",Dn,[e.renderSlot(c.$slots,"default",{},void 0,!0)]),e.unref(ae)?(e.openBlock(),e.createElementBlock("div",Nn,[y[5]||(y[5]=e.createElementVNode("div",null,"mach-report debug",-1)),e.createElementVNode("div",null,"pages: "+e.toDisplayString(e.unref(ae).pages)+" | window: ["+e.toDisplayString(e.unref(ae).window)+"]",1),e.createElementVNode("div",null,"zoom: "+e.toDisplayString(e.unref(ae).zoom)+" | load: "+e.toDisplayString(e.unref(ae).loadMs),1),e.createElementVNode("div",null,"plan: "+e.toDisplayString(e.unref(ae).planKB)+"KB",1)])):e.createCommentVNode("",!0)],4))}}),pt=We(Vn,[["__scopeId","data-v-294f34ce"]]),On=Object.freeze(Object.defineProperty({__proto__:null,default:pt},Symbol.toStringTag,{value:"Module"}));exports.DEFAULT_MESSAGES=lt;exports.DEFAULT_THEME=st;exports.MachReportError=ne;exports.PlanLoadError=ye;exports.ReportParamPanel=at;exports.ReportPreview=pt;exports.ReportPreview$1=On;exports.ReportToolbar=ot;exports.SILENT_LOGGER=yn;exports.buildPrintDocument=Le;exports.buildWordHtml=tt;exports.createDefaultPdfExporter=ft;exports.createFetchRequest=It;exports.defineMachReportConfig=it;exports.defineMachReportPreset=wn;exports.joinReportIds=zt;exports.normalizeReportIds=Oe;exports.printPlans=Lt;exports.provideMachReportConfig=bn;exports.resolveConfig=ct;exports.themeToCssVars=ut;exports.toErrorDetail=mt;exports.useMachReportConfig=dt;exports.usePageWindow=_e;exports.usePrintExport=nt;exports.useZoom=et;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const w="#333333",F="#000000",N="1.0.0-mach";function M(o=96){return o/25.4}function z(o,r=96){return(o||0)*M(r)}function U(o,r=96){return o/M(r)}function O(o,r=96){return o*r/72}function B(o,r){const s=10**r;return Math.round(o*s)/s}const b={a3:{widthMm:297,heightMm:420},a4:{widthMm:210,heightMm:297},a5:{widthMm:148,heightMm:210},b4:{widthMm:250,heightMm:353},b5:{widthMm:176,heightMm:250}};function k(o,r=96,s=10.5){if(o?.fontSizePx!=null)return{fontSizePt:o.fontSizePx*72/r,fontSizePx:o.fontSizePx};const h=o?.fontSize??s;return{fontSizePt:h,fontSizePx:O(h,r)}}function G(o,r=w){return{color:o?.borderColor??o?.lineColor??r,widthPt:o?.lineWidthPt??.75}}function $(o,r=F){return o?.color??r}function y(o){return o?.lineHeight??1.35}function K(o){const r=o?.borderTop!==!1,s=o?.borderRight!==!1,h=o?.borderBottom!==!1,l=o?.borderLeft!==!1;return{top:r,right:s,bottom:h,left:l,inner:r||s||h||l}}function g(o,r){const s=o.length;if(s===0)return[];const h=o.reduce((i,f)=>i+f,0),l=h>0&&r>0?r/h:1,c=[];let u=0;for(let i=0;i<s;i++){const f=Math.max(0,o[i]*l);c.push({pos:u,size:f}),u+=f}return c}function V(o,r,s){const h=o.cells??[],l=Math.max(h.length,1),c=o.colWidthsMm?.length??Math.max(1,...h.map(t=>Array.isArray(t)?t.length:0)),u=o.colWidthsMm?.length?g(o.colWidthsMm,r):Array.from({length:c},(t,n)=>({pos:r*n/c,size:r/c})),i=t=>t<=0?0:t>=c?u[u.length-1].pos+u[u.length-1].size:u[t].pos,f=o.rowHeightsMm?.length?g(o.rowHeightsMm,s):Array.from({length:l},(t,n)=>({pos:s*n/l,size:s/l})),T=t=>t<=0?0:t>=l?f[f.length-1].pos+f[f.length-1].size:f[t].pos,d=new Set,C=(t,n)=>`${t}:${n}`,L=[],A=new Set,R=new Set,p=(t,n)=>`v${t}:${n}`,x=(t,n)=>`h${t}:${n}`;h.forEach((t,n)=>{if(!Array.isArray(t))return;let e=0;for(const S of t){for(;e<c&&d.has(C(n,e));)e++;if(e>=c)break;const H=Math.max(1,Math.min(S?.colSpan??1,c-e)),v=Math.max(1,S?.rowSpan??1),P=Math.min(l,n+v),E=Math.min(c,e+H);for(let _=n;_<P;_++)for(let a=e;a<E;a++)d.add(C(_,a));for(let _=e+1;_<E;_++)for(let a=n;a<P;a++)A.add(p(_,a));for(let _=n+1;_<P;_++)for(let a=e;a<E;a++)R.add(x(_,a));const D=i(e),I=T(n);L.push({ri:n,ci:e,cell:S??{},xMm:D,yMm:I,widthMm:i(E)-D,heightMm:T(P)-I}),e=E}});const m=[];for(let t=1;t<c;t++){let n=-1;for(let e=0;e<=l;e++){const S=e<l&&!A.has(p(t,e));S&&n<0&&(n=e),!S&&n>=0&&(m.push({kind:"v",pos:i(t),from:T(n),to:T(e)}),n=-1)}}for(let t=1;t<l;t++){let n=-1;for(let e=0;e<=c;e++){const S=e<c&&!R.has(x(t,e));S&&n<0&&(n=e),!S&&n>=0&&(m.push({kind:"h",pos:T(t),from:i(n),to:i(e)}),n=-1)}}return{columns:u,rows:f,cells:L,edges:m}}exports.CSS_DPI=96;exports.DEFAULT_BORDER_PT=.75;exports.DEFAULT_FONT_PT=10.5;exports.DEFAULT_STROKE_COLOR=w;exports.DEFAULT_TEXT_COLOR=F;exports.LINE_HEIGHT=1.35;exports.MM_PER_INCH=25.4;exports.PAPER_SIZES=b;exports.SCHEMA_VERSION_MACH=N;exports.mmToPx=z;exports.mmToPxFactor=M;exports.ptToPx=O;exports.pxToMm=U;exports.resolveBoxBorders=K;exports.resolveFontSize=k;exports.resolveGridLayout=V;exports.resolveLineHeight=y;exports.resolveStroke=G;exports.resolveTextColor=$;exports.round=B;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
const H = 1.35, O = 10.5, B = 0.75, b = "#333333", v = "#000000", N = "1.0.0-mach", k = 25.4, U = 96;
|
|
2
|
+
function I(t = 96) {
|
|
3
|
+
return t / 25.4;
|
|
4
|
+
}
|
|
5
|
+
function $(t, s = 96) {
|
|
6
|
+
return (t || 0) * I(s);
|
|
7
|
+
}
|
|
8
|
+
function y(t, s = 96) {
|
|
9
|
+
return t / I(s);
|
|
10
|
+
}
|
|
11
|
+
function F(t, s = 96) {
|
|
12
|
+
return t * s / 72;
|
|
13
|
+
}
|
|
14
|
+
function G(t, s) {
|
|
15
|
+
const r = 10 ** s;
|
|
16
|
+
return Math.round(t * r) / r;
|
|
17
|
+
}
|
|
18
|
+
const K = {
|
|
19
|
+
a3: { widthMm: 297, heightMm: 420 },
|
|
20
|
+
a4: { widthMm: 210, heightMm: 297 },
|
|
21
|
+
a5: { widthMm: 148, heightMm: 210 },
|
|
22
|
+
b4: { widthMm: 250, heightMm: 353 },
|
|
23
|
+
b5: { widthMm: 176, heightMm: 250 }
|
|
24
|
+
};
|
|
25
|
+
function W(t, s = 96, r = 10.5) {
|
|
26
|
+
if (t?.fontSizePx != null)
|
|
27
|
+
return { fontSizePt: t.fontSizePx * 72 / s, fontSizePx: t.fontSizePx };
|
|
28
|
+
const h = t?.fontSize ?? r;
|
|
29
|
+
return { fontSizePt: h, fontSizePx: F(h, s) };
|
|
30
|
+
}
|
|
31
|
+
function j(t, s = b) {
|
|
32
|
+
return {
|
|
33
|
+
color: t?.borderColor ?? t?.lineColor ?? s,
|
|
34
|
+
widthPt: t?.lineWidthPt ?? 0.75
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function V(t, s = v) {
|
|
38
|
+
return t?.color ?? s;
|
|
39
|
+
}
|
|
40
|
+
function X(t) {
|
|
41
|
+
return t?.lineHeight ?? 1.35;
|
|
42
|
+
}
|
|
43
|
+
function Z(t) {
|
|
44
|
+
const s = t?.borderTop !== !1, r = t?.borderRight !== !1, h = t?.borderBottom !== !1, a = t?.borderLeft !== !1;
|
|
45
|
+
return { top: s, right: r, bottom: h, left: a, inner: s || r || h || a };
|
|
46
|
+
}
|
|
47
|
+
function L(t, s) {
|
|
48
|
+
const r = t.length;
|
|
49
|
+
if (r === 0) return [];
|
|
50
|
+
const h = t.reduce((l, i) => l + i, 0), a = h > 0 && s > 0 ? s / h : 1, c = [];
|
|
51
|
+
let S = 0;
|
|
52
|
+
for (let l = 0; l < r; l++) {
|
|
53
|
+
const i = Math.max(0, t[l] * a);
|
|
54
|
+
c.push({ pos: S, size: i }), S += i;
|
|
55
|
+
}
|
|
56
|
+
return c;
|
|
57
|
+
}
|
|
58
|
+
function q(t, s, r) {
|
|
59
|
+
const h = t.cells ?? [], a = Math.max(h.length, 1), c = t.colWidthsMm?.length ?? Math.max(1, ...h.map((o) => Array.isArray(o) ? o.length : 0)), S = t.colWidthsMm?.length ? L(t.colWidthsMm, s) : Array.from({ length: c }, (o, n) => ({
|
|
60
|
+
pos: s * n / c,
|
|
61
|
+
size: s / c
|
|
62
|
+
})), l = (o) => o <= 0 ? 0 : o >= c ? S[S.length - 1].pos + S[S.length - 1].size : S[o].pos, i = t.rowHeightsMm?.length ? L(t.rowHeightsMm, r) : Array.from({ length: a }, (o, n) => ({
|
|
63
|
+
pos: r * n / a,
|
|
64
|
+
size: r / a
|
|
65
|
+
})), d = (o) => o <= 0 ? 0 : o >= a ? i[i.length - 1].pos + i[i.length - 1].size : i[o].pos, p = /* @__PURE__ */ new Set(), E = (o, n) => `${o}:${n}`, T = [], g = /* @__PURE__ */ new Set(), w = /* @__PURE__ */ new Set(), x = (o, n) => `v${o}:${n}`, C = (o, n) => `h${o}:${n}`;
|
|
66
|
+
h.forEach((o, n) => {
|
|
67
|
+
if (!Array.isArray(o)) return;
|
|
68
|
+
let e = 0;
|
|
69
|
+
for (const m of o) {
|
|
70
|
+
for (; e < c && p.has(E(n, e)); ) e++;
|
|
71
|
+
if (e >= c) break;
|
|
72
|
+
const R = Math.max(1, Math.min(m?.colSpan ?? 1, c - e)), z = Math.max(1, m?.rowSpan ?? 1), P = Math.min(a, n + z), M = Math.min(c, e + R);
|
|
73
|
+
for (let f = n; f < P; f++)
|
|
74
|
+
for (let u = e; u < M; u++)
|
|
75
|
+
p.add(E(f, u));
|
|
76
|
+
for (let f = e + 1; f < M; f++)
|
|
77
|
+
for (let u = n; u < P; u++) g.add(x(f, u));
|
|
78
|
+
for (let f = n + 1; f < P; f++)
|
|
79
|
+
for (let u = e; u < M; u++) w.add(C(f, u));
|
|
80
|
+
const A = l(e), D = d(n);
|
|
81
|
+
T.push({
|
|
82
|
+
ri: n,
|
|
83
|
+
ci: e,
|
|
84
|
+
cell: m ?? {},
|
|
85
|
+
xMm: A,
|
|
86
|
+
yMm: D,
|
|
87
|
+
widthMm: l(M) - A,
|
|
88
|
+
heightMm: d(P) - D
|
|
89
|
+
}), e = M;
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
const _ = [];
|
|
93
|
+
for (let o = 1; o < c; o++) {
|
|
94
|
+
let n = -1;
|
|
95
|
+
for (let e = 0; e <= a; e++) {
|
|
96
|
+
const m = e < a && !g.has(x(o, e));
|
|
97
|
+
m && n < 0 && (n = e), !m && n >= 0 && (_.push({ kind: "v", pos: l(o), from: d(n), to: d(e) }), n = -1);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
for (let o = 1; o < a; o++) {
|
|
101
|
+
let n = -1;
|
|
102
|
+
for (let e = 0; e <= c; e++) {
|
|
103
|
+
const m = e < c && !w.has(C(o, e));
|
|
104
|
+
m && n < 0 && (n = e), !m && n >= 0 && (_.push({ kind: "h", pos: d(o), from: l(n), to: l(e) }), n = -1);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { columns: S, rows: i, cells: T, edges: _ };
|
|
108
|
+
}
|
|
109
|
+
export {
|
|
110
|
+
U as C,
|
|
111
|
+
O as D,
|
|
112
|
+
H as L,
|
|
113
|
+
k as M,
|
|
114
|
+
K as P,
|
|
115
|
+
N as S,
|
|
116
|
+
G as a,
|
|
117
|
+
j as b,
|
|
118
|
+
Z as c,
|
|
119
|
+
X as d,
|
|
120
|
+
V as e,
|
|
121
|
+
q as f,
|
|
122
|
+
v as g,
|
|
123
|
+
B as h,
|
|
124
|
+
b as i,
|
|
125
|
+
I as j,
|
|
126
|
+
y as k,
|
|
127
|
+
$ as m,
|
|
128
|
+
F as p,
|
|
129
|
+
W as r
|
|
130
|
+
};
|
package/dist/index.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("./style-CFZ-HE2s.cjs"),fe=require("./grid-geometry-BXpOxznT.cjs"),Ce=require("./report-params-D1NeY-eR.cjs");function ge(e){const t=/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/.exec(e.trim());if(t){const r=new Date(Number(t[1]),Number(t[2])-1,Number(t[3]));return Number.isNaN(r.getTime())?null:r}const n=new Date(e);return Number.isNaN(n.getTime())?null:n}function Z(e,t){return e.toLocaleString("en-US",{minimumFractionDigits:t,maximumFractionDigits:t})}function Ae(e,t){const n=r=>String(r).padStart(2,"0");return t.replace(/YYYY/g,String(e.getFullYear())).replace(/MM/g,n(e.getMonth()+1)).replace(/DD/g,n(e.getDate())).replace(/hh/g,n(e.getHours())).replace(/mm/g,n(e.getMinutes())).replace(/ss/g,n(e.getSeconds()))}function Re(e,t,n){return n!=null?t?Z(e,n):e.toFixed(n):t?Z(e):String(e)}function q(e){const t=typeof e=="number"?e:Number(String(e).replace(/,/g,""));return Number.isFinite(t)?t:null}function K(e,t){if(e==null||e===""||!t)return String(e??"");switch(t.kind){case"number":{const n=q(e);return n==null?String(e):Re(n,t.thousands===!0,t.digits)}case"percent":{const n=q(e);return n==null?String(e):`${Z(n*100,t.digits??2)}%`}case"date":{const n=t.pattern??"YYYY-MM-DD",r=e instanceof Date?e:ge(String(e));return r?Ae(r,n):String(e)}default:return String(e)}}function ue(e,t){const n=e[t.field];if(n==null||n==="")return!1;if(typeof t.value=="number"){const i=q(n);if(i==null)return!1;switch(t.op){case">":return i>t.value;case">=":return i>=t.value;case"<":return i<t.value;case"<=":return i<=t.value;case"==":return i===t.value;case"!=":return i!==t.value}}const r=String(n),o=String(t.value);switch(t.op){case"==":return r===o;case"!=":return r!==o;case">":return r>o;case">=":return r>=o;case"<":return r<o;case"<=":return r<=o}return!1}const He=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function j(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Ne(e,t,n,r){const o=e[t];(typeof o!="number"||!Number.isFinite(o))&&r.push({path:`${n}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(o)}`})}function X(e,t,n,r=[]){if(!j(e)){n.push({path:t,message:"组件应为对象"});return}const o=e.kind;typeof o!="string"?n.push({path:`${t}.kind`,message:"组件缺少 kind 字符串"}):He.has(o)||r.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(o)},将以兜底方式渲染`});for(const s of["leftMm","topMm","widthMm","heightMm"])Ne(e,s,t,n);typeof e.leftMm=="number"&&e.leftMm<-100&&n.push({path:`${t}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const s of["widthMm","heightMm"])typeof e[s]=="number"&&e[s]<0&&n.push({path:`${t}.${s}`,message:"组件尺寸不能为负数"});const i=e.grid;i!==void 0&&(!j(i)||!Array.isArray(i.cells)?n.push({path:`${t}.grid.cells`,message:"grid.cells 应为二维数组"}):i.cells.forEach((s,l)=>{if(!Array.isArray(s)){n.push({path:`${t}.grid.cells.${l}`,message:"行应为数组"});return}s.forEach((m,f)=>{m!=null&&j(m)&&Array.isArray(m.children)&&m.children.forEach((h,c)=>{X(h,`${t}.grid.cells.${l}.${f}.children.${c}`,n,r)})})}));const a=e.richParagraphs;a!==void 0&&(Array.isArray(a)?a.forEach((s,l)=>{(!j(s)||!Array.isArray(s.segments))&&n.push({path:`${t}.richParagraphs.${l}`,message:"段落缺少 segments 数组"})}):n.push({path:`${t}.richParagraphs`,message:"richParagraphs 应为数组"}))}function pe(e,t,n,r=[]){if(!j(e)){n.push({path:t,message:"页应为对象"});return}const o=e.pageWidthMm,i=e.pageHeightMm;(typeof o!="number"||!(o>0&&o<3e3))&&n.push({path:`${t}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(o)}`}),(typeof i!="number"||!(i>0&&i<5e3))&&n.push({path:`${t}.pageHeightMm`,message:`页高非法: ${JSON.stringify(i)}`});const a=e.components;Array.isArray(a)?Array.isArray(a)&&a.forEach((s,l)=>X(s,`${t}.components.${l}`,n,r)):n.push({path:`${t}.components`,message:"components 应为数组"})}function Q(e){const t=[],n=[],r=j(e)?e.pages:void 0;if(!Array.isArray(r))t.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{r.forEach((i,a)=>pe(i,`$.pages.${a}`,t,n)),r.length>2e3&&n.push({path:"$.pages",message:`页数异常大(${r.length} 页),渲染与打印耗时可能显著增加`});const o=r.reduce((i,a)=>i+(j(a)&&Array.isArray(a.components)?a.components.length:0),0);o>5e4&&n.push({path:"$.pages",message:`组件总数异常大(${o} 个),可能触发浏览器性能限制`})}return{ok:t.length===0,errors:t,warnings:n}}function Le(e){const t=Q(e);if(!t.ok){const n=t.errors.slice(0,3).map(r=>`${r.path}: ${r.message}`).join("; ");throw new Error(`渲染计划校验失败(${t.errors.length} 处): ${n}`)}return e.pages}function de(e){return{widthMm:e.widthMm,heightMm:e.heightMm,marginTopMm:e.marginTopMm??0,marginBottomMm:e.marginBottomMm??0,marginLeftMm:e.marginLeftMm??0,marginRightMm:e.marginRightMm??0,components:[]}}function _e(e,t){return t.heightMm-(e.marginBottomMm??t.marginBottomMm)}function Fe(e,t){const r=(e.fontSizePt??d.DEFAULT_FONT_PT)*d.LINE_HEIGHT*25.4/72,o=(e.paddingMm??1)*2;return Math.max(e.rowHeightMm??0,t*r+o)}function Me(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number")return String(e);if(typeof e=="boolean")return e?"是":"否";if(e instanceof Date)return e.toISOString().slice(0,10);try{return JSON.stringify(e)}catch{return String(e)}}function Be(e,t){const n=e.fontSizePt??d.DEFAULT_FONT_PT,r=e.paddingMm??1,o=e.columns.map(u=>({fontSize:n,align:"left",verticalAlign:"middle",...u.style})),i=e.columns.map(u=>({fontSize:n,bold:e.headerBold??!0,align:"center",verticalAlign:"middle",backgroundColor:e.headerBackgroundColor,...u.style||{}})),a=e.columns.map(u=>u.header),s=a.map((u,g)=>d.wrapText(u,e.columns[g].widthMm-r*2,{fontSizePt:n,bold:e.headerBold??!0},t)),l=Math.max(...s.map(u=>u.length),1),m=Fe(e,l),f=a.map((u,g)=>({text:u,style:i[g]})),h=e.border===!1?{borderTop:!1,borderRight:!1,borderBottom:!1,borderLeft:!1}:{borderBottom:!0,borderLeft:!0,borderRight:!0,borderTop:!0},c=e.columns.map(u=>u.widthMm);return{fontSizePt:n,paddingMm:r,cellStyles:o,borderStyle:h,headerHeightMm:m,headerGrid:{cells:[f],colWidthsMm:c,rowHeightsMm:[m]},colWidthsMm:c,columns:e.columns}}function me(e,t,n){const r=e.columns,o=new Array(r.length);let i=1;for(let f=0;f<r.length;f++){const h=r[f];o[f]=h.format?K(t[h.field],h.format):Me(t[h.field])}const a=new Array(r.length);for(let f=0;f<r.length;f++){const h=d.wrapText(o[f],r[f].widthMm-e.paddingMm*2,{fontSizePt:e.fontSizePt},n);a[f]=h,h.length>i&&(i=h.length)}const s=e.fontSizePt*d.LINE_HEIGHT*25.4/72,l=Math.max(e.rowHeightFloorMm,i*s+e.paddingMm*2),m=new Array(r.length);for(let f=0;f<r.length;f++){const h=r[f];let c=e.cellStyles[f];if(h.rules){for(const u of h.rules)if(ue(t,u.when)){c={...c??{},...u.style};break}}m[f]={text:o[f],style:c}}return{grid:{cells:[m],colWidthsMm:e.colWidthsMm,rowHeightsMm:[l]},heightMm:l}}function we(e,t,n={}){const r=typeof n=="number"?{mmPerRow:n}:n,o=r.mmPerRow??0,i=r.measurer??d.heuristicMeasurer,a=[],s=[];let l=0;const m=h=>`${h}_${(++l).toString(36)}`,f=[];for(const h of e.pages){const c=de(h),u=()=>_e(h,c),g=c.marginTopMm,S=[],P=()=>{if(s.push({pageWidthMm:c.widthMm,pageHeightMm:c.heightMm,marginTopMm:c.marginTopMm,marginBottomMm:c.marginBottomMm,marginLeftMm:c.marginLeftMm,marginRightMm:c.marginRightMm,components:c.components}),S.length>0){const x=s.length;for(const w of S){const v={...w,text:String(w.text??"").replace(/\{page\}/g,String(x))};s[s.length-1].components.push(v),v.text.includes("{totalPages}")&&f.push(v)}}};for(const x of h.components){if(x.kind!=="list"){if(x.kind==="text"&&typeof x.text=="string"){const y=x.text;if(y.includes("{page}")||y.includes("{totalPages}")){S.push(x);continue}}c.components.push(x);continue}const w=x,v=t[w.dataset];Array.isArray(v)||a.push(`数据集 ${w.dataset} 未提供数据,列表 ${w.id??""} 输出为空`);const p=Array.isArray(v)?v:[],E=w.columns.reduce((y,M)=>y+M.widthMm,0),G=E>w.widthMm?w.widthMm/E:1,C=G===1?w:{...w,columns:w.columns.map(y=>({...y,widthMm:y.widthMm*G}))},k={...Be(C,i),rowHeightFloorMm:C.rowHeightMm??0},U={kind:"rect",leftMm:w.leftMm,topMm:0,widthMm:w.widthMm,heightMm:k.headerHeightMm,grid:k.headerGrid,nid:m("listh"),style:k.borderStyle};let b=w.topMm;const H=(y,M)=>{y.components.push({...U,topMm:M})};H(c,b),b+=k.headerHeightMm+o;const _=y=>{if(b+y>u()){P();const M=de(h);c.components=M.components,c.heightMm=M.heightMm,C.headerEveryPage!==!1?(H(c,w.topMm),b=w.topMm+k.headerHeightMm):b=g}},T=(y,M,$)=>{const A=C.headerEveryPage!==!1?w.topMm+k.headerHeightMm:g,B=u()-A;M>B&&a.push(`列表 ${w.id??w.dataset} 行高 ${M.toFixed(2)}mm 超出单页可用高度 ${B.toFixed(2)}mm,预览与打印可能截断内容`),_(M),c.components.push({kind:"rect",leftMm:w.leftMm,topMm:b,widthMm:w.widthMm,heightMm:M,grid:y,nid:m($),style:k.borderStyle}),b+=M},N=()=>me(k,{},i).heightMm,R=(y,M,$,A)=>{const B=[],se=Math.max(1,Math.min(A,C.columns.length)),le={fontSize:k.fontSizePt,...$};B.push({text:y,colSpan:se,style:{bold:!0,...le}});for(let J=se;J<C.columns.length;J++){const $e=C.columns[J];B.push({text:M.get($e.field)??"",style:le})}const ke=k.fontSizePt*d.LINE_HEIGHT*25.4/72,ce=Math.max(k.rowHeightFloorMm,ke+k.paddingMm*2);return{grid:{cells:[B],colWidthsMm:k.colWidthsMm,rowHeightsMm:[ce]},heightMm:ce}},I=(y,M)=>{let $=0;for(const A of y){const B=typeof A[M]=="number"?A[M]:Number(A[M]);Number.isFinite(B)&&($+=B)}return $},Y=(y,M)=>{const $=C.columns.find(A=>A.field===M);return K(I(y,M),$?.format??{kind:"number",thousands:!0})},F=C.groupBy,ie=y=>{const M=C.columns.findIndex($=>y.includes($.field));return M>0?M:1},V=[];if(F){const y=new Map;for(const M of p){const $=Me(M[F.field]),A=y.get($);A?A.push(M):y.set($,[M])}for(const[M,$]of y){V.push({kind:"groupHeader",label:(F.headerTemplate??"{value}").replace(/\{value\}/g,M)});for(const A of $)V.push({kind:"row",row:A});F.subtotal&&F.subtotal.length>0&&V.push({kind:"subtotal",label:F.subtotalLabel??"小计",rows:$})}}else for(const y of p)V.push({kind:"row",row:y});const ae=N();for(const y of V)if(y.kind==="row"){const M=me(k,y.row,i);T(M.grid,M.heightMm,"listr")}else if(y.kind==="groupHeader"){const M=R(y.label,new Map,F?.headerStyle??{},C.columns.length);F?.keepWithNext!==!1&&b+M.heightMm+ae>u()&&_(M.heightMm+ae),T(M.grid,M.heightMm,"listg")}else if(y.kind==="subtotal"){const M=new Map;for(const A of F.subtotal??[])M.set(A,Y(y.rows,A));const $=R(y.label,M,F?.subtotalStyle??{},ie(F.subtotal??[]));T($.grid,$.heightMm,"listst")}if(C.grandTotal){const y=typeof C.grandTotal=="object"?C.grandTotal:void 0,M=y?.fields??F?.subtotal??[];if(M.length>0){const $=new Map;for(const B of M)$.set(B,Y(p,B));const A=R(y?.label??"合计",$,y?.style??{},ie(M));T(A.grid,A.heightMm,"listgt")}else a.push(`列表 ${w.id??""} 配置了 grandTotal 但未提供合计字段(groupBy.subtotal 或 grandTotal.fields)`)}}P()}for(const h of f){const c=h.text;typeof c=="string"&&c.includes("{totalPages}")&&(h.text=c.replace(/\{totalPages\}/g,String(s.length)))}return{plan:{schemaVersion:d.RENDER_PLAN_SCHEMA_VERSION,pages:s},warnings:a}}const ze={root:"mr-root",page:"mr-page",comp:"mr-comp",text:"mr-text",lines:"mr-lines",line:"mr-line",rich:"mr-rich",paragraph:"mr-paragraph",segment:"mr-segment",image:"mr-image",shape:"mr-shape",grid:"mr-grid",row:"mr-row",cell:"mr-cell",unknown:"mr-unknown"};function L(e,t){return t?.classNames?.[e]??ze[e]}class z{constructor(){this.props=[]}add(t,n){return n==null||n===!1||n===""?this:(this.props.push([t,String(n)]),this)}mm(t,n,r,o=2){return this.add(t,`${d.round(d.mmToPx(n,r),o)}px`)}toString(){let t="";for(const[n,r]of this.props)t+=`${n}:${r};`;return t}applyTo(t){const n=this.toString();n&&(t.style.cssText=n)}}function be(e,t,n){const r=t.style||{};e.add("color",r.color).add("background-color",r.backgroundColor).add("font-family",r.fontFamily).add("font-weight",r.bold?"700":void 0).add("font-style",r.italic?"italic":void 0).add("text-decoration",r.underline?"underline":void 0).add("letter-spacing",r.letterSpacing!=null?`${r.letterSpacing}pt`:void 0).add("opacity",r.opacity!=null?String(r.opacity):void 0).add("transform",r.rotateDeg?`rotate(${r.rotateDeg}deg)`:void 0);const o=d.resolveFontSize(r,n);e.add("font-size",`${d.round(o.fontSizePx,2)}px`)}function De(e,t,n,r,o){const i=o.createElement("table");if(i.className=L("grid",r),new z().add("width","100%").add("height","100%").add("border-collapse","collapse").add("table-layout",e.colWidthsMm?"fixed":"auto").applyTo(i),e.colWidthsMm){const m=o.createElement("colgroup");for(const f of e.colWidthsMm){const h=o.createElement("col");new z().mm("width",f,n).applyTo(h),m.appendChild(h)}i.appendChild(m)}const a=d.resolveBoxBorders(t.style),s=d.resolveStroke(t.style),l=a.inner?`${d.round(s.widthPt*n/72,2)}px solid ${s.color}`:"";return e.cells.forEach((m,f)=>{const h=o.createElement("tr");h.className=L("row",r),e.rowHeightsMm?.[f]!=null&&new z().mm("height",e.rowHeightsMm[f],n).applyTo(h),(m||[]).forEach(c=>{const u=o.createElement("td");u.className=L("cell",r),c?.colSpan&&(u.colSpan=c.colSpan),c?.rowSpan&&(u.rowSpan=c.rowSpan);const g=new z;if(l&&g.add("border",l),c?.style){const S=c.style;g.add("text-align",S.align).add("vertical-align",S.verticalAlign).add("background-color",S.backgroundColor).add("color",S.color).add("font-weight",S.bold?"700":void 0),g.add("font-size",`${d.round(d.resolveFontSize(S,n).fontSizePx,2)}px`)}if(g.applyTo(u),c?.text!=null&&(u.textContent=c.text),c?.children?.length)for(const S of c.children)u.appendChild(ee(S,n,r,o));h.appendChild(u)}),i.appendChild(h)}),i}function Oe(e,t,n,r){const o=r.createElement("div");o.className=L("text",n);const i=e.style||{},a=new z().add("text-align",i.align).add("display","flex").add("flex-direction","column").add("justify-content",i.verticalAlign==="middle"?"center":i.verticalAlign==="bottom"?"flex-end":"flex-start").add("overflow","hidden");if(be(a,e,t),a.applyTo(o),d.isRichText(e)){const s=r.createElement("div");s.className=L("rich",n);for(const l of e.richParagraphs){const m=r.createElement("div");m.className=L("paragraph",n),new z().add("text-align",l.align).add("line-height",l.lineHeight!=null?String(l.lineHeight):void 0).mm("margin-top",l.spaceBeforeMm??0,t).mm("margin-bottom",l.spaceAfterMm??0,t).mm("text-indent",l.indentMm??0,t).applyTo(m);for(const h of l.segments||[]){const c=r.createElement("span");if(c.className=L("segment",n),c.textContent=h.kind==="field"?h.field??"":h.text??"",h.style){const u=new z().add("color",h.style.color).add("font-weight",h.style.bold?"700":void 0);u.add("font-size",`${d.round(d.resolveFontSize(h.style,t).fontSizePx,2)}px`),u.applyTo(c)}m.appendChild(c)}s.appendChild(m)}return o.appendChild(s),o}if(Array.isArray(e.lines)&&e.lines.length>0){const s=r.createElement("div");s.className=L("lines",n),i.lineHeight!=null&&new z().add("line-height",String(i.lineHeight)).applyTo(s);for(const l of e.lines){const m=r.createElement("div");m.className=L("line",n),m.textContent=l,s.appendChild(m)}return o.appendChild(s),o}return o.textContent=e.text??"",o}function Ie(e,t,n){const r=n.createElement("img");return r.className=L("image",t),r.src=e.imageData,new z().add("width","100%").add("height","100%").add("object-fit","contain").add("display","block").applyTo(r),r.alt=e.kind,r}function he(e,t,n,r){const o=r.createElement("div");o.className=L("shape",n);const i=e.style||{},a=d.resolveStroke(i),s=d.resolveBoxBorders(i),l=`${d.round(a.widthPt*t/72,2)}px solid ${a.color}`,m=new z;return e.grid||e.kind==="rect"?(s.top&&m.add("border-top",l),s.right&&m.add("border-right",l),s.bottom&&m.add("border-bottom",l),s.left&&m.add("border-left",l)):e.kind==="ellipse"?(s.inner&&m.add("border",l).add("border-radius","50%"),i.backgroundColor&&m.add("background-color",i.backgroundColor)):e.kind==="line"&&m.add("height","0").add("border-top",l),m.add("box-sizing","border-box").add("width","100%").add("height","100%"),m.applyTo(o),o}function ee(e,t,n,r){const o=r.createElement("div");o.className=`${L("comp",n)} mr-kind-${e.kind}`;const i=new z().add("position","absolute").mm("left",e.leftMm,t).mm("top",e.topMm,t).mm("width",e.widthMm,t).mm("height",e.heightMm,t).add("box-sizing","border-box");if(be(i,e,t),i.applyTo(o),d.isImageBackedComponent(e))return o.appendChild(Ie(e,n,r)),o;if(e.kind==="text")return o.appendChild(Oe(e,t,n,r)),o;if(e.grid){const s=he(e,t,n,r);return s.appendChild(De(e.grid,e,t,n,r)),o.appendChild(s),o}if(e.kind==="line"||e.kind==="rect"||e.kind==="ellipse"||e.kind==="chart")return o.appendChild(he(e,t,n,r)),o;const a=r.createElement("div");return a.className=L("unknown",n),a.textContent=e.fallbackText??"",o.appendChild(a),o}function ye(e,t,n,r){const o=r.createElement("div");o.className=L("page",n),new z().add("position","relative").mm("width",e.pageWidthMm,t).mm("height",e.pageHeightMm,t).add("background-color","#fff").add("overflow","hidden").add("box-sizing","border-box").applyTo(o);for(const i of e.components)o.appendChild(ee(i,t,n,r));return o}function We(e,t,n={}){const r=n.dpi??96,o=t.createElement("div");return o.className=L("root",n),o.dataset.schemaVersion=e.schemaVersion,e.pages.forEach(i=>{o.appendChild(ye(i,r,n,t))}),o}function Se(e){const{pageHeightsPx:t,viewportHeightPx:n,scrollTopPx:r,overscan:o=1,gapPx:i=0}=e,a=t.length;if(a===0)return{start:0,end:-1,padTopPx:0,padBottomPx:0};const s=Math.max(0,i),l=new Array(a+1);l[0]=0;for(let p=0;p<a;p++)l[p+1]=l[p]+Math.max(0,t[p]??0)+s;const m=l[a],f=Math.max(0,r);let h=0,c=0,u=a-1;for(;c<=u;){const p=c+u>>1;l[p]<=f?(h=p,c=p+1):u=p-1}const g=Math.max(0,Math.min(a-1,h-o)),S=l[h]+Math.max(0,n);let P=a-1;for(c=0,u=a-1;c<=u;){const p=c+u>>1;l[p+1]<S?c=p+1:(P=p,u=p-1)}const x=Math.min(a-1,P+o),w=l[g],v=Math.max(0,m-l[x+1]);return{start:g,end:x,padTopPx:w,padBottomPx:v}}const te=96/25.4;function ne(e,t=96){const n=t/96*te;return{widthPx:Math.max(1,Math.round(e.pageWidthMm*n)),heightPx:Math.max(1,Math.round(e.pageHeightMm*n))}}function je(e,t,n){const r=document.createElement("canvas"),{widthPx:o,heightPx:i}=ne(e,n);r.width=Math.round(o*t),r.height=Math.round(i*t),r.style.width=`${o}px`,r.style.height=`${i}px`;const a=r.getContext("2d");if(!a)throw new Error("当前环境不支持 Canvas 2D(测试需真浏览器,见 e2e/canvas.spec.ts)");return a.scale(t,t),a.fillStyle="#ffffff",a.fillRect(0,0,o,i),{canvas:r,ctx:a}}function Ge(e,t=96){return d.resolveFontSize(e,t).fontSizePx}function Te(e,t,n,r,o,i,a,s="top"){e.font=`${t.bold?"bold ":""}${t.fontSizePx}px ${a}`,e.fillStyle=t.color,e.textBaseline="alphabetic";const l=t.fontSizePx*t.lineHeight,m=t.text===""?[""]:t.text.split(`
|
|
2
|
-
`),f=
|
|
3
|
-
`);
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("./grid-geometry-DBH9ExuY.cjs"),x=require("./textwrap-DqiFwAV3.cjs"),Qe=require("./page-window-index-DEjnM6IB.cjs"),et=require("./report-params-D1gZ1DME.cjs");function ye(e){if(!e||e.kind==="date")return;const t=e.digits;if(!(t!==void 0&&(!Number.isInteger(t)||t<0||t>100))){if(e.kind==="percent"){const n=t??2;return`0${n?`.${"0".repeat(n)}`:""}%`}return t===void 0?e.thousands?"#,##0.###############":void 0:`${e.thousands?"#,##0":"0"}${t?`.${"0".repeat(t)}`:""}`}}function Oe(e){const t=/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/.exec(e.trim());if(t){const r=new Date(Number(t[1]),Number(t[2])-1,Number(t[3]));return Number.isNaN(r.getTime())?null:r}const n=new Date(e);return Number.isNaN(n.getTime())?null:n}function pe(e,t){return e.toLocaleString("en-US",{minimumFractionDigits:t,maximumFractionDigits:t})}function tt(e,t){const n=r=>String(r).padStart(2,"0");return t.replace(/YYYY/g,String(e.getFullYear())).replace(/MM/g,n(e.getMonth()+1)).replace(/DD/g,n(e.getDate())).replace(/hh/g,n(e.getHours())).replace(/mm/g,n(e.getMinutes())).replace(/ss/g,n(e.getSeconds()))}function nt(e,t,n){return n!=null?t?pe(e,n):e.toFixed(n):t?pe(e):String(e)}function de(e){const t=typeof e=="number"?e:Number(String(e).replace(/,/g,""));return Number.isFinite(t)?t:null}function Me(e,t){if(e==null||e===""||!t)return String(e??"");switch(t.kind){case"number":{const n=de(e);return n==null?String(e):nt(n,t.thousands===!0,t.digits)}case"percent":{const n=de(e);return n==null?String(e):`${pe(n*100,t.digits??2)}%`}case"date":{const n=t.pattern??"YYYY-MM-DD",r=e instanceof Date?e:Oe(String(e));return r?tt(r,n):String(e)}default:return String(e)}}function Fe(e,t){const n=e[t.field];if(n==null||n==="")return!1;if(typeof t.value=="number"){const s=de(n);if(s==null)return!1;switch(t.op){case">":return s>t.value;case">=":return s>=t.value;case"<":return s<t.value;case"<=":return s<=t.value;case"==":return s===t.value;case"!=":return s!==t.value}}const r=String(n),o=String(t.value);switch(t.op){case"==":return r===o;case"!=":return r!==o;case">":return r>o;case">=":return r>=o;case"<":return r<o;case"<=":return r<=o}return!1}const rt=new Set(["text","image","barcode","qrcode","chart","line","rect","ellipse"]);function K(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function ot(e,t,n,r){const o=e[t];(typeof o!="number"||!Number.isFinite(o))&&r.push({path:`${n}.${t}`,message:`应为有限数字,实际 ${JSON.stringify(o)}`})}function he(e,t,n,r=[]){if(!K(e)){n.push({path:t,message:"组件应为对象"});return}const o=e.kind;typeof o!="string"?n.push({path:`${t}.kind`,message:"组件缺少 kind 字符串"}):rt.has(o)||r.push({path:`${t}.kind`,message:`未知组件类型 ${JSON.stringify(o)},将以兜底方式渲染`});for(const a of["leftMm","topMm","widthMm","heightMm"])ot(e,a,t,n);typeof e.leftMm=="number"&&e.leftMm<-100&&n.push({path:`${t}.leftMm`,message:"几何数值异常(leftMm<-100)"});for(const a of["widthMm","heightMm"])typeof e[a]=="number"&&e[a]<0&&n.push({path:`${t}.${a}`,message:"组件尺寸不能为负数"});const s=e.grid;s!==void 0&&(!K(s)||!Array.isArray(s.cells)?n.push({path:`${t}.grid.cells`,message:"grid.cells 应为二维数组"}):s.cells.forEach((a,l)=>{if(!Array.isArray(a)){n.push({path:`${t}.grid.cells.${l}`,message:"行应为数组"});return}a.forEach((c,f)=>{c!=null&&K(c)&&Array.isArray(c.children)&&c.children.forEach((h,m)=>{he(h,`${t}.grid.cells.${l}.${f}.children.${m}`,n,r)})})}));const i=e.richParagraphs;i!==void 0&&(Array.isArray(i)?i.forEach((a,l)=>{(!K(a)||!Array.isArray(a.segments))&&n.push({path:`${t}.richParagraphs.${l}`,message:"段落缺少 segments 数组"})}):n.push({path:`${t}.richParagraphs`,message:"richParagraphs 应为数组"}))}function Be(e,t,n,r=[]){if(!K(e)){n.push({path:t,message:"页应为对象"});return}const o=e.pageWidthMm,s=e.pageHeightMm;(typeof o!="number"||!(o>0&&o<3e3))&&n.push({path:`${t}.pageWidthMm`,message:`页宽非法: ${JSON.stringify(o)}`}),(typeof s!="number"||!(s>0&&s<5e3))&&n.push({path:`${t}.pageHeightMm`,message:`页高非法: ${JSON.stringify(s)}`});const i=e.components;Array.isArray(i)?Array.isArray(i)&&i.forEach((a,l)=>he(a,`${t}.components.${l}`,n,r)):n.push({path:`${t}.components`,message:"components 应为数组"})}function be(e){const t=[],n=[],r=K(e)?e.pages:void 0;if(!Array.isArray(r))t.push({path:"$.pages",message:e==null?"渲染计划为空":"渲染计划缺少 pages 数组"});else{r.forEach((s,i)=>Be(s,`$.pages.${i}`,t,n)),r.length>2e3&&n.push({path:"$.pages",message:`页数异常大(${r.length} 页),渲染与打印耗时可能显著增加`});const o=r.reduce((s,i)=>s+(K(i)&&Array.isArray(i.components)?i.components.length:0),0);o>5e4&&n.push({path:"$.pages",message:`组件总数异常大(${o} 个),可能触发浏览器性能限制`})}return{ok:t.length===0,errors:t,warnings:n}}function it(e){const t=be(e);if(!t.ok){const n=t.errors.slice(0,3).map(r=>`${r.path}: ${r.message}`).join("; ");throw new Error(`渲染计划校验失败(${t.errors.length} 处): ${n}`)}return e.pages}function Re(e){return{widthMm:e.widthMm,heightMm:e.heightMm,marginTopMm:e.marginTopMm??0,marginBottomMm:e.marginBottomMm??0,marginLeftMm:e.marginLeftMm??0,marginRightMm:e.marginRightMm??0,components:[]}}function st(e,t){return t.heightMm-(e.marginBottomMm??t.marginBottomMm)}function Le(e){if(e==null)return"";if(typeof e=="string")return e;if(typeof e=="number")return String(e);if(typeof e=="boolean")return e?"是":"否";if(e instanceof Date)return e.toISOString().slice(0,10);try{return JSON.stringify(e)}catch{return String(e)}}function Ie(e,t){let n=e.textMetrics.get(t);if(!n){const r=g.resolveFontSize(t).fontSizePt;n={measureOptions:{fontSizePt:r,bold:t.bold,letterSpacingPt:t.letterSpacing===void 0?void 0:t.letterSpacing*72/96},lineMm:r*(t.lineHeight??g.LINE_HEIGHT)*25.4/72},e.textMetrics.set(t,n)}return n}function De(e,t){return t?.kind==="number"||t?.kind==="percent"?"right":t?.kind==="date"||e instanceof Date||typeof e=="boolean"?"center":typeof e=="number"&&Number.isFinite(e)?"right":"left"}function at(e){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e}function lt(e,t){const n=e.fontSizePt??g.DEFAULT_FONT_PT,r=e.paddingMm??1,o=e.columns.map(d=>d.align??d.style?.align??e.align??"left"),s=e.columns.map((d,p)=>({fontSize:n,verticalAlign:"middle",...d.style,align:o[p]==="auto"?"left":o[p]})),i=s.map((d,p)=>o[p]==="auto"?{left:d,center:{...d,align:"center"},right:{...d,align:"right"}}:void 0),a=e.columns.map((d,p)=>d.rules?.map(S=>{const T=i[p];if(T)return{left:{...T.left,...S.style},center:{...T.center,...S.style},right:{...T.right,...S.style}};const u={...s[p],...S.style};return{left:u,center:u,right:u}})),l=e.columns.map(d=>({fontSize:n,bold:e.headerBold??!0,align:"center",verticalAlign:"middle",backgroundColor:e.headerBackgroundColor,...d.style||{},...e.headerAlign===void 0?{}:{align:e.headerAlign},...e.headerStyle,...d.headerAlign===void 0?{}:{align:d.headerAlign},...d.headerStyle})),c=e.columns.map(d=>d.header);let f=e.rowHeightMm??0;for(let d=0;d<c.length;d++){const p=l[d],S=g.resolveFontSize(p).fontSizePt,T=x.wrapText(c[d],e.columns[d].widthMm-r*2,{fontSizePt:S,bold:p.bold},t),u=S*(p.lineHeight??g.LINE_HEIGHT)*25.4/72;f=Math.max(f,Math.max(T.length,1)*u+r*2)}const h=c.map((d,p)=>({text:d,style:l[p]})),m=e.border===!1?{borderTop:!1,borderRight:!1,borderBottom:!1,borderLeft:!1}:{borderBottom:!0,borderLeft:!0,borderRight:!0,borderTop:!0},w=e.columns.map(d=>d.widthMm);return{fontSizePt:n,paddingMm:r,cellStyles:s,autoStyles:i,ruleStyles:a,textMetrics:new WeakMap,numberFormats:e.columns.map(d=>ye(d.format)),borderStyle:m,headerHeightMm:f,headerGrid:{cells:[h],colWidthsMm:w,rowHeightsMm:[f]},colWidthsMm:w,columns:e.columns}}function Ce(e,t,n){const r=e.columns;let o=e.rowHeightFloorMm;const s=new Array(r.length);for(let i=0;i<r.length;i++){const a=r[i],l=t[a.field],c=e.autoStyles[i]?De(l,a.format):"left";let f=e.autoStyles[i]?.[c]??e.cellStyles[i];if(a.rules)for(let S=0;S<a.rules.length;S++){const T=a.rules[S];if(Fe(t,T.when)){f=e.ruleStyles[i][S][c];break}}const h=a.format?Me(l,a.format):Le(l),m=Ie(e,f),w=x.wrapText(h,a.widthMm-e.paddingMm*2,m.measureOptions,n);o=Math.max(o,w.length*m.lineMm+e.paddingMm*2);const d=at(l),p={text:h,style:f};d!==void 0&&(p.value=d),typeof d=="number"&&e.numberFormats[i]!==void 0&&(p.numberFormat=e.numberFormats[i]),s[i]=p}return{grid:{cells:[s],colWidthsMm:e.colWidthsMm,rowHeightsMm:[o]},heightMm:o}}function ze(e,t,n={}){const r=typeof n=="number"?{mmPerRow:n}:n,o=r.mmPerRow??0,s=r.measurer??x.heuristicMeasurer,i=[],a=[];let l=0;const c=h=>`${h}_${(++l).toString(36)}`,f=[];for(const h of e.pages){const m=Re(h),w=()=>st(h,m),d=m.marginTopMm,p=[],S=()=>{if(a.push({pageWidthMm:m.widthMm,pageHeightMm:m.heightMm,marginTopMm:m.marginTopMm,marginBottomMm:m.marginBottomMm,marginLeftMm:m.marginLeftMm,marginRightMm:m.marginRightMm,components:m.components}),p.length>0){const T=a.length;for(const u of p){const k={...u,text:String(u.text??"").replace(/\{page\}/g,String(T))};a[a.length-1].components.push(k),k.text.includes("{totalPages}")&&f.push(k)}}};for(const T of h.components){if(T.kind!=="list"){if(T.kind==="text"&&typeof T.text=="string"){const $=T.text;if($.includes("{page}")||$.includes("{totalPages}")){p.push(T);continue}}m.components.push(T);continue}const u=T,k=t[u.dataset];Array.isArray(k)||i.push(`数据集 ${u.dataset} 未提供数据,列表 ${u.id??""} 输出为空`);const A=Array.isArray(k)?k:[],v=u.columns.reduce(($,M)=>$+M.widthMm,0),V=v>u.widthMm?u.widthMm/v:1,y=V===1?u:{...u,columns:u.columns.map($=>({...$,widthMm:$.widthMm*V}))},E={...lt(y,s),rowHeightFloorMm:y.rowHeightMm??0},Z={kind:"rect",leftMm:u.leftMm,topMm:0,widthMm:u.widthMm,heightMm:E.headerHeightMm,grid:E.headerGrid,nid:c("listh"),style:E.borderStyle};let b=u.topMm;const H=($,M)=>{$.components.push({...Z,topMm:M})};H(m,b),b+=E.headerHeightMm+o;const D=$=>{if(b+$>w()){S();const M=Re(h);m.components=M.components,m.heightMm=M.heightMm,y.headerEveryPage!==!1?(H(m,u.topMm),b=u.topMm+E.headerHeightMm):b=d}},P=($,M,N)=>{const R=y.headerEveryPage!==!1?u.topMm+E.headerHeightMm:d,F=w()-R;M>F&&i.push(`列表 ${u.id??u.dataset} 行高 ${M.toFixed(2)}mm 超出单页可用高度 ${F.toFixed(2)}mm,预览与打印可能截断内容`),D(M),m.components.push({kind:"rect",leftMm:u.leftMm,topMm:b,widthMm:u.widthMm,heightMm:M,grid:$,nid:c(N),style:E.borderStyle}),b+=M},O=()=>Ce(E,{},s).heightMm,_=($,M,N,R)=>{const F=[],ie=Math.max(1,Math.min(R,y.columns.length)),Ne={fontSize:E.fontSizePt,...N};F.push({text:$,colSpan:ie,style:{bold:!0,...Ne}});for(let G=ie;G<y.columns.length;G++){const te=y.columns[G],ne=M.get(te.field),le=E.autoStyles[G]?.[De(ne?.value,te.format)]??E.cellStyles[G];F.push({...ne,text:ne?.text??"",style:{...le,...Ne}})}let se=E.rowHeightFloorMm,ae=0;for(const G of F){let te=0;const ne=ae+(G.colSpan??1);for(;ae<ne;ae++)te+=E.colWidthsMm[ae]??0;const le=Ie(E,G.style),Ze=x.wrapText(G.text??"",te-E.paddingMm*2,le.measureOptions,s);se=Math.max(se,Ze.length*le.lineMm+E.paddingMm*2)}return{grid:{cells:[F],colWidthsMm:E.colWidthsMm,rowHeightsMm:[se]},heightMm:se}},Y=($,M)=>{let N=0;for(const R of $){const F=typeof R[M]=="number"?R[M]:Number(R[M]);Number.isFinite(F)&&(N+=F)}return N},oe=($,M)=>{const R=y.columns.find(ie=>ie.field===M)?.format??{kind:"number",thousands:!0},F=Y($,M);return{text:Me(F,R),value:F,numberFormat:ye(R)}},j=y.groupBy,ke=$=>{const M=y.columns.findIndex(N=>$.includes(N.field));return M>0?M:1},ee=[];if(j){const $=new Map;for(const M of A){const N=Le(M[j.field]),R=$.get(N);R?R.push(M):$.set(N,[M])}for(const[M,N]of $){ee.push({kind:"groupHeader",label:(j.headerTemplate??"{value}").replace(/\{value\}/g,M)});for(const R of N)ee.push({kind:"row",row:R});j.subtotal&&j.subtotal.length>0&&ee.push({kind:"subtotal",label:j.subtotalLabel??"小计",rows:N})}}else for(const $ of A)ee.push({kind:"row",row:$});const xe=O();for(const $ of ee)if($.kind==="row"){const M=Ce(E,$.row,s);P(M.grid,M.heightMm,"listr")}else if($.kind==="groupHeader"){const M=_($.label,new Map,j?.headerStyle??{},y.columns.length);j?.keepWithNext!==!1&&b+M.heightMm+xe>w()&&D(M.heightMm+xe),P(M.grid,M.heightMm,"listg")}else if($.kind==="subtotal"){const M=new Map;for(const R of j.subtotal??[])M.set(R,oe($.rows,R));const N=_($.label,M,j?.subtotalStyle??{},ke(j.subtotal??[]));P(N.grid,N.heightMm,"listst")}if(y.grandTotal){const $=typeof y.grandTotal=="object"?y.grandTotal:void 0,M=$?.fields??j?.subtotal??[];if(M.length>0){const N=new Map;for(const F of M)N.set(F,oe(A,F));const R=_($?.label??"合计",N,$?.style??{},ke(M));P(R.grid,R.heightMm,"listgt")}else i.push(`列表 ${u.id??""} 配置了 grandTotal 但未提供合计字段(groupBy.subtotal 或 grandTotal.fields)`)}}S()}for(const h of f){const m=h.text;typeof m=="string"&&m.includes("{totalPages}")&&(h.text=m.replace(/\{totalPages\}/g,String(a.length)))}return{plan:{schemaVersion:x.RENDER_PLAN_SCHEMA_VERSION,pages:a},warnings:i}}const ct={root:"mr-root",page:"mr-page",comp:"mr-comp",text:"mr-text",lines:"mr-lines",line:"mr-line",rich:"mr-rich",paragraph:"mr-paragraph",segment:"mr-segment",image:"mr-image",shape:"mr-shape",grid:"mr-grid",row:"mr-row",cell:"mr-cell",unknown:"mr-unknown"};function L(e,t){return t?.classNames?.[e]??ct[e]}class W{constructor(){this.props=[]}add(t,n){return n==null||n===!1||n===""?this:(this.props.push([t,String(n)]),this)}mm(t,n,r,o=2){return this.add(t,`${g.round(g.mmToPx(n,r),o)}px`)}toString(){let t="";for(const[n,r]of this.props)t+=`${n}:${r};`;return t}applyTo(t){const n=this.toString();n&&(t.style.cssText=n)}}function je(e,t,n){const r=t.style||{};e.add("color",r.color).add("background-color",r.backgroundColor).add("font-family",r.fontFamily).add("font-weight",r.bold?"700":void 0).add("font-style",r.italic?"italic":void 0).add("text-decoration",r.underline?"underline":void 0).add("letter-spacing",r.letterSpacing!=null?`${r.letterSpacing}pt`:void 0).add("opacity",r.opacity!=null?String(r.opacity):void 0).add("transform",r.rotateDeg?`rotate(${r.rotateDeg}deg)`:void 0);const o=g.resolveFontSize(r,n);e.add("font-size",`${g.round(o.fontSizePx,2)}px`)}function dt(e,t,n,r,o){const s=o.createElement("table");if(s.className=L("grid",r),new W().add("width","100%").add("height","100%").add("border-collapse","collapse").add("table-layout",e.colWidthsMm?"fixed":"auto").applyTo(s),e.colWidthsMm){const c=o.createElement("colgroup");for(const f of e.colWidthsMm){const h=o.createElement("col");new W().mm("width",f,n).applyTo(h),c.appendChild(h)}s.appendChild(c)}const i=g.resolveBoxBorders(t.style),a=g.resolveStroke(t.style),l=i.inner?`${g.round(a.widthPt*n/72,2)}px solid ${a.color}`:"";return e.cells.forEach((c,f)=>{const h=o.createElement("tr");h.className=L("row",r),e.rowHeightsMm?.[f]!=null&&new W().mm("height",e.rowHeightsMm[f],n).applyTo(h),(c||[]).forEach(m=>{const w=o.createElement("td");w.className=L("cell",r),m?.colSpan&&(w.colSpan=m.colSpan),m?.rowSpan&&(w.rowSpan=m.rowSpan);const d=new W;if(l&&d.add("border",l),m?.style){const p=m.style;d.add("text-align",p.align).add("vertical-align",p.verticalAlign).add("background-color",p.backgroundColor).add("color",p.color).add("font-weight",p.bold?"700":void 0),d.add("font-size",`${g.round(g.resolveFontSize(p,n).fontSizePx,2)}px`)}if(d.applyTo(w),m?.text!=null&&(w.textContent=m.text),m?.children?.length)for(const p of m.children)w.appendChild(we(p,n,r,o));h.appendChild(w)}),s.appendChild(h)}),s}function mt(e,t,n,r){const o=r.createElement("div");o.className=L("text",n);const s=e.style||{},i=new W().add("text-align",s.align).add("display","flex").add("flex-direction","column").add("justify-content",s.verticalAlign==="middle"?"center":s.verticalAlign==="bottom"?"flex-end":"flex-start").add("overflow","hidden");if(je(i,e,t),i.applyTo(o),x.isRichText(e)){const a=r.createElement("div");a.className=L("rich",n);for(const l of e.richParagraphs){const c=r.createElement("div");c.className=L("paragraph",n),new W().add("text-align",l.align).add("line-height",l.lineHeight!=null?String(l.lineHeight):void 0).mm("margin-top",l.spaceBeforeMm??0,t).mm("margin-bottom",l.spaceAfterMm??0,t).mm("text-indent",l.indentMm??0,t).applyTo(c);for(const h of l.segments||[]){const m=r.createElement("span");if(m.className=L("segment",n),m.textContent=h.kind==="field"?h.field??"":h.text??"",h.style){const w=new W().add("color",h.style.color).add("font-weight",h.style.bold?"700":void 0);w.add("font-size",`${g.round(g.resolveFontSize(h.style,t).fontSizePx,2)}px`),w.applyTo(m)}c.appendChild(m)}a.appendChild(c)}return o.appendChild(a),o}if(Array.isArray(e.lines)&&e.lines.length>0){const a=r.createElement("div");a.className=L("lines",n),s.lineHeight!=null&&new W().add("line-height",String(s.lineHeight)).applyTo(a);for(const l of e.lines){const c=r.createElement("div");c.className=L("line",n),c.textContent=l,a.appendChild(c)}return o.appendChild(a),o}return o.textContent=e.text??"",o}function ft(e,t,n){const r=n.createElement("img");return r.className=L("image",t),r.src=e.imageData,new W().add("width","100%").add("height","100%").add("object-fit","contain").add("display","block").applyTo(r),r.alt=e.kind,r}function _e(e,t,n,r){const o=r.createElement("div");o.className=L("shape",n);const s=e.style||{},i=g.resolveStroke(s),a=g.resolveBoxBorders(s),l=`${g.round(i.widthPt*t/72,2)}px solid ${i.color}`,c=new W;return e.grid||e.kind==="rect"?(a.top&&c.add("border-top",l),a.right&&c.add("border-right",l),a.bottom&&c.add("border-bottom",l),a.left&&c.add("border-left",l)):e.kind==="ellipse"?(a.inner&&c.add("border",l).add("border-radius","50%"),s.backgroundColor&&c.add("background-color",s.backgroundColor)):e.kind==="line"&&c.add("height","0").add("border-top",l),c.add("box-sizing","border-box").add("width","100%").add("height","100%"),c.applyTo(o),o}function we(e,t,n,r){const o=r.createElement("div");o.className=`${L("comp",n)} mr-kind-${e.kind}`;const s=new W().add("position","absolute").mm("left",e.leftMm,t).mm("top",e.topMm,t).mm("width",e.widthMm,t).mm("height",e.heightMm,t).add("box-sizing","border-box");if(je(s,e,t),s.applyTo(o),x.isImageBackedComponent(e))return o.appendChild(ft(e,n,r)),o;if(e.kind==="text")return o.appendChild(mt(e,t,n,r)),o;if(e.grid){const a=_e(e,t,n,r);return a.appendChild(dt(e.grid,e,t,n,r)),o.appendChild(a),o}if(e.kind==="line"||e.kind==="rect"||e.kind==="ellipse"||e.kind==="chart")return o.appendChild(_e(e,t,n,r)),o;const i=r.createElement("div");return i.className=L("unknown",n),i.textContent=e.fallbackText??"",o.appendChild(i),o}function We(e,t,n,r){const o=r.createElement("div");o.className=L("page",n),new W().add("position","relative").mm("width",e.pageWidthMm,t).mm("height",e.pageHeightMm,t).add("background-color","#fff").add("overflow","hidden").add("box-sizing","border-box").applyTo(o);for(const s of e.components)o.appendChild(we(s,t,n,r));return o}function ht(e,t,n={}){const r=n.dpi??96,o=t.createElement("div");return o.className=L("root",n),o.dataset.schemaVersion=e.schemaVersion,e.pages.forEach(s=>{o.appendChild(We(s,r,n,t))}),o}function Ve(e){return Qe.createPageWindowIndex(e.pageHeightsPx,e.gapPx).window(e.viewportHeightPx,e.scrollTopPx,e.overscan)}const Se=96/25.4;function $e(e,t=96){const n=t/96*Se;return{widthPx:Math.max(1,Math.round(e.pageWidthMm*n)),heightPx:Math.max(1,Math.round(e.pageHeightMm*n))}}function gt(e,t,n){const r=document.createElement("canvas"),{widthPx:o,heightPx:s}=$e(e,n);r.width=Math.round(o*t),r.height=Math.round(s*t),r.style.width=`${o}px`,r.style.height=`${s}px`;const i=r.getContext("2d");if(!i)throw new Error("当前环境不支持 Canvas 2D(测试需真浏览器,见 e2e/canvas.spec.ts)");return i.scale(t,t),i.fillStyle="#ffffff",i.fillRect(0,0,o,s),{canvas:r,ctx:i}}function ut(e,t=96){return g.resolveFontSize(e,t).fontSizePx}function Ge(e,t,n,r,o,s,i,a="top"){e.font=`${t.bold?"bold ":""}${t.fontSizePx}px ${i}`,e.fillStyle=t.color,e.textBaseline="alphabetic";const l=t.fontSizePx*t.lineHeight,c=t.text===""?[""]:t.text.split(`
|
|
2
|
+
`),f=c.length*l;let h=r;a==="middle"?h=r+(s-f)/2:a==="bottom"&&(h=r+s-f),c.forEach((m,w)=>{e.textAlign=t.align==="center"?"center":t.align==="right"?"right":"left";const d=t.align==="center"?n+o/2:t.align==="right"?n+o:n;e.fillText(m,d,h+w*l+t.fontSizePx*.8,o)}),e.textAlign="left"}function pt(e,t,n,r,o,s,i,a,l,c,f){const h=g.resolveGridLayout(t,s/a,i/a),m=g.resolveBoxBorders(n.style),w=g.resolveStroke(n.style);for(const d of h.cells){const p=d.cell.style?.backgroundColor;p&&(e.fillStyle=p,e.fillRect(r+d.xMm*a,o+d.yMm*a,d.widthMm*a,d.heightMm*a))}if(m.inner){e.strokeStyle=w.color,e.lineWidth=g.ptToPx(w.widthPt,l);for(const d of h.edges)e.beginPath(),d.kind==="v"?(e.moveTo(r+d.pos*a,o+d.from*a),e.lineTo(r+d.pos*a,o+d.to*a)):(e.moveTo(r+d.from*a,o+d.pos*a),e.lineTo(r+d.to*a,o+d.pos*a)),e.stroke();e.beginPath(),m.top&&(e.moveTo(r,o),e.lineTo(r+s,o)),m.right&&(e.moveTo(r+s,o),e.lineTo(r+s,o+i)),m.bottom&&(e.moveTo(r+s,o+i),e.lineTo(r,o+i)),m.left&&(e.moveTo(r,o+i),e.lineTo(r,o)),e.stroke()}for(const d of h.cells){const p=typeof d.cell.text=="string"?d.cell.text:"";if(!p)continue;const S=d.cell.style,T=S?.fontSize??g.DEFAULT_FONT_PT,u=x.wrapText(p,d.widthMm-1,{fontSizePt:T},f).join(`
|
|
3
|
+
`);Ge(e,{text:u,fontSizePx:g.resolveFontSize(S,l).fontSizePx,bold:S?.bold??!1,color:S?.color??g.resolveTextColor(n.style,g.DEFAULT_TEXT_COLOR),align:S?.align??"left",lineHeight:g.LINE_HEIGHT},r+(d.xMm+.5)*a,o+d.yMm*a,Math.max(0,(d.widthMm-1)*a),d.heightMm*a,c,S?.verticalAlign??"middle")}}function Ue(e,t,n,r,o,s){const i=t.leftMm*n,a=t.topMm*n,l=t.widthMm*n,c=t.heightMm*n,f=t.style??{};if(t.grid){pt(e,t.grid,t,i,a,l,c,n,r,o,s);return}switch(t.kind){case"text":{const h=f.fontSize??g.DEFAULT_FONT_PT,m=x.isRichText(t)?t.richParagraphs.map(w=>(w.segments??[]).map(d=>d.text??d.field??"").join("")).join(`
|
|
4
4
|
`):Array.isArray(t.lines)&&t.lines.length>0?t.lines.join(`
|
|
5
|
-
`):
|
|
6
|
-
`);Te(e,{text:c,fontSizePx:d.resolveFontSize(f,r).fontSizePx,bold:f.bold??!1,color:d.resolveTextColor(f),align:f.align??"left",lineHeight:d.resolveLineHeight(f)},a,s,l,m,o,f.verticalAlign);break}case"rect":{const h=d.resolveStroke(f),c=d.resolveBoxBorders(f);f.backgroundColor&&(e.fillStyle=f.backgroundColor,e.fillRect(a,s,l,m)),c.inner&&(e.strokeStyle=h.color,e.lineWidth=d.ptToPx(h.widthPt,r),e.beginPath(),c.top&&(e.moveTo(a,s),e.lineTo(a+l,s)),c.right&&(e.moveTo(a+l,s),e.lineTo(a+l,s+m)),c.bottom&&(e.moveTo(a+l,s+m),e.lineTo(a,s+m)),c.left&&(e.moveTo(a,s+m),e.lineTo(a,s)),e.stroke());break}case"line":{const h=d.resolveStroke({...f,borderColor:f.lineColor??f.borderColor});e.strokeStyle=h.color,e.lineWidth=d.ptToPx(h.widthPt,r),e.beginPath(),e.moveTo(a,s+m/2),e.lineTo(a+l,s+m/2),e.stroke();break}case"ellipse":{const h=d.resolveStroke(f);e.strokeStyle=h.color,e.lineWidth=d.ptToPx(h.widthPt,r),f.backgroundColor&&(e.fillStyle=f.backgroundColor,e.beginPath(),e.ellipse(a+l/2,s+m/2,l/2,m/2,0,0,Math.PI*2),e.fill()),e.beginPath(),e.ellipse(a+l/2,s+m/2,l/2,m/2,0,0,Math.PI*2),e.stroke();break}}}async function Ve(e,t={}){if(typeof document>"u")throw new Error("renderPlanToImages 需要浏览器环境(SSR/Node 请在客户端钩子中调用)");const{format:n="png",quality:r=.92,...o}=t,{canvases:i}=Pe(e,o),a=n==="jpeg"?"image/jpeg":"image/png",s=[];for(const l of i)s.push(await new Promise(m=>l.toBlob(f=>m(f),a,r))??new Blob([],{type:a}));return{blobs:s}}function Pe(e,t={}){if(typeof document>"u")throw new Error("renderPlanToCanvas 需要浏览器环境(SSR 请在客户端钩子中调用)");const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),r=t.dpi??96,o=r/96*te,i=t.fontFamily??'"Microsoft YaHei", sans-serif',a=t.measurer??d.heuristicMeasurer,s=Math.max(0,t.start??0),l=Math.min(e.pages.length-1,t.end??e.pages.length-1),m=[];for(let f=s;f<=l;f++){const h=e.pages[f],{canvas:c,ctx:u}=je(h,n,r);for(const g of h.components)ve(u,g,o,r,i,a);m.push(c)}return{canvases:m}}function Ye(e,t={}){const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),r=t.dpi??96,o=r/96*te,i=t.fontFamily??'"Microsoft YaHei", sans-serif',a=t.measurer??d.heuristicMeasurer,s=t.overscan??1,l=t.gapPx??18,m=t.pagesPerFrame??1,f=e.pages.map(b=>b.pageHeightMm*o),h=Math.max(1,...e.pages.map(b=>b.pageWidthMm*o)),c={start:0,end:-1};let u=null,g=null,S=null,P=null,x=[],w=0,v=[];function p(){const b=u;b.innerHTML="",g=document.createElement("div"),g.style.cssText=`width:${h}px;margin:0 auto;`,S=document.createElement("div"),P=document.createElement("div"),g.appendChild(S),x=[];const H=Math.min(e.pages.length,3+s*2);for(let _=0;_<H;_++){const T=document.createElement("div");T.style.cssText=`margin:0 auto ${l}px;box-shadow:0 2px 8px rgba(0,0,0,.35);background:#fff;`,g.appendChild(T),x.push(T)}g.appendChild(P),b.appendChild(g)}function E(b,H){const _=e.pages[H],{widthPx:T,heightPx:N}=ne(_,r);let R=b.firstElementChild;(!R||R.tagName!=="CANVAS")&&(R=document.createElement("canvas"),b.innerHTML="",b.appendChild(R)),R.width=Math.round(T*n),R.height=Math.round(N*n),R.style.width=`${T}px`,R.style.height=`${N}px`;const I=R.getContext("2d");if(I){I.setTransform(1,0,0,1,0,0),I.scale(n,n),I.fillStyle="#ffffff",I.fillRect(0,0,T,N);for(const Y of _.components)ve(I,Y,o,r,i,a);R.dataset.canvasPage=String(H),b.style.height=`${N}px`,b.style.width=`${T}px`}}function G(b){c.start=b.start,c.end=b.end,S.style.height=`${b.start*l+f.slice(0,b.start).reduce((T,N)=>T+N,0)}px`;const H=e.pages.length-1-b.end;P.style.height=`${H*l+f.slice(b.end+1).reduce((T,N)=>T+N,0)}px`;const _=b.end-b.start+1;x.forEach((T,N)=>{if(N<_){T.style.display="";const R=b.start+N;T.style.height=`${f[R]??0}px`}else T.style.display="none"}),v=[];for(let T=b.start;T<=b.end;T++){const N=x[T-b.start];if(!N)continue;N.firstElementChild?.dataset?.canvasPage!==String(T)&&v.push(T)}C()}function C(){w||v.length===0||(w=requestAnimationFrame(()=>{w=0;let b=Math.max(1,m);for(;v.length>0&&b-- >0;){const H=v.shift(),_=x[H-c.start];_&&E(_,H)}v.length>0&&C()}))}function k(){w||(w=requestAnimationFrame(()=>{w=0;const b=u,H=Se({pageHeightsPx:f,viewportHeightPx:b.clientHeight,scrollTopPx:b.scrollTop,overscan:s,gapPx:l});H.start!==c.start||H.end!==c.end?G(H):C()}))}let U=null;return{attach(b){if(typeof document>"u")throw new Error("createCanvasPager 需要浏览器环境(SSR 请在客户端钩子中调用 attach)");u=b,p(),b.addEventListener("scroll",k,{passive:!0}),typeof ResizeObserver<"u"&&(U=new ResizeObserver(()=>k()),U.observe(b)),k()},destroy(){w&&cancelAnimationFrame(w),w=0,U?.disconnect(),U=null,u?.removeEventListener("scroll",k),v=[],g?.remove(),u=null},window(){return{...c}}}}function re(e,t,n){let r,o;if(typeof e=="string"){const i=d.PAPER_SIZES[e];if(!i)throw new Error(`未知纸张预设 "${e}"(可用:${Object.keys(d.PAPER_SIZES).join("/")})`);r=i.widthMm,o=i.heightMm}else typeof e=="number"?(r=e,o=t??297):(r=e.widthMm,o=e.heightMm);return n?{widthMm:o,heightMm:r}:{widthMm:r,heightMm:o}}class Ee{constructor(){this.pages=[],this.pending=null,this.templateParams=void 0}params(t){return this.templateParams=t,this}page(t="a4",n={},r){this.collect();const i=r!=null&&!("margins"in r)&&!("landscape"in r)&&("marginTopMm"in r||"marginBottomMm"in r||"marginLeftMm"in r||"marginRightMm"in r)?{margins:r}:typeof n=="number"?r??{}:n,{widthMm:a,heightMm:s}=re(t,typeof n=="number"?n:void 0,i.landscape),l=i.margins??{};return this.pending=new xe(this,{widthMm:a,heightMm:s,marginTopMm:l.marginTopMm??10,marginBottomMm:l.marginBottomMm??10,marginLeftMm:l.marginLeftMm??10,marginRightMm:l.marginRightMm??10}),this.pending}collect(){this.pending&&(this.pages.push(this.pending.buildPage()),this.pending=null)}build(){if(this.collect(),this.pages.length===0)throw new Error("模板至少需要一页:先调用 .page() 添加内容");return this.templateParams?{params:this.templateParams,pages:this.pages}:{pages:this.pages}}}class xe{constructor(t,n){this.parent=t,this.page=n,this.components=[]}text(t,n={},r={}){return this.components.push({kind:"text",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??60,heightMm:n.heightMm??8,text:t,style:r}),this}list(t,n,r,o={}){return this.components.push({kind:"list",leftMm:n.leftMm??10,topMm:n.topMm??30,widthMm:n.widthMm??180,dataset:t,columns:r,...o}),this}rect(t,n={}){return this.components.push({kind:"rect",...t,style:n}),this}line(t,n,r,o={}){return this.components.push({kind:"line",leftMm:t,topMm:n,widthMm:r,heightMm:.5,style:o}),this}barcode(t,n){return this.components.push({kind:"barcode",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??40,heightMm:n.heightMm??12,fallbackText:t}),this}qrcode(t,n,r,o){return this.components.push({kind:"qrcode",leftMm:r,topMm:o,widthMm:n,heightMm:n,fallbackText:t}),this}buildPage(){return{...this.page,components:this.components}}done(){return this.parent}build(){return this.done().build()}}function qe(){return new Ee}function O(e,t,n=!1){if(!Number.isFinite(e)||(n?e<0:e<=0))throw new Error(`${t} 必须是有限${n?"非负":"正"}数`)}function Je(e){if(!e||typeof e!="object")throw new Error("标准明细模板需要 options 对象");if(!Array.isArray(e.columns)||e.columns.length===0)throw new Error("columns 至少需要一列");const t=e.paper===void 0?"a4":e.paper;if(typeof t!="string"&&(typeof t!="object"||t===null)||e.landscape!==void 0&&typeof e.landscape!="boolean")throw new Error("paper 必须是纸张预设名或 { widthMm, heightMm } 对象,landscape 必须是布尔值");if(typeof t=="string"&&!Object.prototype.hasOwnProperty.call(d.PAPER_SIZES,t))throw new Error(`未知纸张预设 "${t}"(可用:${Object.keys(d.PAPER_SIZES).join("/")})`);const{widthMm:n,heightMm:r}=re(t,void 0,e.landscape);if(O(n,"纸张 widthMm"),O(r,"纸张 heightMm"),e.margins!==void 0&&(!e.margins||typeof e.margins!="object"||Array.isArray(e.margins)))throw new Error("margins 必须是页边距对象");const o=e.margins??{},i={marginTopMm:o.marginTopMm===void 0?10:o.marginTopMm,marginBottomMm:o.marginBottomMm===void 0?10:o.marginBottomMm,marginLeftMm:o.marginLeftMm===void 0?10:o.marginLeftMm,marginRightMm:o.marginRightMm===void 0?10:o.marginRightMm};for(const[p,E]of Object.entries(i))O(E,p,!0);const a=n-i.marginLeftMm-i.marginRightMm,s=r-i.marginTopMm-i.marginBottomMm;if(a<=0||s<=0)throw new Error("页边距占满纸张,必须保留正的可用宽度和高度");const l=e.dataset===void 0?"detail":e.dataset;if(typeof l!="string"||!l.trim())throw new Error("dataset 必须是非空字符串");if(e.title!==void 0&&typeof e.title!="string")throw new Error("title 必须是字符串");const m=e.titleHeightMm===void 0?10:e.titleHeightMm,f=e.titleGapMm===void 0?4:e.titleGapMm;O(m,"titleHeightMm"),O(f,"titleGapMm",!0);const h=e.title!==void 0&&e.title.length>0,c=h?m+f:0;if(c>=s)throw new Error("标题高度与间距占满页面,必须为表格保留可用高度");if(e.listOptions!==void 0&&(!e.listOptions||typeof e.listOptions!="object"||Array.isArray(e.listOptions)))throw new Error("listOptions 必须是列表配置对象");const u=e.listOptions??{};for(const p of["fontSizePt","rowHeightMm","paddingMm"]){const E=u[p];E!==void 0&&O(E,`listOptions.${p}`,p==="paddingMm")}let g=0,S=0;for(const[p,E]of e.columns.entries()){if(!E||typeof E.header!="string"||typeof E.field!="string"||!E.field.trim())throw new Error(`columns[${p}] 需要字符串 header 与非空 field`);E.flex!==void 0&&O(E.flex,`columns[${p}].flex`),E.widthMm!==void 0?(O(E.widthMm,`columns[${p}].widthMm`),g+=E.widthMm):S=Math.max(S,E.flex??1)}if(g>a)throw new Error(`固定列宽 ${g}mm 超出页面可用宽度 ${a}mm`);const P=a-g;if(S>0&&P<=0)throw new Error("固定列占满页面可用宽度,自动列需要正的剩余宽度");const x=S>0?e.columns.reduce((p,E)=>p+(E.widthMm===void 0?(E.flex??1)/S:0),0):0,w=e.columns.map(({widthMm:p,flex:E,...G},C)=>{const k=p??P*((E??1)/S)/x;return O(k,`columns[${C}] 分配后的 widthMm`),{...G,widthMm:k}}),v={widthMm:n,heightMm:r,...i,components:[]};return h&&v.components.push({kind:"text",text:e.title,leftMm:i.marginLeftMm,topMm:i.marginTopMm,widthMm:a,heightMm:m,style:{fontSize:16,bold:!0,align:"center",verticalAlign:"middle",...e.titleStyle}}),v.components.push({...u,kind:"list",dataset:l,columns:w,leftMm:i.marginLeftMm,topMm:i.marginTopMm+c,widthMm:S>0?a:g}),e.params===void 0?{pages:[v]}:{params:e.params,pages:[v]}}function Ze(e){if(!("mapData"in e))return e;const{load:t,mapData:n,...r}=e;return{...r,load:async o=>{const i=await t(o);W(o.signal);try{return n(i,o)}catch(a){throw new D("validate",`报表 ${o.reportId} 数据映射失败`,a)}}}}class D extends Error{constructor(t,n,r){super(n),this.name="ReportSourceError",this.code=t,this.cause=r}}function oe(e){const t=new Error("报表加载已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e.reason}),t}function W(e){if(e?.aborted)throw oe(e)}function Ke(e,t){return t?new Promise((n,r)=>{const o=()=>t.removeEventListener("abort",i),i=()=>{o(),r(oe(t))};t.addEventListener("abort",i,{once:!0}),t.aborted&&i(),Promise.resolve(e).then(a=>{o(),n(a)},a=>{o(),r(a)})}):Promise.resolve(e)}function Xe(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new D("validate",`报表 ${t} 的数据集应为对象`);for(const[n,r]of Object.entries(e))if(!Array.isArray(r)||r.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new D("validate",`报表 ${t} 的数据集 ${n} 应为对象数组`)}function Qe(e,t={}){function n(o){const i=Object.prototype.hasOwnProperty.call(e,o)?e[o]:void 0;if(!i)throw new D("config",`未注册报表 ${o}`);return i}return Object.assign(async({reportIds:o,params:i,signal:a,onWarning:s})=>{if(W(a),o.length===0)throw new D("config","缺少报表 ID");const l=o.map(n),m=[],f=[];for(const[g,S]of l.entries()){W(a);const P=o[g],x={reportId:P,params:{...i},signal:a};let w;try{w=await Ke(S.load?S.load(x):S.datasets??{},a)}catch(p){throw a?.aborted?oe(a):p instanceof D?p:new D("fetch",`报表 ${P} 取数失败:${p instanceof Error?p.message:String(p)}`,p)}W(a),Xe(w,P);let v;try{v=we(S.template,w,S.pagination)}catch(p){throw new D("validate",`报表 ${P} 排版失败:${p instanceof Error?p.message:String(p)}`,p)}for(const p of v.plan.pages)m.push(p);f.push(...v.warnings.map(p=>`${P}: ${p}`))}W(a);const h={schemaVersion:d.RENDER_PLAN_SCHEMA_VERSION,pages:m},c=Q(h);if(!c.ok)throw new D("validate",`渲染计划校验失败:${c.errors.slice(0,3).map(g=>`${g.path}: ${g.message}`).join("; ")}`);f.push(...c.warnings.map(g=>`${g.path}: ${g.message}`));const u=s??t.onWarning??(g=>console.warn("[mach-report]",g));for(const g of f)W(a),u(g);return W(a),h},{getParamDefs:o=>Ce.getReportParamDefs(e,o)})}exports.CSS_DPI=d.CSS_DPI;exports.DEFAULT_BORDER_PT=d.DEFAULT_BORDER_PT;exports.DEFAULT_FONT_PT=d.DEFAULT_FONT_PT;exports.DEFAULT_STROKE_COLOR=d.DEFAULT_STROKE_COLOR;exports.DEFAULT_TEXT_COLOR=d.DEFAULT_TEXT_COLOR;exports.LINE_HEIGHT=d.LINE_HEIGHT;exports.MM_PER_INCH=d.MM_PER_INCH;exports.PAPER_SIZES=d.PAPER_SIZES;exports.RENDER_PLAN_SCHEMA_VERSION=d.RENDER_PLAN_SCHEMA_VERSION;exports.SCHEMA_VERSION_MACH=d.SCHEMA_VERSION_MACH;exports.charWidthEm=d.charWidthEm;exports.createCanvasMeasurer=d.createCanvasMeasurer;exports.createHeuristicMeasurer=d.createHeuristicMeasurer;exports.heuristicMeasurer=d.heuristicMeasurer;exports.isImageBackedComponent=d.isImageBackedComponent;exports.isRichText=d.isRichText;exports.measureTextMm=d.measureTextMm;exports.mmToPx=d.mmToPx;exports.mmToPxFactor=d.mmToPxFactor;exports.ptToPx=d.ptToPx;exports.pxToMm=d.pxToMm;exports.resolveBoxBorders=d.resolveBoxBorders;exports.resolveFontSize=d.resolveFontSize;exports.resolveLineHeight=d.resolveLineHeight;exports.resolveStroke=d.resolveStroke;exports.resolveTextColor=d.resolveTextColor;exports.round=d.round;exports.wrapText=d.wrapText;exports.resolveGridLayout=fe.resolveGridLayout;exports.PageBuilder=xe;exports.ReportSourceError=D;exports.TemplateBuilder=Ee;exports.assertRenderPlan=Le;exports.classOf=L;exports.computePageWindow=Se;exports.createCanvasPager=Ye;exports.createReportSource=Qe;exports.createTableTemplate=Je;exports.createTemplate=qe;exports.defineReport=Ze;exports.evalStyleRule=ue;exports.formatValue=K;exports.measurePageSizePx=ne;exports.paginateTemplate=we;exports.parseDateLocal=ge;exports.planFontSizePx=Ge;exports.renderComponent=ee;exports.renderPage=ye;exports.renderPlan=We;exports.renderPlanToCanvas=Pe;exports.renderPlanToImages=Ve;exports.resolvePaper=re;exports.toNumber=q;exports.validateComponent=X;exports.validatePage=pe;exports.validateRenderPlan=Q;
|
|
5
|
+
`):x.wrapText(t.text??"",t.widthMm,{fontSizePt:h},s).join(`
|
|
6
|
+
`);Ge(e,{text:m,fontSizePx:g.resolveFontSize(f,r).fontSizePx,bold:f.bold??!1,color:g.resolveTextColor(f),align:f.align??"left",lineHeight:g.resolveLineHeight(f)},i,a,l,c,o,f.verticalAlign);break}case"rect":{const h=g.resolveStroke(f),m=g.resolveBoxBorders(f);f.backgroundColor&&(e.fillStyle=f.backgroundColor,e.fillRect(i,a,l,c)),m.inner&&(e.strokeStyle=h.color,e.lineWidth=g.ptToPx(h.widthPt,r),e.beginPath(),m.top&&(e.moveTo(i,a),e.lineTo(i+l,a)),m.right&&(e.moveTo(i+l,a),e.lineTo(i+l,a+c)),m.bottom&&(e.moveTo(i+l,a+c),e.lineTo(i,a+c)),m.left&&(e.moveTo(i,a+c),e.lineTo(i,a)),e.stroke());break}case"line":{const h=g.resolveStroke({...f,borderColor:f.lineColor??f.borderColor});e.strokeStyle=h.color,e.lineWidth=g.ptToPx(h.widthPt,r),e.beginPath(),e.moveTo(i,a+c/2),e.lineTo(i+l,a+c/2),e.stroke();break}case"ellipse":{const h=g.resolveStroke(f);e.strokeStyle=h.color,e.lineWidth=g.ptToPx(h.widthPt,r),f.backgroundColor&&(e.fillStyle=f.backgroundColor,e.beginPath(),e.ellipse(i+l/2,a+c/2,l/2,c/2,0,0,Math.PI*2),e.fill()),e.beginPath(),e.ellipse(i+l/2,a+c/2,l/2,c/2,0,0,Math.PI*2),e.stroke();break}}}async function yt(e,t={}){if(typeof document>"u")throw new Error("renderPlanToImages 需要浏览器环境(SSR/Node 请在客户端钩子中调用)");const{format:n="png",quality:r=.92,...o}=t,{canvases:s}=Je(e,o),i=n==="jpeg"?"image/jpeg":"image/png",a=[];for(const l of s)a.push(await new Promise(c=>l.toBlob(f=>c(f),i,r))??new Blob([],{type:i}));return{blobs:a}}function Je(e,t={}){if(typeof document>"u")throw new Error("renderPlanToCanvas 需要浏览器环境(SSR 请在客户端钩子中调用)");const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),r=t.dpi??96,o=r/96*Se,s=t.fontFamily??'"Microsoft YaHei", sans-serif',i=t.measurer??x.heuristicMeasurer,a=Math.max(0,t.start??0),l=Math.min(e.pages.length-1,t.end??e.pages.length-1),c=[];for(let f=a;f<=l;f++){const h=e.pages[f],{canvas:m,ctx:w}=gt(h,n,r);for(const d of h.components)Ue(w,d,o,r,s,i);c.push(m)}return{canvases:c}}function Mt(e,t={}){const n=t.dpr??(typeof devicePixelRatio=="number"?devicePixelRatio:1),r=t.dpi??96,o=r/96*Se,s=t.fontFamily??'"Microsoft YaHei", sans-serif',i=t.measurer??x.heuristicMeasurer,a=t.overscan??1,l=t.gapPx??18,c=t.pagesPerFrame??1,f=e.pages.map(b=>b.pageHeightMm*o),h=Math.max(1,...e.pages.map(b=>b.pageWidthMm*o)),m={start:0,end:-1};let w=null,d=null,p=null,S=null,T=[],u=0,k=[];function A(){const b=w;b.innerHTML="",d=document.createElement("div"),d.style.cssText=`width:${h}px;margin:0 auto;`,p=document.createElement("div"),S=document.createElement("div"),d.appendChild(p),T=[];const H=Math.min(e.pages.length,3+a*2);for(let D=0;D<H;D++){const P=document.createElement("div");P.style.cssText=`margin:0 auto ${l}px;box-shadow:0 2px 8px rgba(0,0,0,.35);background:#fff;`,d.appendChild(P),T.push(P)}d.appendChild(S),b.appendChild(d)}function v(b,H){const D=e.pages[H],{widthPx:P,heightPx:O}=$e(D,r);let _=b.firstElementChild;(!_||_.tagName!=="CANVAS")&&(_=document.createElement("canvas"),b.innerHTML="",b.appendChild(_)),_.width=Math.round(P*n),_.height=Math.round(O*n),_.style.width=`${P}px`,_.style.height=`${O}px`;const Y=_.getContext("2d");if(Y){Y.setTransform(1,0,0,1,0,0),Y.scale(n,n),Y.fillStyle="#ffffff",Y.fillRect(0,0,P,O);for(const oe of D.components)Ue(Y,oe,o,r,s,i);_.dataset.canvasPage=String(H),b.style.height=`${O}px`,b.style.width=`${P}px`}}function V(b){m.start=b.start,m.end=b.end,p.style.height=`${b.start*l+f.slice(0,b.start).reduce((P,O)=>P+O,0)}px`;const H=e.pages.length-1-b.end;S.style.height=`${H*l+f.slice(b.end+1).reduce((P,O)=>P+O,0)}px`;const D=b.end-b.start+1;T.forEach((P,O)=>{if(O<D){P.style.display="";const _=b.start+O;P.style.height=`${f[_]??0}px`}else P.style.display="none"}),k=[];for(let P=b.start;P<=b.end;P++){const O=T[P-b.start];if(!O)continue;O.firstElementChild?.dataset?.canvasPage!==String(P)&&k.push(P)}y()}function y(){u||k.length===0||(u=requestAnimationFrame(()=>{u=0;let b=Math.max(1,c);for(;k.length>0&&b-- >0;){const H=k.shift(),D=T[H-m.start];D&&v(D,H)}k.length>0&&y()}))}function E(){u||(u=requestAnimationFrame(()=>{u=0;const b=w,H=Ve({pageHeightsPx:f,viewportHeightPx:b.clientHeight,scrollTopPx:b.scrollTop,overscan:a,gapPx:l});H.start!==m.start||H.end!==m.end?V(H):y()}))}let Z=null;return{attach(b){if(typeof document>"u")throw new Error("createCanvasPager 需要浏览器环境(SSR 请在客户端钩子中调用 attach)");w=b,A(),b.addEventListener("scroll",E,{passive:!0}),typeof ResizeObserver<"u"&&(Z=new ResizeObserver(()=>E()),Z.observe(b)),E()},destroy(){u&&cancelAnimationFrame(u),u=0,Z?.disconnect(),Z=null,w?.removeEventListener("scroll",E),k=[],d?.remove(),w=null},window(){return{...m}}}}function Te(e,t,n){let r,o;if(typeof e=="string"){const s=g.PAPER_SIZES[e];if(!s)throw new Error(`未知纸张预设 "${e}"(可用:${Object.keys(g.PAPER_SIZES).join("/")})`);r=s.widthMm,o=s.heightMm}else typeof e=="number"?(r=e,o=t??297):(r=e.widthMm,o=e.heightMm);return n?{widthMm:o,heightMm:r}:{widthMm:r,heightMm:o}}class Ye{constructor(){this.pages=[],this.pending=null,this.templateParams=void 0}params(t){return this.templateParams=t,this}page(t="a4",n={},r){this.collect();const s=r!=null&&!("margins"in r)&&!("landscape"in r)&&("marginTopMm"in r||"marginBottomMm"in r||"marginLeftMm"in r||"marginRightMm"in r)?{margins:r}:typeof n=="number"?r??{}:n,{widthMm:i,heightMm:a}=Te(t,typeof n=="number"?n:void 0,s.landscape),l=s.margins??{};return this.pending=new qe(this,{widthMm:i,heightMm:a,marginTopMm:l.marginTopMm??10,marginBottomMm:l.marginBottomMm??10,marginLeftMm:l.marginLeftMm??10,marginRightMm:l.marginRightMm??10}),this.pending}collect(){this.pending&&(this.pages.push(this.pending.buildPage()),this.pending=null)}build(){if(this.collect(),this.pages.length===0)throw new Error("模板至少需要一页:先调用 .page() 添加内容");return this.templateParams?{params:this.templateParams,pages:this.pages}:{pages:this.pages}}}class qe{constructor(t,n){this.parent=t,this.page=n,this.components=[]}text(t,n={},r={}){return this.components.push({kind:"text",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??60,heightMm:n.heightMm??8,text:t,style:r}),this}list(t,n,r,o={}){return this.components.push({kind:"list",leftMm:n.leftMm??10,topMm:n.topMm??30,widthMm:n.widthMm??180,dataset:t,columns:r,...o}),this}rect(t,n={}){return this.components.push({kind:"rect",...t,style:n}),this}line(t,n,r,o={}){return this.components.push({kind:"line",leftMm:t,topMm:n,widthMm:r,heightMm:.5,style:o}),this}barcode(t,n){return this.components.push({kind:"barcode",leftMm:n.leftMm??0,topMm:n.topMm??0,widthMm:n.widthMm??40,heightMm:n.heightMm??12,fallbackText:t}),this}qrcode(t,n,r,o){return this.components.push({kind:"qrcode",leftMm:r,topMm:o,widthMm:n,heightMm:n,fallbackText:t}),this}buildPage(){return{...this.page,components:this.components}}done(){return this.parent}build(){return this.done().build()}}function bt(){return new Ye}function U(e,t,n=!1){if(!Number.isFinite(e)||(n?e<0:e<=0))throw new Error(`${t} 必须是有限${n?"非负":"正"}数`)}function ce(e,t,n){if(e!==void 0&&!["left","center","right","justify",...n?["auto"]:[]].includes(e))throw new Error(`${t} 必须是 left/center/right/justify${n?"/auto":""}`)}function wt(e){if(!e||typeof e!="object")throw new Error("标准明细模板需要 options 对象");if(!Array.isArray(e.columns)||e.columns.length===0)throw new Error("columns 至少需要一列");const t=e.paper===void 0?"a4":e.paper;if(typeof t!="string"&&(typeof t!="object"||t===null)||e.landscape!==void 0&&typeof e.landscape!="boolean")throw new Error("paper 必须是纸张预设名或 { widthMm, heightMm } 对象,landscape 必须是布尔值");if(typeof t=="string"&&!Object.prototype.hasOwnProperty.call(g.PAPER_SIZES,t))throw new Error(`未知纸张预设 "${t}"(可用:${Object.keys(g.PAPER_SIZES).join("/")})`);const{widthMm:n,heightMm:r}=Te(t,void 0,e.landscape);if(U(n,"纸张 widthMm"),U(r,"纸张 heightMm"),e.margins!==void 0&&(!e.margins||typeof e.margins!="object"||Array.isArray(e.margins)))throw new Error("margins 必须是页边距对象");const o=e.margins??{},s={marginTopMm:o.marginTopMm===void 0?10:o.marginTopMm,marginBottomMm:o.marginBottomMm===void 0?10:o.marginBottomMm,marginLeftMm:o.marginLeftMm===void 0?10:o.marginLeftMm,marginRightMm:o.marginRightMm===void 0?10:o.marginRightMm};for(const[A,v]of Object.entries(s))U(v,A,!0);const i=n-s.marginLeftMm-s.marginRightMm,a=r-s.marginTopMm-s.marginBottomMm;if(i<=0||a<=0)throw new Error("页边距占满纸张,必须保留正的可用宽度和高度");const l=e.dataset===void 0?"detail":e.dataset;if(typeof l!="string"||!l.trim())throw new Error("dataset 必须是非空字符串");if(e.title!==void 0&&typeof e.title!="string")throw new Error("title 必须是字符串");const c=e.titleHeightMm===void 0?10:e.titleHeightMm,f=e.titleGapMm===void 0?4:e.titleGapMm;U(c,"titleHeightMm"),U(f,"titleGapMm",!0);const h=e.title!==void 0&&e.title.length>0,m=h?c+f:0;if(m>=a)throw new Error("标题高度与间距占满页面,必须为表格保留可用高度");if(e.listOptions!==void 0&&(!e.listOptions||typeof e.listOptions!="object"||Array.isArray(e.listOptions)))throw new Error("listOptions 必须是列表配置对象");const w=e.listOptions??{};ce(w.align,"listOptions.align",!0),ce(w.headerAlign,"listOptions.headerAlign",!1);for(const A of["fontSizePt","rowHeightMm","paddingMm"]){const v=w[A];v!==void 0&&U(v,`listOptions.${A}`,A==="paddingMm")}let d=0,p=0;for(const[A,v]of e.columns.entries()){if(!v||typeof v.header!="string"||typeof v.field!="string"||!v.field.trim())throw new Error(`columns[${A}] 需要字符串 header 与非空 field`);ce(v.align,`columns[${A}].align`,!0),ce(v.headerAlign,`columns[${A}].headerAlign`,!1),v.flex!==void 0&&U(v.flex,`columns[${A}].flex`),v.widthMm!==void 0?(U(v.widthMm,`columns[${A}].widthMm`),d+=v.widthMm):p=Math.max(p,v.flex??1)}if(d>i)throw new Error(`固定列宽 ${d}mm 超出页面可用宽度 ${i}mm`);const S=i-d;if(p>0&&S<=0)throw new Error("固定列占满页面可用宽度,自动列需要正的剩余宽度");const T=p>0?e.columns.reduce((A,v)=>A+(v.widthMm===void 0?(v.flex??1)/p:0),0):0,u=e.columns.map(({widthMm:A,flex:v,...V},y)=>{const E=A??S*((v??1)/p)/T;return U(E,`columns[${y}] 分配后的 widthMm`),{...V,widthMm:E}}),k={widthMm:n,heightMm:r,...s,components:[]};return h&&k.components.push({kind:"text",text:e.title,leftMm:s.marginLeftMm,topMm:s.marginTopMm,widthMm:i,heightMm:c,style:{fontSize:16,bold:!0,align:"center",verticalAlign:"middle",...e.titleStyle}}),k.components.push({align:"auto",headerAlign:"center",...w,kind:"list",dataset:l,columns:u,leftMm:s.marginLeftMm,topMm:s.marginTopMm+m,widthMm:p>0?i:d}),e.params===void 0?{pages:[k]}:{params:e.params,pages:[k]}}const Ee="1.0";class X extends Error{constructor(t){super(`模板校验失败:${t.slice(0,3).map(n=>`${n.path}: ${n.message}`).join("; ")}`),this.errors=t,this.name="ReportTemplateError"}}const St=new Set(["__proto__","prototype","constructor"]),$t=new Set(["schemaVersion","id","name","revision","description","template"]),Tt=new Set(["left","center","right","justify"]),ue=2e5,Et=64,ve=1e7;function C(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function Pe(e,t){const n=new Set;let r=0,o=0,s=!1;const i=(a,l,c)=>{if(s)return;if(++r>ue){r===ue+1&&t.push({path:l,message:"模板超过 JSON 节点安全上限"});return}if(c>Et){t.push({path:l,message:"模板嵌套层级过深"});return}if(typeof a=="string"){o+=a.length,o>ve&&(s=!0,t.push({path:l,message:"模板文本超过 1000 万字符的安全上限"}));return}if(a===null||typeof a=="boolean"||typeof a=="number"&&Number.isFinite(a))return;if(!a||typeof a!="object"){t.push({path:l,message:"模板只允许 JSON 值,不允许函数、undefined 或非有限数字"});return}if(n.has(a)){t.push({path:l,message:"模板不能包含循环引用"});return}const f=Object.getPrototypeOf(a);if(Array.isArray(a)&&f!==Array.prototype||!Array.isArray(a)&&f!==Object.prototype&&f!==null){t.push({path:l,message:"模板对象必须使用普通 JSON 对象原型"});return}if(Array.isArray(a)&&(Object.keys(a).length!==a.length||Object.keys(a).some(h=>!/^(0|[1-9]\d*)$/.test(h)||Number(h)>=a.length))){t.push({path:l,message:"模板数组不能包含空位或额外属性"});return}if(Object.getOwnPropertySymbols(a).length>0){t.push({path:l,message:"模板不能包含 Symbol 键"});return}n.add(a);for(const[h,m]of Object.entries(Object.getOwnPropertyDescriptors(a)))if(!(Array.isArray(a)&&h==="length")&&(St.has(h)?t.push({path:`${l}.${h}`,message:"模板不能包含可能污染原型的键"}):m.get||m.set||!m.enumerable?t.push({path:`${l}.${h}`,message:"模板不能包含访问器或不可枚举字段"}):i(m.value,`${l}.${h}`,c+1),r>ue||s))break;n.delete(a)};i(e,"$",0)}function B(e,t,n,r,o=!1){const s=e[t];s===void 0&&!o||(typeof s!="string"||o&&!s.trim())&&r.push({path:`${n}.${t}`,message:o?"应为非空字符串":"应为字符串"})}function z(e,t,n,r,o=0,s=!1){const i=e[t];i===void 0&&!s||(typeof i!="number"||!Number.isFinite(i)||i<o)&&r.push({path:`${n}.${t}`,message:`应为大于等于 ${o} 的有限数字`})}function re(e,t,n,r){e[t]!==void 0&&typeof e[t]!="boolean"&&r.push({path:`${n}.${t}`,message:"应为布尔值"})}function Q(e,t,n,r=!1){e!==void 0&&!Tt.has(e)&&!(r&&e==="auto")&&n.push({path:t,message:`未知对齐方式${r?"(支持 auto)":""}`})}function J(e,t,n){if(e!==void 0){if(!C(e)){n.push({path:t,message:"样式应为对象"});return}Q(e.align,`${t}.align`,n),e.verticalAlign!==void 0&&!["top","middle","bottom"].includes(e.verticalAlign)&&n.push({path:`${t}.verticalAlign`,message:"未知垂直对齐方式"});for(const r of["fontSize","fontSizePx","lineWidthPt","lineHeight"])z(e,r,t,n);for(const r of["letterSpacing","rotateDeg"])z(e,r,t,n,-1/0);z(e,"opacity",t,n),typeof e.opacity=="number"&&e.opacity>1&&n.push({path:`${t}.opacity`,message:"透明度不能大于 1"});for(const r of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])re(e,r,t,n);for(const r of["fontFamily","color","backgroundColor","lineColor","borderColor"])B(e,r,t,n)}}function vt(e,t,n){if(e===void 0)return;if(!Array.isArray(e)){n.push({path:t,message:"参数定义应为数组"});return}const r=new Set;e.forEach((o,s)=>{const i=`${t}.${s}`;if(!C(o)){n.push({path:i,message:"参数定义应为对象"});return}B(o,"field",i,n,!0),typeof o.field=="string"&&(r.has(o.field)&&n.push({path:`${i}.field`,message:"参数名重复"}),r.add(o.field)),o.type!==void 0&&!["text","number","date","select"].includes(o.type)&&n.push({path:`${i}.type`,message:"未知参数类型"});for(const a of["label","defaultValue","placeholder"])B(o,a,i,n);re(o,"required",i,n),o.options!==void 0&&(Array.isArray(o.options)?o.options.forEach((a,l)=>{const c=`${i}.options.${l}`;if(!C(a))n.push({path:c,message:"选项应为对象"});else for(const f of["label","value"])typeof a[f]!="string"&&n.push({path:`${c}.${f}`,message:"选项标签与值应为字符串(允许空白选项)"})}):n.push({path:`${i}.options`,message:"选项应为数组"}))})}function Pt(e,t,n){for(const r of["leftMm","topMm"])z(e,r,t,n,-1/0,!0);z(e,"widthMm",t,n,Number.MIN_VALUE,!0),B(e,"dataset",t,n,!0),!Array.isArray(e.columns)||e.columns.length===0?n.push({path:`${t}.columns`,message:"列表至少需要一列"}):e.columns.forEach((r,o)=>{const s=`${t}.columns.${o}`;if(!C(r)){n.push({path:s,message:"列应为对象"});return}if(typeof r.header!="string"&&n.push({path:`${s}.header`,message:"表头应为字符串(允许空白表头)"}),B(r,"field",s,n,!0),z(r,"widthMm",s,n,Number.MIN_VALUE,!0),J(r.style,`${s}.style`,n),J(r.headerStyle,`${s}.headerStyle`,n),Q(r.align,`${s}.align`,n,!0),Q(r.headerAlign,`${s}.headerAlign`,n),r.format!==void 0)if(!C(r.format)||!["number","percent","date"].includes(r.format.kind))n.push({path:`${s}.format`,message:"未知列格式"});else{const i=r.format.digits;i!==void 0&&(typeof i!="number"||!Number.isInteger(i)||i<0||i>100)&&n.push({path:`${s}.format.digits`,message:"小数位应为 0–100 的整数"}),re(r.format,"thousands",`${s}.format`,n),B(r.format,"pattern",`${s}.format`,n)}r.rules!==void 0&&(Array.isArray(r.rules)?r.rules.forEach((i,a)=>{const l=`${s}.rules.${a}`;if(!C(i)||!C(i.when)){n.push({path:l,message:"条件格式缺少 when 对象"});return}B(i.when,"field",`${l}.when`,n,!0),[">",">=","<","<=","==","!="].includes(i.when.op)||n.push({path:`${l}.when.op`,message:"未知条件运算符"}),typeof i.when.value!="number"&&typeof i.when.value!="string"&&n.push({path:`${l}.when.value`,message:"条件值应为数字或字符串"}),J(i.style,`${l}.style`,n)}):n.push({path:`${s}.rules`,message:"条件格式应为数组"}))});for(const r of["fontSizePt","rowHeightMm"])z(e,r,t,n,Number.MIN_VALUE);z(e,"paddingMm",t,n);for(const r of["headerBold","headerEveryPage","border"])re(e,r,t,n);if(B(e,"headerBackgroundColor",t,n),Q(e.align,`${t}.align`,n,!0),Q(e.headerAlign,`${t}.headerAlign`,n),J(e.headerStyle,`${t}.headerStyle`,n),e.groupBy!==void 0)if(!C(e.groupBy))n.push({path:`${t}.groupBy`,message:"分组应为对象"});else{B(e.groupBy,"field",`${t}.groupBy`,n,!0);for(const r of["headerTemplate","subtotalLabel"])B(e.groupBy,r,`${t}.groupBy`,n);for(const r of["headerStyle","subtotalStyle"])J(e.groupBy[r],`${t}.groupBy.${r}`,n);re(e.groupBy,"keepWithNext",`${t}.groupBy`,n),e.groupBy.subtotal!==void 0&&(!Array.isArray(e.groupBy.subtotal)||e.groupBy.subtotal.some(r=>typeof r!="string"))&&n.push({path:`${t}.groupBy.subtotal`,message:"小计字段应为字符串数组"})}e.grandTotal!==void 0&&typeof e.grandTotal!="boolean"&&(C(e.grandTotal)?(B(e.grandTotal,"label",`${t}.grandTotal`,n),J(e.grandTotal.style,`${t}.grandTotal.style`,n),e.grandTotal.fields!==void 0&&(!Array.isArray(e.grandTotal.fields)||e.grandTotal.fields.some(r=>typeof r!="string"))&&n.push({path:`${t}.grandTotal.fields`,message:"合计字段应为字符串数组"})):n.push({path:`${t}.grandTotal`,message:"合计应为布尔值或对象"}))}function Xe(e,t,n){J(e.style,`${t}.style`,n);for(const o of["text","rawText","imageData","fallbackText","nid","rkey"])B(e,o,t,n);if(e.lines!==void 0&&(!Array.isArray(e.lines)||e.lines.some(o=>typeof o!="string"))&&n.push({path:`${t}.lines`,message:"文本行应为字符串数组"}),Array.isArray(e.richParagraphs)&&e.richParagraphs.forEach((o,s)=>{if(!C(o))return;const i=`${t}.richParagraphs.${s}`;Q(o.align,`${i}.align`,n);for(const a of["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"])z(o,a,i,n);Array.isArray(o.segments)&&o.segments.forEach((a,l)=>{const c=`${i}.segments.${l}`;if(!C(a)){n.push({path:c,message:"富文本片段应为对象"});return}a.kind!==void 0&&a.kind!=="text"&&a.kind!=="field"&&n.push({path:`${c}.kind`,message:"未知富文本片段类型"});for(const f of["text","field"])B(a,f,c,n);J(a.style,`${c}.style`,n)})}),!C(e.grid))return;const r=e.grid;z(r,"gapMm",`${t}.grid`,n);for(const o of["colWidthsMm","rowHeightsMm"]){const s=r[o];s!==void 0&&(!Array.isArray(s)||s.some(i=>typeof i!="number"||!Number.isFinite(i)||i<0))&&n.push({path:`${t}.grid.${o}`,message:"网格尺寸应为有限非负数字数组"})}Array.isArray(r.cells)&&r.cells.forEach((o,s)=>{Array.isArray(o)&&o.forEach((i,a)=>{const l=`${t}.grid.cells.${s}.${a}`;if(i!==null){if(!C(i)){n.push({path:l,message:"网格单元格应为对象或 null"});return}for(const c of["text","rawText","numberFormat"])B(i,c,l,n);for(const c of["colSpan","rowSpan"]){const f=i[c];f!==void 0&&(typeof f!="number"||!Number.isInteger(f)||f<=0)&&n.push({path:`${l}.${c}`,message:"跨度应为正整数"})}i.value!==void 0&&i.value!==null&&!["string","number","boolean"].includes(typeof i.value)&&n.push({path:`${l}.value`,message:"Excel 原始值应为字符串、数字、布尔值或 null"}),J(i.style,`${l}.style`,n),i.children!==void 0&&(Array.isArray(i.children)?i.children.forEach((c,f)=>{C(c)&&Xe(c,`${l}.children.${f}`,n)}):n.push({path:`${l}.children`,message:"嵌套组件应为数组"}))}})})}function Ae(e){const t=[],n=[];return Pe(e,t),t.length?{ok:!1,errors:t,warnings:n}:(C(e)?(e.schemaVersion!==void 0&&e.schemaVersion!==x.RENDER_PLAN_SCHEMA_VERSION&&t.push({path:"$.schemaVersion",message:"不支持的模板 schemaVersion"}),vt(e.params,"$.params",t),!Array.isArray(e.pages)||e.pages.length===0?t.push({path:"$.pages",message:"模板至少需要一页"}):e.pages.forEach((r,o)=>{const s=`$.pages.${o}`;if(!C(r)){t.push({path:s,message:"页应为对象"});return}z(r,"widthMm",s,t,Number.MIN_VALUE,!0),z(r,"heightMm",s,t,Number.MIN_VALUE,!0),typeof r.widthMm=="number"&&r.widthMm>=3e3&&t.push({path:`${s}.widthMm`,message:"页宽应小于 3000mm"}),typeof r.heightMm=="number"&&r.heightMm>=5e3&&t.push({path:`${s}.heightMm`,message:"页高应小于 5000mm"});for(const i of["marginTopMm","marginBottomMm","marginLeftMm","marginRightMm"])z(r,i,s,t);typeof r.widthMm=="number"&&Number(r.marginLeftMm??0)+Number(r.marginRightMm??0)>=r.widthMm&&t.push({path:s,message:"横向页边距占满页面"}),typeof r.heightMm=="number"&&Number(r.marginTopMm??0)+Number(r.marginBottomMm??0)>=r.heightMm&&t.push({path:s,message:"纵向页边距占满页面"}),Array.isArray(r.components)?r.components.forEach((i,a)=>{const l=`${s}.components.${a}`;C(i)&&i.kind==="list"?Pt(i,l,t):(he(i,l,t,n),C(i)&&Xe(i,l,t))}):t.push({path:`${s}.components`,message:"组件应为数组"})})):t.push({path:"$",message:"模板应为对象"}),{ok:t.length===0,errors:t,warnings:n})}function Ke(e){const t=[],n=[];if(Pe(e,t),t.length)return{ok:!1,errors:t,warnings:n};if(!C(e))t.push({path:"$",message:"模板文档应为对象"});else{for(const o of Object.keys(e))$t.has(o)||t.push({path:`$.${o}`,message:"模板文档存在未知字段;只保存模板与描述,不保存取数或业务数据"});e.schemaVersion!==Ee&&t.push({path:"$.schemaVersion",message:"不支持的模板文档版本"});for(const o of["id","name"])B(e,o,"$",t,!0);for(const o of["revision","description"])B(e,o,"$",t);const r=Ae(e.template);t.push(...r.errors.map(o=>({...o,path:`$.template${o.path.slice(1)}`}))),n.push(...r.warnings.map(o=>({...o,path:`$.template${o.path.slice(1)}`})))}return{ok:t.length===0,errors:t,warnings:n}}function ge(e){const t=Ke(e);if(!t.ok)throw new X(t.errors)}function At(e){const t=[];if(Pe(e,t),t.length)throw new X(t);const n={...e,schemaVersion:e.schemaVersion??Ee};return ge(n),me(n)}function kt(e){let t=e;if(typeof e=="string"){if(e.length>ve)throw new X([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);try{t=JSON.parse(e)}catch{throw new X([{path:"$",message:"模板 JSON 语法无效"}])}}return ge(t),me(t)}function xt(e){ge(e);const t=JSON.stringify(e,null,2);if(t.length>ve)throw new X([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);return t}function me(e){return JSON.parse(JSON.stringify(e))}function Nt(e=[]){const t=new Map,n={get:r=>{const o=t.get(r);return o?me(o):void 0},list:()=>Array.from(t.values(),({template:r,...o})=>({...o})),register:(r,o={})=>{if(ge(r),t.has(r.id)&&!o.replace)throw new X([{path:"$.id",message:`模板 ID ${r.id} 已注册;更新需显式 replace:true`}]);t.set(r.id,me(r))},remove:r=>t.delete(r)};for(const r of e)n.register(r);return n}function Rt(e){if(!("mapData"in e))return e;const{load:t,mapData:n,...r}=e;return{...r,load:async o=>{const s=await t(o);q(o.signal);try{return n(s,o)}catch(i){throw new I("validate",`报表 ${o.reportId} 数据映射失败`,i)}}}}class I extends Error{constructor(t,n,r){super(n),this.name="ReportSourceError",this.code=t,this.cause=r}}function fe(e){const t=new Error("报表加载已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e.reason}),t}function q(e){if(e?.aborted)throw fe(e)}function He(e,t){return t?new Promise((n,r)=>{const o=()=>t.removeEventListener("abort",s),s=()=>{o(),r(fe(t))};t.addEventListener("abort",s,{once:!0}),t.aborted&&s(),Promise.resolve(e).then(i=>{o(),n(i)},i=>{o(),r(i)})}):Promise.resolve(e)}function Ct(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new I("validate",`报表 ${t} 的数据集应为对象`);for(const[n,r]of Object.entries(e))if(!Array.isArray(r)||r.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new I("validate",`报表 ${t} 的数据集 ${n} 应为对象数组`)}function _t(e,t={}){function n(o){const s=Object.prototype.hasOwnProperty.call(e,o)?e[o]:void 0;if(!s)throw new I("config",`未注册报表 ${o}`);return s}return Object.assign(async({reportIds:o,params:s,signal:i,onWarning:a})=>{q(i);const l=[...o],c={...s};if(l.length===0)throw new I("config","缺少报表 ID");const f=l.map(n),h=[],m=[];for(const[S,T]of f.entries()){q(i);const u=l[S],k={reportId:u,params:{...c},signal:i};let A;if(typeof T.template=="function")try{A=await He(T.template(k),i),q(i);const y=Ae(A);if(!y.ok)throw new I("validate",`报表 ${u} 模板校验失败:${y.errors.slice(0,3).map(E=>`${E.path}: ${E.message}`).join("; ")}`);m.push(...y.warnings.map(E=>`${u}: ${E.path}: ${E.message}`))}catch(y){throw i?.aborted?fe(i):y instanceof I?y:y instanceof X?new I("validate",`报表 ${u} 模板校验失败:${y.message}`,y):new I("fetch",`报表 ${u} 模板加载失败:${y instanceof Error?y.message:String(y)}`,y)}else A=T.template;let v;try{v=await He(T.load?T.load(k):T.datasets??{},i)}catch(y){throw i?.aborted?fe(i):y instanceof I?y:new I("fetch",`报表 ${u} 取数失败:${y instanceof Error?y.message:String(y)}`,y)}q(i),Ct(v,u);let V;try{V=ze(A,v,T.pagination)}catch(y){throw new I("validate",`报表 ${u} 排版失败:${y instanceof Error?y.message:String(y)}`,y)}for(const y of V.plan.pages)h.push(y);m.push(...V.warnings.map(y=>`${u}: ${y}`))}q(i);const w={schemaVersion:x.RENDER_PLAN_SCHEMA_VERSION,pages:h},d=be(w);if(!d.ok)throw new I("validate",`渲染计划校验失败:${d.errors.slice(0,3).map(S=>`${S.path}: ${S.message}`).join("; ")}`);m.push(...d.warnings.map(S=>`${S.path}: ${S.message}`));const p=a??t.onWarning??(S=>console.warn("[mach-report]",S));for(const S of m)q(i),p(S);return q(i),w},{getParamDefs:o=>et.getReportParamDefs(e,o)})}exports.CSS_DPI=g.CSS_DPI;exports.DEFAULT_BORDER_PT=g.DEFAULT_BORDER_PT;exports.DEFAULT_FONT_PT=g.DEFAULT_FONT_PT;exports.DEFAULT_STROKE_COLOR=g.DEFAULT_STROKE_COLOR;exports.DEFAULT_TEXT_COLOR=g.DEFAULT_TEXT_COLOR;exports.LINE_HEIGHT=g.LINE_HEIGHT;exports.MM_PER_INCH=g.MM_PER_INCH;exports.PAPER_SIZES=g.PAPER_SIZES;exports.SCHEMA_VERSION_MACH=g.SCHEMA_VERSION_MACH;exports.mmToPx=g.mmToPx;exports.mmToPxFactor=g.mmToPxFactor;exports.ptToPx=g.ptToPx;exports.pxToMm=g.pxToMm;exports.resolveBoxBorders=g.resolveBoxBorders;exports.resolveFontSize=g.resolveFontSize;exports.resolveGridLayout=g.resolveGridLayout;exports.resolveLineHeight=g.resolveLineHeight;exports.resolveStroke=g.resolveStroke;exports.resolveTextColor=g.resolveTextColor;exports.round=g.round;exports.RENDER_PLAN_SCHEMA_VERSION=x.RENDER_PLAN_SCHEMA_VERSION;exports.charWidthEm=x.charWidthEm;exports.createCanvasMeasurer=x.createCanvasMeasurer;exports.createHeuristicMeasurer=x.createHeuristicMeasurer;exports.heuristicMeasurer=x.heuristicMeasurer;exports.isImageBackedComponent=x.isImageBackedComponent;exports.isRichText=x.isRichText;exports.measureTextMm=x.measureTextMm;exports.wrapText=x.wrapText;exports.PageBuilder=qe;exports.REPORT_TEMPLATE_DOCUMENT_VERSION=Ee;exports.ReportSourceError=I;exports.ReportTemplateError=X;exports.TemplateBuilder=Ye;exports.assertRenderPlan=it;exports.classOf=L;exports.computePageWindow=Ve;exports.createCanvasPager=Mt;exports.createReportSource=_t;exports.createTableTemplate=wt;exports.createTemplate=bt;exports.createTemplateRegistry=Nt;exports.defineReport=Rt;exports.defineReportTemplate=At;exports.evalStyleRule=Fe;exports.formatValue=Me;exports.measurePageSizePx=$e;exports.paginateTemplate=ze;exports.parseDateLocal=Oe;exports.parseReportTemplate=kt;exports.planFontSizePx=ut;exports.renderComponent=we;exports.renderPage=We;exports.renderPlan=ht;exports.renderPlanToCanvas=Je;exports.renderPlanToImages=yt;exports.resolvePaper=Te;exports.serializeReportTemplate=xt;exports.toExcelNumberFormat=ye;exports.toNumber=de;exports.validateComponent=he;exports.validatePage=Be;exports.validateRenderPlan=be;exports.validateReportTemplate=Ae;exports.validateReportTemplateDocument=Ke;
|