@worm-vue3-print/core 1.3.7 → 1.3.8

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.
@@ -1,18 +1,20 @@
1
1
  /*!
2
- * @worm-vue3-print/core v1.3.7
2
+ * @worm-vue3-print/core v1.3.8
3
3
  * Copyright (c) 2026 worm <liu_long_qqcom@qq.com>
4
4
  * SPDX-FileCopyrightText: 2026 worm <liu_long_qqcom@qq.com>
5
5
  * SPDX-License-Identifier: MIT
6
6
  */
7
7
  import {
8
8
  TemplateEngine
9
- } from "../chunk-WLGEOVFK.js";
9
+ } from "../chunk-ZKHVOCU5.js";
10
10
  import {
11
11
  BARCODE_BAR_HEIGHT_MODULES,
12
12
  BARCODE_MARGIN_BOTTOM_MODULES,
13
13
  BARCODE_MODULE_WIDTH_MM,
14
14
  BARCODE_QUIET_ZONE_MODULES,
15
15
  BARCODE_TEXT_FONT_SIZE_MODULES,
16
+ CROP_SCALE_MAX,
17
+ CROP_SCALE_MIN,
16
18
  DEFAULT_SHRINK_MIN_FONT_SIZE_PT,
17
19
  ELEMENT_BORDER_SIDES,
18
20
  MIN_SHRINK_FONT_SIZE_PT,
@@ -26,7 +28,10 @@ import {
26
28
  cellFitCapMm,
27
29
  cellFitKey,
28
30
  cellFitWidthMm,
31
+ cellImageBoxMm,
29
32
  count,
33
+ cropScalePct,
34
+ cropStyleDeclarations,
30
35
  divideNumbers,
31
36
  floorFontSize,
32
37
  formatDate,
@@ -49,10 +54,11 @@ import {
49
54
  roundFontSize,
50
55
  roundHalfEven,
51
56
  roundUp,
57
+ sanitizeObjectPosition,
52
58
  subtractNumbers,
53
59
  sum,
54
60
  toUpperCaseAmount
55
- } from "../chunk-TCI5XQKI.js";
61
+ } from "../chunk-TQJGFV2V.js";
56
62
 
57
63
  // src/designer/utils/scale.ts
58
64
  var MIN_SCALE_PERCENT = 25;
@@ -92,6 +98,15 @@ function resolveToolbarOverflow(input) {
92
98
  return { movedIds: [...moved], overflowRemains: true };
93
99
  }
94
100
 
101
+ // src/designer/utils/overlay-placement.ts
102
+ function resolveOverlayPlacement(input) {
103
+ const gap = input.gap ?? 4;
104
+ const below = input.boundaryBottom - input.triggerBottom - gap;
105
+ const above = input.triggerTop - input.boundaryTop - gap;
106
+ if (below >= input.overlayHeight) return "down";
107
+ return above > below ? "up" : "down";
108
+ }
109
+
95
110
  // src/designer/utils/migrate.ts
96
111
  var PT_KEYS = ["left", "top", "width", "height"];
97
112
  function convertElement(el) {
@@ -806,13 +821,18 @@ var PROPERTY_REGISTRY = [
806
821
  },
807
822
  {
808
823
  key: "ap-img-fit",
809
- keywords: ["\u7F29\u653E\u6A21\u5F0F", "\u62C9\u4F38", "\u7B49\u6BD4", "fit", "contain", "cover", "\u586B\u5145", "\u88C1\u526A"],
810
- tip: "\u56FE\u7247\u5728\u5143\u7D20\u6846\u5185\u7684\u7F29\u653E\u65B9\u5F0F\uFF1A\u5305\u542B\uFF1D\u5B8C\u6574\u663E\u793A\u53EF\u80FD\u7559\u767D\uFF1B\u8986\u76D6\uFF1D\u94FA\u6EE1\u6846\u53EF\u80FD\u88C1\u8FB9\uFF1B\u62C9\u4F38\uFF1D\u586B\u6EE1\u6846\u4F1A\u53D8\u5F62\uFF1B\u539F\u59CB\u5C3A\u5BF8/\u7F29\u5C0F\u4E0D\u653E\u5927\u3002\u753B\u5E03\u4E0E\u4E09\u6761\u51FA\u7EB8\u94FE\u8DEF\u540C\u4E00\u53E3\u5F84\uFF08\u7F3A\u7701\u5305\u542B\uFF09"
824
+ keywords: ["\u7F29\u653E\u6A21\u5F0F", "\u62C9\u4F38", "\u7B49\u6BD4", "fit", "contain", "cover", "\u586B\u5145", "\u88C1\u526A", "\u526A\u88C1", "\u951A\u70B9"],
825
+ tip: "\u56FE\u7247\u5728\u5143\u7D20\u6846\u5185\u7684\u7F29\u653E\u65B9\u5F0F\uFF1A\u5305\u542B\uFF1D\u5B8C\u6574\u663E\u793A\u3001\u53EF\u80FD\u7559\u767D\uFF1B\u526A\u88C1\uFF1D\u94FA\u6EE1\u6846\u5E76\u6309\u300C\u88C1\u526A\u951A\u70B9\u300D\u53D6\u4E00\u5757\uFF1B\u62C9\u4F38\uFF1D\u586B\u6EE1\u6846\u4F1A\u53D8\u5F62\uFF1B\u539F\u59CB\u5C3A\u5BF8\u4E0E\u7F29\u5C0F\u4E0D\u653E\u5927\u3002\u753B\u5E03\u4E0E\u4E09\u6761\u51FA\u7EB8\u94FE\u8DEF\u540C\u4E00\u53E3\u5F84\uFF08\u7F3A\u7701\u5305\u542B\uFF09"
811
826
  },
812
827
  {
813
828
  key: "ap-img-object-position",
814
- keywords: ["\u88C1\u526A\u951A\u70B9", "\u951A\u70B9", "objectposition", "object-position", "\u5BF9\u9F50\u70B9", "\u4E0A\u79FB", "\u5934\u9876"],
815
- tip: "\u88C1\u526A\u65F6\u4FDD\u7559\u6846\u5185\u7684\u54EA\u4E00\u90E8\u5206\uFF0CCSS object-position \u503C\u539F\u6837\u751F\u6548\uFF08\u5982 center 20% \u8BA9\u753B\u9762\u4E0A\u79FB\u3001\u4FDD\u4F4F\u8BC1\u4EF6\u7167\u5934\u9876\uFF09\uFF1B\u53EA\u5728\u53D1\u751F\u88C1\u5207\u65F6\u53EF\u89C1\uFF0C\u7F3A\u7701\u6309 50% 50% \u5C45\u4E2D\u3002\u542B\u5206\u53F7\u3001\u5F15\u53F7\u3001url() \u7684\u503C\u4F1A\u88AB\u6574\u6761\u4E22\u5F03"
829
+ keywords: ["\u88C1\u526A\u951A\u70B9", "\u526A\u88C1\u951A\u70B9", "\u951A\u70B9", "objectposition", "object-position", "\u5BF9\u9F50\u70B9", "\u4E0A\u79FB", "\u5934\u9876"],
830
+ tip: "\u53D6\u4F4D\uFF08\u4EC5\u300C\u526A\u88C1\u300D\u6863\u6709\u8FD9\u4E00\u884C\uFF09\uFF1A\u526A\u88C1\u628A\u56FE\u7B49\u6BD4\u94FA\u6EE1\u5143\u7D20\u6846\uFF0C\u591A\u51FA\u6765\u7684\u90A3\u4E00\u6761\u8FB9\u6309\u8FD9\u91CC\u9009\u7684\u4F4D\u7F6E\u53D6\u820D\u3002\u5148\u9009\u4F4D\u7F6E\u6863\uFF08\u8D34\u8FB9\uFF0F\u5C45\u4E2D\uFF0F\u8D34\u53E6\u4E00\u5934\uFF09\uFF0C\u518D\u6309\u767E\u5206\u6BD4\u5FAE\u8C03\uFF0C0 \u8D34\u5DE6\uFF0F\u8D34\u9876\uFF0C100 \u632A\u5230\u53E6\u4E00\u5934\uFF0C\u6C34\u5E73\u4E0E\u5782\u76F4\u5404\u81EA\u72EC\u7ACB\uFF1B\u7F3A\u7701\u53D6\u6B63\u4E2D\u95F4\uFF08\u4FDD\u4F4F\u8BC1\u4EF6\u7167\u5934\u9876\u5C31\u9009\u9876\u90E8\uFF09\u3002\u5176\u4F59\u7F29\u653E\u6A21\u5F0F\u56FE\u6BD4\u6846\u5C0F\u6216\u521A\u597D\u94FA\u6EE1\uFF0C\u6CA1\u6709\u53EF\u88C1\u7684\u8FB9\uFF0C\u6240\u4EE5\u4E0D\u51FA\u672C\u884C"
831
+ },
832
+ {
833
+ key: "ap-img-fit-scale",
834
+ keywords: ["\u653E\u5927\u6BD4\u4F8B", "\u526A\u88C1\u653E\u5927", "\u653E\u5927\u500D\u6570", "\u53D6\u666F", "\u88C1\u5207\u8303\u56F4", "fitscale", "zoom"],
835
+ tip: "\u526A\u88C1\u653E\u5927\uFF1A\u7B49\u6BD4\u94FA\u6EE1\u4E4B\u540E\u628A\u753B\u9762\u518D\u63A8\u5927\u8FD9\u4E48\u591A\uFF0C\u4E24\u8F74\u624D\u771F\u7684\u5404\u591A\u51FA\u4E00\u6761\u8FB9\u53EF\u88C1\u2014\u2014\u56FE\u4E0E\u6846\u540C\u6BD4\u4F8B\u65F6\u4E0D\u653E\u5927\u5C31\u4EC0\u4E48\u90FD\u88C1\u4E0D\u6389\u3002100\uFF1D\u4E0D\u653E\u5927\uFF08\u7F3A\u7701\uFF09\uFF0C\u4E0A\u9650 400\uFF1B\u8D85\u51FA\u6846\u7684\u90E8\u5206\u7531\u5143\u7D20\u6846\u88C1\u6389\u3002\u951A\u70B9\u9009\u4E2D\u7684\u90A3\u4E00\u70B9\u65E2\u662F\u53D6\u4F4D\u7684\u9489\u4F4F\u70B9\u3001\u4E5F\u662F\u653E\u5927\u7684\u4E2D\u5FC3\uFF0C\u4E24\u8005\u5171\u7528\u540C\u4E00\u4E2A\u503C\u3002\u4EC5\u300C\u526A\u88C1\u300D\u6863\u751F\u6548\uFF0C\u5176\u4F59\u7F29\u653E\u6A21\u5F0F\u4E0D\u51FA\u672C\u884C"
816
836
  }
817
837
  ]
818
838
  },
