@agile-team/mach-report 2.2.0 → 2.3.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 CHANGED
@@ -3,12 +3,12 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- <strong>面向业务单据、明细台账与打印场景的 TypeScript 报表引擎</strong><br />
7
- 框架无关内核 · 毫米级页面模型 · Vue 3 预览 · PDF / Excel 输出
6
+ <strong>面向业务宽表、明细台账与标准打印的 TypeScript 报表引擎</strong><br />
7
+ 完整列宽预览 · 连续 Excel · A3 / A4 选配 · 框架无关内核
8
8
  </p>
9
9
 
10
10
  <p align="center">
11
- <img src="https://img.shields.io/badge/source-2.2.0-2563eb" alt="Source version 2.2.0" />
11
+ <img src="https://img.shields.io/badge/source-2.3.0-2563eb" alt="Source version 2.3.0" />
12
12
  <a href="https://www.npmjs.com/package/@agile-team/mach-report"><img src="https://img.shields.io/npm/v/@agile-team/mach-report?label=npm&color=3178c6" alt="npm version" /></a>
13
13
  <a href="https://github.com/ChenyCHENYU/MachReport/actions/workflows/ci.yml"><img src="https://github.com/ChenyCHENYU/MachReport/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
14
14
  <a href="https://github.com/ChenyCHENYU/MachReport/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-authorization%20required-dc2626" alt="Authorization required" /></a>
@@ -18,6 +18,7 @@
18
18
 
19
19
  <p align="center">
20
20
  <a href="#60-秒开始"><strong>快速开始</strong></a> ·
21
+ <a href="#完整宽表与标准纸张"><strong>完整宽表</strong></a> ·
21
22
  <a href="#excel-报表能力与边界"><strong>Excel 能力</strong></a> ·
22
23
  <a href="#对齐与可读性">对齐配置</a> ·
23
24
  <a href="#模板配置与管理扩展">模板管理</a> ·
@@ -32,11 +33,12 @@
32
33
 
33
34
  ## 为什么选择 MachReport
34
35
 
35
- MachReport 把模板、数据和输出分开:用 TypeScript DSL 或 JSON 定义纸张与内容,由分页引擎生成统一的 `RenderPlan`,再交给预览、打印或文件导出。适合出入库单、工艺卡、订单明细和分组汇总等需要明确纸张尺寸与分页的业务场景。
36
+ MachReport 把模板、数据和输出分开:用 TypeScript DSL 或 JSON 定义布局与内容,由引擎生成统一的 `RenderPlan`,再交给预览、打印或文件导出。生产日报等多列报表按完整列宽展开;出入库单、工艺卡和订单明细可选标准纸张与分页。
36
37
 
37
38
  | 维度 | 已具备的能力 |
38
39
  | --- | --- |
39
40
  | 页面模型 | 毫米单位、纸张预设与自定义尺寸、页边距、横纵向、文本与表格几何 |
41
+ | 完整宽表 | 自然列宽、横向滚动、默认 100% 预览;纵向分段窗口化,Excel 自动合并连续 Sheet |
40
42
  | 明细与汇总 | 自动折行与分页、重复表头、连续分组小计、末尾总计、页码占位符 |
41
43
  | 数据呈现 | 表头与内容独立对齐、类型自动对齐、数值 / 百分比 / 日期格式化、条件格式 |
42
44
  | 预览交互 | 正文与缩略图双窗口渲染、缩放与适宽、可取消分片搜索、参数面板 |
