@cecee/document-flip-book 1.0.19 → 1.0.21

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.
Files changed (91) hide show
  1. package/dist/cjs/AccountingBook/assets/active-line.png +0 -0
  2. package/dist/cjs/AccountingBook/assets/default-line.png +0 -0
  3. package/dist/cjs/AccountingBook/assets/filp-bg.png +0 -0
  4. package/dist/cjs/AccountingBook/components/AccountingVoucher/index.d.ts +26 -0
  5. package/dist/cjs/AccountingBook/components/AccountingVoucher/index.js +398 -0
  6. package/dist/cjs/AccountingBook/components/AccountingVoucher/index.less +231 -0
  7. package/dist/cjs/AccountingBook/components/ExportModal.d.ts +10 -0
  8. package/dist/cjs/AccountingBook/components/ExportModal.js +96 -0
  9. package/dist/cjs/AccountingBook/components/FilpPage.d.ts +7 -0
  10. package/dist/cjs/AccountingBook/components/FilpPage.js +39 -0
  11. package/dist/cjs/AccountingBook/components/HeaderBar.d.ts +28 -0
  12. package/dist/cjs/AccountingBook/components/HeaderBar.js +245 -0
  13. package/dist/cjs/AccountingBook/components/ImagePageRenderer.d.ts +11 -0
  14. package/dist/cjs/AccountingBook/components/ImagePageRenderer.js +91 -0
  15. package/dist/cjs/AccountingBook/components/LoadingComponent.d.ts +7 -0
  16. package/dist/cjs/AccountingBook/components/LoadingComponent.js +54 -0
  17. package/dist/cjs/AccountingBook/components/PDFPageRenderer.d.ts +13 -0
  18. package/dist/cjs/AccountingBook/components/PDFPageRenderer.js +259 -0
  19. package/dist/cjs/AccountingBook/components/index.less +6 -0
  20. package/dist/cjs/AccountingBook/constants.d.ts +11 -0
  21. package/dist/cjs/AccountingBook/constants.js +25 -0
  22. package/dist/cjs/AccountingBook/hooks/useAmountSearch.d.ts +24 -0
  23. package/dist/cjs/AccountingBook/hooks/useAmountSearch.js +165 -0
  24. package/dist/cjs/AccountingBook/hooks/usePageFlip.d.ts +15 -0
  25. package/dist/cjs/AccountingBook/hooks/usePageFlip.js +67 -0
  26. package/dist/cjs/AccountingBook/index.d.ts +29 -1
  27. package/dist/cjs/AccountingBook/index.js +1163 -7
  28. package/dist/cjs/AccountingBook/index.less +188 -0
  29. package/dist/cjs/AccountingBook/types.d.ts +84 -0
  30. package/dist/cjs/AccountingBook/types.js +5 -0
  31. package/dist/cjs/AccountingBook/utils/canvasUtils.d.ts +51 -0
  32. package/dist/cjs/AccountingBook/utils/canvasUtils.js +499 -0
  33. package/dist/cjs/AccountingBook/utils/html.d.ts +9 -0
  34. package/dist/cjs/AccountingBook/utils/html.js +97 -0
  35. package/dist/cjs/AccountingBook/utils/utils.d.ts +38 -0
  36. package/dist/cjs/AccountingBook/utils/utils.js +204 -0
  37. package/dist/cjs/DocumentFlipBook/ExportModal.d.ts +1 -1
  38. package/dist/cjs/DocumentFlipBook/ExportModal.js +1 -1
  39. package/dist/cjs/DocumentFlipBook/HeaderBar.d.ts +2 -1
  40. package/dist/cjs/DocumentFlipBook/HeaderBar.js +13 -11
  41. package/dist/cjs/DocumentFlipBook/SideTabs.js +111 -6
  42. package/dist/cjs/DocumentFlipBook/index.d.ts +1 -0
  43. package/dist/cjs/DocumentFlipBook/index.js +6 -3
  44. package/dist/cjs/DocumentFlipBook/index.less +235 -9
  45. package/dist/cjs/declarations.d.ts +21 -0
  46. package/dist/esm/AccountingBook/assets/active-line.png +0 -0
  47. package/dist/esm/AccountingBook/assets/default-line.png +0 -0
  48. package/dist/esm/AccountingBook/assets/filp-bg.png +0 -0
  49. package/dist/esm/AccountingBook/components/AccountingVoucher/index.d.ts +26 -0
  50. package/dist/esm/AccountingBook/components/AccountingVoucher/index.js +391 -0
  51. package/dist/esm/AccountingBook/components/AccountingVoucher/index.less +231 -0
  52. package/dist/esm/AccountingBook/components/ExportModal.d.ts +10 -0
  53. package/dist/esm/AccountingBook/components/ExportModal.js +88 -0
  54. package/dist/esm/AccountingBook/components/FilpPage.d.ts +7 -0
  55. package/dist/esm/AccountingBook/components/FilpPage.js +33 -0
  56. package/dist/esm/AccountingBook/components/HeaderBar.d.ts +28 -0
  57. package/dist/esm/AccountingBook/components/HeaderBar.js +236 -0
  58. package/dist/esm/AccountingBook/components/ImagePageRenderer.d.ts +11 -0
  59. package/dist/esm/AccountingBook/components/ImagePageRenderer.js +85 -0
  60. package/dist/esm/AccountingBook/components/LoadingComponent.d.ts +7 -0
  61. package/dist/esm/AccountingBook/components/LoadingComponent.js +48 -0
  62. package/dist/esm/AccountingBook/components/PDFPageRenderer.d.ts +13 -0
  63. package/dist/esm/AccountingBook/components/PDFPageRenderer.js +252 -0
  64. package/dist/esm/AccountingBook/components/index.less +6 -0
  65. package/dist/esm/AccountingBook/constants.d.ts +11 -0
  66. package/dist/esm/AccountingBook/constants.js +17 -0
  67. package/dist/esm/AccountingBook/hooks/useAmountSearch.d.ts +24 -0
  68. package/dist/esm/AccountingBook/hooks/useAmountSearch.js +158 -0
  69. package/dist/esm/AccountingBook/hooks/usePageFlip.d.ts +15 -0
  70. package/dist/esm/AccountingBook/hooks/usePageFlip.js +61 -0
  71. package/dist/esm/AccountingBook/index.d.ts +29 -1
  72. package/dist/esm/AccountingBook/index.js +1162 -6
  73. package/dist/esm/AccountingBook/index.less +188 -0
  74. package/dist/esm/AccountingBook/types.d.ts +84 -0
  75. package/dist/esm/AccountingBook/types.js +1 -0
  76. package/dist/esm/AccountingBook/utils/canvasUtils.d.ts +51 -0
  77. package/dist/esm/AccountingBook/utils/canvasUtils.js +493 -0
  78. package/dist/esm/AccountingBook/utils/html.d.ts +9 -0
  79. package/dist/esm/AccountingBook/utils/html.js +89 -0
  80. package/dist/esm/AccountingBook/utils/utils.d.ts +38 -0
  81. package/dist/esm/AccountingBook/utils/utils.js +195 -0
  82. package/dist/esm/DocumentFlipBook/ExportModal.d.ts +1 -1
  83. package/dist/esm/DocumentFlipBook/ExportModal.js +1 -1
  84. package/dist/esm/DocumentFlipBook/HeaderBar.d.ts +2 -1
  85. package/dist/esm/DocumentFlipBook/HeaderBar.js +13 -11
  86. package/dist/esm/DocumentFlipBook/SideTabs.js +110 -5
  87. package/dist/esm/DocumentFlipBook/index.d.ts +1 -0
  88. package/dist/esm/DocumentFlipBook/index.js +6 -3
  89. package/dist/esm/DocumentFlipBook/index.less +235 -9
  90. package/dist/esm/declarations.d.ts +21 -0
  91. package/package.json +8 -2