@@ -914,6 +934,321 @@ function searchProperties(search) {
914
934
  return { groups, itemKeys };
915
935
  }
916
936
 
937
+ // src/designer/utils/engine.ts
938
+ var engine = new TemplateEngine();
939
+
940
+ // src/designer/utils/expression-eval.ts
941
+ var EXTENDED_FUNCTIONS = {
942
+ MONEY: formatMoney,
943
+ CONCAT: (...args) => args.filter((v) => v != null).join(""),
944
+ IF: ifFn,
945
+ FORMAT: (value) => {
946
+ if (typeof value !== "number") return String(value);
947
+ return value.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
948
+ },
949
+ SUBSTR: (str, start, len) => String(str).slice(start, len ? start + len : void 0),
950
+ LEN: (str) => String(str).length,
951
+ // 四则运算(与 +/-/*// 运算符同一套数值语义,供不方便写运算符的场景使用)
952
+ ADD: addNumbers,
953
+ SUB: subtractNumbers,
954
+ MUL: multiplyNumbers,
955
+ DIV: divideNumbers,
956
+ // 数值修约
957
+ ROUND: round,
958
+ ROUNDUP: roundUp,
959
+ CEIL: roundUp,
960
+ ROUNDDOWN: roundDown,
961
+ FLOOR: roundDown,
962
+ ROUNDBANK: roundHalfEven,
963
+ NOW: () => (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
964
+ IFEMPTY: (value, defaultVal) => value != null && value !== "" ? String(value) : defaultVal,
965
+ PAD: (value, len, char) => String(value).padStart(len, char),
966
+ REPLACE: (str, from, to) => String(str).replace(new RegExp(from, "g"), to),
967
+ JSON: (value) => JSON.stringify(value, null, 2),
968
+ DATE: formatDate,
969
+ UPPER: toUpperCaseAmount
970
+ };
971
+ for (const [name, fn] of Object.entries(EXTENDED_FUNCTIONS)) {
972
+ engine.registerFunction(name, fn);
973
+ }
974
+ function aggregate(fn, field, rows) {
975
+ switch (fn.toUpperCase()) {
976
+ case "SUM":
977
+ return sum(rows, field);
978
+ case "AVG":
979
+ return avg(rows, field);
980
+ case "COUNT":
981
+ return count(rows, field);
982
+ case "MIN":
983
+ return min(rows, field);
984
+ case "MAX":
985
+ return max(rows, field);
986
+ default:
987
+ return 0;
988
+ }
989
+ }
990
+ function safeEval(expr, context, _callableNames) {
991
+ return engine.evaluate(expr, context);
992
+ }
993
+ function evaluateTemplate(text, ctx) {
994
+ if (!text) return "";
995
+ if (!text.includes("{")) return text;
996
+ const rows = Array.isArray(ctx.rows) ? ctx.rows : [];
997
+ let processedText = text.replace(/\{([^}]+)\}/g, (_match, inner) => {
998
+ let expr = inner.trim();
999
+ expr = expr.replace(/\b(SUM|AVG|COUNT|MIN|MAX)\(([^)]+)\)/g, (_m, fn, arg) => {
1000
+ const field = arg.trim().replace(/^['"]|['"]$/g, "");
1001
+ return String(aggregate(fn, field, rows));
1002
+ });
1003
+ return `{${expr}}`;
1004
+ });
1005
+ try {
1006
+ const result = engine.render(processedText, ctx);
1007
+ return result;
1008
+ } catch {
1009
+ return text;
1010
+ }
1011
+ }
1012
+
1013
+ // src/designer/utils/demo-data.ts
1014
+ function getDemoData() {
1015
+ return DEFAULT_DEMO_DATA;
1016
+ }
1017
+ var DEFAULT_DEMO_DATA = {
1018
+ supplier: {
1019
+ name: "\u946B\u8FBE\u4E94\u91D1\u6709\u9650\u516C\u53F8",
1020
+ phone: "0571-88776655",
1021
+ address: "\u676D\u5DDE\u5E02\u8427\u5C71\u533A\u7ECF\u6D4E\u5F00\u53D1\u533A88\u53F7"
1022
+ },
1023
+ receiver: {
1024
+ name: "\u674E\u56DB",
1025
+ phone: "13912345678",
1026
+ address: "\u676D\u5DDE\u5E02\u4F59\u676D\u533A\u6587\u4E00\u897F\u8DEF998\u53F7"
1027
+ },
1028
+ order: {
1029
+ no: "PO20260801001",
1030
+ date: "2026-08-01",
1031
+ total: 69543.75
1032
+ },
1033
+ // 50 条商品明细, 用于验证多页分页效果
1034
+ goods: [
1035
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 100, price: 0.5, amount: 50, remark: "A\u7EA7" },
1036
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 117, price: 0.75, amount: 87.75, remark: "" },
1037
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 134, price: 1, amount: 134, remark: "" },
1038
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 151, price: 1.25, amount: 188.75, remark: "" },
1039
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 168, price: 1.5, amount: 252, remark: "" },
1040
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 185, price: 1.75, amount: 323.75, remark: "" },
1041
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 202, price: 2, amount: 404, remark: "" },
1042
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 219, price: 2.25, amount: 492.75, remark: "A\u7EA7" },
1043
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 236, price: 2.5, amount: 590, remark: "" },
1044
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 253, price: 2.75, amount: 695.75, remark: "" },
1045
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD720", unit: "\u4E2A", qty: 270, price: 3, amount: 810, remark: "" },
1046
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD721", unit: "\u5957", qty: 287, price: 3.25, amount: 932.75, remark: "" },
1047
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD722", unit: "\u76D2", qty: 304, price: 3.5, amount: 1064, remark: "" },
1048
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD723", unit: "\u652F", qty: 321, price: 3.75, amount: 1203.75, remark: "" },
1049
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD724", unit: "\u888B", qty: 338, price: 4, amount: 1352, remark: "A\u7EA7" },
1050
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD725", unit: "\u4EF6", qty: 355, price: 4.25, amount: 1508.75, remark: "" },
1051
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD726", unit: "\u6839", qty: 372, price: 4.5, amount: 1674, remark: "" },
1052
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD727", unit: "\u5305", qty: 389, price: 4.75, amount: 1847.75, remark: "" },
1053
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD728", unit: "\u53EA", qty: 406, price: 5, amount: 2030, remark: "" },
1054
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD729", unit: "\u7EC4", qty: 423, price: 5.25, amount: 2220.75, remark: "" },
1055
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD730", unit: "\u4E2A", qty: 440, price: 0.5, amount: 220, remark: "" },
1056
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD731", unit: "\u5957", qty: 457, price: 0.75, amount: 342.75, remark: "A\u7EA7" },
1057
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD732", unit: "\u76D2", qty: 474, price: 1, amount: 474, remark: "" },
1058
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD733", unit: "\u652F", qty: 491, price: 1.25, amount: 613.75, remark: "" },
1059
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD734", unit: "\u888B", qty: 508, price: 1.5, amount: 762, remark: "" },
1060
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD735", unit: "\u4EF6", qty: 525, price: 1.75, amount: 918.75, remark: "" },
1061
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD736", unit: "\u6839", qty: 542, price: 2, amount: 1084, remark: "" },
1062
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD737", unit: "\u5305", qty: 559, price: 2.25, amount: 1257.75, remark: "" },
1063
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD738", unit: "\u53EA", qty: 576, price: 2.5, amount: 1440, remark: "A\u7EA7" },
1064
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD739", unit: "\u7EC4", qty: 593, price: 2.75, amount: 1630.75, remark: "" },
1065
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD740", unit: "\u4E2A", qty: 610, price: 3, amount: 1830, remark: "" },
1066
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD741", unit: "\u5957", qty: 627, price: 3.25, amount: 2037.75, remark: "" },
1067
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD742", unit: "\u76D2", qty: 644, price: 3.5, amount: 2254, remark: "" },
1068
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD743", unit: "\u652F", qty: 661, price: 3.75, amount: 2478.75, remark: "" },
1069
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD744", unit: "\u888B", qty: 678, price: 4, amount: 2712, remark: "" },
1070
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD745", unit: "\u4EF6", qty: 695, price: 4.25, amount: 2953.75, remark: "A\u7EA7" },
1071
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD746", unit: "\u6839", qty: 712, price: 4.5, amount: 3204, remark: "" },
1072
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD747", unit: "\u5305", qty: 729, price: 4.75, amount: 3462.75, remark: "" },
1073
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD748", unit: "\u53EA", qty: 746, price: 5, amount: 3730, remark: "" },
1074
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD749", unit: "\u7EC4", qty: 763, price: 5.25, amount: 4005.75, remark: "" },
1075
+ { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 780, price: 0.5, amount: 390, remark: "" },
1076
+ { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 797, price: 0.75, amount: 597.75, remark: "" },
1077
+ { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 814, price: 1, amount: 814, remark: "A\u7EA7" },
1078
+ { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 831, price: 1.25, amount: 1038.75, remark: "" },
1079
+ { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 848, price: 1.5, amount: 1272, remark: "" },
1080
+ { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 865, price: 1.75, amount: 1513.75, remark: "" },
1081
+ { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 882, price: 2, amount: 1764, remark: "" },
1082
+ { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 899, price: 2.25, amount: 2022.75, remark: "" },
1083
+ { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 916, price: 2.5, amount: 2290, remark: "" },
1084
+ { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 933, price: 2.75, amount: 2565.75, remark: "A\u7EA7" }
1085
+ ]
1086
+ };
1087
+
1088
+ // src/designer/utils/crop-anchor.ts
1089
+ var AXIS_X = { left: 0, center: 50, right: 100 };
1090
+ var AXIS_Y = { top: 0, center: 50, bottom: 100 };
1091
+ function clampPct(v) {
1092
+ if (!Number.isFinite(v)) return 50;
1093
+ return Math.round(Math.min(100, Math.max(0, v)));
1094
+ }
1095
+ function roundMm(v) {
1096
+ return Math.round(v * 100) / 100;
1097
+ }
1098
+ function buildCropAnchor(x, y) {
1099
+ const cx = clampPct(x);
1100
+ const cy = clampPct(y);
1101
+ if (cx === 50 && cy === 50) return void 0;
1102
+ return `${cx}% ${cy}%`;
1103
+ }
1104
+ function asPct(token) {
1105
+ return /^\d+(?:\.\d+)?%$/.test(token) ? parseFloat(token) : void 0;
1106
+ }
1107
+ function parseCropAnchor(value) {
1108
+ const raw = (value ?? "").trim();
1109
+ if (!raw) return { kind: "empty" };
1110
+ const tokens = raw.toLowerCase().split(/\s+/);
1111
+ let x;
1112
+ let y;
1113
+ for (let i = 0; i < tokens.length; i++) {
1114
+ const t = tokens[i];
1115
+ const pct = asPct(t);
1116
+ if (i === 0) {
1117
+ if (t in AXIS_X) x = AXIS_X[t];
1118
+ else if (pct !== void 0) x = pct;
1119
+ else if (t in AXIS_Y) y = AXIS_Y[t];
1120
+ else return { kind: "custom", raw: value };
1121
+ } else {
1122
+ if (t in AXIS_Y && y === void 0) y = AXIS_Y[t];
1123
+ else if (pct !== void 0 && x === void 0) x = pct;
1124
+ else if (pct !== void 0 && y === void 0) y = pct;
1125
+ else if (t in AXIS_X && x === void 0) x = AXIS_X[t];
1126
+ else return { kind: "custom", raw: value };
1127
+ }
1128
+ }
1129
+ return { kind: "axes", x: clampPct(x ?? 50), y: clampPct(y ?? 50) };
1130
+ }
1131
+ var MM_PER_PX = 25.4 / 96;
1132
+ function contentMm(box) {
1133
+ const { widthMm, heightMm, naturalWidth, naturalHeight } = box;
1134
+ if (!naturalWidth || !naturalHeight || !widthMm || !heightMm) return null;
1135
+ const k = widthMm / naturalWidth;
1136
+ const l = heightMm / naturalHeight;
1137
+ const zoom = (cropScalePct(box.fit, box.scalePct) ?? CROP_SCALE_MIN) / 100;
1138
+ switch (box.fit || "contain") {
1139
+ // 拉伸填满:图被钉成框,两轴都挪不动(放大比例只给剪裁档,这里不受影响)
1140
+ case "fill":
1141
+ return { w: widthMm, h: heightMm };
1142
+ case "cover": {
1143
+ const s = Math.max(k, l) * zoom;
1144
+ return { w: naturalWidth * s, h: naturalHeight * s };
1145
+ }
1146
+ // 原始尺寸不缩放:按图片内在像素尺寸绘制
1147
+ case "none":
1148
+ return { w: naturalWidth * MM_PER_PX, h: naturalHeight * MM_PER_PX };
1149
+ case "scale-down": {
1150
+ const s = Math.min(1, Math.min(k, l));
1151
+ return { w: naturalWidth * s, h: naturalHeight * s };
1152
+ }
1153
+ default: {
1154
+ const s = Math.min(k, l);
1155
+ return { w: naturalWidth * s, h: naturalHeight * s };
1156
+ }
1157
+ }
1158
+ }
1159
+ function resolveCropTravel(box) {
1160
+ const c = contentMm(box);
1161
+ if (!c) return { x: null, y: null };
1162
+ return {
1163
+ x: roundMm(Math.abs(box.widthMm - c.w)),
1164
+ y: roundMm(Math.abs(box.heightMm - c.h))
1165
+ };
1166
+ }
1167
+ function cropWindow(box, x, y) {
1168
+ const c = contentMm(box);
1169
+ if (!c) return null;
1170
+ const fx = Math.min(1, box.widthMm / c.w);
1171
+ const fy = Math.min(1, box.heightMm / c.h);
1172
+ return {
1173
+ leftPct: (1 - fx) * clampPct(x),
1174
+ topPct: (1 - fy) * clampPct(y),
1175
+ widthPct: fx * 100,
1176
+ heightPct: fy * 100
1177
+ };
1178
+ }
1179
+ function resolveDesignImageSrc(raw) {
1180
+ const value = String(raw ?? "");
1181
+ if (!value) return "";
1182
+ return value.includes("{") ? String(evaluateTemplate(value, DEFAULT_DEMO_DATA)) : value;
1183
+ }
1184
+ var CROP_AXIS_OPTIONS = {
1185
+ vertical: [
1186
+ { value: 0, label: "\u9876\u90E8" },
1187
+ { value: 50, label: "\u5C45\u4E2D" },
1188
+ { value: 100, label: "\u5E95\u90E8" }
1189
+ ],
1190
+ horizontal: [
1191
+ { value: 0, label: "\u5DE6\u4FA7" },
1192
+ { value: 50, label: "\u5C45\u4E2D" },
1193
+ { value: 100, label: "\u53F3\u4FA7" }
1194
+ ]
1195
+ };
1196
+ var CROP_GRID_OPTIONS = [
1197
+ { x: 0, y: 0, label: "\u5DE6\u4E0A" },
1198
+ { x: 50, y: 0, label: "\u4E0A\u4E2D" },
1199
+ { x: 100, y: 0, label: "\u53F3\u4E0A" },
1200
+ { x: 0, y: 50, label: "\u5DE6\u4E2D" },
1201
+ { x: 50, y: 50, label: "\u5C45\u4E2D" },
1202
+ { x: 100, y: 50, label: "\u53F3\u4E2D" },
1203
+ { x: 0, y: 100, label: "\u5DE6\u4E0B" },
1204
+ { x: 50, y: 100, label: "\u4E0B\u4E2D" },
1205
+ { x: 100, y: 100, label: "\u53F3\u4E0B" }
1206
+ ];
1207
+ var IMAGE_FIT_OPTIONS = [
1208
+ { value: "contain", label: "\u5305\u542B\uFF08\u4FDD\u6301\u6BD4\u4F8B\uFF09" },
1209
+ { value: "cover", label: "\u526A\u88C1\uFF08\u7B49\u6BD4\u94FA\u6EE1\u540E\u88C1\u8FB9\uFF09" },
1210
+ { value: "fill", label: "\u62C9\u4F38\u586B\u6EE1" },
1211
+ { value: "none", label: "\u539F\u59CB\u5C3A\u5BF8" },
1212
+ { value: "scale-down", label: "\u7F29\u5C0F\uFF08\u4FDD\u6301\u6BD4\u4F8B\uFF09" }
1213
+ ];
1214
+ var CROP_SAMPLE_IMAGE = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMjAiIGhlaWdodD0iMTIwIiB2aWV3Qm94PSIwIDAgMTIwIDEyMCI+PHJlY3Qgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiIGZpbGw9IiNmZmZmZmYiLz48cGF0aCBkPSJNNDAgMFYxMjBNODAgMFYxMjBNMCA0MEgxMjBNMCA4MEgxMjAiIHN0cm9rZT0iI2VlZjFmNiIgc3Ryb2tlLXdpZHRoPSIxIi8+PGNpcmNsZSBjeD0iMjAiIGN5PSIyMCIgcj0iMy41IiBmaWxsPSIjOGI5NWE1Ii8+PGNpcmNsZSBjeD0iMTAwIiBjeT0iMjAiIHI9IjMuNSIgZmlsbD0iIzhiOTVhNSIvPjxjaXJjbGUgY3g9IjIwIiBjeT0iMTAwIiByPSIzLjUiIGZpbGw9IiM4Yjk1YTUiLz48Y2lyY2xlIGN4PSIxMDAiIGN5PSIxMDAiIHI9IjMuNSIgZmlsbD0iIzhiOTVhNSIvPjxjaXJjbGUgY3g9IjYwIiBjeT0iMjAiIHI9IjciIGZpbGw9IiNjMDM5MmIiLz48Y2lyY2xlIGN4PSI2MCIgY3k9IjEwMCIgcj0iNyIgZmlsbD0iIzFmNGZhMyIvPjxjaXJjbGUgY3g9IjIwIiBjeT0iNjAiIHI9IjciIGZpbGw9IiMyYzdhNGEiLz48Y2lyY2xlIGN4PSIxMDAiIGN5PSI2MCIgcj0iNyIgZmlsbD0iI2UwN2EyMCIvPjxjaXJjbGUgY3g9IjYwIiBjeT0iNjAiIHI9IjE0IiBmaWxsPSJub25lIiBzdHJva2U9IiMyZjNhNGEiIHN0cm9rZS13aWR0aD0iNCIvPjxjaXJjbGUgY3g9IjYwIiBjeT0iNjAiIHI9IjYiIGZpbGw9IiMyZjNhNGEiLz48L3N2Zz4=";
1215
+ var CROP_SAMPLE_NOTE = "\u56FE\u7247\u8FD8\u6CA1\u8BBE\u7F6E\uFF0C\u4E0A\u9762\u6309\u5185\u7F6E\u793A\u4F8B\u56FE\u6F14\u793A\u53D6\u4F4D\uFF1B\u6362\u4E0A\u771F\u56FE\u540E\u6863\u4F4D\u4E0E\u53EF\u632A\u91CF\u6309\u771F\u56FE\u91CD\u7B97";
1216
+ function resolveCropPreview(resolvedSrc) {
1217
+ const value = String(resolvedSrc ?? "").trim();
1218
+ if (!value || value.includes("{") || value.includes("}")) return { src: CROP_SAMPLE_IMAGE, isSample: true };
1219
+ return { src: value, isSample: false };
1220
+ }
1221
+ function cropAxisLabel(axis) {
1222
+ return axis === "vertical" ? "\u5782\u76F4\u4F4D\u7F6E (%)" : "\u6C34\u5E73\u4F4D\u7F6E (%)";
1223
+ }
1224
+ var CROP_SCALE_LABEL = "\u653E\u5927\u6BD4\u4F8B (%)";
1225
+ function cropAxisNote(travel, keepRaw = false) {
1226
+ if (keepRaw) return "\u5DF2\u4FDD\u7559\u6A21\u677F\u91CC\u7684\u539F\u503C\uFF1B\u6539\u52A8\u4E0B\u9762\u4EFB\u4E00\u9879\u5C31\u6574\u4F53\u66FF\u6362\u6210\u65B0\u7684\u53D6\u4F4D";
1227
+ const { x, y } = travel;
1228
+ if (x === null || y === null) return "";
1229
+ if (x > 0 && y > 0) return `\u6C34\u5E73\u53EF\u632A ${x}mm\u3001\u5782\u76F4\u53EF\u632A ${y}mm\uFF1A0 \u8D34\u5DE6\uFF0F\u8D34\u9876\uFF0C100 \u8D34\u53F3\uFF0F\u8D34\u5E95`;
1230
+ if (x > 0) return `\u6C34\u5E73\u53EF\u632A ${x}mm\uFF1B\u5782\u76F4\u8FD9\u4E00\u8F74\u5DF2\u8D34\u6EE1\uFF0C\u632A\u4E0D\u52A8`;
1231
+ if (y > 0) return `\u5782\u76F4\u53EF\u632A ${y}mm\uFF1B\u6C34\u5E73\u8FD9\u4E00\u8F74\u5DF2\u8D34\u6EE1\uFF0C\u632A\u4E0D\u52A8`;
1232
+ return "\u8FD9\u4E2A\u7F29\u653E\u4E0B\u56FE\u4E0E\u6846\u6B63\u597D\u4E00\u6837\u5927\uFF0C\u4E24\u8F74\u90FD\u6CA1\u6709\u53EF\u632A\u7684\u4F59\u91CF";
1233
+ }
1234
+ function cropAxisFields(travel, x, y) {
1235
+ return [
1236
+ { name: "horizontal", label: cropAxisLabel("horizontal"), value: x, travelMm: travel.x },
1237
+ { name: "vertical", label: cropAxisLabel("vertical"), value: y, travelMm: travel.y }
1238
+ ];
1239
+ }
1240
+ function cropPresetOptions(travel, x, y) {
1241
+ const movX = travel.x !== null && travel.x > 0;
1242
+ const movY = travel.y !== null && travel.y > 0;
1243
+ if (movY && !movX) {
1244
+ return CROP_AXIS_OPTIONS.vertical.map((o) => ({ value: `${x},${o.value}`, label: o.label }));
1245
+ }
1246
+ if (movX && !movY) {
1247
+ return CROP_AXIS_OPTIONS.horizontal.map((o) => ({ value: `${o.value},${y}`, label: o.label }));
1248
+ }
1249
+ return CROP_GRID_OPTIONS.map((o) => ({ value: `${o.x},${o.y}`, label: o.label }));
1250
+ }
1251
+
917
1252
  // src/designer/utils/field-groups.ts