@@ -84,6 +86,33 @@ const fetcher = createLocalFetcher({
84
86
 
85
87
  标准明细只定义标题和列:默认 A4、10 mm 页边距、`detail` 数据集、表头居中,按内容类型对齐,自动分配列宽并分页。支持固定列宽、权重、横向纸张、分组与总计;复杂单据继续使用 `createTemplate()` 自由排版。
86
88
 
89
+ ### 完整宽表与标准纸张
90
+
91
+ 同一个工厂增加 `layout: "wide"`,列数增加时表格随之展开。自动列默认每列 30 mm,`columnWidthMm` 调整统一宽度;单列 `widthMm` 优先,`flex` 是基准宽度的倍数。页面接入、接口和数据集写法保持一致。
92
+
93
+ ```ts
94
+ const template = createTableTemplate({
95
+ layout: "wide",
96
+ title: "炼钢生产日报",
97
+ columns: [
98
+ { header: "日期", field: "date", widthMm: 32 },
99
+ { header: "班组", field: "team", widthMm: 24 },
100
+ { header: "产量", field: "output", format: { kind: "number", digits: 3 } }
101
+ // 继续声明全部业务列,列宽不受 A3/A4 限制。
102
+ ]
103
+ });
104
+ ```
105
+
106
+ 宽表默认按 100% 显示,横向滚动查看全部列;适宽和缩放仍可手动选择。内部纵向分段用于预览窗口化,Excel 默认把同一逻辑表还原为一张连续 Sheet,保留全部列、行与原始值,重复页头只写一次。
107
+
108
+ | 使用目标 | 配置 |
109
+ | --- | --- |
110
+ | 完整宽表预览 + 连续 Excel | 模板 `layout: "wide"`;导出无需额外配置 |
111
+ | 宽表的 Excel 另选打印纸型 | 应用配置 `xlsx: { paperSize: "a3" }` 或 `"a4"`,只影响打印设置 |
112
+ | 按标准纸张排版预览 / PDF / 打印 | 模板 `paper: "a3", landscape: true` 或 `paper: "a4"`,保持默认 `layout: "page"` |
113
+
114
+ `wide` 与模板的 `paper / landscape` 分别表达自然列宽和固定纸张,不同时设置。标准纸张模式保持原有余量分配;显式固定列宽超出纸张会报错。列很多时优先宽表,避免把所有列挤进一张纸的可用宽度。Excel 打印纸型不会改写工作表列宽。
115
+
87
116
  ### 项目接入:注册一次,页面只传 ID 和参数
88
117
 
89
118
  模板与业务取数集中注册,分页、校验、参数面板、多报表合并及请求生命周期交给包内处理。Vue 用户从同一个 `/vue` 入口获取组件和核心能力。
@@ -149,17 +178,17 @@ await writeFile("report.xlsx", new Uint8Array(buffer));
149
178
 
150
179
  | 项目 | 当前行为 |
151
180
  | --- | --- |
152
- | 工作簿结构 | 每个报表页生成一张工作表,默认 `Sheet1`、`Sheet2`…,可自定义名称 |
181
+ | 工作簿结构 | 默认 `sheetMode: "auto"`:宽表按逻辑表生成连续 Sheet,普通页面仍每页一张;可显式选择 pages / continuous |
153
182
  | 表格结构 | 表头、明细、小计 / 总计的渲染结果,列宽、行高、跨行 / 跨列合并 |
154
183
  | 基础样式 | 字号、字体族、加粗 / 斜体 / 下划线、颜色、水平 / 垂直对齐、换行、底色与边框开关 |
155
184
  | 标题文本 | 按组件顺序写入合并行;页面绝对坐标转换为工作表行流 |
156
- | 单元格类型 | 默认 `text` 保留显示文本;`raw` 保留列表原始数值、布尔、文本编号、空值和汇总数值 |
185
+ | 单元格类型 | 宽表默认 raw,普通页面默认 text;可显式覆盖,raw 保留数值、布尔、文本编号、空值和汇总数值 |
157
186
  | 数字格式 | `raw` 模式沿用小数位、千分位和百分比格式,不猜测文本编号的类型 |
158
187
  | 非表格内容 | 图片、条码、二维码、图表、嵌套组件和无文本回退的富文本等暂不导出,跳过时返回 `warnings` |
159
- | 版式与打印 | 自动识别 A3 / A4 / A5,可配置 `paperSize`;自定义尺寸回退有告警,绝对坐标仍转为行流 |
188
+ | 版式与打印 | 普通页面自动识别 A3 / A4 / A5;宽表默认不强制纸型,可选 paperSize,工作表列宽保持完整 |
160
189
  | Excel 编辑工作流 | 尚无 `.xlsx` 模板导入、交互式工作簿编辑、公式计算或透视表 API |
161
190
 
162
- 列表自动保留原始值,Vue 可在配置中一次启用 `xlsx: { valueMode: "raw" }`;旧计划没有原始值时继续导出显示文本。日期对象、公式和自定义布局仍需业务明确处理。Excel 不做 PDF 坐标复刻;可使用返回的 ExcelJS `workbook` 继续处理并重新序列化。
191
+ 列表自动保留原始值,Vue 可在配置中一次启用 `xlsx: { valueMode: "raw" }`;旧计划没有原始值时继续导出显示文本。连续导出使用包内记录的逻辑行与列身份,不按文字猜测重复表头;多报表保持独立 Sheet。显式 continuous 要求可识别的列表结构,不支持的布局会报错。日期对象、公式和自由布局仍需业务明确处理。Excel 不做 PDF 坐标复刻;可使用返回的 ExcelJS `workbook` 继续处理并重新序列化。
163
192
 
164
193
  完整示例、类型保留策略和注意事项见 [Excel 导出指南](https://github.com/ChenyCHENYU/MachReport/blob/main/docs/EXCEL.md)。
165
194
 
@@ -367,7 +396,7 @@ CI 使用同一套校验命令,并在构建后检查实际发布产物。协
367
396
 
368
397
  ## 版本与授权
369
398
 
370
- 当前源码版本为 `2.2.0`,以 [`packages/mach-report/package.json`](https://github.com/ChenyCHENYU/MachReport/blob/main/packages/mach-report/package.json) 为准;npm 已发布版本由顶部 npm 标识展示。
399
+ 当前源码版本为 `2.3.0`,以 [`packages/mach-report/package.json`](https://github.com/ChenyCHENYU/MachReport/blob/main/packages/mach-report/package.json) 为准;npm 已发布版本由顶部 npm 标识展示。
371
400
 
372
401
  Copyright © 2026 ChenyCHENYU (Agile Team). All rights reserved.
373
402
 
@@ -0,0 +1,6 @@
1
+ "use strict";var zt=Object.create;var et=Object.defineProperty;var Wt=Object.getOwnPropertyDescriptor;var Lt=Object.getOwnPropertyNames;var At=Object.getPrototypeOf,Ht=Object.prototype.hasOwnProperty;var qt=(t,n,a,l)=>{if(n&&typeof n=="object"||typeof n=="function")for(let r of Lt(n))!Ht.call(t,r)&&r!==a&&et(t,r,{get:()=>n[r],enumerable:!(l=Wt(n,r))||l.enumerable});return t};var tt=(t,n,a)=>(a=t!=null?zt(At(t)):{},qt(n||!t||!t.__esModule?et(a,"default",{value:t,enumerable:!0}):a,t));const e=require("vue"),le=require("@agile-team/mach-report"),lt=require("./page-window-index-DEjnM6IB.cjs"),se=require("./plugin-MSh_OhoW.cjs");function He(t){return t==null?[]:Array.isArray(t)?t.map(String).filter(n=>n!==""):String(t).split(",").map(n=>n.trim()).filter(n=>n!=="")}function jt(t){return He(t).join(",")}class Pe extends Error{constructor(n){super(n),this.name="PlanLoadError"}}function Ut(t={}){const{baseUrl:n="",headers:a,credentials:l,timeoutMs:r=3e4}=t,o=n.replace(/\/+$/,"");return async({url:i,method:u,params:p,signal:v})=>{let d=`${o}${i}`;if(p&&Object.keys(p).length>0){const y=d.indexOf("#"),B=y>=0?d.slice(y):"",E=y>=0?d.slice(0,y):d,M=E.indexOf("?"),C=M>=0?E.slice(0,M):E,P=new URLSearchParams(M>=0?E.slice(M+1):"");for(const[N,I]of Object.entries(p))P.set(N,I);d=`${C}?${P}${B}`}const m=(y,B)=>{const E=new Pe(y);return Object.defineProperty(E,"cause",{value:B,configurable:!0,writable:!0}),E};if(v?.aborted)throw m(`请求已取消: ${i}`,v.reason);const h=new AbortController;let g;const F=()=>{h.signal.aborted||(g="external",h.abort(v?.reason))};v?.addEventListener("abort",F,{once:!0});const R=setTimeout(()=>{h.signal.aborted||(g="timeout",h.abort())},r);try{const y=await fetch(d,{method:u.toUpperCase(),headers:{Accept:"application/json",...a},credentials:l,signal:h.signal});if(!y.ok)throw new Pe(`HTTP ${y.status} ${i}`);return await y.json()}catch(y){throw g==="timeout"?m(`请求超时(${r}ms): ${i}`,y):g==="external"?m(`请求已取消: ${i}`,y):y instanceof Pe?y:m(`请求失败(${i}): ${y instanceof Error?y.message:String(y)}`,y)}finally{clearTimeout(R),v?.removeEventListener("abort",F)}}}function st(t,n,a={}){const l=a.pxPerMm??3.7795275590551185,r=e.computed(()=>Math.max(0,e.unref(a.gapPx)??18)),o=e.ref(0),i=e.ref(800),u=e.computed(()=>{const y=t.value?.pages??[];return lt.createPageWindowIndex(y.map(B=>B.pageHeightMm*l),r.value)}),p=e.computed(()=>{let y=0;for(const B of t.value?.pages??[])y=Math.max(y,B.pageWidthMm*l);return{w:y,h:u.value.totalHeightPx}}),v=e.computed(()=>u.value.window(i.value/n.value,o.value/n.value,e.unref(a.overscan)??1)),d=e.computed(()=>{const y=t.value;if(!y)return[];const{start:B,end:E}=v.value;return y.pages.slice(B,E+1).map((M,C)=>({page:M,index:B+C}))});let m=0,h=!1;function g(y){y&&(o.value=y.scrollTop,i.value=y.clientHeight||800)}function F(y,B){return E=>{m||h||(m=requestAnimationFrame(()=>{if(m=0,h||(g(E),B.value<=0))return;const M=Math.max(0,E.scrollTop+32)/n.value;y.value=Math.min(B.value,u.value.pageAt(M)+1)}))}}function R(){h=!0,m&&cancelAnimationFrame(m),m=0}return e.onScopeDispose(R),{contentSize:p,windowRange:v,visiblePages:d,makeScrollHandler:F,refreshViewport:g,pageOffsetPx:y=>u.value.offsetAt(y),destroy:R}}function it(t){const n=e.ref(1),a=e.ref("fit");let l=0;function r(){l&&cancelAnimationFrame(l),l=0}function o(){r(),l=requestAnimationFrame(()=>{if(l=0,a.value!=="fit")return;const u=t();!u?.viewport||u.viewport.clientWidth<=48||!Number.isFinite(u.pageWidthPx)||(n.value=Math.min(1,(u.viewport.clientWidth-48)/Math.max(1,u.pageWidthPx)))})}function i(u){if(u==="fit")a.value="fit",o();else{if(!Number.isFinite(u))return;r(),a.value="raw",n.value=Math.min(3,Math.max(.3,u/100))}}return e.getCurrentScope()&&e.onScopeDispose(r),{zoom:n,zoomMode:a,applyFitZoom:o,setZoom:i}}const Ce=8;function Be(){return new Promise(t=>setTimeout(t,0))}function ke(t){return`p${Math.round(t.pageWidthMm)}x${Math.round(t.pageHeightMm)}`}function qe(t){const n=new Map;return t.pages.forEach(r=>{n.has(ke(r))||n.set(ke(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 ${ke(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 je(t){const n=le.renderPage(t,96,{},document);return n.style.page=ke(t),n.outerHTML}function Ue(t){return{head:qe(t),pageChunks:t.pages.map(je)}}async function Kt(t,n={}){const a={schemaVersion:"mach-report-batch-print",pages:t.flatMap(i=>i.pages)};if(a.pages.length===0)return;const l=qe(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 i=r.contentDocument;i.open(),i.write(l);for(let u=0;u<a.pages.length;u++)i.write(je(a.pages[u])),u%Ce===Ce-1&&(n.onProgress?.(u+1,a.pages.length),await Be());i.write("</body></html>"),i.close(),await Be(),n.onProgress?.(a.pages.length,a.pages.length),o=!0,r.contentWindow?.focus(),r.contentWindow?.print()}catch(i){n.onError?.(i instanceof Error?`批量打印失败: ${i.message}`:"批量打印失败")}finally{o?setTimeout(()=>r.remove(),6e4):r.remove()}}function ct(t){const{head:n,pageChunks:a}=Ue(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 ut(t,n){let a=null,l=!1,r=!1,o=0;const i=new Map,u=new Map;let p=null,v=null,d=null,m=null,h=null;function g(s,f){return!r&&t.value===s&&o===f}function F(){if(r)return;const s=[...i.values()].reverse().find(f=>g(f.plan,f.epoch))?.format??null;s!==p&&(p=s,n.onBusy?.(s))}function R(s,f,x){const k={};return i.set(k,{plan:s,epoch:f,format:x}),F(),k}function y(s){i.delete(s),F()}function B(){for(const[s,f]of u)g(f.plan,f.epoch)||(s.close(),u.delete(s))}const E=e.watch(t,()=>{o++,F(),B()},{flush:"sync"});function M(){a?.remove(),a=null}function C(){r=!0,o++,E(),M(),B(),i.clear(),n.onPrinting?.(!1)}function P(s,f){const x=URL.createObjectURL(s);setTimeout(()=>URL.revokeObjectURL(x),1e4);const k=document.createElement("a");k.href=x,k.download=f,k.click()}async function N(){if(l)return;const s=t.value;if(r||!s||s.pages.length===0)return;const f=o;l=!0,n.onPrinting?.(!0),M();const x=qe(s);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 $=k.contentDocument;$.open(),$.write(x);for(let W=0;W<s.pages.length;W++)if($.write(je(s.pages[W])),W%Ce===Ce-1&&await Be(),k!==a)return;if($.write("</body></html>"),$.close(),await Be(),!g(s,f)||k!==a)return;k.contentWindow?.focus(),k.contentWindow?.print()}catch{k===a&&M(),g(s,f)&&n.onError("调用打印失败,请改用导出 PDF","print")}finally{l=!1,r||n.onPrinting?.(!1)}}function I(s,f){if(v?.plan===s&&v.epoch===f)return v.promise;const x=Promise.resolve().then(()=>{if(!g(s,f))throw new Error("报表已切换或卸载");return n.getPdfExporter()(s,k=>{g(s,f)&&n.onWarning?.(k)})}).finally(()=>{v?.promise===x&&(v=null)});return v={plan:s,epoch:f,promise:x},x}async function V(){const s=t.value;if(r||!s||s.pages.length===0)return;const f=o;if(d?.plan===s&&d.epoch===f)return d.promise;const x=R(s,f,"PDF"),k=(async()=>{try{const $=await I(s,f);if(!g(s,f))return;P(new Blob([$],{type:"application/pdf"}),"mach-report.pdf")}catch($){g(s,f)&&n.onError($ instanceof Error?`PDF 导出失败: ${$.message}`:"PDF 导出失败","pdf")}finally{y(x),d?.token===x&&(d=null)}})();return d={plan:s,epoch:f,promise:k,token:x},k}async function L(){const s=t.value;if(r||!s||s.pages.length===0)return;const f=o;if(m?.plan===s&&m.epoch===f)return m.promise;const x={...n.getXlsxOptions?.()},k=R(s,f,"Excel"),$=(async()=>{try{const{renderPlanToXlsx:W}=await import("@agile-team/mach-report/xlsx");if(!g(s,f))return;const{buffer:H,warnings:q}=await W(s,x);if(!g(s,f)||(q.length>0&&n.onWarning?.(`Excel 导出有 ${q.length} 条提示:${q.slice(0,2).join(";")}`),!g(s,f)))return;P(new Blob([H],{type:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"}),"mach-report.xlsx")}catch(W){g(s,f)&&n.onError(W instanceof Error?`Excel 导出失败: ${W.message}`:"Excel 导出失败","export")}finally{y(k),m?.token===k&&(m=null)}})();return m={plan:s,epoch:f,promise:$,token:k},$}async function S(){const s=t.value;if(r||!s||s.pages.length===0)return;const f=o;if(h?.plan===s&&h.epoch===f)return h.promise;const x=R(s,f,"图片"),k=(async()=>{try{const{blobs:$}=await le.renderPlanToImages(s,{dpr:Math.min(2,typeof devicePixelRatio=="number"?devicePixelRatio:1)});if(!g(s,f))return;$.forEach((W,H)=>{P(W,$.length>1?`mach-report-page-${H+1}.png`:"mach-report.png")})}catch($){g(s,f)&&n.onError($ instanceof Error?`图片导出失败: ${$.message}`:"图片导出失败","export")}finally{y(x),h?.token===x&&(h=null)}})();return h={plan:s,epoch:f,promise:k,token:x},k}function Z(){const s=t.value;if(!(r||!s||s.pages.length===0))try{const{html:f,filename:x}=ct(s);P(new Blob([f],{type:"application/msword;charset=utf-8"}),x)}catch(f){n.onError(f instanceof Error?`Word 导出失败: ${f.message}`:"Word 导出失败","export")}}async function K(s){const f=t.value;if(!(r||!f||f.pages.length===0)){if(s==="pdf"){await V();return}if(s==="xlsx"||s==="excel"){await L();return}if(s==="png"||s==="image"){await S();return}if(s==="word"||s==="doc"){Z();return}if(s!=="html"){n.onError(`不支持的导出格式:${s}`,"export");return}try{const{head:x,pageChunks:k}=Ue(f),$=`${x}${k.join("")}</body></html>`;P(new Blob([$],{type:"text/html;charset=utf-8"}),"mach-report.html")}catch(x){n.onError(x instanceof Error?`HTML 导出失败: ${x.message}`:"HTML 导出失败","export")}}}function re(){const s=t.value;if(r||!s||s.pages.length===0)return;const f=o,x=window.open("","_blank");if(!x){n.onError("浏览器拦截了弹窗,请允许弹窗后重试","pdf");return}u.set(x,{plan:s,epoch:f});const k=R(s,f,"PDF");I(s,f).then($=>{if(!g(s,f)||x.closed){u.delete(x)&&x.close();return}const W=URL.createObjectURL(new Blob([$],{type:"application/pdf"}));setTimeout(()=>URL.revokeObjectURL(W),6e4);const H=x.document;H.title="PDF 预览",H.documentElement.style.height="100%",H.body.style.cssText="margin:0;height:100%;";const q=H.createElement("iframe");q.title="PDF 预览",q.style.cssText="display:block;width:100%;height:100%;border:0;",q.src=W,H.body.replaceChildren(q),u.delete(x)}).catch($=>{x.close(),u.delete(x),g(s,f)&&n.onError($ instanceof Error?`PDF 预览失败: ${$.message}`:"PDF 预览失败","pdf")}).finally(()=>y(k))}return{print:N,exportAs:K,exportImages:S,exportWord:Z,openPdfWindow:re,releasePrintFrame:M,dispose:C}}const dt="mrp-hit";function Gt(t){t.querySelectorAll(`mark.${dt}`).forEach(a=>{const l=a.parentNode;if(l){for(;a.firstChild;)l.insertBefore(a.firstChild,a);a.remove(),l.normalize()}})}function Yt(t,n){const a=n.trim();if(!a)return 0;const l=a.toLowerCase(),r=document.createTreeWalker(t,NodeFilter.SHOW_TEXT,{acceptNode(u){const p=u.parentElement;return!p||p.closest("mark")||/^(SCRIPT|STYLE)$/.test(p.tagName)?NodeFilter.FILTER_REJECT:(u.nodeValue??"").toLowerCase().includes(l)?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}}),o=[];for(let u=r.nextNode();u;u=r.nextNode())o.push(u);let i=0;for(const u of o){const p=u.nodeValue??"",v=p.toLowerCase(),d=u.parentElement;if(!d)continue;const m=document.createDocumentFragment();let h=0,g=v.indexOf(l);for(;g>=0;){g>h&&m.appendChild(document.createTextNode(p.slice(h,g)));const F=document.createElement("mark");F.className=dt,F.textContent=p.slice(g,g+a.length),m.appendChild(F),i++,h=g+a.length,g=v.indexOf(l,h)}h<p.length&&m.appendChild(document.createTextNode(p.slice(h))),d.replaceChild(m,u)}return i}function Zt(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*Jt(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*Xt(t){for(let n=0;n<t.pages.length;n++){for(const a of Jt(t.pages[n].components))yield{text:a,pageIndex:n};yield{text:"",pageIndex:n}}}function Qt(t){const{plan:n,gotoPage:a,highlight:l,clearHighlights:r}=t,o=e.ref(!1),i=e.ref(""),u=e.ref(0),p=e.ref(0),v=e.ref(!1);let d=[];const m=e.computed(()=>{if(p.value===0)return null;const C=u.value;let P=0,N=d.length-1;for(;P<N;){const V=P+N>>>1;d[V].cumulative<=C?P=V+1:N=V}const I=d[P];return I?{pageIndex:I.pageIndex,occurrence:C-(d[P-1]?.cumulative??0)}:null});let h=null,g=null,F=0;function R(){F++,h&&clearTimeout(h),g&&clearTimeout(g),h=g=null,v.value=!1}function y(C){i.value=C,u.value=0,p.value=0,d=[],v.value=!1;const P=C.trim().toLowerCase(),N=n.value;if(!P||!N)return;v.value=!0;const I=F,V=Xt(N),L=[];let S=0;function Z(){if(g=null,I!==F||N!==n.value)return;const K=performance.now();let re=0;for(;re<5e3&&performance.now()-K<4;){const s=V.next();if(s.done){d=L,p.value=S,v.value=!1,d[0]&&a(d[0].pageIndex+1);return}const f=Zt(s.value.text,P);if(f>0){S+=f;const x=L[L.length-1];x?.pageIndex===s.value.pageIndex?x.cumulative=S:L.push({pageIndex:s.value.pageIndex,cumulative:S})}re++}g=setTimeout(Z,0)}Z()}function B(C){if(R(),i.value=C,u.value=p.value=0,d=[],!C.trim()){y("");return}v.value=!0,h=setTimeout(()=>{h=null,y(C)},Math.max(0,e.unref(t.debounceMs)??200))}function E(C){const P=p.value;if(P===0||v.value)return;u.value=(u.value+C+P)%P;let N=0,I=d.length-1;for(;N<I;){const V=N+I>>>1;d[V].cumulative<=u.value?N=V+1:I=V}a(d[N].pageIndex+1)}function M(){R(),i.value="",u.value=p.value=0,d=[]}return e.watch(n,M,{flush:"sync"}),e.onScopeDispose(M),{visible:o,query:i,matchIndex:u,matchCount:p,activeMatch:m,searching:v,toggle:()=>{o.value=!o.value},onInput:B,onNav:E,apply:C=>{i.value.trim()&&l(C,i.value.trim())},clear:C=>{r(C)},reset:M}}function _t(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 en(t,n){const{thumbsRoot:a,visible:l,renderThumbCanvas:r}=n,o=e.ref(0),i=e.ref(800),u=e.computed(()=>(t.value?.pages??[]).map(E=>Math.round(E.pageHeightMm/E.pageWidthMm*116))),p=e.computed(()=>lt.createPageWindowIndex(u.value.map(E=>E+20),8)),v=e.computed(()=>p.value.window(i.value,o.value,1)),d=e.computed(()=>{if(!l.value)return[];const{start:E,end:M}=v.value;return u.value.slice(E,M+1).map((C,P)=>({index:E+P,height:C}))});let m=0,h=0,g=!1;function F(){const E=a.value;E&&(o.value=E.scrollTop,i.value=E.clientHeight||800)}function R(){g||h||(h=requestAnimationFrame(()=>{h=0,F()}))}function y(){if(d.value,m&&cancelAnimationFrame(m),m=0,g||!l.value||!t.value||!a.value)return;F();const E=d.value,M=t.value,C=a.value;let P=0;function N(){if(m=0,!(g||!l.value||t.value!==M||a.value!==C)){for(let I=0;P<E.length&&I<2;I++,P++){const V=E[P].index,L=C.querySelector(`[data-thumb="${V+1}"]`);if(!L||L.childElementCount>0)continue;const S=r(V);S&&(S.style.width="100%",S.style.height="100%",S.style.display="block",L.appendChild(S))}P<E.length&&(m=requestAnimationFrame(N))}}m=requestAnimationFrame(N)}function B(){g=!0,m&&cancelAnimationFrame(m),h&&cancelAnimationFrame(h),m=h=0}return e.onScopeDispose(B),{schedule:y,destroy:B,onScroll:R,windowRange:v,visibleThumbs:d}}function tn(){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 nn={class:"mrp-toolbar"},rn={class:"mrp-title"},on=["disabled"],an={class:"mrp-pageinfo"},ln=["disabled"],sn={key:1,class:"mrp-search"},cn=["placeholder","value"],un={key:0,class:"mrp-search-count",role:"status"},dn=["disabled"],fn=["disabled"],mn=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,i){return r.replace("{cur}",String(o)).replace("{total}",String(i))}return(r,o)=>(e.openBlock(),e.createElementBlock("div",nn,[e.createElementVNode("span",rn,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]=i=>r.$emit("goto",t.currentPage-1))},e.toDisplayString(t.messages.prevPage),9,on),e.createElementVNode("span",an,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]=i=>r.$emit("goto",t.currentPage+1))},e.toDisplayString(t.messages.nextPage),9,ln)],64)):e.createCommentVNode("",!0),o[17]||(o[17]=e.createElementVNode("span",{class:"mrp-spacer"},null,-1)),t.search.visible?(e.openBlock(),e.createElementBlock("div",sn,[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]=i=>r.$emit("search-input",i.target.value))},null,40,cn),t.search.query?(e.openBlock(),e.createElementBlock("span",un,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]=i=>r.$emit("search-nav",-1))},e.toDisplayString(t.messages.prevMatch),9,dn),e.createElementVNode("button",{class:"mrp-nav",type:"button",disabled:t.search.matchCount===0,onClick:o[4]||(o[4]=i=>r.$emit("search-nav",1))},e.toDisplayString(t.messages.nextMatch),9,fn)])):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]=i=>r.$emit("search-toggle"))}," 🔍 ",2),e.createElementVNode("button",{class:e.normalizeClass(["mrp-nav",{"mrp-active":t.thumbsVisible}]),type:"button",onClick:o[6]||(o[6]=i=>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]=i=>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]=i=>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]=i=>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]=i=>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]=i=>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]=i=>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]=i=>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]=i=>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]=i=>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]=i=>r.$emit("pdf-window"))},e.toDisplayString(t.messages.pdfWindow),1)):e.createCommentVNode("",!0)]))}}),Ke=(t,n)=>{const a=t.__vccOpts||t;for(const[l,r]of n)a[l]=r;return a},ft=Ke(mn,[["__scopeId","data-v-601f8fa8"]]),pn={class:"mrp-params"},vn={class:"mrp-params-title"},gn={class:"mrp-params-grid"},hn={class:"mrp-param-label"},wn={key:0,class:"mrp-param-star"},yn=["value","onChange"],bn={value:"",disabled:"",hidden:""},xn=["value"],En=["type","placeholder","value","onInput"],Pn={class:"mrp-params-actions"},kn=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 i(p,v){r.value={...r.value,[p]:v},l("update:modelValue",{...r.value})}function u(p){const v=a.defs.find(d=>d.field===p);return a.attempted&&v?.required===!0&&!(r.value[p]??"").trim()}return(p,v)=>(e.openBlock(),e.createElementBlock("div",pn,[e.createElementVNode("span",vn,e.toDisplayString(t.messages.paramsTitle),1),e.createElementVNode("div",gn,[(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":u(d.def.field)}])},[e.createElementVNode("span",hn,[e.createTextVNode(e.toDisplayString(d.label),1),d.def.required?(e.openBlock(),e.createElementBlock("i",wn,"*")):e.createCommentVNode("",!0)]),(d.def.type??"text")==="select"?(e.openBlock(),e.createElementBlock("select",{key:0,class:"mrp-param-input",value:d.value,onChange:m=>i(d.def.field,m.target.value),onKeydown:v[0]||(v[0]=e.withKeys(m=>p.$emit("query"),["enter"]))},[e.createElementVNode("option",bn,e.toDisplayString(d.def.placeholder??`请选择${d.label}`),1),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(d.def.options??[],m=>(e.openBlock(),e.createElementBlock("option",{key:m.value,value:m.value},e.toDisplayString(m.label),9,xn))),128))],40,yn)):(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:m=>i(d.def.field,m.target.value),onKeydown:v[1]||(v[1]=e.withKeys(m=>p.$emit("query"),["enter"]))},null,40,En))],2))),128))]),e.createElementVNode("div",Pn,[e.createElementVNode("button",{class:"mrp-nav mrp-param-query",type:"button",onClick:v[2]||(v[2]=d=>p.$emit("query"))},e.toDisplayString(t.messages.query),1),e.createElementVNode("button",{class:"mrp-nav",type:"button",onClick:v[3]||(v[3]=d=>p.$emit("reset"))},e.toDisplayString(t.messages.reset),1)])]))}}),mt=Ke(kn,[["__scopeId","data-v-aafce92d"]]),pt={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:"搜索中…"},vt={shellBg:"#525659",shellFg:"#e8e8e8",toolbarBg:"#323639",toolbarBorder:"#22252a",toolbarFg:"#e8e8e8",btnFg:"#cfcfcf",btnBorder:"#4a4d52",btnHoverBg:"#414549",btnHoverFg:"#ffffff",btnActiveBg:"#2d5fb8"};function gt(t={}){return{...t,defaults:t.defaults??{},presets:t.presets??{}}}function $n(t){return t}const te={showExport:!0,showPrint:!0,showPdfWindow:!0,showParams:!0,gapPx:18,pdfFontUrl:"/simhei.ttf",logger:console},Cn={warn:()=>{},info:()=>{}};function $e(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 ht(t,n){const a=n?t?.presets?.[n]:t?.defaultPreset?t?.presets?.[t.defaultPreset]:void 0,l=$e(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:{...vt,...l.theme},messages:{...pt,...l.messages},logger:l.logger??te.logger,preview:{overscanPages:nt(l.preview?.overscanPages,1,10,!0),searchDebounceMs:nt(l.preview?.searchDebounceMs,200,2e3)},xlsx:{...l.xlsx}}}function nt(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 wt(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(se.MACH_REPORT_CONFIG_KEY,null),a=e.computed(()=>{const l=n?.value??null,r="defaults"in t||"presets"in t||"defaultPreset"in t?gt(t):{defaults:t,presets:{}};if(!l)return r;const o={...l.presets,...r.presets};for(const i of Object.keys(o))o[i]=$e($e(l.presets[i],r.defaults),r.presets[i]);return{defaults:$e(l.defaults,r.defaults),presets:o,defaultPreset:r.defaultPreset??l.defaultPreset}});e.provide(se.MACH_REPORT_CONFIG_KEY,a)}function yt(){return e.inject(se.MACH_REPORT_CONFIG_KEY,e.computed(()=>null))}const rt=new Map,ae=new Map,Sn=15e3;function Ae(t,n){return Object.assign(new Error(t),{cause:n})}function pe(t,n){return`PDF 字体 ${JSON.stringify(t)}:${n}。请部署支持报表文字的字体文件,并将 pdfFontUrl 配置为可访问的字体 URL;西文报表可设为空串`}function Se(t){if(t?.reason instanceof Error&&t.reason.name==="AbortError")return t.reason;const n=Ae("PDF 字体检查已取消",t?.reason);return n.name="AbortError",n}async function Mn(t,n){let a=!1;const l=setTimeout(()=>{a=!0,n.abort()},Sn);try{const r=await fetch(t,{method:"HEAD",signal:n.signal});if(n.signal.aborted)throw Se(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 i=new Error(`字体请求返回 HTTP ${r.status}`);return{status:"error",fontUrl:t,message:pe(t,i.message),cause:i}}const o=r.headers.get("content-type")??"";if(/text\/html|application\/xhtml\+xml/i.test(o)){const i=new Error("字体 URL 返回 HTML 页面(可能是 SPA 路由回退),不是字体文件");return{status:"error",fontUrl:t,message:pe(t,i.message),cause:i}}if(/^text\//i.test(o)||/(?:\/|\+)json(?:\s*;|$)/i.test(o)){const i=new Error(`字体 URL 返回 ${o} 文本响应,不是字体文件`);return{status:"error",fontUrl:t,message:pe(t,i.message),cause:i}}return{status:"available",fontUrl:t,message:"PDF 字体资源可达;文字覆盖范围将在实际导出时校验"}}catch(r){if(n.signal.aborted&&!a)throw Se(n.signal);return{status:"error",fontUrl:t,message:pe(t,a?"字体检查超时,请检查网络或字体服务":"字体检查失败,请检查网络、字体服务或跨域访问配置"),cause:r}}finally{clearTimeout(l)}}function Rn(t,n){if(n?.aborted)return Promise.reject(Se(n));if(!t)return Promise.resolve({status:"disabled",fontUrl:t,message:"已停用自定义 PDF 字体;内置字体用于西文,其他文字会在导出时校验"});const a=rt.get(t);if(a)return Promise.resolve(a);let l=ae.get(t);if(!l){const o=new AbortController;l={controller:o,promise:Mn(t,o),subscribers:0};const i=l;ae.set(t,i),i.promise=i.promise.then(u=>(!o.signal.aborted&&u.status==="available"&&rt.set(t,u),u)).finally(()=>{ae.get(t)===i&&ae.delete(t)})}const r=l;return r.subscribers++,new Promise((o,i)=>{let u=!1;const p=()=>u?!1:(u=!0,r.subscribers--,n?.removeEventListener("abort",v),!0),v=()=>{p()&&(r.subscribers===0&&(ae.get(t)===r&&ae.delete(t),r.controller.abort()),i(Se(n)))};n?.addEventListener("abort",v,{once:!0}),r.promise.then(d=>{p()&&o(d)},d=>{p()&&i(d)}),n?.aborted&&v()})}function bt(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(m){const h=m instanceof Error?m.message:String(m);throw Ae(pe(t.fontUrl,h),m)}let i;try{i=await n.renderPlanToPdf(l,o?{customFontBytes:o}:{})}catch(m){if(!o)throw m;const h=m instanceof Error?m.message:String(m);throw Ae(`PDF 生成失败:${h}。当前字体 URL 为 ${JSON.stringify(t.fontUrl)};请确认该文件是有效字体,或重新配置 pdfFontUrl`,m)}const{bytes:u,unsupportedTextCount:p,pageErrors:v,fidelityWarnings:d}=i;if(p>0)throw new Error(`PDF 中有 ${p} 行文字无法编码;请部署支持所用文字的字体并配置 pdfFontUrl`);if(v.length>0)throw new Error(`PDF 有 ${v.length} 页渲染失败:${v[0]}`);return d.length>0&&r?.(`PDF 有 ${d.length} 处版式降级:${d.slice(0,2).join(";")}`),u};return a.checkFont=l=>Rn(t.fontUrl,l),a}class ne extends Error{constructor(n,a,l){super(a),this.name="MachReportError",this.code=n,this.cause=l}}function xt(t){return t instanceof ne?{code:t.code,cause:t.cause}:{code:"render",cause:t}}const Fn={key:2,class:"mrp-export-notice mrp-export-warning",role:"status"},Tn={class:"mrp-main"},Dn={key:0,class:"mrp-state"},Nn={key:1,class:"mrp-state mrp-error"},Vn={key:2,class:"mrp-state"},In=["data-page"],On=["onClick"],zn=["data-thumb"],Wn={class:"mrp-thumb-no"},Ln={class:"mrp-overlay"},An={key:3,class:"mrp-debug","aria-hidden":"true"},Ee=96/25.4,ot="mach-report:ui",at="mach-report:ui:wide",Hn=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=>({v5d32312f:C.value+"px"}));const l=t,r=a,o=e.shallowRef(null),i=e.ref(!1),u=e.ref(""),p=e.shallowRef(null),v=e.ref(null),d=e.ref(!1),m=e.shallowRef(Object.freeze({status:"unchecked",fontUrl:""})),h=e.ref(null),g=e.ref(1),F=e.ref(null),R=e.ref(null),y=e.ref(null),B=e.ref(!1),E=tn(),M=e.computed(()=>!!o.value?.pages.length&&o.value.pages.every(c=>c.layout==="wide")),C=e.computed(()=>Math.max(0,W.value));let P=ot;const N=e.inject(se.MACH_REPORT_FETCHER_KEY,null),I=e.inject(se.MACH_REPORT_PDF_EXPORTER_KEY,null),V=e.computed(()=>He(l.reportId)),L=e.computed(()=>l.fetcher??N),S=e.computed(()=>o.value?.pages.length??0),Z=e.computed(()=>Object.freeze({loading:i.value,hasPlan:S.value>0,pageCount:S.value,currentPage:g.value,exporting:v.value,printing:d.value,canExport:!i.value&&S.value>0&&v.value===null,canPrint:!i.value&&S.value>0&&!d.value,error:p.value,pdfFont:m.value}));function K(c,w,b){p.value=Object.freeze({message:c,code:w,cause:b}),r("error",c,{code:w,cause:b})}const re=yt(),s=e.computed(()=>ht(re.value,l.preset)),f=e.computed(()=>({...s.value.messages,...l.messages})),x=e.computed(()=>l.showExport??s.value.showExport),k=e.computed(()=>l.showPrint??s.value.showPrint),$=e.computed(()=>l.showPdfWindow??s.value.showPdfWindow),W=e.computed(()=>l.gapPx??(M.value?0:s.value.gapPx)),H=e.computed(()=>l.showParams??s.value.showParams);let q=null,Me=null;function Ge(){if(I)return I;const c=s.value.pdfFontUrl;return(!Me||q!==c)&&(q=c,Me=bt({fontUrl:c})),Me}let ve=0,ie=null,ge=null,ce=!1;function Re(){ve++,ie?.abort(),ie=null}async function he(){if(ce)throw new ne("config","报表预览已卸载");Re();const c=ve,w=new AbortController;ie=w;const b=s.value.pdfFontUrl;m.value=Object.freeze({status:"checking",fontUrl:b});try{const O=Ge(),z=O.checkFont?await O.checkFont(w.signal):{status:"unverified",fontUrl:"",message:"自定义 PDF 导出器未提供字体预检查;字体由宿主确认"};return!ce&&c===ve&&!w.signal.aborted&&(m.value=Object.freeze({...z})),z}catch(O){if(w.signal.aborted)throw O;const z={status:"error",fontUrl:b,message:O instanceof Error?O.message:"PDF 字体检查失败",cause:O};return!ce&&c===ve&&(m.value=Object.freeze(z)),z}finally{ie===w&&(ie=null)}}function Pt(){he().catch(()=>{})}e.watch([o,()=>s.value.pdfFontUrl,x,$],()=>{const c=m.value.fontUrl===s.value.pdfFontUrl;Re(),(!c||m.value.status==="checking")&&(m.value=Object.freeze({status:"unchecked",fontUrl:s.value.pdfFontUrl})),!ce&&S.value>0&&(x.value||$.value)&&he().catch(()=>{})},{immediate:!0});const J=e.computed(()=>l.paramDefs??L.value?.getParamDefs?.(V.value)??[]),_=e.ref({}),Fe=e.ref(!1);function ue(c){const w={};for(const b of c)w[b.field]=l.params[b.field]??b.defaultValue??"";_.value=w,Fe.value=!1}ue(J.value),e.watch(J,c=>ue(c)),e.watch(V,()=>ue(J.value)),e.watch(()=>JSON.stringify(l.params),()=>ue(J.value));const kt=e.computed(()=>{const c={...l.params};for(const[w,b]of Object.entries(_.value))b===""?delete c[w]:c[w]=b;return c});function $t(){return J.value.filter(c=>c.required===!0&&!(_.value[c.field]??"").trim())}function Ct(){Fe.value=!0;const c=$t();if(c.length>0){const w=c[0].label??c[0].field,b=f.value.paramRequired.replace("{label}",w);u.value=b,K(b,"param");return}ee()}function Bt(){ue(J.value)}const St=e.computed(()=>({height:l.height,...wt(s.value.theme)})),{zoom:A,zoomMode:de,applyFitZoom:Ye,setZoom:fe}=it(()=>({viewport:R.value,pageWidthPx:Te.contentSize.value.w||210*Ee})),Te=st(o,A,{pxPerMm:Ee,gapPx:W,overscan:e.computed(()=>s.value.preview.overscanPages)}),{contentSize:De,windowRange:me,visiblePages:Ze,makeScrollHandler:Mt,refreshViewport:Ne}=Te,Rt=Mt(g,S);function Ve(c){fe(c*100)}function we(){Ft(),o.value=null,g.value=1,T.reset()}let X=0,G=null;async function ee(){const c=++X;G?.abort(),G=null;const w=L.value;if(i.value=!1,p.value=null,V.value.length===0){u.value="缺少报表 ID",we(),K(u.value,"param");return}if(!w){u.value="未提供渲染数据源 fetcher",we(),K(u.value,"config");return}i.value=!0,u.value="",h.value=null,we();const b=E.start(),O=new AbortController;G=O;const z=new Set;function be(D){c!==X||O.signal.aborted||z.has(D)||(z.add(D),s.value.logger.warn("[mach-report] 报表告警:",D),r("warning",D))}try{const D=await w({reportIds:V.value,params:{...kt.value},signal:O.signal,onWarning:be});if(c!==X)return;const j=le.validateRenderPlan(D);if(!j.ok){const xe=j.errors.slice(0,3).map(_e=>`${_e.path}: ${_e.message}`).join("; ");throw new ne("validate",`渲染计划校验失败(${j.errors.length} 处): ${xe}`)}if(j.warnings.forEach(xe=>be(`${xe.path}: ${xe.message}`)),c!==X||O.signal.aborted)return;o.value=D,g.value=1,E.end(b),R.value&&(R.value.scrollTop=0,R.value.scrollLeft=0);const Q=M.value?at:ot;Q!==P&&(P=Q,Qe()),de.value==="fit"&&Ye(),r("loaded",D.pages.length)}catch(D){if(c!==X)return;const j=D instanceof ne?D:D instanceof le.ReportSourceError?new ne(D.code,D.message,D.cause):new ne("fetch",D instanceof Error?D.message:"预览加载失败",D);u.value=j.message;const Q=xt(j);K(j.message,Q.code,Q.cause)}finally{c===X&&(i.value=!1),G===O&&(G=null)}}function Y(c){if(S.value<=0)return;const w=Math.max(1,Math.min(S.value,c));g.value=w;const b=R.value;b&&(b.scrollTop=Te.pageOffsetPx(w-1)*A.value,Ne(b))}const ye=ut(o,{getPdfExporter:Ge,getXlsxOptions:()=>s.value.xlsx,onError:(c,w)=>{h.value={kind:"error",message:c},K(c,w??"print")},onWarning:c=>{h.value={kind:"warning",message:c},r("warning",c)},onBusy:c=>{v.value=c,c?h.value={kind:"progress",message:f.value.exporting.replace("{format}",c)}:h.value?.kind==="progress"&&(h.value=null)},onPrinting:c=>{d.value=c}}),{releasePrintFrame:Ft,dispose:Tt}=ye;async function Ie(){p.value=null,await ye.print()}async function Oe(c){p.value=null,await ye.exportAs(c)}function ze(){p.value=null,ye.openPdfWindow()}async function Je(c,w={}){_.value={..._.value,...c},w.reload!==!1&&await ee()}const Dt={reload:ee,print:Ie,exportAs:Oe,openPdfWindow:ze,gotoPage:Y,setParams:Je,checkPdfFont:he,get state(){return Z.value}};e.provide(se.MACH_REPORT_CONTROLLER_KEY,Dt);const T=Qt({plan:o,gotoPage:Y,debounceMs:e.computed(()=>s.value.preview.searchDebounceMs),highlight:Yt,clearHighlights:Gt});function Nt(c){c.ctrlKey&&(c.preventDefault(),Ve(A.value*(c.deltaY<0?1.1:1/1.1)))}function Vt(c){if((c.ctrlKey||c.metaKey)&&c.key.toLowerCase()==="f"){c.preventDefault(),T.visible.value||T.toggle();return}switch(c.key){case"PageDown":c.preventDefault(),Y(g.value+1);break;case"PageUp":c.preventDefault(),Y(g.value-1);break;case"Home":c.preventDefault(),Y(1);break;case"End":c.preventDefault(),Y(S.value);break;case"+":case"=":c.preventDefault(),Ve(A.value*1.1);break;case"-":c.preventDefault(),Ve(A.value/1.1);break}}function It(){try{localStorage.setItem(P,JSON.stringify({zoomMode:de.value==="fit"?"fit":Math.round(A.value*100)}))}catch{}}e.watch([de,A],It);let We="";function Xe(c=!1){const w=T.activeMatch.value;if(!M.value||!w)return;const b=`${T.query.value}:${T.matchIndex.value}:${w.pageIndex}`;if(!c&&b===We)return;const z=F.value?.querySelector(`[data-page="${w.pageIndex+1}"]`)?.querySelectorAll("mark.mrp-hit")[w.occurrence];z&&(z.scrollIntoView?.({block:"nearest",inline:"nearest"}),We=b)}e.watchEffect(()=>{const c=o.value;if(!c)return;const w=T.activeMatch.value;T.matchIndex.value,w||(We=""),Ze.value;const b=F.value;if(!b)return;b.querySelectorAll(".mrp-page-holder").forEach(z=>{const be=Number(z.dataset.page??0)-1,D=c.pages[be];if(!D||z.childElementCount>0){if(z.firstElementChild){const Q=z.firstElementChild;T.clear(Q),T.apply(Q)}return}z.style.width=`${D.pageWidthMm*Ee}px`;const j=le.renderPage(D,96,{},document);T.apply(j),z.appendChild(j)}),Xe()},{flush:"post"}),e.watch(()=>T.query.value,c=>{c||F.value?.querySelectorAll(".mrp-page-holder").forEach(w=>{T.clear(w)})});const U=en(o,{thumbsRoot:y,visible:B,renderThumbCanvas:c=>{try{const w=o.value.pages[c],b=Math.min(.2,116/Math.max(1,w.pageWidthMm*Ee)),{canvases:O}=le.renderPlanToCanvas(o.value,{start:c,end:c,dpr:b});return O[0]??null}catch{return null}}});e.watchEffect(()=>{U.schedule()},{flush:"post"});const Ot=e.computed(()=>l.debug),{debugStats:oe}=_t(Ot,{plan:o,pageCount:S,windowRange:me,zoom:A,loadMs:E.loadMs});function Le(){Ne(R.value),U.schedule(),de.value==="fit"&&Ye(),Xe(!0)}function Qe(){fe(P===at?100:"fit");try{const c=JSON.parse(localStorage.getItem(P)??"{}");c.zoomMode==="fit"?fe("fit"):typeof c.zoomMode=="number"&&fe(c.zoomMode)}catch{}}return e.onMounted(()=>{window.addEventListener("resize",Le),typeof ResizeObserver<"u"&&R.value&&(ge=new ResizeObserver(Le),ge.observe(R.value)),Ne(R.value),Qe(),l.autoLoad&&ee()}),e.onUnmounted(()=>{ce=!0,Re(),X++,G?.abort(),G=null,window.removeEventListener("resize",Le),ge?.disconnect(),ge=null,U.destroy(),T.reset(),Tt()}),e.watch(()=>[JSON.stringify(V.value),JSON.stringify(l.params),L.value],()=>{if(l.autoLoad){ee();return}X++,G?.abort(),G=null,i.value=!1,u.value="",p.value=null,h.value=null,we()}),n({reload:ee,print:Ie,exportAs:Oe,openPdfWindow:ze,gotoPage:Y,setParams:Je,checkPdfFont:he,state:Z}),(c,w)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["mach-report-preview",{"mrp-wide-report":M.value}]),style:e.normalizeStyle(St.value)},[H.value&&J.value.length>0?(e.openBlock(),e.createBlock(mt,{key:0,defs:J.value,modelValue:_.value,"onUpdate:modelValue":w[0]||(w[0]=b=>_.value=b),messages:f.value,attempted:Fe.value,onQuery:Ct,onReset:Bt},null,8,["defs","modelValue","messages","attempted"])):e.createCommentVNode("",!0),e.createVNode(ft,{"page-count":S.value,"current-page":g.value,"zoom-mode":e.unref(de),zoom:e.unref(A),"show-export":x.value,"show-print":k.value,"show-pdf-window":$.value,messages:f.value,search:{visible:e.unref(T).visible.value,query:e.unref(T).query.value,matchIndex:e.unref(T).matchIndex.value,matchCount:e.unref(T).matchCount.value,searching:e.unref(T).searching.value},"thumbs-visible":B.value,onGoto:Y,onZoom:e.unref(fe),onExport:w[1]||(w[1]=b=>Oe(b)),onPrint:Ie,onPdfWindow:ze,onSearchInput:e.unref(T).onInput,onSearchNav:e.unref(T).onNav,onSearchToggle:e.unref(T).toggle,onThumbsToggle:w[2]||(w[2]=b=>B.value=!B.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),m.value.status==="error"&&(x.value||$.value)?(e.openBlock(),e.createElementBlock("div",Fn,[e.createTextVNode(e.toDisplayString(f.value.pdfFontUnavailable)+" ",1),e.createElementVNode("button",{type:"button",onClick:Pt},e.toDisplayString(f.value.retry),1)])):e.createCommentVNode("",!0),e.createElementVNode("div",Tn,[e.createElementVNode("div",{ref_key:"viewportRef",ref:R,class:"mrp-body",tabindex:"0",onWheel:Nt,onKeydown:Vt,onScrollPassive:w[3]||(w[3]=b=>e.unref(Rt)(b.target))},[i.value?(e.openBlock(),e.createElementBlock("div",Dn,e.toDisplayString(f.value.loading),1)):u.value?(e.openBlock(),e.createElementBlock("div",Nn,[e.createTextVNode(e.toDisplayString(u.value)+" ",1),e.createElementVNode("button",{class:"mrp-retry",type:"button",onClick:ee},e.toDisplayString(f.value.retry),1)])):!o.value||S.value===0?(e.openBlock(),e.createElementBlock("div",Vn,e.toDisplayString(f.value.empty),1)):(e.openBlock(),e.createElementBlock("div",{key:3,class:"mrp-scale",style:e.normalizeStyle({width:`${e.unref(De).w*e.unref(A)}px`,height:`${e.unref(De).h*e.unref(A)}px`})},[e.createElementVNode("div",{ref_key:"containerRef",ref:F,class:"mrp-scale-inner",style:e.normalizeStyle({transform:`scale(${e.unref(A)})`,transformOrigin:"top left",width:`${e.unref(De).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(Ze),b=>(e.openBlock(),e.createElementBlock("div",{key:b.index,class:"mrp-page-holder","data-page":b.index+1},null,8,In))),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),B.value&&S.value>0?(e.openBlock(),e.createElementBlock("aside",{key:0,ref_key:"thumbsRef",ref:y,class:"mrp-thumbs",onScrollPassive:w[4]||(w[4]=(...b)=>e.unref(U).onScroll&&e.unref(U).onScroll(...b))},[e.unref(U).windowRange.value.padTopPx>0?(e.openBlock(),e.createElementBlock("div",{key:0,class:"mrp-thumb-spacer",style:e.normalizeStyle({height:`${e.unref(U).windowRange.value.padTopPx}px`}),"aria-hidden":"true"},null,4)):e.createCommentVNode("",!0),(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(e.unref(U).visibleThumbs.value,b=>(e.openBlock(),e.createElementBlock("div",{key:b.index,class:e.normalizeClass(["mrp-thumb",{"mrp-thumb-active":b.index+1===g.value}]),style:e.normalizeStyle({height:`${b.height+20}px`}),onClick:O=>Y(b.index+1)},[e.createElementVNode("div",{class:"mrp-thumb-box","data-thumb":b.index+1,style:e.normalizeStyle({height:`${b.height}px`})},null,12,zn),e.createElementVNode("span",Wn,e.toDisplayString(b.index+1),1)],14,On))),128)),e.unref(U).windowRange.value.padBottomPx>0?(e.openBlock(),e.createElementBlock("div",{key:1,class:"mrp-thumb-spacer",style:e.normalizeStyle({height:`${e.unref(U).windowRange.value.padBottomPx}px`}),"aria-hidden":"true"},null,4)):e.createCommentVNode("",!0)],544)):e.createCommentVNode("",!0)]),e.createElementVNode("div",Ln,[e.renderSlot(c.$slots,"default",{},void 0,!0)]),e.unref(oe)?(e.openBlock(),e.createElementBlock("div",An,[w[5]||(w[5]=e.createElementVNode("div",null,"mach-report debug",-1)),e.createElementVNode("div",null,"pages: "+e.toDisplayString(e.unref(oe).pages)+" | window: ["+e.toDisplayString(e.unref(oe).window)+"]",1),e.createElementVNode("div",null,"zoom: "+e.toDisplayString(e.unref(oe).zoom)+" | load: "+e.toDisplayString(e.unref(oe).loadMs),1),e.createElementVNode("div",null,"plan: "+e.toDisplayString(e.unref(oe).planKB)+"KB",1)])):e.createCommentVNode("",!0)],6))}}),Et=Ke(Hn,[["__scopeId","data-v-449298a6"]]),qn=Object.freeze(Object.defineProperty({__proto__:null,default:Et},Symbol.toStringTag,{value:"Module"}));exports.DEFAULT_MESSAGES=pt;exports.DEFAULT_THEME=vt;exports.MachReportError=ne;exports.PlanLoadError=Pe;exports.ReportParamPanel=mt;exports.ReportPreview=Et;exports.ReportPreview$1=qn;exports.ReportToolbar=ft;exports.SILENT_LOGGER=Cn;exports.buildPrintDocument=Ue;exports.buildWordHtml=ct;exports.createDefaultPdfExporter=bt;exports.createFetchRequest=Ut;exports.defineMachReportConfig=gt;exports.defineMachReportPreset=$n;exports.joinReportIds=jt;exports.normalizeReportIds=He;exports.printPlans=Kt;exports.provideMachReportConfig=Bn;exports.resolveConfig=ht;exports.themeToCssVars=wt;exports.toErrorDetail=xt;exports.useMachReportConfig=yt;exports.usePageWindow=st;exports.usePrintExport=ut;exports.useZoom=it;