@@ -0,0 +1,493 @@
1
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
2
+ function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw new Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator.return && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw new Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, catch: function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw new Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
3
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
5
+ import html2canvas from 'html2canvas';
6
+ import { pdfjs } from 'react-pdf';
7
+ import { PDFPageRenderer } from "../components/PDFPageRenderer";
8
+ import { ImagePageRenderer } from "../components/ImagePageRenderer";
9
+ import { getVoucherCanvasHtml, getAttachmentCanvasHtml, getCoverCanvasHtml } from "./html";
10
+ import React from 'react';
11
+
12
+ // ====================== 全局工具:图片/PDF/Canvas 处理 ======================
13
+
14
+ /**
15
+ * 预加载单张图片并转 Base64
16
+ */
17
+ export var preloadAndConvertImage = function preloadAndConvertImage(url) {
18
+ return new Promise(function (resolve) {
19
+ var img = new Image();
20
+ var timeout = setTimeout(function () {
21
+ console.warn('图片加载超时:', url);
22
+ resolve(null);
23
+ }, 30000);
24
+ img.onload = function () {
25
+ clearTimeout(timeout);
26
+ try {
27
+ var canvas = document.createElement('canvas');
28
+ var ctx = canvas.getContext('2d');
29
+ canvas.width = img.naturalWidth;
30
+ canvas.height = img.naturalHeight;
31
+ if (ctx) {
32
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
33
+ ctx.drawImage(img, 0, 0);
34
+ var base64 = canvas.toDataURL('image/png');
35
+ resolve(base64);
36
+ } else {
37
+ resolve(null);
38
+ }
39
+ } catch (error) {
40
+ console.error('图片转换失败:', url, error);
41
+ resolve(null);
42
+ }
43
+ };
44
+ img.onerror = function (error) {
45
+ clearTimeout(timeout);
46
+ console.error('图片加载失败:', url, error);
47
+ resolve(null);
48
+ };
49
+ img.crossOrigin = 'anonymous';
50
+ var imageUrl = url.includes('?') ? "".concat(url, "&_t=").concat(Date.now()) : "".concat(url, "?_t=").concat(Date.now());
51
+ img.src = imageUrl;
52
+ });
53
+ };
54
+
55
+ /**
56
+ * 批量预加载图片
57
+ */
58
+ export var batchPreloadImages = /*#__PURE__*/function () {
59
+ var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee2(imageUrls) {
60
+ var imageMap, batchSize, i, batch, promises;
61
+ return _regeneratorRuntime().wrap(function _callee2$(_context2) {
62
+ while (1) switch (_context2.prev = _context2.next) {
63
+ case 0:
64
+ console.log("\u5F00\u59CB\u6279\u91CF\u9884\u52A0\u8F7D ".concat(imageUrls.length, " \u5F20\u56FE\u7247"));
65
+ imageMap = new Map();
66
+ batchSize = 3;
67
+ i = 0;
68
+ case 4:
69
+ if (!(i < imageUrls.length)) {
70
+ _context2.next = 15;
71
+ break;
72
+ }
73
+ batch = imageUrls.slice(i, i + batchSize);
74
+ promises = batch.map( /*#__PURE__*/function () {
75
+ var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(url) {
76
+ var base64;
77
+ return _regeneratorRuntime().wrap(function _callee$(_context) {
78
+ while (1) switch (_context.prev = _context.next) {
79
+ case 0:
80
+ _context.next = 2;
81
+ return preloadAndConvertImage(url);
82
+ case 2:
83
+ base64 = _context.sent;
84
+ if (base64) imageMap.set(url, base64);
85
+ return _context.abrupt("return", {
86
+ url: url,
87
+ success: !!base64
88
+ });
89
+ case 5:
90
+ case "end":
91
+ return _context.stop();
92
+ }
93
+ }, _callee);
94
+ }));
95
+ return function (_x2) {
96
+ return _ref2.apply(this, arguments);
97
+ };
98
+ }());
99
+ _context2.next = 9;
100
+ return Promise.all(promises);
101
+ case 9:
102
+ if (!(i + batchSize < imageUrls.length)) {
103
+ _context2.next = 12;
104
+ break;
105
+ }
106
+ _context2.next = 12;
107
+ return new Promise(function (resolve) {
108
+ return setTimeout(resolve, 500);
109
+ });
110
+ case 12:
111
+ i += batchSize;
112
+ _context2.next = 4;
113
+ break;
114
+ case 15:
115
+ console.log("\u56FE\u7247\u9884\u52A0\u8F7D\u5B8C\u6210: ".concat(imageMap.size, "/").concat(imageUrls.length));
116
+ return _context2.abrupt("return", imageMap);
117
+ case 17:
118
+ case "end":
119
+ return _context2.stop();
120
+ }
121
+ }, _callee2);
122
+ }));
123
+ return function batchPreloadImages(_x) {
124
+ return _ref.apply(this, arguments);
125
+ };
126
+ }();
127
+
128
+ /**
129
+ * 从 React 节点提取附件信息
130
+ */
131
+ export var extractAttachmentInfo = function extractAttachmentInfo(pageElement) {
132
+ try {
133
+ if (pageElement.type === ImagePageRenderer) {
134
+ return {
135
+ type: 'image',
136
+ src: pageElement.props.src,
137
+ alt: pageElement.props.alt || '',
138
+ attachmentCount: pageElement.props.attachmentCount || 1,
139
+ amount: pageElement.props.amount || '0.00'
140
+ };
141
+ }
142
+ if (pageElement.type === PDFPageRenderer) {
143
+ return {
144
+ type: 'pdf',
145
+ src: pageElement.props.pdfPath,
146
+ pageNumber: pageElement.props.pageNumber || 1,
147
+ attachmentCount: pageElement.props.attachmentCount || 1,
148
+ amount: pageElement.props.amount || '0.00'
149
+ };
150
+ }
151
+ var props = pageElement.props;
152
+ if (props && props.children && /*#__PURE__*/React.isValidElement(props.children)) {
153
+ var childProps = props.children.props;
154
+ if (childProps) {
155
+ if (childProps.src && !childProps.pdfPath) {
156
+ return {
157
+ type: 'image',
158
+ src: childProps.src,
159
+ alt: childProps.alt || '',
160
+ attachmentCount: childProps.attachmentCount || 1,
161
+ amount: childProps.amount || '0.00'
162
+ };
163
+ } else if (childProps.pdfPath) {
164
+ return {
165
+ type: 'pdf',
166
+ src: childProps.pdfPath,
167
+ pageNumber: childProps.pageNumber || 1,
168
+ attachmentCount: childProps.attachmentCount || 1,
169
+ amount: childProps.amount || '0.00'
170
+ };
171
+ }
172
+ }
173
+ }
174
+ return null;
175
+ } catch (error) {
176
+ console.error('提取附件信息失败:', error);
177
+ return null;
178
+ }
179
+ };
180
+
181
+ /**
182
+ * Base64 转图片元素
183
+ */
184
+ export var createImageElementFromBase64 = function createImageElementFromBase64(base64Data) {
185
+ return new Promise(function (resolve) {
186
+ var img = new Image();
187
+ img.onload = function () {
188
+ return resolve(img);
189
+ };
190
+ img.onerror = function () {
191
+ return resolve(null);
192
+ };
193
+ img.src = base64Data;
194
+ });
195
+ };
196
+
197
+ /**
198
+ * 直接通过 URL 创建图片元素
199
+ */
200
+ export var createImageElementDirect = function createImageElementDirect(imageSrc) {
201
+ return new Promise(function (resolve) {
202
+ var img = new Image();
203
+ var timeout = setTimeout(function () {
204
+ console.error('直接图片加载超时:', imageSrc);
205
+ resolve(null);
206
+ }, 15000);
207
+ img.onload = function () {
208
+ clearTimeout(timeout);
209
+ resolve(img);
210
+ };
211
+ img.onerror = function () {
212
+ clearTimeout(timeout);
213
+ resolve(null);
214
+ };
215
+ img.crossOrigin = 'anonymous';
216
+ img.src = imageSrc;
217
+ });
218
+ };
219
+
220
+ /**
221
+ * PDF 页面转图片 Base64
222
+ */
223
+ export var renderPDFPageToImageBase64 = /*#__PURE__*/function () {
224
+ var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(pdfPath) {
225
+ var pageNumber,
226
+ pdf,
227
+ page,
228
+ canvas,
229
+ context,
230
+ scale,
231
+ viewport,
232
+ _args3 = arguments;
233
+ return _regeneratorRuntime().wrap(function _callee3$(_context3) {
234
+ while (1) switch (_context3.prev = _context3.next) {
235
+ case 0:
236
+ pageNumber = _args3.length > 1 && _args3[1] !== undefined ? _args3[1] : 1;
237
+ _context3.prev = 1;
238
+ _context3.next = 4;
239
+ return pdfjs.getDocument({
240
+ url: pdfPath,
241
+ cMapUrl: "https://unpkg.com/pdfjs-dist@".concat(pdfjs.version, "/cmaps/"),
242
+ cMapPacked: true
243
+ }).promise;
244
+ case 4:
245
+ pdf = _context3.sent;
246
+ _context3.next = 7;
247
+ return pdf.getPage(pageNumber);
248
+ case 7:
249
+ page = _context3.sent;
250
+ canvas = document.createElement('canvas');
251
+ context = canvas.getContext('2d');
252
+ scale = 2.0;
253
+ viewport = page.getViewport({
254
+ scale: scale
255
+ });
256
+ canvas.width = viewport.width;
257
+ canvas.height = viewport.height;
258
+ if (context) {
259
+ _context3.next = 16;
260
+ break;
261
+ }
262
+ throw new Error('Canvas 上下文获取失败');
263
+ case 16:
264
+ _context3.next = 18;
265
+ return page.render({
266
+ canvas: canvas,
267
+ canvasContext: context,
268
+ viewport: viewport
269
+ }).promise;
270
+ case 18:
271
+ return _context3.abrupt("return", canvas.toDataURL('image/jpeg', 0.9));
272
+ case 21:
273
+ _context3.prev = 21;
274
+ _context3.t0 = _context3["catch"](1);
275
+ console.error('PDF转图片失败:', _context3.t0);
276
+ return _context3.abrupt("return", null);
277
+ case 25:
278
+ case "end":
279
+ return _context3.stop();
280
+ }
281
+ }, _callee3, null, [[1, 21]]);
282
+ }));
283
+ return function renderPDFPageToImageBase64(_x3) {
284
+ return _ref3.apply(this, arguments);
285
+ };
286
+ }();
287
+
288
+ /**
289
+ * 创建凭证 Canvas(用于导出)
290
+ */
291
+ export var createVoucherCanvas = /*#__PURE__*/function () {
292
+ var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee4(voucherProps, baseVoucherInfo) {
293
+ var pageDiv;
294
+ return _regeneratorRuntime().wrap(function _callee4$(_context4) {
295
+ while (1) switch (_context4.prev = _context4.next) {
296
+ case 0:
297
+ pageDiv = document.createElement('div');
298
+ pageDiv.style.cssText = "\n position: absolute; left: -9999px; top: -9999px;\n width: 998px; height: 520px; background: #fff;\n ";
299
+ pageDiv.innerHTML = getVoucherCanvasHtml(voucherProps, baseVoucherInfo);
300
+ document.body.appendChild(pageDiv);
301
+ _context4.prev = 4;
302
+ _context4.next = 7;
303
+ return new Promise(function (r) {
304
+ return setTimeout(r, 200);
305
+ });
306
+ case 7:
307
+ _context4.next = 9;
308
+ return html2canvas(pageDiv, {
309
+ width: 998,
310
+ height: 520,
311
+ scale: 1.5,
312
+ useCORS: true,
313
+ allowTaint: false,
314
+ backgroundColor: '#fff',
315
+ logging: false
316
+ });
317
+ case 9:
318
+ return _context4.abrupt("return", _context4.sent);
319
+ case 12:
320
+ _context4.prev = 12;
321
+ _context4.t0 = _context4["catch"](4);
322
+ console.error('凭证画布生成失败', _context4.t0);
323
+ return _context4.abrupt("return", null);
324
+ case 16:
325
+ _context4.prev = 16;
326
+ document.body.contains(pageDiv) && document.body.removeChild(pageDiv);
327
+ return _context4.finish(16);
328
+ case 19:
329
+ case "end":
330
+ return _context4.stop();
331
+ }
332
+ }, _callee4, null, [[4, 12, 16, 19]]);
333
+ }));
334
+ return function createVoucherCanvas(_x4, _x5) {
335
+ return _ref4.apply(this, arguments);
336
+ };
337
+ }();
338
+
339
+ /**
340
+ * 创建附件 Canvas
341
+ */
342
+ export var createAttachmentCanvasFixed = /*#__PURE__*/function () {
343
+ var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee5(attachmentInfo, preloadedImages) {
344
+ var container, attachmentDiv, contentDiv, loadingPlaceholder, imageElement, base64, pdfBase64;
345
+ return _regeneratorRuntime().wrap(function _callee5$(_context5) {
346
+ while (1) switch (_context5.prev = _context5.next) {
347
+ case 0:
348
+ container = document.createElement('div');
349
+ container.style.cssText = "\n position: absolute; left: -9999px; top: -9999px;\n width: 998px; height: 520px; background: white;\n ";
350
+ document.body.appendChild(container);
351
+ _context5.prev = 3;
352
+ attachmentDiv = document.createElement('div');
353
+ attachmentDiv.innerHTML = getAttachmentCanvasHtml(attachmentInfo);
354
+ container.appendChild(attachmentDiv);
355
+ contentDiv = attachmentDiv.querySelector('#attachment-content');
356
+ loadingPlaceholder = attachmentDiv.querySelector('#loading-placeholder');
357
+ imageElement = null;
358
+ if (!(attachmentInfo.type === 'image')) {
359
+ _context5.next = 23;
360
+ break;
361
+ }
362
+ base64 = preloadedImages.get(attachmentInfo.src);
363
+ if (!base64) {
364
+ _context5.next = 18;
365
+ break;
366
+ }
367
+ _context5.next = 15;
368
+ return createImageElementFromBase64(base64);
369
+ case 15:
370
+ imageElement = _context5.sent;
371
+ _context5.next = 21;
372
+ break;
373
+ case 18:
374
+ _context5.next = 20;
375
+ return createImageElementDirect(attachmentInfo.src);
376
+ case 20:
377
+ imageElement = _context5.sent;
378
+ case 21:
379
+ _context5.next = 31;
380
+ break;
381
+ case 23:
382
+ if (!(attachmentInfo.type === 'pdf')) {
383
+ _context5.next = 31;
384
+ break;
385
+ }
386
+ _context5.next = 26;
387
+ return renderPDFPageToImageBase64(attachmentInfo.src, attachmentInfo.pageNumber || 1);
388
+ case 26:
389
+ pdfBase64 = _context5.sent;
390
+ if (!pdfBase64) {
391
+ _context5.next = 31;
392
+ break;
393
+ }
394
+ _context5.next = 30;
395
+ return createImageElementFromBase64(pdfBase64);
396
+ case 30:
397
+ imageElement = _context5.sent;
398
+ case 31:
399
+ if (!(imageElement && contentDiv)) {
400
+ _context5.next = 37;
401
+ break;
402
+ }
403
+ loadingPlaceholder.style.display = 'none';
404
+ imageElement.style.cssText = "max-width:95%;max-height:95%;object-fit:contain";
405
+ contentDiv.appendChild(imageElement);
406
+ _context5.next = 37;
407
+ return new Promise(function (r) {
408
+ return setTimeout(r, 800);
409
+ });
410
+ case 37:
411
+ _context5.next = 39;
412
+ return html2canvas(attachmentDiv, {
413
+ width: 998,
414
+ height: 520,
415
+ scale: 1.5,
416
+ useCORS: false,
417
+ allowTaint: true,
418
+ backgroundColor: '#fff',
419
+ logging: false
420
+ });
421
+ case 39:
422
+ return _context5.abrupt("return", _context5.sent);
423
+ case 42:
424
+ _context5.prev = 42;
425
+ _context5.t0 = _context5["catch"](3);
426
+ console.error('附件画布生成失败', _context5.t0);
427
+ return _context5.abrupt("return", null);
428
+ case 46:
429
+ _context5.prev = 46;
430
+ document.body.contains(container) && document.body.removeChild(container);
431
+ return _context5.finish(46);
432
+ case 49:
433
+ case "end":
434
+ return _context5.stop();
435
+ }
436
+ }, _callee5, null, [[3, 42, 46, 49]]);
437
+ }));
438
+ return function createAttachmentCanvasFixed(_x6, _x7) {
439
+ return _ref5.apply(this, arguments);
440
+ };
441
+ }();
442
+
443
+ /**
444
+ * 创建封面 Canvas
445
+ */
446
+ export var createCoverCanvas = /*#__PURE__*/function () {
447
+ var _ref6 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee6(coverData, companyName) {
448
+ var container, coverDiv;
449
+ return _regeneratorRuntime().wrap(function _callee6$(_context6) {
450
+ while (1) switch (_context6.prev = _context6.next) {
451
+ case 0:
452
+ container = document.createElement('div');
453
+ container.style.cssText = "\n position: absolute; left: -9999px; top: -9999px;\n width: 998px; height: 520px; background: white;\n ";
454
+ document.body.appendChild(container);
455
+ _context6.prev = 3;
456
+ coverDiv = document.createElement('div');
457
+ coverDiv.innerHTML = getCoverCanvasHtml(coverData, companyName);
458
+ container.appendChild(coverDiv);
459
+ _context6.next = 9;
460
+ return new Promise(function (r) {
461
+ return setTimeout(r, 300);
462
+ });
463
+ case 9:
464
+ _context6.next = 11;
465
+ return html2canvas(coverDiv, {
466
+ width: 998,
467
+ height: 520,
468
+ scale: 1.5,
469
+ useCORS: true,
470
+ backgroundColor: '#CBA172',
471
+ logging: false
472
+ });
473
+ case 11:
474
+ return _context6.abrupt("return", _context6.sent);
475
+ case 14:
476
+ _context6.prev = 14;
477
+ _context6.t0 = _context6["catch"](3);
478
+ console.error('封面生成失败', _context6.t0);
479
+ return _context6.abrupt("return", null);
480
+ case 18:
481
+ _context6.prev = 18;
482
+ document.body.contains(container) && document.body.removeChild(container);
483
+ return _context6.finish(18);
484
+ case 21:
485
+ case "end":
486
+ return _context6.stop();
487
+ }
488
+ }, _callee6, null, [[3, 14, 18, 21]]);
489
+ }));
490
+ return function createCoverCanvas(_x8, _x9) {
491
+ return _ref6.apply(this, arguments);
492
+ };
493
+ }();
@@ -0,0 +1,9 @@
1
+ /**
2
+ * HTML 模板工具类
3
+ * 所有动态拼接的 HTML 统一抽离在这里
4
+ */
5
+ export declare function getAttachmentPasteHtml(attachment: any, amount: string, count: number): string;
6
+ export declare function getVoucherCanvasHtml(voucherProps: any, baseVoucherInfo: any): string;
7
+ export declare function getAttachmentCanvasHtml(attachmentInfo: any): string;
8
+ export declare function getCoverCanvasHtml(coverData: any, companyName: string): string;
9
+ export declare function getFullFlipbookHtml(pageDataArray: any[], coverData: any, filpBgBase64: string, defaultLineBase64: string, activeLineBase64: string): string;
@@ -0,0 +1,89 @@
1
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
+ /**
8
+ * HTML 模板工具类
9
+ * 所有动态拼接的 HTML 统一抽离在这里
10
+ */
11
+
12
+ import moment from 'moment';
13
+ import { formatAmount } from "./utils";
14
+
15
+ // ------------------------------
16
+ // 1. 原始凭证粘贴单 HTML
17
+ // ------------------------------
18
+ export function getAttachmentPasteHtml(attachment, amount, count) {
19
+ var isPDF = attachment.path.toLowerCase().endsWith('.pdf');
20
+ var formattedAmount = amount ? Number(amount).toLocaleString('zh-CN', {
21
+ minimumFractionDigits: 2
22
+ }) : '0.00';
23
+ return "\n <div style=\"width:100%;height:100%;padding:20px;box-sizing:border-box;background-color:#ffffff;\">\n <div style=\"text-align:center;font-size:24px;font-weight:bold;margin-bottom:15px;color:#8b4513;\">\n \u539F\u59CB\u51ED\u8BC1\u7C98\u8D34\u5355\n </div>\n <div style=\"position:absolute;top:20px;right:20px;text-align:right;font-size:14px;color:#8b4513;\">\n <div>\u539F\u59CB\u51ED\u8BC1: <span style=\"border-bottom:1px solid #8b4513;\">".concat(count, "</span> \u5F20</div>\n <div>\u91D1\u989D: <span style=\"border-bottom:1px solid #8b4513;\">").concat(formattedAmount, "</span></div>\n </div>\n <div style=\"width:100%;height:85%;display:flex;justify-content:center;align-items:center;\n border:1px dashed #8b4513;margin-top:20px;background-color:white;\">\n ").concat(isPDF ? "<div style=\"color:#666;font-size:16px;\">PDF\u9644\u4EF6 (".concat(attachment.path.split('/').pop(), ")</div>") : "<img src=\"".concat(attachment.path, "\" style=\"max-width:100%;max-height:100%;object-fit:contain;\"\n onerror=\"this.style.display='none';this.parentElement.innerHTML='<div style=\\\"color:red;font-size:20px;\\\">\u56FE\u7247\u52A0\u8F7D\u5931\u8D25</div>'\">"), "\n </div>\n </div>\n ");
24
+ }
25
+
26
+ // ------------------------------
27
+ // 2. 记账凭证画布 HTML(导出PDF用)
28
+ // ------------------------------
29
+ export function getVoucherCanvasHtml(voucherProps, baseVoucherInfo) {
30
+ var _voucherProps$date;
31
+ var originalEntries = voucherProps.entries || [];
32
+ var MIN_ROWS = 5;
33
+ var paddedEntries = _toConsumableArray(originalEntries);
34
+ while (paddedEntries.length < MIN_ROWS) {
35
+ paddedEntries.push({
36
+ summary: '',
37
+ account: '',
38
+ debit: '0',
39
+ credit: '0',
40
+ trade_direction: ''
41
+ });
42
+ }
43
+ return "\n <div class=\"voucher-wrapper\" style=\"\n background-color: #ffffff;\n color: #000;\n width: 998px;\n height: 520px;\n display: flex;\n justify-content: center;\n align-items: center;\n \">\n <div class=\"voucher-container\" style=\"\n max-width: 100%;\n max-height: 100%;\n background-color: #ffffff;\n position: relative;\n \">\n <div class=\"voucher-header\" style=\"text-align: center;\">\n <h1 style=\"font-size: 24px; margin: 0; letter-spacing: 4px; color: #000;\">\u8BB0 \u8D26 \u51ED \u8BC1</h1>\n <div class=\"header-line\" style=\"height: 1px; background-color: #000; margin: 8px auto; width: 300px; position: relative;\">\n <div style=\"position: absolute; top: 2px; left: 0; right: 0; height: 1px; background-color: #000;\"></div>\n </div>\n <div class=\"date\" style=\"font-size: 16px; margin-top: 10px;\">".concat(((_voucherProps$date = voucherProps.date) === null || _voucherProps$date === void 0 ? void 0 : _voucherProps$date.replace(/<[^>]+>/g, '')) || '', "</div>\n </div>\n\n <div class=\"company-info\" style=\"display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; font-size: 14px;\">\n <div class=\"company-name\" style=\"margin-right: 5px;\">\n <span style=\"color: #000;\">\u516C\u53F8\uFF1A</span>\n ").concat(voucherProps.company || baseVoucherInfo.company, "\n </div>\n <div class=\"voucher-no\" style=\"margin-right: 20px;\">\n <span style=\"color: #000;\">\u5B57\u7B2C</span> ").concat(voucherProps.voucherNo || '', " <span style=\"color: #000;\">\u53F7</span>\n </div>\n </div>\n\n <div class=\"voucher-table-wrapper\" style=\"border: 1px solid #000; padding: 1px; width: 890px;\">\n <table class=\"voucher-table\" style=\"width: 100%; border-collapse: collapse; border: 1px solid #000;\">\n <thead>\n <tr>\n <th class=\"summary\" style=\"width: 40%; text-align: center; border: 1px solid #000; height: 40px;\">\n <span style=\"color: #000;\">\u6458\u8981</span>\n </th>\n <th class=\"subject\" style=\"width: 45%; text-align: center; border: 1px solid #000; height: 40px;\">\n <span style=\"color: #000;\">\u79D1\u76EE</span>\n </th>\n <th class=\"checkmark\" style=\"width: 20px; text-align: center; border: 1px solid #000; color: #000; font-weight: normal; border-right: none; height: 40px;\"></th>\n <th class=\"amount\" colspan=\"11\" style=\"width: 22.5%; padding: 0; border: 1px solid #000; height: 40px;\">\n <div class=\"amount-header\" style=\"border-bottom: 1px solid #000; padding: 5px 0;\">\n <span style=\"color: #000;\">\u501F\u65B9\u91D1\u989D</span>\n </div>\n <div class=\"amount-grid\" style=\"display: grid; grid-template-columns: repeat(11, 1fr);\">\n ").concat(['亿', '千', '百', '十', '万', '千', '百', '十', '元', '角', '分'].map(function (unit) {
44
+ return "\n <span style=\"border-right: 1px solid #000; font-size: 12px; height: 24px; line-height: 24px; display: flex; align-items: center; justify-content: center; color: #000;\">".concat(unit, "</span>\n ");
45
+ }).join(''), "\n </div>\n </th>\n <th class=\"checkmark\" style=\"text-align: center; border: 1px solid #000; color: #000; font-weight: normal; border-right: none; height: 40px;\"></th>\n <th class=\"amount\" colspan=\"11\" style=\"width: 22.5%; padding: 0; border: 1px solid #000; height: 40px;\">\n <div class=\"amount-header\" style=\"border-bottom: 1px solid #000; padding: 5px 0;\">\n <span style=\"color: #000;\">\u8D37\u65B9\u91D1\u989D</span>\n </div>\n <div class=\"amount-grid\" style=\"display: grid; grid-template-columns: repeat(11, 1fr);\">\n ").concat(['亿', '千', '百', '十', '万', '千', '百', '十', '元', '角', '分'].map(function (unit) {
46
+ return "\n <span style=\"border-right: 1px solid #000; font-size: 12px; height: 24px; line-height: 24px; display: flex; align-items: center; justify-content: center; color: #000;\">".concat(unit, "</span>\n ");
47
+ }).join(''), "\n </div>\n </th>\n </tr>\n </thead>\n <tbody>\n ").concat(paddedEntries.map(function (entry) {
48
+ return "\n <tr style=\"height: 20px;\">\n <td class=\"summary\" style=\"text-align: left; font-family: \u5B8B\u4F53; border: 1px solid #000; height: 40px;\">".concat(entry.summary || '', "</td>\n <td class=\"subject\" style=\"text-align: left; font-family: \u5B8B\u4F53; border: 1px solid #000; height: 40px;\">").concat(entry.account || '', "</td>\n <td class=\"checkmark\" style=\"text-align: center; border: 1px solid #000; color: #000; font-weight: normal; border-right: none; height: 40px;\">").concat(entry.debit && parseFloat(entry.debit) > 0 ? '✓' : '', "</td>\n <td class=\"amount\" colspan=\"11\" style=\"padding: 0; border: 1px solid #000; height: 40px;\">\n <div class=\"money-grid\" style=\"display: grid; grid-template-columns: repeat(11, 1fr); height: 100%;\">\n ").concat(formatAmount(entry.debit).map(function (digit) {
49
+ return "\n <span class=\"money-cell\" style=\"width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; border-right: 1px solid #000; color: #000;\">".concat(digit, "</span>\n ");
50
+ }).join(''), "\n </div>\n </td>\n <td class=\"checkmark\" style=\"text-align: center; border: 1px solid #000; color: #000; font-weight: normal; border-right: none; height: 40px;\">").concat(entry.credit && parseFloat(entry.credit) > 0 ? '✓' : '', "</td>\n <td class=\"amount\" colspan=\"11\" style=\"padding: 0; border: 1px solid #000; height: 40px;\">\n <div class=\"money-grid\" style=\"display: grid; grid-template-columns: repeat(11, 1fr); height: 100%;\">\n ").concat(formatAmount(entry.credit).map(function (digit) {
51
+ return "\n <span class=\"money-cell\" style=\"width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; border-right: 1px solid #000; color: #000;\">".concat(digit, "</span>\n ");
52
+ }).join(''), "\n </div>\n </td>\n </tr>\n ");
53
+ }).join(''), "\n ").concat(voucherProps.showTotal ? "\n <tr class=\"total-row\" style=\"height: 20px;\">\n <td class=\"summary\" style=\"text-align: center; color: #000; border: 1px solid #000; height: 40px;\">\u5408\u8BA1</td>\n <td class=\"subject\" style=\"border: 1px solid #000; height: 40px;\"></td>\n <td class=\"checkmark\" style=\"text-align: center; border: 1px solid #000; color: #000; font-weight: normal; border-right: none; height: 40px;\">".concat(parseFloat(voucherProps.totalDebit) > 0 ? '✓' : '', "</td>\n <td class=\"amount\" colspan=\"11\" style=\"padding: 0; border: 1px solid #000; height: 40px;\">\n <div class=\"money-grid\" style=\"display: grid; grid-template-columns: repeat(11, 1fr); height: 100%;\">\n ").concat(formatAmount(voucherProps.totalDebit).map(function (digit) {
54
+ return "\n <span class=\"money-cell\" style=\"width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; border-right: 1px solid #000; color: #000;\">".concat(digit, "</span>\n ");
55
+ }).join(''), "\n </div>\n </td>\n <td class=\"checkmark\" style=\"text-align: center; border: 1px solid #000; color: #000; font-weight: normal; border-right: none; height: 40px;\">").concat(parseFloat(voucherProps.totalCredit) > 0 ? '✓' : '', "</td>\n <td class=\"amount\" colspan=\"11\" style=\"padding: 0; border: 1px solid #000; height: 40px;\">\n <div class=\"money-grid\" style=\"display: grid; grid-template-columns: repeat(11, 1fr); height: 100%;\">\n ").concat(formatAmount(voucherProps.totalCredit).map(function (digit) {
56
+ return "\n <span class=\"money-cell\" style=\"width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; border-right: 1px solid #000; color: #000;\">".concat(digit, "</span>\n ");
57
+ }).join(''), "\n </div>\n </td>\n </tr>\n ") : '', "\n </tbody>\n </table>\n </div>\n\n <div class=\"voucher-footer\" style=\"display: flex; justify-content: space-between; margin-top: 20px; font-size: 14px;\">\n <div class=\"footer-item\" style=\"margin-right: 5px;\">\n <span style=\"color: #000;\">\u4F1A\u8BA1\u4E3B\u7BA1\uFF1A</span>\n <span style=\"margin-left: 10px;\">").concat(voucherProps.accountant || baseVoucherInfo.accountant, "</span>\n </div>\n <div class=\"footer-item\" style=\"margin-right: 5px;\">\n <span style=\"color: #000;\">\u8BB0\u8D26\uFF1A</span>\n <span style=\"margin-left: 10px;\">").concat(voucherProps.recorder || baseVoucherInfo.recorder, "</span>\n </div>\n <div class=\"footer-item\">\n <span style=\"color: #000;\">\u5236\u5355\uFF1A</span>\n <span style=\"margin-left: 10px;\">").concat(voucherProps.maker || baseVoucherInfo.maker, "</span>\n </div>\n </div>\n </div>\n </div>\n ");
58
+ }
59
+
60
+ // ------------------------------
61
+ // 3. 附件画布 HTML(导出PDF用)
62
+ // ------------------------------
63
+ export function getAttachmentCanvasHtml(attachmentInfo) {
64
+ var formattedAmount = attachmentInfo.amount ? Number(attachmentInfo.amount).toLocaleString('zh-CN', {
65
+ minimumFractionDigits: 2
66
+ }) : '0.00';
67
+ return "\n <div style=\"width: 998px; height: 520px; background: #ffffff; padding: 20px; box-sizing: border-box; font-family: 'Microsoft YaHei', sans-serif; position: relative;\">\n <div style=\"text-align: center; font-size: 28px; font-weight: bold; margin-bottom: 25px; color: #597461;\">\n \u539F\u59CB\u51ED\u8BC1\u7C98\u8D34\u5355\n </div>\n <div style=\"position: absolute; top: 20px; right: 30px; text-align: right; font-size: 16px; color: #597461; line-height: 2;\">\n <div>\u539F\u59CB\u51ED\u8BC1: <span style=\"border-bottom: 1px solid #597461; padding-bottom: 2px;\">".concat(attachmentInfo.attachmentCount, "</span> \u5F20</div>\n <div>\u91D1\u989D: <span style=\"border-bottom: 1px solid #597461; padding-bottom: 2px;\">").concat(formattedAmount, "</span></div>\n </div>\n <div id=\"attachment-content\" style=\"\n width: calc(100% - 40px);\n height: 450px;\n border: 2px solid #597461;\n background: white;\n display: flex;\n align-items: center;\n justify-content: center;\n margin: 30px 20px 0;\n overflow: hidden;\n position: relative;\n \">\n <div id=\"loading-placeholder\" style=\"\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n color: #666;\n font-size: 18px;\n text-align: center;\n \">\n <div style=\"font-size: 24px; margin-bottom: 10px;\">\u23F3</div>\n <div>\u6B63\u5728\u5904\u7406\u9644\u4EF6...</div>\n </div>\n </div>\n </div>\n ");
68
+ }
69
+
70
+ // ------------------------------
71
+ // 4. 封面画布 HTML
72
+ // ------------------------------
73
+ export function getCoverCanvasHtml(coverData, companyName) {
74
+ var formattedDate = coverData.expiryDate || moment().format('YYYY-MM-DD');
75
+ return "\n <div style=\"\n width: 998px;\n height: 520px;\n background-image: url('/assets/material.jpg');\n background-size: cover;\n background-blend-mode: multiply;\n position: relative;\n box-shadow: -4px 0px 0px 0px #b08e67;\n font-family: 'Songti SC', 'SimSun', serif;\n color: #AD352F;\n padding: 40px 0;\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n \">\n <div style=\"\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n width: 160px;\n height: 39%;\n border-right: 2px solid #B48F65;\n transform: skewX(-45deg);\n transform-origin: top left;\n \"></div>\n <div style=\"\n position: absolute;\n top: 10px;\n left: 80px;\n transform: translateX(-50%) rotate(45deg);\n \">\n <div style=\"\n width: 24px;\n height: 24px;\n background: #8B6842;\n border: 6px solid #D9D9D9;\n border-radius: 50%;\n \"></div>\n <div style=\"\n width: 24px;\n height: 24px;\n background: #8B6842;\n border: 6px solid #D9D9D9;\n border-radius: 50%;\n margin-top: 80px;\n \"></div>\n </div>\n <div style=\"\n text-align: center;\n font-size: 36px;\n font-weight: bold;\n margin-bottom: 20px;\n color: #AD352F;\n \">\u4F1A\u8BA1\u51ED\u8BC1\u5C01\u9762</div>\n <div style=\"\n width: 300px;\n height: 2px;\n background-color: #AD352F;\n margin: 4px auto;\n \"></div>\n <div style=\"\n width: 300px;\n height: 2px;\n background-color: #AD352F;\n margin: 4px auto 40px;\n \"></div>\n <table style=\"\n width: 80%;\n margin: 0 auto;\n border-collapse: collapse;\n font-size: 20px;\n color: #AD352F;\n \">\n <tbody>\n <tr>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center; width: 25%;\">\u5355\u4F4D\u540D\u79F0</td>\n <td colspan=\"3\" style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\n <span style=\"color: #3A4662; font-weight: 600;\">".concat(companyName || '', "</span>\n </td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center; width: 25%;\">\u51ED\u8BC1\u518C\u53F7</td>\n <td colspan=\"3\" style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\n <span style=\"color: #3A4662; font-weight: 600;\">").concat(coverData.credentialCode || '', "</span>\n </td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\u51ED\u8BC1\u65E5\u671F</td>\n <td colspan=\"3\" style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\n <span style=\"color: #3A4662; font-weight: 600;\">").concat(formattedDate, "</span>\n </td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\u51ED\u8BC1\u518C\u6570</td>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center; width: 30%;\">\n \u5171<span style=\"color: #3A4662; font-weight: 600;\">").concat(coverData.total_page || 1, "</span>\u518C\u7B2C<span style=\"color: #3A4662; font-weight: 600;\">").concat(coverData.page_num || 1, "</span>\u518C\n </td>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center; width: 25%;\">\u51ED\u8BC1\u53F7\u6570</td>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\n <span style=\"color: #3A4662; font-weight: 600;\">").concat(coverData.credentialNumber || '', "</span>\n </td>\n </tr>\n <tr>\n <td style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\u88C5\u8BA2\u65F6\u95F4</td>\n <td colspan=\"3\" style=\"border: 1px solid #AD352F; padding: 12px; text-align: center;\">\n <span style=\"color: #3A4662; font-weight: 600;\">").concat(coverData.modificationTime || moment().format('YYYY-MM-DD HH:mm:ss'), "</span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n ");
76
+ }
77
+
78
+ // ------------------------------
79
+ // 5. 最终导出翻书 HTML(完整页面)
80
+ // ------------------------------
81
+ export function getFullFlipbookHtml(pageDataArray, coverData, filpBgBase64, defaultLineBase64, activeLineBase64) {
82
+ var now = moment();
83
+ var title = coverData !== null && coverData !== void 0 && coverData.credentialCode ? "".concat(coverData.credentialCode, " - \u8BB0\u8D26\u51ED\u8BC1") : "\u8BB0\u8D26\u51ED\u8BC1 - ".concat(now.format('YYYY年MM月DD日'));
84
+ var pagesHTML = pageDataArray.map(function (pageData, index) {
85
+ var isCover = index === 0;
86
+ return "<div class=\"page ".concat(isCover ? 'cover-page' : '', "\" data-page=\"").concat(index + 1, "\">").concat(pageData.html, "</div>");
87
+ }).join('\n');
88
+ return "<!DOCTYPE html>\n<html lang=\"zh-CN\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>".concat(title, "</title>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js\"></script>\n <script src=\"https://cdnjs.cloudflare.com/ajax/libs/turn.js/3/turn.min.js\"></script>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { font-family: \"Microsoft YaHei\", sans-serif; background: linear-gradient(135deg, #8c7739 0%, #6b5528 50%, #4a381c 100%); min-height: 100vh; display: flex; flex-direction: column; align-items: center; }\n .flipbook-container { position: relative; perspective: 2000px; width: 1100px; height: 660px; margin: 0 auto 20px; }\n .flipbook-bg { position: absolute; top: 10px; left: -76px; height: 487px; z-index: 1; opacity: 0; transition: opacity 0.3s; box-shadow: 4px 4px 4px 0 #b08e67; pointer-events: none; }\n .flipbook-bg.show { opacity: 1; }\n .flipbook-line-default, .flipbook-line-active { position: absolute; top: 50px; left: -88px; width: 416px; height: 266px; z-index: 3; transform: rotate(-10.9deg); opacity: 0; transition: opacity 0.3s; pointer-events: none; }\n .flipbook-line-default.show, .flipbook-line-active.show { opacity: 1; }\n #flipbook { width: 998px; height: 520px; margin: 0 auto; position: absolute; left: 110px; top: 140px; z-index: 2; box-shadow: 4px 4px 4px 0 #b08e67; }\n #flipbook .page { width: 998px; height: 520px; background: white; box-shadow: 0 10px 40px rgba(0,0,0,0.3); border: 1px solid #ddd; overflow: hidden; }\n #flipbook .page-content { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; background: white; }\n .controls { display: flex; justify-content: center; gap: 20px; margin: 40px auto; }\n .btn { padding: 12px 24px; background: white; color: #667eea; border: none; border-radius: 25px; cursor: pointer; transition: all 0.3s; }\n .btn:hover { background: #667eea; color: white; }\n .page-info { color: white; padding: 10px 20px; border-radius: 20px; background: rgba(255,255,255,0.2); }\n </style>\n</head>\n<body>\n <div id=\"loading\" style=\"position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);display:flex;justify-content:center;align-items:center;color:white;z-index:9999;\">\n <div style=\"width:60px;height:60px;border:4px solid rgba(255,255,255,0.3);border-top:4px solid white;border-radius:50%;animation:spin 1s linear infinite;\"></div>\n </div>\n <div class=\"flipbook-container\">\n ").concat(filpBgBase64 ? "<img src=\"".concat(filpBgBase64, "\" class=\"flipbook-bg\" />") : '', "\n ").concat(defaultLineBase64 ? "<img src=\"".concat(defaultLineBase64, "\" class=\"flipbook-line-default\" />") : '', "\n ").concat(activeLineBase64 ? "<img src=\"".concat(activeLineBase64, "\" class=\"flipbook-line-active\" />") : '', "\n <div id=\"flipbook\">").concat(pagesHTML, "</div>\n </div>\n <div class=\"controls\">\n <button class=\"btn\" id=\"btn-first\">\u9996\u9875</button>\n <button class=\"btn\" id=\"btn-prev\">\u4E0A\u4E00\u9875</button>\n <div class=\"page-info\">\u7B2C <span id=\"current-page\">1</span> \u9875 / \u5171 <span id=\"total-pages\">").concat(pageDataArray.length, "</span> \u9875</div>\n <button class=\"btn\" id=\"btn-next\">\u4E0B\u4E00\u9875</button>\n <button class=\"btn\" id=\"btn-last\">\u672B\u9875</button>\n </div>\n <script>\n $(function(){\n const total = ").concat(pageDataArray.length, ";\n $('#flipbook').turn({width:998,height:520,autoCenter:true,duration:1000,display:'single'});\n $('#btn-first').click(()=>$('#flipbook').turn('page',1));\n $('#btn-prev').click(()=>$('#flipbook').turn('previous'));\n $('#btn-next').click(()=>$('#flipbook').turn('next'));\n $('#btn-last').click(()=>$('#flipbook').turn('page',total));\n setTimeout(()=>$('#loading').fadeOut(),500);\n });\n @keyframes spin{0%{transform:rotate(0deg);}100%{transform:rotate(360deg);}}\n </script>\n</body>\n</html>");
89
+ }