918
1253
  function groupFields(fields) {
919
1254
  const sorted = [...fields].sort((a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0));
@@ -1027,157 +1362,6 @@ function getElementBindings(element) {
1027
1362
  return [...staticBindings, ...dynamicBindings];
1028
1363
  }
1029
1364
 
1030
- // src/designer/utils/demo-data.ts
1031
- function getDemoData() {
1032
- return DEFAULT_DEMO_DATA;
1033
- }
1034
- var DEFAULT_DEMO_DATA = {
1035
- supplier: {
1036
- name: "\u946B\u8FBE\u4E94\u91D1\u6709\u9650\u516C\u53F8",
1037
- phone: "0571-88776655",
1038
- address: "\u676D\u5DDE\u5E02\u8427\u5C71\u533A\u7ECF\u6D4E\u5F00\u53D1\u533A88\u53F7"
1039
- },
1040
- receiver: {
1041
- name: "\u674E\u56DB",
1042
- phone: "13912345678",
1043
- address: "\u676D\u5DDE\u5E02\u4F59\u676D\u533A\u6587\u4E00\u897F\u8DEF998\u53F7"
1044
- },
1045
- order: {
1046
- no: "PO20260801001",
1047
- date: "2026-08-01",
1048
- total: 69543.75
1049
- },
1050
- // 50 条商品明细, 用于验证多页分页效果
1051
- goods: [
1052
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 100, price: 0.5, amount: 50, remark: "A\u7EA7" },
1053
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 117, price: 0.75, amount: 87.75, remark: "" },
1054
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 134, price: 1, amount: 134, remark: "" },
1055
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 151, price: 1.25, amount: 188.75, remark: "" },
1056
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 168, price: 1.5, amount: 252, remark: "" },
1057
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 185, price: 1.75, amount: 323.75, remark: "" },
1058
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 202, price: 2, amount: 404, remark: "" },
1059
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 219, price: 2.25, amount: 492.75, remark: "A\u7EA7" },
1060
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 236, price: 2.5, amount: 590, remark: "" },
1061
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 253, price: 2.75, amount: 695.75, remark: "" },
1062
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD720", unit: "\u4E2A", qty: 270, price: 3, amount: 810, remark: "" },
1063
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD721", unit: "\u5957", qty: 287, price: 3.25, amount: 932.75, remark: "" },
1064
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD722", unit: "\u76D2", qty: 304, price: 3.5, amount: 1064, remark: "" },
1065
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD723", unit: "\u652F", qty: 321, price: 3.75, amount: 1203.75, remark: "" },
1066
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD724", unit: "\u888B", qty: 338, price: 4, amount: 1352, remark: "A\u7EA7" },
1067
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD725", unit: "\u4EF6", qty: 355, price: 4.25, amount: 1508.75, remark: "" },
1068
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD726", unit: "\u6839", qty: 372, price: 4.5, amount: 1674, remark: "" },
1069
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD727", unit: "\u5305", qty: 389, price: 4.75, amount: 1847.75, remark: "" },
1070
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD728", unit: "\u53EA", qty: 406, price: 5, amount: 2030, remark: "" },
1071
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD729", unit: "\u7EC4", qty: 423, price: 5.25, amount: 2220.75, remark: "" },
1072
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD730", unit: "\u4E2A", qty: 440, price: 0.5, amount: 220, remark: "" },
1073
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD731", unit: "\u5957", qty: 457, price: 0.75, amount: 342.75, remark: "A\u7EA7" },
1074
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD732", unit: "\u76D2", qty: 474, price: 1, amount: 474, remark: "" },
1075
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD733", unit: "\u652F", qty: 491, price: 1.25, amount: 613.75, remark: "" },
1076
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD734", unit: "\u888B", qty: 508, price: 1.5, amount: 762, remark: "" },
1077
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD735", unit: "\u4EF6", qty: 525, price: 1.75, amount: 918.75, remark: "" },
1078
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD736", unit: "\u6839", qty: 542, price: 2, amount: 1084, remark: "" },
1079
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD737", unit: "\u5305", qty: 559, price: 2.25, amount: 1257.75, remark: "" },
1080
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD738", unit: "\u53EA", qty: 576, price: 2.5, amount: 1440, remark: "A\u7EA7" },
1081
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD739", unit: "\u7EC4", qty: 593, price: 2.75, amount: 1630.75, remark: "" },
1082
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD740", unit: "\u4E2A", qty: 610, price: 3, amount: 1830, remark: "" },
1083
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD741", unit: "\u5957", qty: 627, price: 3.25, amount: 2037.75, remark: "" },
1084
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD742", unit: "\u76D2", qty: 644, price: 3.5, amount: 2254, remark: "" },
1085
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD743", unit: "\u652F", qty: 661, price: 3.75, amount: 2478.75, remark: "" },
1086
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD744", unit: "\u888B", qty: 678, price: 4, amount: 2712, remark: "" },
1087
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD745", unit: "\u4EF6", qty: 695, price: 4.25, amount: 2953.75, remark: "A\u7EA7" },
1088
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD746", unit: "\u6839", qty: 712, price: 4.5, amount: 3204, remark: "" },
1089
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD747", unit: "\u5305", qty: 729, price: 4.75, amount: 3462.75, remark: "" },
1090
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD748", unit: "\u53EA", qty: 746, price: 5, amount: 3730, remark: "" },
1091
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD749", unit: "\u7EC4", qty: 763, price: 5.25, amount: 4005.75, remark: "" },
1092
- { name: "\u78B3\u94A2\u87BA\u4E1D M8", spec: "M14\xD710", unit: "\u4E2A", qty: 780, price: 0.5, amount: 390, remark: "" },
1093
- { name: "\u4E0D\u9508\u94A2\u87BA\u6BCD M10", spec: "M16\xD711", unit: "\u5957", qty: 797, price: 0.75, amount: 597.75, remark: "" },
1094
- { name: "\u5F39\u7C27\u57AB\u5708 M12", spec: "M6\xD712", unit: "\u76D2", qty: 814, price: 1, amount: 814, remark: "A\u7EA7" },
1095
- { name: "\u516D\u89D2\u87BA\u6813 M14", spec: "M5\xD713", unit: "\u652F", qty: 831, price: 1.25, amount: 1038.75, remark: "" },
1096
- { name: "\u5185\u516D\u89D2\u87BA\u9489 M16", spec: "M20\xD714", unit: "\u888B", qty: 848, price: 1.5, amount: 1272, remark: "" },
1097
- { name: "\u5E73\u57AB\u5708 M6", spec: "M4\xD715", unit: "\u4EF6", qty: 865, price: 1.75, amount: 1513.75, remark: "" },
1098
- { name: "\u81EA\u653B\u87BA\u9489 M5", spec: "M3\xD716", unit: "\u6839", qty: 882, price: 2, amount: 1764, remark: "" },
1099
- { name: "\u53CC\u5934\u87BA\u67F1 M20", spec: "M8\xD717", unit: "\u5305", qty: 899, price: 2.25, amount: 2022.75, remark: "" },
1100
- { name: "\u7D27\u5B9A\u87BA\u9489 M4", spec: "M10\xD718", unit: "\u53EA", qty: 916, price: 2.5, amount: 2290, remark: "" },
1101
- { name: "\u5341\u5B57\u76D8\u5934\u9489 M3", spec: "M12\xD719", unit: "\u7EC4", qty: 933, price: 2.75, amount: 2565.75, remark: "A\u7EA7" }
1102
- ]
1103
- };
1104
-
1105
- // src/designer/utils/engine.ts
1106
- var engine = new TemplateEngine();
1107
-
1108
- // src/designer/utils/expression-eval.ts
1109
- var EXTENDED_FUNCTIONS = {
1110
- MONEY: formatMoney,
1111
- CONCAT: (...args) => args.filter((v) => v != null).join(""),
1112
- IF: ifFn,
1113
- FORMAT: (value) => {
1114
- if (typeof value !== "number") return String(value);
1115
- return value.toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
1116
- },
1117
- SUBSTR: (str, start, len) => String(str).slice(start, len ? start + len : void 0),
1118
- LEN: (str) => String(str).length,
1119
- // 四则运算(与 +/-/*// 运算符同一套数值语义,供不方便写运算符的场景使用)
1120
- ADD: addNumbers,
1121
- SUB: subtractNumbers,
1122
- MUL: multiplyNumbers,
1123
- DIV: divideNumbers,
1124
- // 数值修约
1125
- ROUND: round,
1126
- ROUNDUP: roundUp,
1127
- CEIL: roundUp,
1128
- ROUNDDOWN: roundDown,
1129
- FLOOR: roundDown,
1130
- ROUNDBANK: roundHalfEven,
1131
- NOW: () => (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
1132
- IFEMPTY: (value, defaultVal) => value != null && value !== "" ? String(value) : defaultVal,
1133
- PAD: (value, len, char) => String(value).padStart(len, char),
1134
- REPLACE: (str, from, to) => String(str).replace(new RegExp(from, "g"), to),
1135
- JSON: (value) => JSON.stringify(value, null, 2),
1136
- DATE: formatDate,
1137
- UPPER: toUpperCaseAmount
1138
- };
1139
- for (const [name, fn] of Object.entries(EXTENDED_FUNCTIONS)) {
1140
- engine.registerFunction(name, fn);
1141
- }
1142
- function aggregate(fn, field, rows) {
1143
- switch (fn.toUpperCase()) {
1144
- case "SUM":
1145
- return sum(rows, field);
1146
- case "AVG":
1147
- return avg(rows, field);
1148
- case "COUNT":
1149
- return count(rows, field);
1150
- case "MIN":
1151
- return min(rows, field);
1152
- case "MAX":
1153
- return max(rows, field);
1154
- default:
1155
- return 0;
1156
- }
1157
- }
1158
- function safeEval(expr, context, _callableNames) {
1159
- return engine.evaluate(expr, context);
1160
- }
1161
- function evaluateTemplate(text, ctx) {
1162
- if (!text) return "";
1163
- if (!text.includes("{")) return text;
1164
- const rows = Array.isArray(ctx.rows) ? ctx.rows : [];
1165
- let processedText = text.replace(/\{([^}]+)\}/g, (_match, inner) => {
1166
- let expr = inner.trim();
1167
- expr = expr.replace(/\b(SUM|AVG|COUNT|MIN|MAX)\(([^)]+)\)/g, (_m, fn, arg) => {
1168
- const field = arg.trim().replace(/^['"]|['"]$/g, "");
1169
- return String(aggregate(fn, field, rows));
1170
- });
1171
- return `{${expr}}`;
1172
- });
1173
- try {
1174
- const result = engine.render(processedText, ctx);
1175
- return result;
1176
- } catch {
1177
- return text;
1178
- }
1179
- }
1180
-
1181
1365
  // src/designer/utils/binding.ts
1182
1366
  function createFieldElement(field) {
1183
1367
  return createRuntimeElement("text", {
@@ -1706,6 +1890,13 @@ export {
1706
1890
  BARCODE_MODULE_WIDTH_MM,
1707
1891
  BARCODE_QUIET_ZONE_MODULES,
1708
1892
  BARCODE_TEXT_FONT_SIZE_MODULES,
1893
+ CROP_AXIS_OPTIONS,
1894
+ CROP_GRID_OPTIONS,
1895
+ CROP_SAMPLE_IMAGE,
1896
+ CROP_SAMPLE_NOTE,
1897
+ CROP_SCALE_LABEL,
1898
+ CROP_SCALE_MAX,
1899
+ CROP_SCALE_MIN,
1709
1900
  DEFAULT_DEMO_DATA,
1710
1901
  DEFAULT_SHRINK_MIN_FONT_SIZE_PT,
1711
1902
  ELEMENT_BINDING_REGISTRY,
@@ -1713,6 +1904,7 @@ export {
1713
1904
  EXTENDED_FUNCTIONS,
1714
1905
  FIT_SCALE_MIN_PERCENT,
1715
1906
  GHOST_BORDER_CSS,
1907
+ IMAGE_FIT_OPTIONS,
1716
1908
  LABEL_PAPER_GROUP,
1717
1909
  MIN_COL_WIDTH_MM,
1718
1910
  MIN_SCALE_PERCENT,
@@ -1729,12 +1921,14 @@ export {
1729
1921
  barcodeAvailableBoxMm,
1730
1922
  barcodePreferredModuleWidthMm,
1731
1923
  barcodeUnitsPerModule,
1924
+ buildCropAnchor,
1732
1925
  buildRulerTicks,
1733
1926
  calcResizeRect,
1734
1927
  canMergeReason,
1735
1928
  cellFitCapMm,
1736
1929
  cellFitKey,
1737
1930
  cellFitWidthMm,
1931
+ cellImageBoxMm,
1738
1932
  chooseMajorStepMM,
1739
1933
  clampResizedColumnWidth,
1740
1934
  clampScalePercent,
@@ -1746,6 +1940,13 @@ export {
1746
1940
  createDefaultTable,
1747
1941
  createFieldElement,
1748
1942
  createRuntimeElement,
1943
+ cropAxisFields,
1944
+ cropAxisLabel,
1945
+ cropAxisNote,
1946
+ cropPresetOptions,
1947
+ cropScalePct,
1948
+ cropStyleDeclarations,
1949
+ cropWindow,
1749
1950
  deleteCol,
1750
1951
  deleteRow,
1751
1952
  engine,
@@ -1777,6 +1978,7 @@ export {
1777
1978
  normalizeSelection,
1778
1979
  normalizeTemplateUnits,
1779
1980
  parseCellFitKey,
1981
+ parseCropAnchor,
1780
1982
  propertyTip,
1781
1983
  ptToMm,
1782
1984
  pxToMm,
@@ -1784,13 +1986,18 @@ export {
1784
1986
  resolveBarcodeSize,
1785
1987
  resolveCellBorderCss,
1786
1988
  resolveCellTextFit,
1989
+ resolveCropPreview,
1990
+ resolveCropTravel,
1991
+ resolveDesignImageSrc,
1787
1992
  resolveElementBorder,
1788
1993
  resolveElementTextFit,
1994
+ resolveOverlayPlacement,
1789
1995
  resolveShrinkMinFontSize,
1790
1996
  resolveTextBinding,
1791
1997
  resolveToolbarOverflow,
1792
1998
  roundFontSize,
1793
1999
  safeEval,
2000
+ sanitizeObjectPosition,
1794
2001
  searchProperties,
1795
2002
  setHeaderRepeat,
1796
2003
  setRowType,