@agile-team/mach-report 2.8.3 → 2.9.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 +28 -10
- package/dist/ExcelBindingWizard-DiaxvWpQ.cjs +1 -0
- package/dist/ExcelBindingWizard-RLJIXKKG.js +816 -0
- package/dist/{ReportPreview-DRBAUkxj.js → ReportPreview-B5ZNEasW.js} +23 -22
- package/dist/ReportPreview-DRtVPUYo.cjs +6 -0
- package/dist/RuleEditor-N4qnMZ-Z.cjs +1 -0
- package/dist/RuleEditor-ynnUEK0s.js +1575 -0
- package/dist/TemplateReviewPanel-C_Lmzis6.cjs +1 -0
- package/dist/TemplateReviewPanel-Cn32OY4_.js +173 -0
- package/dist/{_plugin-vue_export-helper-DPbiz14D.js → _plugin-vue_export-helper-8SL1F89S.js} +2 -2
- package/dist/analytics.cjs +1 -1
- package/dist/analytics.d.cts +188 -5
- package/dist/analytics.d.ts +188 -5
- package/dist/analytics.js +68 -202
- package/dist/{assets-B9qJku3V.js → assets-DDsfEi8R.js} +3 -3
- package/dist/{assets-RZan7EyL.cjs → assets-ahTRUXRk.cjs} +1 -1
- package/dist/binding-preview-B5834rml.cjs +2 -0
- package/dist/binding-preview-ChXjN5L5.js +649 -0
- package/dist/{capabilities-joSutDF8.js → capabilities-Cm9hZ3uV.js} +5 -5
- package/dist/{capabilities-xGTpnPjJ.cjs → capabilities-DYzWL7KS.cjs} +1 -1
- package/dist/dataset-BkRmwgeJ.cjs +1 -0
- package/dist/dataset-H5pFuQGU.js +121 -0
- package/dist/defaults-DXhiM1ZD.js +10 -0
- package/dist/defaults-xhmcLLrf.cjs +1 -0
- package/dist/designer.cjs +2 -1
- package/dist/designer.d.cts +1391 -6
- package/dist/designer.d.ts +1391 -6
- package/dist/designer.js +2636 -673
- package/dist/grid-geometry-BNptEcMm.js +65 -0
- package/dist/grid-geometry-CZ_cYB6O.cjs +1 -0
- package/dist/import-template-CNMLJSQw.js +23030 -0
- package/dist/import-template-CpxunKVp.cjs +29 -0
- package/dist/index.cjs +7 -7
- package/dist/index.d.cts +202 -3
- package/dist/index.d.ts +202 -3
- package/dist/index.js +554 -535
- package/dist/matrix-CNPDJxED.js +745 -0
- package/dist/matrix-Div9Ilh3.cjs +1 -0
- package/dist/pdf.cjs +46 -46
- package/dist/pdf.d.cts +2 -0
- package/dist/pdf.d.ts +2 -0
- package/dist/pdf.js +17 -16
- package/dist/{plugin-BurDDMcd.js → plugin-BWwIgZXV.js} +1 -1
- package/dist/{plugin-DSFu51Ua.cjs → plugin-Dg-J1Rbm.cjs} +1 -1
- package/dist/progress-7OSZbFok.js +39 -0
- package/dist/progress-BnLiS5eH.cjs +1 -0
- package/dist/render-plan-7xpGrCEl.cjs +1 -0
- package/dist/render-plan-Ck6koX9L.js +13 -0
- package/dist/server/node.d.cts +62 -0
- package/dist/server/node.d.ts +62 -0
- package/dist/server-node.cjs +1 -1
- package/dist/server-node.js +373 -145
- package/dist/server.cjs +1 -1
- package/dist/server.d.cts +311 -0
- package/dist/server.d.ts +311 -0
- package/dist/server.js +590 -186
- package/dist/{style-Dv5o_x6b.js → style-CQ1PK8ZB.js} +5 -5
- package/dist/style-UgIJSA1F.cjs +1 -0
- package/dist/style.css +1 -1
- package/dist/template-registry-CHMYZ7SD.cjs +1 -0
- package/dist/template-registry-R61AMCr0.js +433 -0
- package/dist/template-review-hvWWQFsi.js +1027 -0
- package/dist/template-review-jEcOfmGr.cjs +1 -0
- package/dist/textwrap-CWHyzkBH.cjs +4 -0
- package/dist/{textwrap-DOl04hCQ.js → textwrap-DE1kgcJB.js} +1 -1
- package/dist/{validate-DfHPD8wX.cjs → validate-BDiMqkJC.cjs} +1 -1
- package/dist/{validate-S6CgIm5d.js → validate-DWPF7icl.js} +13 -13
- package/dist/vue/async.d.cts +186 -0
- package/dist/vue/async.d.ts +186 -0
- package/dist/vue/index.d.cts +271 -3
- package/dist/vue/index.d.ts +271 -3
- 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/worker.cjs +1 -1
- package/dist/worker.d.cts +2 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.js +1 -1
- package/dist/xlsx.cjs +2 -30
- package/dist/xlsx.d.cts +268 -0
- package/dist/xlsx.d.ts +268 -0
- package/dist/xlsx.js +220 -23440
- package/package.json +1 -1
- package/dist/ReportPreview-DjGeWHY-.cjs +0 -6
- package/dist/progress-DD964VAB.js +0 -102
- package/dist/progress-KvhwXZ1Q.cjs +0 -1
- package/dist/render-plan-CckPEQyf.cjs +0 -1
- package/dist/render-plan-uzZYYSy1.js +0 -19
- package/dist/report-source-BXHNy_AD.js +0 -755
- package/dist/report-source-CCAvFE3t.cjs +0 -1
- package/dist/style-CpwiOPyB.cjs +0 -1
- package/dist/template-registry-DWExx0gU.cjs +0 -1
- package/dist/template-registry-NpOakidD.js +0 -354
- package/dist/textwrap-CnGsEum6.cjs +0 -4
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const T=require("./render-plan-CckPEQyf.cjs"),A=require("./textwrap-CnGsEum6.cjs"),x=require("./style-CpwiOPyB.cjs"),ae=require("./validate-DfHPD8wX.cjs"),ie=require("./report-params-CjWrjPl6.cjs"),B=require("./template-registry-DWExx0gU.cjs"),j=require("./param-validation-CiTxFeZ8.cjs"),se=require("./task-events-DQ276fn2.cjs");function K(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 r=t??2;return`0${r?`.${"0".repeat(r)}`:""}%`}return t===void 0?e.thousands?"#,##0.###############":void 0:`${e.thousands?"#,##0":"0"}${t?`.${"0".repeat(t)}`:""}`}}function Y(e){const t=/^(\d{4})[-/](\d{1,2})[-/](\d{1,2})$/.exec(e.trim());if(t){const n=new Date(Number(t[1]),Number(t[2])-1,Number(t[3]));return Number.isNaN(n.getTime())?null:n}const r=new Date(e);return Number.isNaN(r.getTime())?null:r}function I(e,t){return e.toLocaleString("en-US",{minimumFractionDigits:t,maximumFractionDigits:t})}function me(e,t){const r=n=>String(n).padStart(2,"0");return t.replace(/YYYY/g,String(e.getFullYear())).replace(/MM/g,r(e.getMonth()+1)).replace(/DD/g,r(e.getDate())).replace(/hh/g,r(e.getHours())).replace(/mm/g,r(e.getMinutes())).replace(/ss/g,r(e.getSeconds()))}function ce(e,t,r){return r!=null?t?I(e,r):e.toFixed(r):t?I(e):String(e)}function F(e){const t=typeof e=="number"?e:Number(String(e).replace(/,/g,""));return Number.isFinite(t)?t:null}function q(e,t){if(e==null||e===""||!t)return String(e??"");switch(t.kind){case"number":{const r=F(e);return r==null?String(e):ce(r,t.thousands===!0,t.digits)}case"percent":{const r=F(e);return r==null?String(e):`${I(r*100,t.digits??2)}%`}case"date":{const r=t.pattern??"YYYY-MM-DD",n=e instanceof Date?e:Y(String(e));return n?me(n,r):String(e)}default:return String(e)}}function V(e,t){const r=e[t.field];if(r==null||r==="")return!1;if(typeof t.value=="number"){const i=F(r);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 n=String(r),o=String(t.value);switch(t.op){case"==":return n===o;case"!=":return n!==o;case">":return n>o;case">=":return n>=o;case"<":return n<o;case"<=":return n<=o}return!1}const ue=["text","number","boolean","date","decimal"],le=new Set(["__proto__","prototype","constructor"]);function v(e){throw new Error(`数据契约无效:${e}`)}function J(e){(!e||!Array.isArray(e.fields)||!e.fields.length||e.fields.length>2048)&&v("fields 应包含 1–2048 个字段");const t=new Set;for(const r of e.fields)(!r||typeof r.field!="string"||!r.field.trim()||le.has(r.field)||t.has(r.field))&&v("字段名应安全、非空且唯一"),t.add(r.field),ue.includes(r.type)||v(`未知字段类型 ${r.type}`),he(r),fe(r),de(r);ge(e,t)}function de(e){e.enum!==void 0&&(!Array.isArray(e.enum)||!e.enum.length||e.enum.some(t=>!U(t,e.type)))&&v("enum 应为匹配字段类型的非空标量数组")}function ge(e,t){e.rowKey!==void 0&&((typeof e.rowKey!="string"||!e.rowKey.trim()||!t.has(e.rowKey))&&v("rowKey 应为引用已声明字段的非空字符串"),e.fields.find(r=>r.field===e.rowKey)?.type==="boolean"&&v("布尔字段不能作为业务主键"))}function fe(e){for(const t of["label","unit"])e[t]!==void 0&&typeof e[t]!="string"&&v(`${t} 应为字符串`);for(const t of["required","nullable"])e[t]!==void 0&&typeof e[t]!="boolean"&&v(`${t} 应为布尔值`);e.semanticRole!==void 0&&!["identifier","dimension","measure","date","text"].includes(e.semanticRole)&&v("未知字段语义")}function he(e){for(const t of["min","max","minLength","maxLength"]){const r=e[t];r!==void 0&&(!Number.isFinite(r)||t.includes("Length")&&(!Number.isInteger(r)||r<0))&&v(`${t} 无效`)}e.min!==void 0&&e.max!==void 0&&e.min>e.max&&v("min 不能超过 max"),e.minLength!==void 0&&e.maxLength!==void 0&&e.minLength>e.maxLength&&v("minLength 不能超过 maxLength"),e.type!=="number"&&(e.min!==void 0||e.max!==void 0)&&v("min/max 仅适用于 number,精确小数文本需业务校验"),["number","boolean"].includes(e.type)&&(e.minLength!==void 0||e.maxLength!==void 0)&&v("长度约束仅适用于文本类型")}function pe(e){const t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return!1;const r=Number(t[1]),n=Number(t[2]),o=Number(t[3]),i=r%4===0&&(r%100!==0||r%400===0);return r>0&&n>=1&&n<=12&&o>=1&&o<=[31,i?29:28,31,30,31,30,31,31,30,31,30,31][n-1]}function U(e,t){return t==="number"?typeof e=="number"&&Number.isFinite(e):t==="boolean"?typeof e=="boolean":typeof e!="string"?!1:t==="date"?pe(e):t==="decimal"?e.length<=1e4&&/^-?(?:0|[1-9]\d*)(?:\.\d+)?$/.test(e):!0}function ye(e,t){if(e==null)return t.required||e===null&&t.nullable===!1?{code:"required",message:"缺少必需字段值"}:void 0;if(!U(e,t.type))return{code:"type",message:`值应为 ${t.type},不会自动转换原始值`};if(t.enum&&!t.enum.includes(e))return{code:"enum",message:"值不在允许的枚举中"};if(typeof e=="number"&&(t.min!==void 0&&e<t.min||t.max!==void 0&&e>t.max))return{code:"range",message:"数值超出范围"};if(typeof e=="string"&&!we(e,t))return{code:"range",message:"文本长度超出范围"}}function we(e,t){if(t.minLength===void 0&&t.maxLength===void 0)return!0;let r=0;for(const n of e)r++;return(t.minLength===void 0||r>=t.minLength)&&(t.maxLength===void 0||r<=t.maxLength)}function D(e,t){const r=e??t;if(!Number.isInteger(r)||r<1)throw new Error("数据校验预算应为正整数");return r}function be(e,t,r){const n=Object.prototype.hasOwnProperty.call(e,t)?e[t]:void 0;if((typeof n!="string"||!n.trim())&&!(typeof n=="number"&&Number.isFinite(n)))return"业务主键应为非空字符串或有限数字";const o=JSON.stringify([typeof n,n]);if(r.has(o))return"业务主键重复";r.add(o)}function Q(e,t,r={}){J(t);const n=r.path??"$.rows",o=[],i=D(r.maxIssues,100);if(!Array.isArray(e))return{ok:!1,issues:[{code:"row",path:n,message:"数据集应为对象数组"}]};if(e.length>D(r.maxRows,1e5)||e.length*t.fields.length>D(r.maxCells,2e6))return{ok:!1,issues:[{code:"budget",path:n,message:"数据校验超出行数或单元格预算"}]};const a=new Set;for(let s=0;s<e.length&&o.length<i;s++){const d=e[s];if(!d||typeof d!="object"||Array.isArray(d)){o.push({code:"row",path:`${n}[${s}]`,rowIndex:s,message:"行应为对象"});continue}Me(d,t,s,n,a,o,i)}return{ok:o.length===0,issues:o}}function Me(e,t,r,n,o,i,a){for(const s of t.fields){if(i.length>=a)return;const d=ye(Object.prototype.hasOwnProperty.call(e,s.field)?e[s.field]:void 0,s);d&&i.push({...d,rowIndex:r,field:s.field,path:`${n}[${r}].${s.field}`})}if(t.rowKey&&i.length<a){const s=be(e,t.rowKey,o);s&&i.push({code:"row-key",path:`${n}[${r}].${t.rowKey}`,message:s,rowIndex:r,field:t.rowKey})}}function Se(e){return J(e),{$schema:"https://json-schema.org/draft/2020-12/schema",type:"array",items:{type:"object",properties:Object.fromEntries(e.fields.map(r=>[r.field,ve(r,r.field===e.rowKey)])),required:e.fields.filter(r=>r.required||r.field===e.rowKey).map(r=>r.field),additionalProperties:!0},...e.rowKey?{"x-report-rowKey":e.rowKey}:{}}}function ve(e,t){const r=!t&&e.nullable!==!1&&!e.required;return{type:r?[W(e.type),"null"]:W(e.type),...e.label?{title:e.label}:{},...e.type==="date"?{format:"date"}:{},...e.type==="decimal"?{pattern:"^-?(?:0|[1-9]\\d*)(?:\\.\\d+)?$"}:{},...e.enum?{enum:r?[...e.enum,null]:[...e.enum]}:{},...e.min===void 0?{}:{minimum:e.min},...e.max===void 0?{}:{maximum:e.max},...xe(e,t),...t&&e.type==="text"?{pattern:"\\S"}:{},...e.unit?{"x-report-unit":e.unit}:{},...e.semanticRole?{"x-report-semanticRole":e.semanticRole}:{}}}function xe(e,t){const r={};return(e.minLength!==void 0||t&&e.type!=="number")&&(r.minLength=Math.max(e.minLength??0,t?1:0)),e.type==="decimal"?r.maxLength=Math.min(e.maxLength??1e4,1e4):e.maxLength!==void 0&&(r.maxLength=e.maxLength),r}function W(e){return e==="text"||e==="date"||e==="decimal"?"string":e}class E extends Error{constructor(t,r){super(`报表页数超出上限 ${t}(至少 ${r} 页)`),this.limit=t,this.actual=r,this.code="page-limit",this.name="PaginatePageLimitError"}}function Pe(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.layout==="wide"?t.marginBottomMm:e.marginBottomMm??t.marginBottomMm)}function X(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 Z(e,t){let r=e.textMetrics.get(t);if(!r){const n=x.resolveFontSize(t).fontSizePt;r={measureOptions:{fontSizePt:n,fontFamily:t.fontFamily??T.DEFAULT_FONT_FAMILY,italic:t.italic,bold:t.bold,letterSpacingPt:t.letterSpacing},lineMm:n*(t.lineHeight??T.LINE_HEIGHT)*25.4/72},e.textMetrics.set(t,r)}return r}function ee(e,t,r){return r==="identifier"||r==="dimension"||r==="date"?"center":r==="measure"?"right":r==="text"?"left":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 ke(e){if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e}function Re(e,t){const r=e.fontSizePt??T.DEFAULT_FONT_PT,n=e.paddingMm??1,o=e.columns.map(m=>m.align??m.style?.align??e.align??"left"),i=e.columns.map((m,u)=>({...x.mergeComponentStyles({fontSize:r,verticalAlign:"middle"},m.style),align:o[u]==="auto"?"left":o[u]})),a=i.map((m,u)=>o[u]==="auto"?{left:m,center:{...m,align:"center"},right:{...m,align:"right"}}:void 0),s=e.columns.map((m,u)=>m.rules?.map(b=>{const P=a[u];if(P)return{left:x.mergeComponentStyles(P.left,b.style),center:x.mergeComponentStyles(P.center,b.style),right:x.mergeComponentStyles(P.right,b.style)};const k=x.mergeComponentStyles(i[u],b.style);return{left:k,center:k,right:k}})),d=e.columns.map(m=>{let u=x.mergeComponentStyles({fontSize:r,bold:e.headerBold??!0,align:"center",verticalAlign:"middle",backgroundColor:e.headerBackgroundColor},m.style);return e.headerAlign!==void 0&&(u.align=e.headerAlign),u=x.mergeComponentStyles(u,e.headerStyle),m.headerAlign!==void 0&&(u.align=m.headerAlign),x.mergeComponentStyles(u,m.headerStyle)}),f=e.columns.map(m=>m.header);let c=e.rowHeightMm??0;for(let m=0;m<f.length;m++){const u=d[m],b=x.resolveFontSize(u).fontSizePt,P=A.wrapText(f[m],e.columns[m].widthMm-n*2,{fontSizePt:b,fontFamily:u.fontFamily??T.DEFAULT_FONT_FAMILY,italic:u.italic,bold:u.bold,letterSpacingPt:u.letterSpacing},t),k=b*(u.lineHeight??T.LINE_HEIGHT)*25.4/72;c=Math.max(c,Math.max(P.length,1)*k+n*2)}const g=f.map((m,u)=>({text:m,style:d[u]})),w=e.border===!1?{borderTop:!1,borderRight:!1,borderBottom:!1,borderLeft:!1}:{borderBottom:!0,borderLeft:!0,borderRight:!0,borderTop:!0},p=e.columns.map(m=>m.widthMm),h=Te(e.headerGrid,p,{cells:[g],colWidthsMm:p,rowHeightsMm:[c],paddingMm:n});return{fontSizePt:r,paddingMm:n,cellStyles:i,autoStyles:a,ruleStyles:s,textMetrics:new WeakMap,numberFormats:e.columns.map(m=>K(m.format)),borderStyle:w,headerHeightMm:h.rowHeightsMm.reduce((m,u)=>m+u,0),headerGrid:h,colWidthsMm:p,columns:e.columns}}function Te(e,t,r){if(!e)return r;if(!e.cells.length)throw new Error("自定义列表表头至少需要一行");const n=e.rowHeightsMm??e.cells.map(()=>r.rowHeightsMm[0]);if(n.length!==e.cells.length||n.some(o=>!Number.isFinite(o)||o<=0))throw new Error("自定义列表表头行高无效");return{...e,colWidthsMm:t,rowHeightsMm:n}}function Le(e,t,r){const n=t.format?.kind==="number"||t.format?.kind==="percent";t.valueType!==void 0?e.valueType=t.valueType:n&&(e.valueType="number"),t.editable!==void 0&&(e.editable=t.editable),(typeof e.value=="number"||e.value==null)&&r!==void 0&&(e.numberFormat=r)}function z(e,t,r){const n=e.columns;let o=e.rowHeightFloorMm;const i=new Array(n.length);for(let a=0;a<n.length;a++){const s=n[a],d=t[s.field],f=e.autoStyles[a]?ee(d,s.format,s.semanticRole):"left";let c=e.autoStyles[a]?.[f]??e.cellStyles[a];if(s.rules)for(let u=0;u<s.rules.length;u++){const b=s.rules[u];if(V(t,b.when)){c=e.ruleStyles[a][u][f];break}}const g=s.format?q(d,s.format):X(d),w=Z(e,c),p=A.wrapText(g,s.widthMm-e.paddingMm*2,w.measureOptions,r);o=Math.max(o,p.length*w.lineMm+e.paddingMm*2);const h=ke(d),m={text:g,style:c};h!==void 0&&(m.value=h),Le(m,s,e.numberFormats[a]),i[a]=m}return{grid:{cells:[i],colWidthsMm:e.colWidthsMm,rowHeightsMm:[o],paddingMm:e.paddingMm},heightMm:o}}function*Ee(e,t){if(!t){for(const n of e)yield{kind:"row",row:n};return}const r=new Map;for(const n of e){const o=X(n[t.field]),i=r.get(o);i?i.push(n):r.set(o,[n])}for(const[n,o]of r){yield{kind:"groupHeader",label:(t.headerTemplate??"{value}").replace(/\{value\}/g,n),firstRow:o[0]};for(const i of o)yield{kind:"row",row:i};t.subtotal?.length&&(yield{kind:"subtotal",label:t.subtotalLabel??"小计",rows:o})}}function Ne(e,t){let r=0;for(const n of e){const o=typeof n[t]=="number"?n[t]:Number(n[t]);Number.isFinite(o)&&(r+=o)}return r}function te(e,t,r){return new Map(r.map(n=>{const o=e.find(a=>a.field===n)?.format??{kind:"number",thousands:!0},i=Ne(t,n);return[n,{text:q(i,o),value:i,numberFormat:K(o)}]}))}function re(e,t){const r=e.findIndex(n=>t.includes(n.field));return r>0?r:1}function C(e,t,r,n,o,i){const a=[],s=Math.max(1,Math.min(i,e.columns.length)),d=x.mergeComponentStyles({fontSize:e.fontSizePt},o);a.push({text:r,colSpan:s,style:{bold:!0,...d}});for(let g=s;g<e.columns.length;g++){const w=e.columns[g],p=n.get(w.field),h=e.autoStyles[g]?.[ee(p?.value,w.format)]??e.cellStyles[g];a.push({...p,text:p?.text??"",style:x.mergeComponentStyles(h,o)})}let f=e.rowHeightFloorMm,c=0;for(const g of a){let w=0;const p=c+(g.colSpan??1);for(;c<p;c++)w+=e.colWidthsMm[c]??0;const h=Z(e,g.style),m=A.wrapText(g.text??"",w-e.paddingMm*2,h.measureOptions,t);f=Math.max(f,m.length*h.lineMm+e.paddingMm*2)}return{grid:{cells:[a],colWidthsMm:e.colWidthsMm,rowHeightsMm:[f],paddingMm:e.paddingMm},heightMm:f}}function Fe(e,t,r){const{templatePage:n,current:o,warnings:i,nextId:a,pushCurrent:s}=r,d=()=>$e(n,o),f=o.marginTopMm,c={id:r.tableId,columnKeys:e.columns.map(l=>l.field),...e.layout===void 0?{}:{layout:e.layout},...e.title===void 0?{}:{title:e.title}};let g=0;const w={kind:"rect",leftMm:e.leftMm,topMm:0,widthMm:e.widthMm,heightMm:t.headerHeightMm,grid:t.headerGrid,nid:a("listh"),table:{...c,role:"header",rowIndex:-1},style:t.borderStyle},p=l=>o.components.push({...w,topMm:l});let h=e.topMm;p(h),h+=t.headerHeightMm+r.mmPerRow;function m(){const l=n.layout==="wide"?0:e.topMm;return e.headerEveryPage!==!1?l+t.headerHeightMm:n.layout==="wide"?0:f}function u(){const l=n.layout==="wide"?0:o.marginBottomMm;return n.heightMm-l-m()}function b(l){if(h+l<=d())return;s(),o.components=[],o.heightMm=n.heightMm,n.layout==="wide"&&(o.marginTopMm=0,o.marginBottomMm=0);const M=n.layout==="wide"?0:e.topMm;e.headerEveryPage!==!1?(p(M),h=M+t.headerHeightMm):h=n.layout==="wide"?0:f}function P(l,M,S,R){const L=u();l.heightMm>L&&i.push(`列表 ${e.id??e.dataset} 行高 ${l.heightMm.toFixed(2)}mm 超出单页可用高度 ${L.toFixed(2)}mm,预览与打印可能截断内容`),b(l.heightMm),o.components.push({kind:"rect",leftMm:e.leftMm,topMm:h,widthMm:e.widthMm,heightMm:l.heightMm,grid:l.grid,nid:a(M),table:{...c,role:S,rowIndex:g++,...R?{source:R}:{}},style:t.borderStyle}),h+=l.heightMm}function k(l){l<=u()&&b(l)}return{keepTogether:k,placeGridRow:P}}function Ae(e,t){if(!e.rowKey)return;const r=t[e.rowKey];if((typeof r!="string"||!r.trim())&&!(typeof r=="number"&&Number.isFinite(r)))throw new Error(`数据集 ${e.dataset} 的 ${e.rowKey} 应为稳定的字符串或有限数字主键`);const n=e.revisionField?t[e.revisionField]:void 0,o=e.sourceTokenField?t[e.sourceTokenField]:void 0;if(n!==void 0&&typeof n!="string"&&!(typeof n=="number"&&Number.isFinite(n)))throw new Error("业务修订号应为字符串或有限数字");if(o!==void 0&&typeof o!="string")throw new Error("来源令牌应为字符串");return{datasetId:e.dataset,rowKey:r,...n===void 0?{}:{revision:n},...o===void 0?{}:{sourceToken:o}}}function He(e,t){const r=new Map;if(!e.rowKey)return r;const n=new Set;for(const o of t){const i=Ae(e,o),a=JSON.stringify(i.rowKey);if(n.has(a))throw new Error(`数据集 ${e.dataset} 的业务主键重复:${String(i.rowKey)}`);n.add(a),r.set(o,i)}return r}function De(e,t,r,n,o){if(!e.grandTotal)return;const i=typeof e.grandTotal=="object"?e.grandTotal:void 0,a=i?.fields??e.groupBy?.subtotal??[];if(a.length===0){n.warnings.push(`列表 ${e.id??""} 配置了 grandTotal 但未提供合计字段(groupBy.subtotal 或 grandTotal.fields)`);return}const s=C(r,n.measurer,i?.label??"合计",te(e.columns,t,a),i?.style??{},re(e.columns,a));o.placeGridRow(s,"listgt","grand-total")}function Ie(e,t,r){const n=He(e,t),o=e.columns.reduce((c,g)=>c+g.widthMm,0),i=o>e.widthMm?e.widthMm/o:1,a=i===1?e:{...e,columns:e.columns.map(c=>({...c,widthMm:c.widthMm*i}))},s={...Re(a,r.measurer),rowHeightFloorMm:a.rowHeightMm??0},d=Fe(a,s,r);let f;for(const c of Ee(t,a.groupBy))if(c.kind==="row")d.placeGridRow(f??z(s,c.row,r.measurer),"listr","body",n.get(c.row)),f=void 0;else if(c.kind==="groupHeader"){const g=C(s,r.measurer,c.label,new Map,a.groupBy?.headerStyle??{},a.columns.length);f=z(s,c.firstRow,r.measurer),a.groupBy?.keepWithNext!==!1&&d.keepTogether(g.heightMm+f.heightMm),d.placeGridRow(g,"listg","group-header")}else{const g=a.groupBy?.subtotal??[],w=C(s,r.measurer,c.label,te(a.columns,c.rows,g),a.groupBy?.subtotalStyle??{},re(a.columns,g));d.placeGridRow(w,"listst","subtotal")}De(a,t,s,r,d)}function G(e){return e.kind==="text"&&typeof e.text=="string"&&(e.text.includes("{page}")||e.text.includes("{totalPages}"))}function Ce(e,t,r,n,o,i){const a={pageWidthMm:t.widthMm,pageHeightMm:t.heightMm,...e.layout===void 0?{}:{layout:e.layout},marginTopMm:t.marginTopMm,marginBottomMm:t.marginBottomMm,marginLeftMm:t.marginLeftMm,marginRightMm:t.marginRightMm,components:t.components};n.push(a);for(const s of r){const d={...s,text:String(s.text??"").replace(/\{page\}/g,String(n.length))};a.components.push(d),d.text.includes("{totalPages}")&&o.push(d)}if(e.layout==="wide"){const s=a.components.reduce((d,f)=>Math.max(d,f.topMm+f.heightMm),0);a.marginBottomMm=i?e.marginBottomMm??0:0,a.pageHeightMm=Math.max(1,s+a.marginBottomMm)}}function ne(e,t,r={}){const n=typeof r=="number"?{mmPerRow:r}:r;if(n.maxPages!==void 0&&(!Number.isSafeInteger(n.maxPages)||n.maxPages<1))throw new RangeError("maxPages 应为正安全整数");const o=[],i=[],a=[];let s=0;const d=f=>`${f}_${(++s).toString(36)}`;for(const[f,c]of e.pages.entries()){const g=Pe(c),w=c.components.filter(G),p=(h=!1)=>{if(n.maxPages!==void 0&&i.length>=n.maxPages)throw new E(n.maxPages,i.length+1);Ce(c,g,w,i,a,h)};for(const[h,m]of c.components.entries()){if(G(m))continue;if(m.kind!=="list"){g.components.push(m);continue}const u=t[m.dataset];Array.isArray(u)||o.push(`数据集 ${m.dataset} 未提供数据,列表 ${m.id??""} 输出为空`),Ie(m,Array.isArray(u)?u:[],{templatePage:c,current:g,warnings:o,nextId:d,pushCurrent:p,measurer:n.measurer??A.heuristicMeasurer,mmPerRow:n.mmPerRow??0,tableId:`table:${f}:${h}`})}p(!0)}for(const f of a)f.text=f.text.replace(/\{totalPages\}/g,String(i.length));return{plan:{schemaVersion:T.RENDER_PLAN_SCHEMA_VERSION,pages:i},warnings:o}}function Oe(e){if(!("mapData"in e))return e;const{load:t,mapData:r,...n}=e;return{...n,load:async o=>{const i=await t(o);$(o.signal);try{return r(i,o)}catch(a){throw new y("validate",`报表 ${o.reportId} 数据映射失败`,a)}}}}class y extends Error{constructor(t,r,n){super(r),this.name="ReportSourceError",this.code=t,this.cause=n}}function H(e){const t=new Error("报表加载已取消");return t.name="AbortError",Object.defineProperty(t,"cause",{value:e.reason}),t}function $(e){if(e?.aborted)throw H(e)}function O(e,t){return t?new Promise((r,n)=>{const o=()=>t.removeEventListener("abort",i),i=()=>{o(),n(H(t))};t.addEventListener("abort",i,{once:!0}),t.aborted&&i(),Promise.resolve(e).then(a=>{o(),r(a)},a=>{o(),n(a)})}):Promise.resolve(e)}function Ke(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new y("validate",`报表 ${t} 的数据集应为对象`);for(const[r,n]of Object.entries(e))if(!Array.isArray(n)||n.some(o=>!o||typeof o!="object"||Array.isArray(o)))throw new y("validate",`报表 ${t} 的数据集 ${r} 应为对象数组`)}async function qe(e,t,r){const{reportId:n,signal:o}=t;try{const i=await O(e(t),o);$(o);const a=B.validateReportTemplate(i);if(!a.ok)throw new y("validate",`报表 ${n} 模板校验失败:${a.errors.slice(0,3).map(s=>`${s.path}: ${s.message}`).join("; ")}`);return r.push(...a.warnings.map(s=>`${n}: ${s.path}: ${s.message}`)),i}catch(i){throw o?.aborted?H(o):i instanceof y?i:i instanceof B.ReportTemplateError?new y("validate",`报表 ${n} 模板校验失败:${i.message}`,i):new y("fetch",`报表 ${n} 模板加载失败:${i instanceof Error?i.message:String(i)}`,i)}}async function _e(e,t,r,n){const o=t.signal;let i;try{if(e.load)i=await O(e.load(t),o);else if(e.provider){const a=await O(e.provider.query(t),o);$(o),Be(a,r),i=a.datasets,n?.(r,a)}else i=e.datasets??{}}catch(a){throw o?.aborted?H(o):a instanceof y?a:new y("fetch",`报表 ${r} 取数失败:${a instanceof Error?a.message:String(a)}`,a)}return $(o),i}function Be(e,t){if(!e||typeof e!="object"||Array.isArray(e))throw new y("validate",`报表 ${t} Provider 应返回 datasets 结果对象`);for(const r of["revision","sourceToken"])if(e[r]!==void 0&&typeof e[r]!="string")throw new y("validate",`报表 ${t} Provider ${r} 应为字符串`);if(e.diagnostics!==void 0&&(!Array.isArray(e.diagnostics)||e.diagnostics.some(r=>!r||typeof r.code!="string"||typeof r.message!="string"||!["info","warning","error"].includes(r.severity))))throw new y("validate",`报表 ${t} Provider diagnostics 不符合结构化诊断契约`)}function je(e,t,r){for(const[n,o]of Object.entries(e.dataSchema??{})){let i;try{i=Q(Object.prototype.hasOwnProperty.call(t,n)?t[n]:void 0,o,{...e.dataValidation,path:`$.datasets.${n}`})}catch(a){throw new y("config",`报表 ${r} 数据集 ${n} 字段契约配置无效`,a)}if(!i.ok)throw new y("validate",`报表 ${r} 数据集 ${n} 不符合字段契约:${i.issues[0]?.message}`,{issues:i.issues})}}function We(e,t,r,n,o){const i=o?o.maxPages-o.usedPages:void 0;try{if(i!==void 0&&i<1&&e.pages.length)throw new E(0,1);const a=i===void 0?r.pagination:{...r.pagination,maxPages:Math.max(1,Math.min(i,r.pagination?.maxPages??i))};return ne(e,t,a)}catch(a){const s=a instanceof E&&o&&a.limit===i?new E(o.maxPages,o.usedPages+a.actual):a;throw new y("validate",`报表 ${n} 排版失败:${s instanceof Error?s.message:String(s)}`,s)}}function ze(e,t,r,n){const o=new Map,i=a=>{let s=o.get(a);return s===void 0&&(s=JSON.stringify([r,n,a]),o.set(a,s)),s};for(const a of t.pages)e.push({...a,components:a.components.map(s=>s.table?{...s,table:{...s.table,id:i(s.table.id)}}:s)})}function Ge(e,t={}){if(t.maxPages!==void 0&&(!Number.isSafeInteger(t.maxPages)||t.maxPages<1))throw new y("config","maxPages 应为正安全整数");function r(o){const i=Object.prototype.hasOwnProperty.call(e,o)?e[o]:void 0;if(!i)throw new y("config",`未注册报表 ${o}`);return i}return Object.assign(async({reportIds:o,params:i,signal:a,onWarning:s,onQueryResult:d,...f})=>{$(a);const c=se.createReportTaskReporter({...f,signal:a}),g=[...o],w={...i};if(g.length===0)throw new y("config","缺少报表 ID");const p=g.map(r),h=c.runSync("validate",()=>p.map(l=>j.assertReportParams(l.params??(typeof l.template=="function"?[]:l.template.params)??[],w))),m=[],u=[];for(const[l,M]of p.entries()){$(a);const S=g[l],R={reportId:S,params:h[l],signal:a},L=typeof M.template=="function"?await c.run("query",()=>qe(M.template,R,u),S):M.template;R.params=c.runSync("validate",()=>j.assertReportParams(M.params??L.params??[],R.params),S);const N=await c.run("query",()=>_e(M,R,S,d),S);c.runSync("validate",()=>{Ke(N,S),t.onDatasets?.(S,N,L),je(M,N,S)},S),$(a);const _=c.runSync("layout",()=>We(L,N,M,S,t.maxPages===void 0?void 0:{maxPages:t.maxPages,usedPages:m.length}),S);ze(m,_.plan,l,S),u.push(..._.warnings.map(oe=>`${S}: ${oe}`))}$(a);const b={schemaVersion:T.RENDER_PLAN_SCHEMA_VERSION,pages:m},P=c.runSync("validate",()=>{const l=ae.validateRenderPlan(b);if(!l.ok)throw new y("validate",`渲染计划校验失败:${l.errors.slice(0,3).map(M=>`${M.path}: ${M.message}`).join("; ")}`);return l});u.push(...P.warnings.map(l=>`${l.path}: ${l.message}`));const k=s??t.onWarning??(l=>console.warn("[mach-report]",l));for(const l of u)$(a),k(l);return $(a),b},{getParamDefs:o=>ie.getReportParamDefs(e,o)})}exports.PaginatePageLimitError=E;exports.ReportSourceError=y;exports.createReportSource=Ge;exports.datasetJsonSchema=Se;exports.defineReport=Oe;exports.evalStyleRule=V;exports.formatValue=q;exports.paginateTemplate=ne;exports.parseDateLocal=Y;exports.toExcelNumberFormat=K;exports.toNumber=F;exports.validateDatasetRows=Q;
|
package/dist/style-CpwiOPyB.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const r=require("./render-plan-CckPEQyf.cjs"),l=25.4,i=96;function f(o=i){return o/l}function S(o,t=i){return(o||0)*f(t)}function c(o,t=i){return o/f(t)}function P(o,t=i){return o*t/72}function m(o,t){const e=10**t;return Math.round(o*e)/e}const h={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 s(o,t=96,e=r.DEFAULT_FONT_PT){if(o?.fontSizePx!=null)return{fontSizePt:o.fontSizePx*72/t,fontSizePx:o.fontSizePx};const n=o?.fontSize??e;return{fontSizePt:n,fontSizePx:P(n,t)}}function T(o,t=r.DEFAULT_STROKE_COLOR){return{color:o?.borderColor??o?.lineColor??t,widthPt:o?.lineWidthPt??r.DEFAULT_BORDER_PT}}function x(o,t=r.DEFAULT_TEXT_COLOR){return o?.color??t}function M(o){return o?.lineHeight??r.LINE_HEIGHT}function _(o){const t=o?.borderTop!==!1,e=o?.borderRight!==!1,n=o?.borderBottom!==!1,u=o?.borderLeft!==!1;return{top:t,right:e,bottom:n,left:u,inner:t||e||n||u}}function d(o,t){const e={...o,...t};return t?.fontSize!=null&&t.fontSizePx==null&&delete e.fontSizePx,t?.fontSizePx!=null&&t.fontSize==null&&delete e.fontSize,e}exports.CSS_DPI=i;exports.MM_PER_INCH=l;exports.PAPER_SIZES=h;exports.mergeComponentStyles=d;exports.mmToPx=S;exports.mmToPxFactor=f;exports.ptToPx=P;exports.pxToMm=c;exports.resolveBoxBorders=_;exports.resolveFontSize=s;exports.resolveLineHeight=M;exports.resolveStroke=T;exports.resolveTextColor=x;exports.round=m;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const L=require("./render-plan-CckPEQyf.cjs"),N=require("./validate-DfHPD8wX.cjs"),O=require("./param-validation-CiTxFeZ8.cjs"),E="1.0";class p extends Error{constructor(t){super(`模板校验失败:${t.slice(0,3).map(s=>`${s.path}: ${s.message}`).join("; ")}`),this.errors=t,this.name="ReportTemplateError"}}const P=new Set(["__proto__","prototype","constructor"]),x=new Set(["schemaVersion","id","name","revision","description","template"]),D=new Set(["left","center","right","justify"]),M=2e5,V=64,k=1e7;function r(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function J(e,t,s){const i=Object.getPrototypeOf(e),o=Array.isArray(e);if(o?i!==Array.prototype:i!==Object.prototype&&i!==null)return s.push({path:t,message:"模板对象必须使用普通 JSON 对象原型"}),!1;if(o){const n=Object.keys(e);if(n.length!==e.length||n.some(a=>!/^(0|[1-9]\d*)$/.test(a)||Number(a)>=e.length))return s.push({path:t,message:"模板数组不能包含空位或额外属性"}),!1}return Object.getOwnPropertySymbols(e).length>0?(s.push({path:t,message:"模板不能包含 Symbol 键"}),!1):!0}function I(e,t,s,i){return P.has(e)?(i.push({path:s,message:"模板不能包含可能污染原型的键"}),!1):t.get||t.set||!t.enumerable?(i.push({path:s,message:"模板不能包含访问器或不可枚举字段"}),!1):!0}function C(e){return e===null||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e)}function v(e,t){const s=new Set;let i=0,o=0,n=!1;const a=(f,h,m)=>{if(!n){if(++i>M){i===M+1&&t.push({path:h,message:"模板超过 JSON 节点安全上限"});return}if(m>V){t.push({path:h,message:"模板嵌套层级过深"});return}if(typeof f=="string"){o+=f.length,o>k&&(n=!0,t.push({path:h,message:"模板文本超过 1000 万字符的安全上限"}));return}if(!C(f)){if(!f||typeof f!="object"){t.push({path:h,message:"模板只允许 JSON 值,不允许函数、undefined 或非有限数字"});return}if(s.has(f)){t.push({path:h,message:"模板不能包含循环引用"});return}if(J(f,h,t)){s.add(f);for(const[u,g]of Object.entries(Object.getOwnPropertyDescriptors(f))){if(Array.isArray(f)&&u==="length")continue;const y=`${h}.${u}`;if(I(u,g,y,t)&&a(g.value,y,m+1),i>M||n)break}s.delete(f)}}}};a(e,"$",0)}function l(e,t,s,i,o=!1){const n=e[t];n===void 0&&!o||(typeof n!="string"||o&&!n.trim())&&i.push({path:`${s}.${t}`,message:o?"应为非空字符串":"应为字符串"})}function c(e,t,s,i,o=0,n=!1){const a=e[t];a===void 0&&!n||(typeof a!="number"||!Number.isFinite(a)||a<o)&&i.push({path:`${s}.${t}`,message:`应为大于等于 ${o} 的有限数字`})}function b(e,t,s,i){e[t]!==void 0&&typeof e[t]!="boolean"&&i.push({path:`${s}.${t}`,message:"应为布尔值"})}function $(e,t,s,i=!1){e!==void 0&&!D.has(e)&&!(i&&e==="auto")&&s.push({path:t,message:`未知对齐方式${i?"(支持 auto)":""}`})}function d(e,t,s){if(e!==void 0){if(!r(e)){s.push({path:t,message:"样式应为对象"});return}$(e.align,`${t}.align`,s),e.verticalAlign!==void 0&&!["top","middle","bottom"].includes(e.verticalAlign)&&s.push({path:`${t}.verticalAlign`,message:"未知垂直对齐方式"});for(const i of["fontSize","fontSizePx","lineWidthPt","lineHeight"])c(e,i,t,s);for(const i of["letterSpacing","rotateDeg"])c(e,i,t,s,-1/0);c(e,"opacity",t,s),typeof e.opacity=="number"&&e.opacity>1&&s.push({path:`${t}.opacity`,message:"透明度不能大于 1"});for(const i of["bold","italic","underline","borderTop","borderRight","borderBottom","borderLeft"])b(e,i,t,s);for(const i of["fontFamily","color","backgroundColor","lineColor","borderColor"])l(e,i,t,s)}}function F(e,t,s){if(e===void 0)return;if(!Array.isArray(e)){s.push({path:t,message:"参数定义应为数组"});return}const i=new Set,o=s.length;e.forEach((n,a)=>{const f=`${t}.${a}`;if(!r(n)){s.push({path:f,message:"参数定义应为对象"});return}l(n,"field",f,s,!0),typeof n.field=="string"&&(i.has(n.field)&&s.push({path:`${f}.field`,message:"参数名重复"}),i.add(n.field)),n.type!==void 0&&!["text","number","date","select"].includes(n.type)&&s.push({path:`${f}.type`,message:"未知参数类型"});for(const h of["label","defaultValue","placeholder"])l(n,h,f,s);b(n,"required",f,s);for(const h of["minLength","maxLength"]){const m=n[h];m!==void 0&&(typeof m!="number"||!Number.isSafeInteger(m)||m<0)&&s.push({path:`${f}.${h}`,message:"长度边界应为非负整数"})}j(n,f,s),n.options!==void 0&&(Array.isArray(n.options)?n.options.forEach((h,m)=>{const u=`${f}.options.${m}`;if(!r(h))s.push({path:u,message:"选项应为对象"});else for(const g of["label","value"])typeof h[g]!="string"&&s.push({path:`${u}.${g}`,message:"选项标签与值应为字符串(允许空白选项)"})}):s.push({path:`${f}.options`,message:"选项应为数组"}))}),s.length===o&&s.push(...O.validateReportParamDefinitions(e).map(n=>({path:n.path.replace("$.paramDefs",t),message:n.message})))}function j(e,t,s){for(const n of["min","max"]){const a=e[n];if(a===void 0)continue;(e.type==="date"?typeof a=="string"&&O.isReportDate(a):e.type==="number"&&typeof a=="number"&&Number.isFinite(a))||s.push({path:`${t}.${n}`,message:"number 使用有限数字边界,date 使用有效 YYYY-MM-DD 日期边界"})}const i=typeof e.min=="number"&&typeof e.max=="number"&&e.min>e.max,o=typeof e.min=="string"&&typeof e.max=="string"&&e.min>e.max;(i||o)&&s.push({path:t,message:"最小边界不能大于最大边界"}),typeof e.minLength=="number"&&typeof e.maxLength=="number"&&e.minLength>e.maxLength&&s.push({path:t,message:"最小长度不能大于最大长度"})}function H(e,t,s){if(!Array.isArray(e)||e.length===0){s.push({path:t,message:"列表至少需要一列"});return}e.forEach((i,o)=>{const n=`${t}.${o}`;if(!r(i)){s.push({path:n,message:"列应为对象"});return}if(N.validateEditableMetadata(i,n,s),typeof i.header!="string"&&s.push({path:`${n}.header`,message:"表头应为字符串(允许空白表头)"}),l(i,"field",n,s,!0),c(i,"widthMm",n,s,Number.MIN_VALUE,!0),d(i.style,`${n}.style`,s),d(i.headerStyle,`${n}.headerStyle`,s),$(i.align,`${n}.align`,s,!0),$(i.headerAlign,`${n}.headerAlign`,s),i.semanticRole!==void 0&&!["identifier","dimension","measure","date","text"].includes(i.semanticRole)&&s.push({path:`${n}.semanticRole`,message:"未知列语义"}),i.format!==void 0)if(!r(i.format)||!["number","percent","date"].includes(i.format.kind))s.push({path:`${n}.format`,message:"未知列格式"});else{const a=i.format.digits;a!==void 0&&(typeof a!="number"||!Number.isInteger(a)||a<0||a>100)&&s.push({path:`${n}.format.digits`,message:"小数位应为 0–100 的整数"}),b(i.format,"thousands",`${n}.format`,s),l(i.format,"pattern",`${n}.format`,s)}i.rules!==void 0&&(Array.isArray(i.rules)?i.rules.forEach((a,f)=>{const h=`${n}.rules.${f}`;if(!r(a)||!r(a.when)){s.push({path:h,message:"条件格式缺少 when 对象"});return}l(a.when,"field",`${h}.when`,s,!0),[">",">=","<","<=","==","!="].includes(a.when.op)||s.push({path:`${h}.when.op`,message:"未知条件运算符"}),typeof a.when.value!="number"&&typeof a.when.value!="string"&&s.push({path:`${h}.when.value`,message:"条件值应为数字或字符串"}),d(a.style,`${h}.style`,s)}):s.push({path:`${n}.rules`,message:"条件格式应为数组"}))})}function U(e,t,s){if(e!==void 0){if(!r(e)){s.push({path:t,message:"分组应为对象"});return}l(e,"field",t,s,!0);for(const i of["headerTemplate","subtotalLabel"])l(e,i,t,s);for(const i of["headerStyle","subtotalStyle"])d(e[i],`${t}.${i}`,s);b(e,"keepWithNext",t,s),e.subtotal!==void 0&&(!Array.isArray(e.subtotal)||e.subtotal.some(i=>typeof i!="string"))&&s.push({path:`${t}.subtotal`,message:"小计字段应为字符串数组"})}}function G(e,t,s){if(!(e===void 0||typeof e=="boolean")){if(!r(e)){s.push({path:t,message:"合计应为布尔值或对象"});return}l(e,"label",t,s),d(e.style,`${t}.style`,s),e.fields!==void 0&&(!Array.isArray(e.fields)||e.fields.some(i=>typeof i!="string"))&&s.push({path:`${t}.fields`,message:"合计字段应为字符串数组"})}}function W(e,t,s,i){const o={kind:"rect",leftMm:0,topMm:0,widthMm:1,heightMm:1,grid:e};if(N.validateComponent(o,s,i,[]),R(o,s,i),!r(e)||!Array.isArray(e.cells))return;const n=e.cells,a=Array.isArray(t)?t.length:0;if(n.length*a>M){i.push({path:s,message:"表头逻辑网格超过 20 万格安全上限"});return}e.cells.length||i.push({path:`${s}.cells`,message:"表头至少需要一行"}),Array.isArray(e.colWidthsMm)&&e.colWidthsMm.length!==a&&i.push({path:`${s}.colWidthsMm`,message:"表头列宽数量应与列表列数一致"}),Array.isArray(e.rowHeightsMm)&&e.rowHeightsMm.length!==e.cells.length&&i.push({path:`${s}.rowHeightsMm`,message:"表头行高数量应与行数一致"}),Y(n,a,s,i)}function Y(e,t,s,i){const o=new Set;e.forEach((n,a)=>{if(!Array.isArray(n))return;let f=0;n.forEach((h,m)=>{for(;o.has(`${a}:${f}`);)f++;const u=r(h)&&typeof h.colSpan=="number"?h.colSpan:1,g=r(h)&&typeof h.rowSpan=="number"?h.rowSpan:1;(f+u>t||a+g>e.length)&&i.push({path:`${s}.cells.${a}.${m}`,message:"表头合并区域超出表头边界"});for(let y=a;y<Math.min(e.length,a+g);y++)for(let A=f;A<Math.min(t,f+u);A++)o.has(`${y}:${A}`)&&i.push({path:`${s}.cells.${a}.${m}`,message:"表头合并区域重叠"}),o.add(`${y}:${A}`);f+=u})})}function z(e,t,s){for(const i of["leftMm","topMm"])c(e,i,t,s,-1/0,!0);c(e,"widthMm",t,s,Number.MIN_VALUE,!0),l(e,"dataset",t,s,!0),l(e,"title",t,s);for(const i of["rowKey","revisionField","sourceTokenField"])l(e,i,t,s,e[i]!==void 0);e.headerGrid!==void 0&&W(e.headerGrid,e.columns,`${t}.headerGrid`,s),e.layout!==void 0&&e.layout!=="page"&&e.layout!=="wide"&&s.push({path:`${t}.layout`,message:"布局应为 page 或 wide"}),H(e.columns,`${t}.columns`,s);for(const i of["fontSizePt","rowHeightMm"])c(e,i,t,s,Number.MIN_VALUE);c(e,"paddingMm",t,s);for(const i of["headerBold","headerEveryPage","border"])b(e,i,t,s);l(e,"headerBackgroundColor",t,s),$(e.align,`${t}.align`,s,!0),$(e.headerAlign,`${t}.headerAlign`,s),d(e.headerStyle,`${t}.headerStyle`,s),U(e.groupBy,`${t}.groupBy`,s),G(e.grandTotal,`${t}.grandTotal`,s)}function R(e,t,s){d(e.style,`${t}.style`,s);for(const o of["text","rawText","imageData","fallbackText","nid","rkey"])l(e,o,t,s);if(e.lines!==void 0&&(!Array.isArray(e.lines)||e.lines.some(o=>typeof o!="string"))&&s.push({path:`${t}.lines`,message:"文本行应为字符串数组"}),Array.isArray(e.richParagraphs)&&e.richParagraphs.forEach((o,n)=>{if(!r(o))return;const a=`${t}.richParagraphs.${n}`;$(o.align,`${a}.align`,s);for(const f of["lineHeight","spaceBeforeMm","spaceAfterMm","indentMm"])c(o,f,a,s);Array.isArray(o.segments)&&o.segments.forEach((f,h)=>{const m=`${a}.segments.${h}`;if(!r(f)){s.push({path:m,message:"富文本片段应为对象"});return}f.kind!==void 0&&f.kind!=="text"&&f.kind!=="field"&&s.push({path:`${m}.kind`,message:"未知富文本片段类型"});for(const u of["text","field"])l(f,u,m,s);d(f.style,`${m}.style`,s)})}),!r(e.grid))return;const i=e.grid;c(i,"gapMm",`${t}.grid`,s),c(i,"paddingMm",`${t}.grid`,s);for(const o of["colWidthsMm","rowHeightsMm"]){const n=i[o];n!==void 0&&(!Array.isArray(n)||n.some(a=>typeof a!="number"||!Number.isFinite(a)||a<0))&&s.push({path:`${t}.grid.${o}`,message:"网格尺寸应为有限非负数字数组"})}Array.isArray(i.cells)&&i.cells.forEach((o,n)=>{Array.isArray(o)&&o.forEach((a,f)=>{const h=`${t}.grid.cells.${n}.${f}`;if(a!==null){if(!r(a)){s.push({path:h,message:"网格单元格应为对象或 null"});return}for(const m of["text","rawText","numberFormat"])l(a,m,h,s);for(const m of["colSpan","rowSpan"]){const u=a[m];u!==void 0&&(typeof u!="number"||!Number.isInteger(u)||u<=0)&&s.push({path:`${h}.${m}`,message:"跨度应为正整数"})}a.value!==void 0&&a.value!==null&&!["string","number","boolean"].includes(typeof a.value)&&s.push({path:`${h}.value`,message:"Excel 原始值应为字符串、数字、布尔值或 null"}),d(a.style,`${h}.style`,s),a.children!==void 0&&(Array.isArray(a.children)?a.children.forEach((m,u)=>{r(m)&&R(m,`${h}.children.${u}`,s)}):s.push({path:`${h}.children`,message:"嵌套组件应为数组"}))}})})}function T(e){const t=[],s=[];return v(e,t),t.length?{ok:!1,errors:t,warnings:s}:(r(e)?(e.schemaVersion!==void 0&&e.schemaVersion!==L.RENDER_PLAN_SCHEMA_VERSION&&t.push({path:"$.schemaVersion",message:"不支持的模板 schemaVersion"}),F(e.params,"$.params",t),!Array.isArray(e.pages)||e.pages.length===0?t.push({path:"$.pages",message:"模板至少需要一页"}):e.pages.forEach((i,o)=>{const n=`$.pages.${o}`;if(!r(i)){t.push({path:n,message:"页应为对象"});return}c(i,"widthMm",n,t,Number.MIN_VALUE,!0),c(i,"heightMm",n,t,Number.MIN_VALUE,!0),i.layout!==void 0&&i.layout!=="page"&&i.layout!=="wide"&&t.push({path:`${n}.layout`,message:"布局应为 page 或 wide"}),typeof i.heightMm=="number"&&i.heightMm>=5e3&&t.push({path:`${n}.heightMm`,message:"页高应小于 5000mm"});for(const a of["marginTopMm","marginBottomMm","marginLeftMm","marginRightMm"])c(i,a,n,t);typeof i.widthMm=="number"&&Number(i.marginLeftMm??0)+Number(i.marginRightMm??0)>=i.widthMm&&t.push({path:n,message:"横向页边距占满页面"}),typeof i.heightMm=="number"&&Number(i.marginTopMm??0)+Number(i.marginBottomMm??0)>=i.heightMm&&t.push({path:n,message:"纵向页边距占满页面"}),Array.isArray(i.components)?i.components.forEach((a,f)=>{const h=`${n}.components.${f}`;r(a)&&a.kind==="list"?z(a,h,t):(N.validateComponent(a,h,t,s),r(a)&&R(a,h,t))}):t.push({path:`${n}.components`,message:"组件应为数组"})})):t.push({path:"$",message:"模板应为对象"}),{ok:t.length===0,errors:t,warnings:s})}function _(e){const t=[],s=[];if(v(e,t),t.length)return{ok:!1,errors:t,warnings:s};if(!r(e))t.push({path:"$",message:"模板文档应为对象"});else{for(const o of Object.keys(e))x.has(o)||t.push({path:`$.${o}`,message:"模板文档存在未知字段;只保存模板与描述,不保存取数或业务数据"});e.schemaVersion!==E&&t.push({path:"$.schemaVersion",message:"不支持的模板文档版本"});for(const o of["id","name"])l(e,o,"$",t,!0);for(const o of["revision","description"])l(e,o,"$",t);const i=T(e.template);t.push(...i.errors.map(o=>({...o,path:`$.template${o.path.slice(1)}`}))),s.push(...i.warnings.map(o=>({...o,path:`$.template${o.path.slice(1)}`})))}return{ok:t.length===0,errors:t,warnings:s}}function S(e){const t=_(e);if(!t.ok)throw new p(t.errors)}function K(e){const t=[];if(v(e,t),t.length)throw new p(t);const s={...e,schemaVersion:e.schemaVersion??E};return S(s),w(s)}function X(e){let t=e;if(typeof e=="string"){if(e.length>k)throw new p([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);try{t=JSON.parse(e)}catch{throw new p([{path:"$",message:"模板 JSON 语法无效"}])}}return S(t),w(t)}function q(e){S(e);const t=JSON.stringify(e,null,2);if(t.length>k)throw new p([{path:"$",message:"模板 JSON 超过 1000 万字符的导出/导入上限"}]);return t}function w(e){return JSON.parse(JSON.stringify(e))}function B(e=[]){const t=new Map,s={get:i=>{const o=t.get(i);return o?w(o):void 0},list:()=>Array.from(t.values(),({template:i,...o})=>({...o})),register:(i,o={})=>{if(S(i),t.has(i.id)&&!o.replace)throw new p([{path:"$.id",message:`模板 ID ${i.id} 已注册;更新需显式 replace:true`}]);t.set(i.id,w(i))},remove:i=>t.delete(i)};for(const i of e)s.register(i);return s}exports.REPORT_TEMPLATE_DOCUMENT_VERSION=E;exports.ReportTemplateError=p;exports.createTemplateRegistry=B;exports.defineReportTemplate=K;exports.parseReportTemplate=X;exports.serializeReportTemplate=q;exports.validateReportTemplate=T;exports.validateReportTemplateDocument=_;
|
|
@@ -1,354 +0,0 @@
|
|
|
1
|
-
import { R } from "./render-plan-uzZYYSy1.js";
|
|
2
|
-
import { v, d as L } from "./validate-S6CgIm5d.js";
|
|
3
|
-
import { v as _, i as x } from "./param-validation-BWNjLcN0.js";
|
|
4
|
-
const O = "1.0";
|
|
5
|
-
class p extends Error {
|
|
6
|
-
constructor(t) {
|
|
7
|
-
super(`模板校验失败:${t.slice(0, 3).map((s) => `${s.path}: ${s.message}`).join("; ")}`), this.errors = t, this.name = "ReportTemplateError";
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
const P = /* @__PURE__ */ new Set(["__proto__", "prototype", "constructor"]), T = /* @__PURE__ */ new Set(["schemaVersion", "id", "name", "revision", "description", "template"]), D = /* @__PURE__ */ new Set(["left", "center", "right", "justify"]), M = 2e5, J = 64, N = 1e7;
|
|
11
|
-
function u(e) {
|
|
12
|
-
return !!e && typeof e == "object" && !Array.isArray(e);
|
|
13
|
-
}
|
|
14
|
-
function V(e, t, s) {
|
|
15
|
-
const i = Object.getPrototypeOf(e), f = Array.isArray(e);
|
|
16
|
-
if (f ? i !== Array.prototype : i !== Object.prototype && i !== null)
|
|
17
|
-
return s.push({ path: t, message: "模板对象必须使用普通 JSON 对象原型" }), !1;
|
|
18
|
-
if (f) {
|
|
19
|
-
const n = Object.keys(e);
|
|
20
|
-
if (n.length !== e.length || n.some((a) => !/^(0|[1-9]\d*)$/.test(a) || Number(a) >= e.length))
|
|
21
|
-
return s.push({ path: t, message: "模板数组不能包含空位或额外属性" }), !1;
|
|
22
|
-
}
|
|
23
|
-
return Object.getOwnPropertySymbols(e).length > 0 ? (s.push({ path: t, message: "模板不能包含 Symbol 键" }), !1) : !0;
|
|
24
|
-
}
|
|
25
|
-
function I(e, t, s, i) {
|
|
26
|
-
return P.has(e) ? (i.push({ path: s, message: "模板不能包含可能污染原型的键" }), !1) : t.get || t.set || !t.enumerable ? (i.push({ path: s, message: "模板不能包含访问器或不可枚举字段" }), !1) : !0;
|
|
27
|
-
}
|
|
28
|
-
function F(e) {
|
|
29
|
-
return e === null || typeof e == "boolean" || typeof e == "number" && Number.isFinite(e);
|
|
30
|
-
}
|
|
31
|
-
function k(e, t) {
|
|
32
|
-
const s = /* @__PURE__ */ new Set();
|
|
33
|
-
let i = 0, f = 0, n = !1;
|
|
34
|
-
const a = (o, h, m) => {
|
|
35
|
-
if (!n) {
|
|
36
|
-
if (++i > M) {
|
|
37
|
-
i === M + 1 && t.push({ path: h, message: "模板超过 JSON 节点安全上限" });
|
|
38
|
-
return;
|
|
39
|
-
}
|
|
40
|
-
if (m > J) {
|
|
41
|
-
t.push({ path: h, message: "模板嵌套层级过深" });
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
if (typeof o == "string") {
|
|
45
|
-
f += o.length, f > N && (n = !0, t.push({ path: h, message: "模板文本超过 1000 万字符的安全上限" }));
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (!F(o)) {
|
|
49
|
-
if (!o || typeof o != "object") {
|
|
50
|
-
t.push({ path: h, message: "模板只允许 JSON 值,不允许函数、undefined 或非有限数字" });
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (s.has(o)) {
|
|
54
|
-
t.push({ path: h, message: "模板不能包含循环引用" });
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
if (V(o, h, t)) {
|
|
58
|
-
s.add(o);
|
|
59
|
-
for (const [r, g] of Object.entries(Object.getOwnPropertyDescriptors(o))) {
|
|
60
|
-
if (Array.isArray(o) && r === "length") continue;
|
|
61
|
-
const y = `${h}.${r}`;
|
|
62
|
-
if (I(r, g, y, t) && a(g.value, y, m + 1), i > M || n) break;
|
|
63
|
-
}
|
|
64
|
-
s.delete(o);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
};
|
|
69
|
-
a(e, "$", 0);
|
|
70
|
-
}
|
|
71
|
-
function l(e, t, s, i, f = !1) {
|
|
72
|
-
const n = e[t];
|
|
73
|
-
n === void 0 && !f || (typeof n != "string" || f && !n.trim()) && i.push({ path: `${s}.${t}`, message: f ? "应为非空字符串" : "应为字符串" });
|
|
74
|
-
}
|
|
75
|
-
function c(e, t, s, i, f = 0, n = !1) {
|
|
76
|
-
const a = e[t];
|
|
77
|
-
a === void 0 && !n || (typeof a != "number" || !Number.isFinite(a) || a < f) && i.push({ path: `${s}.${t}`, message: `应为大于等于 ${f} 的有限数字` });
|
|
78
|
-
}
|
|
79
|
-
function b(e, t, s, i) {
|
|
80
|
-
e[t] !== void 0 && typeof e[t] != "boolean" && i.push({ path: `${s}.${t}`, message: "应为布尔值" });
|
|
81
|
-
}
|
|
82
|
-
function $(e, t, s, i = !1) {
|
|
83
|
-
e !== void 0 && !D.has(e) && !(i && e === "auto") && s.push({ path: t, message: `未知对齐方式${i ? "(支持 auto)" : ""}` });
|
|
84
|
-
}
|
|
85
|
-
function d(e, t, s) {
|
|
86
|
-
if (e !== void 0) {
|
|
87
|
-
if (!u(e)) {
|
|
88
|
-
s.push({ path: t, message: "样式应为对象" });
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
$(e.align, `${t}.align`, s), e.verticalAlign !== void 0 && !["top", "middle", "bottom"].includes(e.verticalAlign) && s.push({ path: `${t}.verticalAlign`, message: "未知垂直对齐方式" });
|
|
92
|
-
for (const i of ["fontSize", "fontSizePx", "lineWidthPt", "lineHeight"]) c(e, i, t, s);
|
|
93
|
-
for (const i of ["letterSpacing", "rotateDeg"]) c(e, i, t, s, -1 / 0);
|
|
94
|
-
c(e, "opacity", t, s), typeof e.opacity == "number" && e.opacity > 1 && s.push({ path: `${t}.opacity`, message: "透明度不能大于 1" });
|
|
95
|
-
for (const i of ["bold", "italic", "underline", "borderTop", "borderRight", "borderBottom", "borderLeft"]) b(e, i, t, s);
|
|
96
|
-
for (const i of ["fontFamily", "color", "backgroundColor", "lineColor", "borderColor"]) l(e, i, t, s);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
function j(e, t, s) {
|
|
100
|
-
if (e === void 0) return;
|
|
101
|
-
if (!Array.isArray(e)) {
|
|
102
|
-
s.push({ path: t, message: "参数定义应为数组" });
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
const i = /* @__PURE__ */ new Set(), f = s.length;
|
|
106
|
-
e.forEach((n, a) => {
|
|
107
|
-
const o = `${t}.${a}`;
|
|
108
|
-
if (!u(n)) {
|
|
109
|
-
s.push({ path: o, message: "参数定义应为对象" });
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
l(n, "field", o, s, !0), typeof n.field == "string" && (i.has(n.field) && s.push({ path: `${o}.field`, message: "参数名重复" }), i.add(n.field)), n.type !== void 0 && !["text", "number", "date", "select"].includes(n.type) && s.push({ path: `${o}.type`, message: "未知参数类型" });
|
|
113
|
-
for (const h of ["label", "defaultValue", "placeholder"]) l(n, h, o, s);
|
|
114
|
-
b(n, "required", o, s);
|
|
115
|
-
for (const h of ["minLength", "maxLength"]) {
|
|
116
|
-
const m = n[h];
|
|
117
|
-
m !== void 0 && (typeof m != "number" || !Number.isSafeInteger(m) || m < 0) && s.push({ path: `${o}.${h}`, message: "长度边界应为非负整数" });
|
|
118
|
-
}
|
|
119
|
-
C(n, o, s), n.options !== void 0 && (Array.isArray(n.options) ? n.options.forEach((h, m) => {
|
|
120
|
-
const r = `${o}.options.${m}`;
|
|
121
|
-
if (!u(h)) s.push({ path: r, message: "选项应为对象" });
|
|
122
|
-
else
|
|
123
|
-
for (const g of ["label", "value"]) typeof h[g] != "string" && s.push({ path: `${r}.${g}`, message: "选项标签与值应为字符串(允许空白选项)" });
|
|
124
|
-
}) : s.push({ path: `${o}.options`, message: "选项应为数组" }));
|
|
125
|
-
}), s.length === f && s.push(..._(e).map((n) => ({ path: n.path.replace("$.paramDefs", t), message: n.message })));
|
|
126
|
-
}
|
|
127
|
-
function C(e, t, s) {
|
|
128
|
-
for (const n of ["min", "max"]) {
|
|
129
|
-
const a = e[n];
|
|
130
|
-
if (a === void 0) continue;
|
|
131
|
-
(e.type === "date" ? typeof a == "string" && x(a) : e.type === "number" && typeof a == "number" && Number.isFinite(a)) || s.push({ path: `${t}.${n}`, message: "number 使用有限数字边界,date 使用有效 YYYY-MM-DD 日期边界" });
|
|
132
|
-
}
|
|
133
|
-
const i = typeof e.min == "number" && typeof e.max == "number" && e.min > e.max, f = typeof e.min == "string" && typeof e.max == "string" && e.min > e.max;
|
|
134
|
-
(i || f) && s.push({ path: t, message: "最小边界不能大于最大边界" }), typeof e.minLength == "number" && typeof e.maxLength == "number" && e.minLength > e.maxLength && s.push({ path: t, message: "最小长度不能大于最大长度" });
|
|
135
|
-
}
|
|
136
|
-
function H(e, t, s) {
|
|
137
|
-
if (!Array.isArray(e) || e.length === 0) {
|
|
138
|
-
s.push({ path: t, message: "列表至少需要一列" });
|
|
139
|
-
return;
|
|
140
|
-
}
|
|
141
|
-
e.forEach((i, f) => {
|
|
142
|
-
const n = `${t}.${f}`;
|
|
143
|
-
if (!u(i)) {
|
|
144
|
-
s.push({ path: n, message: "列应为对象" });
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
if (L(i, n, s), typeof i.header != "string" && s.push({ path: `${n}.header`, message: "表头应为字符串(允许空白表头)" }), l(i, "field", n, s, !0), c(i, "widthMm", n, s, Number.MIN_VALUE, !0), d(i.style, `${n}.style`, s), d(i.headerStyle, `${n}.headerStyle`, s), $(i.align, `${n}.align`, s, !0), $(i.headerAlign, `${n}.headerAlign`, s), i.semanticRole !== void 0 && !["identifier", "dimension", "measure", "date", "text"].includes(i.semanticRole) && s.push({ path: `${n}.semanticRole`, message: "未知列语义" }), i.format !== void 0)
|
|
148
|
-
if (!u(i.format) || !["number", "percent", "date"].includes(i.format.kind))
|
|
149
|
-
s.push({ path: `${n}.format`, message: "未知列格式" });
|
|
150
|
-
else {
|
|
151
|
-
const a = i.format.digits;
|
|
152
|
-
a !== void 0 && (typeof a != "number" || !Number.isInteger(a) || a < 0 || a > 100) && s.push({ path: `${n}.format.digits`, message: "小数位应为 0–100 的整数" }), b(i.format, "thousands", `${n}.format`, s), l(i.format, "pattern", `${n}.format`, s);
|
|
153
|
-
}
|
|
154
|
-
i.rules !== void 0 && (Array.isArray(i.rules) ? i.rules.forEach((a, o) => {
|
|
155
|
-
const h = `${n}.rules.${o}`;
|
|
156
|
-
if (!u(a) || !u(a.when)) {
|
|
157
|
-
s.push({ path: h, message: "条件格式缺少 when 对象" });
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
l(a.when, "field", `${h}.when`, s, !0), [">", ">=", "<", "<=", "==", "!="].includes(a.when.op) || s.push({ path: `${h}.when.op`, message: "未知条件运算符" }), typeof a.when.value != "number" && typeof a.when.value != "string" && s.push({ path: `${h}.when.value`, message: "条件值应为数字或字符串" }), d(a.style, `${h}.style`, s);
|
|
161
|
-
}) : s.push({ path: `${n}.rules`, message: "条件格式应为数组" }));
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
function U(e, t, s) {
|
|
165
|
-
if (e !== void 0) {
|
|
166
|
-
if (!u(e)) {
|
|
167
|
-
s.push({ path: t, message: "分组应为对象" });
|
|
168
|
-
return;
|
|
169
|
-
}
|
|
170
|
-
l(e, "field", t, s, !0);
|
|
171
|
-
for (const i of ["headerTemplate", "subtotalLabel"]) l(e, i, t, s);
|
|
172
|
-
for (const i of ["headerStyle", "subtotalStyle"]) d(e[i], `${t}.${i}`, s);
|
|
173
|
-
b(e, "keepWithNext", t, s), e.subtotal !== void 0 && (!Array.isArray(e.subtotal) || e.subtotal.some((i) => typeof i != "string")) && s.push({ path: `${t}.subtotal`, message: "小计字段应为字符串数组" });
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
function G(e, t, s) {
|
|
177
|
-
if (!(e === void 0 || typeof e == "boolean")) {
|
|
178
|
-
if (!u(e)) {
|
|
179
|
-
s.push({ path: t, message: "合计应为布尔值或对象" });
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
l(e, "label", t, s), d(e.style, `${t}.style`, s), e.fields !== void 0 && (!Array.isArray(e.fields) || e.fields.some((i) => typeof i != "string")) && s.push({ path: `${t}.fields`, message: "合计字段应为字符串数组" });
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
function W(e, t, s, i) {
|
|
186
|
-
const f = { kind: "rect", leftMm: 0, topMm: 0, widthMm: 1, heightMm: 1, grid: e };
|
|
187
|
-
if (v(f, s, i, []), E(f, s, i), !u(e) || !Array.isArray(e.cells)) return;
|
|
188
|
-
const n = e.cells, a = Array.isArray(t) ? t.length : 0;
|
|
189
|
-
if (n.length * a > M) {
|
|
190
|
-
i.push({ path: s, message: "表头逻辑网格超过 20 万格安全上限" });
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
e.cells.length || i.push({ path: `${s}.cells`, message: "表头至少需要一行" }), Array.isArray(e.colWidthsMm) && e.colWidthsMm.length !== a && i.push({ path: `${s}.colWidthsMm`, message: "表头列宽数量应与列表列数一致" }), Array.isArray(e.rowHeightsMm) && e.rowHeightsMm.length !== e.cells.length && i.push({ path: `${s}.rowHeightsMm`, message: "表头行高数量应与行数一致" }), Y(n, a, s, i);
|
|
194
|
-
}
|
|
195
|
-
function Y(e, t, s, i) {
|
|
196
|
-
const f = /* @__PURE__ */ new Set();
|
|
197
|
-
e.forEach((n, a) => {
|
|
198
|
-
if (!Array.isArray(n)) return;
|
|
199
|
-
let o = 0;
|
|
200
|
-
n.forEach((h, m) => {
|
|
201
|
-
for (; f.has(`${a}:${o}`); ) o++;
|
|
202
|
-
const r = u(h) && typeof h.colSpan == "number" ? h.colSpan : 1, g = u(h) && typeof h.rowSpan == "number" ? h.rowSpan : 1;
|
|
203
|
-
(o + r > t || a + g > e.length) && i.push({ path: `${s}.cells.${a}.${m}`, message: "表头合并区域超出表头边界" });
|
|
204
|
-
for (let y = a; y < Math.min(e.length, a + g); y++)
|
|
205
|
-
for (let A = o; A < Math.min(t, o + r); A++)
|
|
206
|
-
f.has(`${y}:${A}`) && i.push({ path: `${s}.cells.${a}.${m}`, message: "表头合并区域重叠" }), f.add(`${y}:${A}`);
|
|
207
|
-
o += r;
|
|
208
|
-
});
|
|
209
|
-
});
|
|
210
|
-
}
|
|
211
|
-
function z(e, t, s) {
|
|
212
|
-
for (const i of ["leftMm", "topMm"]) c(e, i, t, s, -1 / 0, !0);
|
|
213
|
-
c(e, "widthMm", t, s, Number.MIN_VALUE, !0), l(e, "dataset", t, s, !0), l(e, "title", t, s);
|
|
214
|
-
for (const i of ["rowKey", "revisionField", "sourceTokenField"]) l(e, i, t, s, e[i] !== void 0);
|
|
215
|
-
e.headerGrid !== void 0 && W(e.headerGrid, e.columns, `${t}.headerGrid`, s), e.layout !== void 0 && e.layout !== "page" && e.layout !== "wide" && s.push({ path: `${t}.layout`, message: "布局应为 page 或 wide" }), H(e.columns, `${t}.columns`, s);
|
|
216
|
-
for (const i of ["fontSizePt", "rowHeightMm"]) c(e, i, t, s, Number.MIN_VALUE);
|
|
217
|
-
c(e, "paddingMm", t, s);
|
|
218
|
-
for (const i of ["headerBold", "headerEveryPage", "border"]) b(e, i, t, s);
|
|
219
|
-
l(e, "headerBackgroundColor", t, s), $(e.align, `${t}.align`, s, !0), $(e.headerAlign, `${t}.headerAlign`, s), d(e.headerStyle, `${t}.headerStyle`, s), U(e.groupBy, `${t}.groupBy`, s), G(e.grandTotal, `${t}.grandTotal`, s);
|
|
220
|
-
}
|
|
221
|
-
function E(e, t, s) {
|
|
222
|
-
d(e.style, `${t}.style`, s);
|
|
223
|
-
for (const f of ["text", "rawText", "imageData", "fallbackText", "nid", "rkey"]) l(e, f, t, s);
|
|
224
|
-
if (e.lines !== void 0 && (!Array.isArray(e.lines) || e.lines.some((f) => typeof f != "string")) && s.push({ path: `${t}.lines`, message: "文本行应为字符串数组" }), Array.isArray(e.richParagraphs) && e.richParagraphs.forEach((f, n) => {
|
|
225
|
-
if (!u(f)) return;
|
|
226
|
-
const a = `${t}.richParagraphs.${n}`;
|
|
227
|
-
$(f.align, `${a}.align`, s);
|
|
228
|
-
for (const o of ["lineHeight", "spaceBeforeMm", "spaceAfterMm", "indentMm"]) c(f, o, a, s);
|
|
229
|
-
Array.isArray(f.segments) && f.segments.forEach((o, h) => {
|
|
230
|
-
const m = `${a}.segments.${h}`;
|
|
231
|
-
if (!u(o)) {
|
|
232
|
-
s.push({ path: m, message: "富文本片段应为对象" });
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
o.kind !== void 0 && o.kind !== "text" && o.kind !== "field" && s.push({ path: `${m}.kind`, message: "未知富文本片段类型" });
|
|
236
|
-
for (const r of ["text", "field"]) l(o, r, m, s);
|
|
237
|
-
d(o.style, `${m}.style`, s);
|
|
238
|
-
});
|
|
239
|
-
}), !u(e.grid)) return;
|
|
240
|
-
const i = e.grid;
|
|
241
|
-
c(i, "gapMm", `${t}.grid`, s), c(i, "paddingMm", `${t}.grid`, s);
|
|
242
|
-
for (const f of ["colWidthsMm", "rowHeightsMm"]) {
|
|
243
|
-
const n = i[f];
|
|
244
|
-
n !== void 0 && (!Array.isArray(n) || n.some((a) => typeof a != "number" || !Number.isFinite(a) || a < 0)) && s.push({ path: `${t}.grid.${f}`, message: "网格尺寸应为有限非负数字数组" });
|
|
245
|
-
}
|
|
246
|
-
Array.isArray(i.cells) && i.cells.forEach((f, n) => {
|
|
247
|
-
Array.isArray(f) && f.forEach((a, o) => {
|
|
248
|
-
const h = `${t}.grid.cells.${n}.${o}`;
|
|
249
|
-
if (a !== null) {
|
|
250
|
-
if (!u(a)) {
|
|
251
|
-
s.push({ path: h, message: "网格单元格应为对象或 null" });
|
|
252
|
-
return;
|
|
253
|
-
}
|
|
254
|
-
for (const m of ["text", "rawText", "numberFormat"]) l(a, m, h, s);
|
|
255
|
-
for (const m of ["colSpan", "rowSpan"]) {
|
|
256
|
-
const r = a[m];
|
|
257
|
-
r !== void 0 && (typeof r != "number" || !Number.isInteger(r) || r <= 0) && s.push({ path: `${h}.${m}`, message: "跨度应为正整数" });
|
|
258
|
-
}
|
|
259
|
-
a.value !== void 0 && a.value !== null && !["string", "number", "boolean"].includes(typeof a.value) && s.push({ path: `${h}.value`, message: "Excel 原始值应为字符串、数字、布尔值或 null" }), d(a.style, `${h}.style`, s), a.children !== void 0 && (Array.isArray(a.children) ? a.children.forEach((m, r) => {
|
|
260
|
-
u(m) && E(m, `${h}.children.${r}`, s);
|
|
261
|
-
}) : s.push({ path: `${h}.children`, message: "嵌套组件应为数组" }));
|
|
262
|
-
}
|
|
263
|
-
});
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
function K(e) {
|
|
267
|
-
const t = [], s = [];
|
|
268
|
-
return k(e, t), t.length ? { ok: !1, errors: t, warnings: s } : (u(e) ? (e.schemaVersion !== void 0 && e.schemaVersion !== R && t.push({ path: "$.schemaVersion", message: "不支持的模板 schemaVersion" }), j(e.params, "$.params", t), !Array.isArray(e.pages) || e.pages.length === 0 ? t.push({ path: "$.pages", message: "模板至少需要一页" }) : e.pages.forEach((i, f) => {
|
|
269
|
-
const n = `$.pages.${f}`;
|
|
270
|
-
if (!u(i)) {
|
|
271
|
-
t.push({ path: n, message: "页应为对象" });
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
c(i, "widthMm", n, t, Number.MIN_VALUE, !0), c(i, "heightMm", n, t, Number.MIN_VALUE, !0), i.layout !== void 0 && i.layout !== "page" && i.layout !== "wide" && t.push({ path: `${n}.layout`, message: "布局应为 page 或 wide" }), typeof i.heightMm == "number" && i.heightMm >= 5e3 && t.push({ path: `${n}.heightMm`, message: "页高应小于 5000mm" });
|
|
275
|
-
for (const a of ["marginTopMm", "marginBottomMm", "marginLeftMm", "marginRightMm"]) c(i, a, n, t);
|
|
276
|
-
typeof i.widthMm == "number" && Number(i.marginLeftMm ?? 0) + Number(i.marginRightMm ?? 0) >= i.widthMm && t.push({ path: n, message: "横向页边距占满页面" }), typeof i.heightMm == "number" && Number(i.marginTopMm ?? 0) + Number(i.marginBottomMm ?? 0) >= i.heightMm && t.push({ path: n, message: "纵向页边距占满页面" }), Array.isArray(i.components) ? i.components.forEach((a, o) => {
|
|
277
|
-
const h = `${n}.components.${o}`;
|
|
278
|
-
u(a) && a.kind === "list" ? z(a, h, t) : (v(a, h, t, s), u(a) && E(a, h, t));
|
|
279
|
-
}) : t.push({ path: `${n}.components`, message: "组件应为数组" });
|
|
280
|
-
})) : t.push({ path: "$", message: "模板应为对象" }), { ok: t.length === 0, errors: t, warnings: s });
|
|
281
|
-
}
|
|
282
|
-
function X(e) {
|
|
283
|
-
const t = [], s = [];
|
|
284
|
-
if (k(e, t), t.length) return { ok: !1, errors: t, warnings: s };
|
|
285
|
-
if (!u(e)) t.push({ path: "$", message: "模板文档应为对象" });
|
|
286
|
-
else {
|
|
287
|
-
for (const f of Object.keys(e))
|
|
288
|
-
T.has(f) || t.push({ path: `$.${f}`, message: "模板文档存在未知字段;只保存模板与描述,不保存取数或业务数据" });
|
|
289
|
-
e.schemaVersion !== O && t.push({ path: "$.schemaVersion", message: "不支持的模板文档版本" });
|
|
290
|
-
for (const f of ["id", "name"]) l(e, f, "$", t, !0);
|
|
291
|
-
for (const f of ["revision", "description"]) l(e, f, "$", t);
|
|
292
|
-
const i = K(e.template);
|
|
293
|
-
t.push(...i.errors.map((f) => ({ ...f, path: `$.template${f.path.slice(1)}` }))), s.push(...i.warnings.map((f) => ({ ...f, path: `$.template${f.path.slice(1)}` })));
|
|
294
|
-
}
|
|
295
|
-
return { ok: t.length === 0, errors: t, warnings: s };
|
|
296
|
-
}
|
|
297
|
-
function S(e) {
|
|
298
|
-
const t = X(e);
|
|
299
|
-
if (!t.ok) throw new p(t.errors);
|
|
300
|
-
}
|
|
301
|
-
function q(e) {
|
|
302
|
-
const t = [];
|
|
303
|
-
if (k(e, t), t.length) throw new p(t);
|
|
304
|
-
const s = { ...e, schemaVersion: e.schemaVersion ?? O };
|
|
305
|
-
return S(s), w(s);
|
|
306
|
-
}
|
|
307
|
-
function ee(e) {
|
|
308
|
-
let t = e;
|
|
309
|
-
if (typeof e == "string") {
|
|
310
|
-
if (e.length > N)
|
|
311
|
-
throw new p([{ path: "$", message: "模板 JSON 超过 1000 万字符的导出/导入上限" }]);
|
|
312
|
-
try {
|
|
313
|
-
t = JSON.parse(e);
|
|
314
|
-
} catch {
|
|
315
|
-
throw new p([{ path: "$", message: "模板 JSON 语法无效" }]);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
return S(t), w(t);
|
|
319
|
-
}
|
|
320
|
-
function te(e) {
|
|
321
|
-
S(e);
|
|
322
|
-
const t = JSON.stringify(e, null, 2);
|
|
323
|
-
if (t.length > N) throw new p([{ path: "$", message: "模板 JSON 超过 1000 万字符的导出/导入上限" }]);
|
|
324
|
-
return t;
|
|
325
|
-
}
|
|
326
|
-
function w(e) {
|
|
327
|
-
return JSON.parse(JSON.stringify(e));
|
|
328
|
-
}
|
|
329
|
-
function se(e = []) {
|
|
330
|
-
const t = /* @__PURE__ */ new Map(), s = {
|
|
331
|
-
get: (i) => {
|
|
332
|
-
const f = t.get(i);
|
|
333
|
-
return f ? w(f) : void 0;
|
|
334
|
-
},
|
|
335
|
-
list: () => Array.from(t.values(), ({ template: i, ...f }) => ({ ...f })),
|
|
336
|
-
register: (i, f = {}) => {
|
|
337
|
-
if (S(i), t.has(i.id) && !f.replace) throw new p([{ path: "$.id", message: `模板 ID ${i.id} 已注册;更新需显式 replace:true` }]);
|
|
338
|
-
t.set(i.id, w(i));
|
|
339
|
-
},
|
|
340
|
-
remove: (i) => t.delete(i)
|
|
341
|
-
};
|
|
342
|
-
for (const i of e) s.register(i);
|
|
343
|
-
return s;
|
|
344
|
-
}
|
|
345
|
-
export {
|
|
346
|
-
O as R,
|
|
347
|
-
p as a,
|
|
348
|
-
X as b,
|
|
349
|
-
se as c,
|
|
350
|
-
q as d,
|
|
351
|
-
ee as p,
|
|
352
|
-
te as s,
|
|
353
|
-
K as v
|
|
354
|
-
};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
"use strict";const w=require("./render-plan-CckPEQyf.cjs"),M=/[\u3000-\u9fff\uff00-\uffef]/,s=new Uint8Array(128);{for(const t of"iljtf.,:;'`|!()[]")s[t.charCodeAt(0)]=1;for(const t of"mwMW@")s[t.charCodeAt(0)]=2;for(let t=48;t<=57;t++)s[t]=3;for(let t=65;t<=90;t++)s[t]=4;s[32]=5}const g=[.54,.26,.95,.59,.67,.3];function d(t){const e=t.charCodeAt(0);return e<128?g[s[e]]:M.test(t)?1:/[A-Z]/.test(t)?.67:.54}const o={measureMm(t,e){const{fontSizePt:i,bold:c=!1,letterSpacingPt:u=0}=e,r=25.4/72;let n=0;for(const h of t)n+=d(h);return c&&(n*=1.04),(n*i+u*Math.max(0,Array.from(t).length-1))*r}};function p(){return o}function A(t,e){return o.measureMm(t,e)}function x(t){let e;return{measureMm(i,c){if(e===void 0&&(e=t()),!e)return o.measureMm(i,c);const u=c.fontSizePt*96/72;e.font=`${c.italic?"italic ":""}${c.bold?"bold ":""}${u}px ${c.fontFamily??w.DEFAULT_FONT_FAMILY}`,"letterSpacing"in e&&(e.letterSpacing="0px");const r=(c.letterSpacingPt??0)*Math.max(0,Array.from(i).length-1);return e.measureText(i).width*25.4/96+r*25.4/72}}}function T(t,e,i){const c=[];let u="";const r=()=>{u&&(c.push({text:u,widthMm:i.measureMm(u,e),cjk:!1}),u="")};for(const n of t){if(n===`
|
|
2
|
-
`){r(),c.push({text:`
|
|
3
|
-
`,widthMm:0,cjk:!1,br:!0});continue}if(n===" "){r(),c.push({text:n,widthMm:i.measureMm(n,e),cjk:!1,space:!0});continue}if(M.test(n)){r(),c.push({text:n,widthMm:i.measureMm(n,e),cjk:!0});continue}u+=n}return r(),c}function S(t,e,i,c=o){if(!t)return[""];t=t.replace(/\r\n?/g,`
|
|
4
|
-
`);const u=[];let r="",n=0;const h=(i.letterSpacingPt??0)*25.4/72,f=()=>{u.push(r),r="",n=0};for(const a of T(t,i,c)){if(a.br){f();continue}const m=r.length>0?h:0;if(n+m+a.widthMm<=e){r+=a.text,n+=m+a.widthMm;continue}if(a.space){f();continue}if(a.cjk){r.length>0&&f(),r=a.text,n=a.widthMm;continue}if(r.length>0&&f(),a.widthMm<=e){r=a.text,n=a.widthMm;continue}for(const l of a.text)c.measureMm(r+l,i)>e&&r.length>0&&f(),r+=l,n=c.measureMm(r,i)}return f(),u}exports.charWidthEm=d;exports.createCanvasMeasurer=x;exports.createHeuristicMeasurer=p;exports.heuristicMeasurer=o;exports.measureTextMm=A;exports.wrapText=S;
|