gm-printer 10.39.4-beta.2 → 10.39.4-beta.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 (37) hide show
  1. package/build/demo.js +9 -9
  2. package/locales/en.json +3 -0
  3. package/locales/th.json +3 -0
  4. package/locales/zh-HK.json +3 -0
  5. package/package.json +1 -1
  6. package/src/common/common_context_menu.js +6 -4
  7. package/src/common/component.js +64 -8
  8. package/src/common/data_key_util.js +35 -0
  9. package/src/common/editor_edit_field.js +288 -167
  10. package/src/common/editor_store.js +230 -42
  11. package/src/common/hoc_with_store.js +9 -0
  12. package/src/common/style.lesss +43 -0
  13. package/src/common/util.js +58 -4
  14. package/src/editor/context_menu.js +17 -0
  15. package/src/editor/store.js +13 -0
  16. package/src/editor_purchase/editor.js +2 -1
  17. package/src/editor_purchase/editor_special_table.js +39 -17
  18. package/src/editor_purchase/editor_sum_table.js +5 -1
  19. package/src/editor_purchase/store.js +48 -45
  20. package/src/finance_voucher/components/table_subtotal_tr.js +12 -18
  21. package/src/index.js +6 -2
  22. package/src/printer/block.js +154 -4
  23. package/src/printer/compute_pages.js +122 -0
  24. package/src/printer/index.js +3 -1
  25. package/src/printer/long_print_table/index.js +14 -4
  26. package/src/printer/multi_column.js +1 -0
  27. package/src/printer/page_summary.js +3 -1
  28. package/src/printer/printer.js +23 -3
  29. package/src/printer/store.js +141 -91
  30. package/src/printer/table.js +11 -3
  31. package/src/printer/table_diy_overallOrder_tr.js +8 -15
  32. package/src/printer/table_diy_summary_tr.js +18 -35
  33. package/src/printer/table_overallOrder_tr.js +49 -37
  34. package/src/printer/table_special_tr.js +17 -2
  35. package/src/printer/table_subtotal_tr.js +100 -16
  36. package/src/util.js +34 -8
  37. package/yarn-error.log +372 -152
@@ -7,8 +7,10 @@ import {
7
7
  getDataKey,
8
8
  caclSingleDetailsPageHeight,
9
9
  getArrayMid,
10
- getOverallOrderTrHeight
10
+ getOverallOrderTrHeight,
11
+ isMaskedValue
11
12
  } from '../util'
13
+ import { isIndependentRolDataKey } from '../common/data_key_util'
12
14
  import _ from 'lodash'
13
15
  import Big from 'big.js'
14
16
  import { Tip } from '../components'
@@ -28,7 +30,21 @@ import {
28
30
  } from './multi_column'
29
31
 
30
32
  export const TR_BASE_HEIGHT = 23
33
+
34
+ /** 分页高度运算:像素精度足够,避免热路径中 Big.js 开销 */
35
+ const roundHeight = n => Math.round(n * 100) / 100
36
+
37
+ /** 判断行是否含可拆分的采购明细(普通长文本列不可拆分) */
38
+ const canSplitRowDetails = (dataKey, row) => {
39
+ if (!row || dataKey.includes('noLineBreak')) return false
40
+ const details = row.__details
41
+ const detailsMulti = row.__details_MULTI_SUFFIX
42
+ return !!(details?.length || detailsMulti?.length)
43
+ }
44
+
31
45
  const price = (n, f = 2) => {
46
+ // 脱敏值 '***' 原样返回(不能走 isNaN 判空,空单元格仍需显空)
47
+ if (isMaskedValue(n)) return n
32
48
  if (isNaN(n)) return null
33
49
  return Big(n || 0).toFixed(f)
34
50
  }
@@ -250,10 +266,10 @@ class PrinterStore {
250
266
  count = details.length + detailsMulti.length + count
251
267
  })
252
268
 
253
- /** 明细data */
254
- const detailsData = tableData[end]?.__details
255
- // 双栏明细data
256
- const detailsDataMulti = tableData[end]?.__details_MULTI_SUFFIX
269
+ /** 明细data(左栏),兜底空数组避免另一侧缺省时切片报错 */
270
+ const detailsData = tableData[end]?.__details || []
271
+ // 双栏明细data(右栏)
272
+ const detailsDataMulti = tableData[end]?.__details_MULTI_SUFFIX || []
257
273
  // 采购单如果使用双栏,取明细最多的那个数据
258
274
  const data =
259
275
  detailsData?.length > (detailsDataMulti?.length || 0)
@@ -276,10 +292,12 @@ class PrinterStore {
276
292
  _.filter(ranges, i => i[0] !== i[1] || (!i[0] && !i[1])), // 过滤掉 {[0,3],[3,3]}这周情况
277
293
  range => {
278
294
  const _tableData = Object.assign({}, tableData[end])
279
- _tableData.__details = data.slice(...range)
295
+ // 左右两栏各用各的明细切片(slice 超出长度自动截断,明细少的一侧在第一片即展示完),
296
+ // 修复:此前两栏都塞明细多的一侧数据,导致明细少的一侧(如双栏右栏)明细被替换、自身明细丢失
297
+ _tableData.__details = detailsData.slice(...range)
280
298
  // 双栏中的数据也要做处理
281
299
  if (isMultiTable(dataKey)) {
282
- _tableData.__details_MULTI_SUFFIX = data.slice(...range)
300
+ _tableData.__details_MULTI_SUFFIX = detailsDataMulti.slice(...range)
283
301
  }
284
302
 
285
303
  return _tableData
@@ -293,17 +311,26 @@ class PrinterStore {
293
311
 
294
312
  @action
295
313
  computedPages() {
296
- this.setIsSave(false)
297
- // 每次先初始化置空
298
- this.pages = []
314
+ // 快照 observable,避免热路径反复触发 MobX依赖追踪
315
+ const pageHeight = this.pageHeight
316
+ const heightMap = { ...this.height }
317
+ const contents = this.config.contents
318
+ const contentsLength = contents.length
319
+ const tablesInfo = this.tablesInfo
320
+ const tableDataMap = this.data._table
321
+
322
+ // 使用本地数组累积分页结果,避免循环中反复触发 observable 更新
323
+ const pages = []
299
324
  // 每页必有 页眉header, 页脚footer , 签名
300
- const allPagesHaveThisHeight = this.height.header + this.height.footer
325
+ const allPagesHaveThisHeight = heightMap.header + heightMap.footer
301
326
  // 退出计算! 因为页眉 + 页脚 > currentPageHeight,页面装不下其他东西
302
- if (allPagesHaveThisHeight > this.pageHeight) {
327
+ if (allPagesHaveThisHeight > pageHeight) {
328
+ this.pages = []
329
+ this.isSave = true
330
+ this.config.isSave = true
303
331
  Tip.warning(
304
332
  i18next.t('检测到当前页面高度不足,无法完整渲染,请重新设置页面高度!')
305
333
  )
306
- this.setIsSave(true)
307
334
  return
308
335
  }
309
336
 
@@ -316,15 +343,19 @@ class PrinterStore {
316
343
  /** 处理配送单有多个表格的情况 */
317
344
  let tableCount = 0
318
345
  /* --- 遍历 contents,将内容动态分配到page --- */
319
- while (index < this.config.contents.length) {
320
- const content = this.config.contents[index]
346
+ while (index < contentsLength) {
347
+ const content = contents[index]
321
348
 
322
349
  /* 表格内容处理 */
323
350
  if (content.type === 'table') {
324
351
  // 是表格就++
325
352
  tableCount++
326
353
  // 表格原始的高度和宽度信息
327
- const table = this.tablesInfo[`contents.table.${index}`]
354
+ const table = tablesInfo[`contents.table.${index}`]
355
+ if (!table?.body?.heights) {
356
+ index++
357
+ continue
358
+ }
328
359
  const {
329
360
  subtotal,
330
361
  dataKey,
@@ -361,17 +392,17 @@ class PrinterStore {
361
392
  const currentPageMinimumHeight =
362
393
  allPagesHaveThisHeight + allTableHaveThisHeight
363
394
  // 最后一项是表格时,末页仍要渲染签名:装行可用高度预留签名,避免空行顶进签名区
364
- const isLastContent = index === this.config.contents.length - 1
395
+ const isLastContent = index === contentsLength - 1
365
396
  const signReserve = isLastContent ? this.getSignHeight() : 0
366
397
  /** 当前page可容纳的table高度 */
367
- let pageAccomodateTableHeight = +new Big(this.pageHeight)
368
- .minus(currentPageHeight)
369
- .minus(signReserve)
370
- .toFixed(2)
371
- const heights = this.getNormalTableBodyHeights(
372
- table.body.heights,
373
- dataKey
398
+ let pageAccomodateTableHeight = roundHeight(
399
+ pageHeight - currentPageHeight - signReserve
374
400
  )
401
+ // 拷贝一份行高数组,避免 splice 触发 observable 副作用
402
+ const heights = [
403
+ ...this.getNormalTableBodyHeights(table.body.heights, dataKey)
404
+ ]
405
+ const tableData = tableDataMap[dataKey] || []
375
406
  // 表格行的索引,用于table.slice(begin, end), 分割到不同页面中
376
407
  let begin = 0
377
408
  let end = 0
@@ -387,27 +418,41 @@ class PrinterStore {
387
418
  let currentRemainTableHeight = 0
388
419
  /** 去最小的tr高度,用于下面的计算compare,(避免特殊情况:一般来说最小tr——height = 23, 比23还小的不考虑计算) */
389
420
  const minHeight = Math.max(getArrayMid(heights), 23)
421
+ // 安全阈值:防止极端情况下内层 while 迭代失控
422
+ const maxIterations = heights.length * 10 + 100
423
+ let loopCount = 0
390
424
  /* 遍历表格每一行,填充表格内容 */
391
425
  while (end < heights.length) {
392
- currentTableHeight += heights[end]
426
+ if (++loopCount > maxIterations) {
427
+ console.warn(
428
+ '[gm-printer] computedPages: iteration limit exceeded, force break'
429
+ )
430
+ break
431
+ }
432
+
433
+ const rowHeight = heights[end]
434
+ currentTableHeight += rowHeight
393
435
  // 用于计算最后一页有footer情况的高度
394
- currentPageHeight += heights[end]
436
+ currentPageHeight += rowHeight
395
437
  // 当前页没有多余空间
396
438
  if (currentTableHeight > pageAccomodateTableHeight) {
397
- currentRemainTableHeight = +Big(pageAccomodateTableHeight)
398
- .minus(currentTableHeight)
399
- .plus(heights[end])
439
+ currentRemainTableHeight = roundHeight(
440
+ pageAccomodateTableHeight - currentTableHeight + rowHeight
441
+ )
442
+
443
+ const row = tableData[end]
444
+ const isRowOversized = rowHeight > pageAccomodateTableHeight
445
+ const shouldTrySplitDetails =
446
+ canSplitRowDetails(dataKey, row) &&
447
+ ((currentRemainTableHeight / minHeight > 1.5 &&
448
+ rowHeight / currentRemainTableHeight > 1) ||
449
+ isRowOversized)
400
450
 
401
451
  /**
402
- * 说明: 1. currentRemainTableHeight至少要是minHeight的 2倍,不然每次到这都进入if,同时留下一点空白距离
403
- * 2. heights[end]至少要是currentRemainTableHeight的 1倍,怕出现打印时最后一行文字显示一半的情况
404
- * 3. heights[end] 高度超过了 pageAccomodateTableHeight
452
+ * 仅对含 __details 的采购明细行尝试拆分;
453
+ * 普通长文本列(如规格)超高时直接整行换页,避免无效 computedData 调用
405
454
  */
406
- if (
407
- (currentRemainTableHeight / minHeight > 1.5 &&
408
- heights[end] / currentRemainTableHeight > 1) ||
409
- heights[end] > pageAccomodateTableHeight
410
- ) {
455
+ if (shouldTrySplitDetails) {
411
456
  const detailsPageHeight = this.computedData(
412
457
  dataKey,
413
458
  table,
@@ -415,7 +460,7 @@ class PrinterStore {
415
460
  currentRemainTableHeight
416
461
  )
417
462
 
418
- // 拆分明细后,同时也要更新body.heights 不能影响后续计算
463
+ // 拆分明细后,同时也要更新 heights 不能影响后续计算
419
464
  if (detailsPageHeight.length > 0) {
420
465
  // 比较剩余高度和minHeight的大小,取最大(防止剩余一条明细时,第二页撑开的高度远大于一条明细的高度)
421
466
  detailsPageHeight[1] = Math.max(
@@ -430,7 +475,8 @@ class PrinterStore {
430
475
  if (begin === 0 && end === 0 && index === 0) {
431
476
  index++
432
477
  this.pages = []
433
- this.setIsSave(true)
478
+ this.isSave = true
479
+ this.config.isSave = true
434
480
  Tip.warning(
435
481
  i18next.t(
436
482
  '检测到当前页面高度不足,无法完整渲染,请重新设置页面高度!'
@@ -438,7 +484,7 @@ class PrinterStore {
438
484
  )
439
485
  break
440
486
  }
441
- // 修复 OOM:某行高度本身超过单页可容纳的表格高度时,end 无法推进会导致 while 死循环
487
+ // 行无法拆分(普通长文本列)或拆分失败时,强制推进 end 防止死循环
442
488
  if (end === begin) {
443
489
  end = end + 1
444
490
  }
@@ -451,28 +497,27 @@ class PrinterStore {
451
497
  end
452
498
  })
453
499
  // 此页完成任务
454
- this.pages.push(page)
500
+ pages.push(page)
455
501
  page = []
456
502
  }
457
503
  // 页面有多个表格时,当同一页的第二个表格的第一行高度加上第一个表格的高度大于页面的高度,需要生成新的一页
458
504
  // 因为是第二个表格,重新走了遍历,end重置0,没有进入到上面的判断(end !== 0),不会生成新的一页
459
505
  if (tableCount > 1 && end === 0) {
460
- this.pages.push(page)
506
+ pages.push(page)
461
507
  page = []
462
508
  }
463
509
 
464
510
  begin = end
465
511
  // 开启新一页,重置页面高度(末项表格仍预留签名)
466
- pageAccomodateTableHeight = +new Big(this.pageHeight)
467
- .minus(allPagesHaveThisHeight)
468
- .minus(signReserve)
469
- .toFixed(2)
512
+ pageAccomodateTableHeight = roundHeight(
513
+ pageHeight - allPagesHaveThisHeight - signReserve
514
+ )
470
515
  currentTableHeight = allTableHaveThisHeight
471
516
  currentPageHeight = currentPageMinimumHeight
472
517
  } else {
473
518
  // 有空间,继续做下行
474
519
  end++
475
- // 最后一行,把信息加入 page,并轮下一个contents
520
+ // 最后一行,把信息加入 page
476
521
  if (end === heights.length) {
477
522
  page.push({
478
523
  type: 'table',
@@ -480,27 +525,35 @@ class PrinterStore {
480
525
  begin,
481
526
  end
482
527
  })
483
- index++
484
528
  }
485
529
  }
486
530
  }
531
+ // 最后一行换页时走 if 分支,内层不会 index++,此处统一推进
532
+ if (end >= heights.length) {
533
+ index++
534
+ } else {
535
+ console.warn(
536
+ '[gm-printer] computedPages: table pagination incomplete, force advance'
537
+ )
538
+ index++
539
+ }
487
540
  }
488
541
  /* 非表格内容处理 */
489
542
  } else {
490
- const panelHeight = this.height[`contents.panel.${index}`]
543
+ const panelHeight = heightMap[`contents.panel.${index}`]
491
544
  currentPageHeight += panelHeight
492
545
 
493
546
  // 当 panel + allPagesHaveThisHeight > 页高度, 停止. 避免死循环
494
- if (panelHeight + allPagesHaveThisHeight > this.pageHeight) {
547
+ if (panelHeight + allPagesHaveThisHeight > pageHeight) {
495
548
  break
496
549
  }
497
550
 
498
551
  // 如果是最后一页,必须要加上sign的高度,否则会重叠
499
- if (index === this.config.contents.length - 1) {
552
+ if (index === contentsLength - 1) {
500
553
  currentPageHeight += this.getSignHeight()
501
554
  }
502
555
 
503
- if (currentPageHeight <= this.pageHeight) {
556
+ if (currentPageHeight <= pageHeight) {
504
557
  // 空间充足,把信息加入 page,并轮下一个contents
505
558
  page.push({
506
559
  type: 'panel',
@@ -510,7 +563,7 @@ class PrinterStore {
510
563
  index++
511
564
  } else {
512
565
  // 此页空间不足,此页完成任务
513
- this.pages.push(page)
566
+ pages.push(page)
514
567
 
515
568
  // 为下一页做准备
516
569
  page = []
@@ -518,19 +571,21 @@ class PrinterStore {
518
571
  }
519
572
  }
520
573
  }
521
- this.pages.push(page)
574
+ pages.push(page)
575
+ this.pages = pages
522
576
 
523
577
  // 末页签名:panel 分支会在「最后一项是 panel」时扣 sign;
524
578
  // 最后一项是 table 时上面不会扣,导致 remain 偏大、空行多填溢页
525
- // 打印 iframe 内 height.sign 可能为 0,必须用 getSignHeight(含配置兜底)
526
- const lastContent = this.config.contents[this.config.contents.length - 1]
579
+ const lastContent = contents[contentsLength - 1]
527
580
  if (lastContent?.type === 'table') {
528
581
  currentPageHeight += this.getSignHeight()
529
582
  }
530
583
 
531
- this.remainPageHeight = +Big(
532
- Math.max(0, this.pageHeight - currentPageHeight)
533
- ).toFixed(0)
584
+ this.remainPageHeight = Math.round(
585
+ Math.max(0, pageHeight - currentPageHeight)
586
+ )
587
+ this.isSave = false
588
+ this.config.isSave = false
534
589
  this.repackVerticalMultiByPages()
535
590
  }
536
591
 
@@ -579,8 +634,8 @@ class PrinterStore {
579
634
  const sourceColNumber = isMultiTable(singleKey)
580
635
  ? getMultiNumber(singleKey)
581
636
  : isMultiTable(sourceKey)
582
- ? colNumber
583
- : 1
637
+ ? colNumber
638
+ : 1
584
639
  const sourceItems = flattenHorizontalPackedRows(
585
640
  sourceRows,
586
641
  sourceColNumber
@@ -666,13 +721,14 @@ class PrinterStore {
666
721
  */
667
722
  templateTableRowSpan(text, dataKey, index, begin) {
668
723
  try {
669
- if (
670
- dataKey !== 'purchase_detail_one_row' &&
671
- dataKey !== 'purchase_independent_rol_sku' &&
672
- dataKey !== 'purchase_independent_rol_address' &&
673
- dataKey !== 'taxRateSales' &&
674
- dataKey !== 'ordinary'
675
- ) {
724
+ // 采购 / 分拣「按明细单行」展开后才做合并单元格(后缀 independent_rol_*)
725
+ const canMerge =
726
+ isIndependentRolDataKey(dataKey) ||
727
+ dataKey === 'taxRateSales' ||
728
+ dataKey === 'ordinary' ||
729
+ dataKey === 'purchase_detail_one_row' ||
730
+ dataKey === 'sorting_detail_detail_one_row'
731
+ if (!canMerge) {
676
732
  return null
677
733
  }
678
734
  const list = this.data._table[dataKey] || this.data._table.orders
@@ -729,13 +785,8 @@ class PrinterStore {
729
785
  row = list[index]
730
786
  }
731
787
  row =
732
- ensureRowSerialKeys(
733
- list,
734
- index,
735
- colNumber,
736
- this.fillIndex,
737
- dataKey
738
- ) || row
788
+ ensureRowSerialKeys(list, index, colNumber, this.fillIndex, dataKey) ||
789
+ row
739
790
 
740
791
  return _.template(text, {
741
792
  interpolate: /{{([\s\S]+?)}}/g
@@ -779,12 +830,15 @@ class PrinterStore {
779
830
  }
780
831
  }
781
832
 
782
- templateSpecialDetails(col, dataKey, index) {
783
- // 做好保护,出错就返回 text
833
+ templateSpecialDetails(col, dataKey, index, fallbackText = '') {
784
834
  const { specialDetailsKey, text, detailLastColType, separator } = col
835
+ const templateText = text || fallbackText
836
+ if (!templateText) return ''
785
837
  try {
786
838
  const row = this.data._table[dataKey][index]
787
- const compiled = _.template(text, { interpolate: /{{([\s\S]+?)}}/g })
839
+ const compiled = _.template(templateText, {
840
+ interpolate: /{{([\s\S]+?)}}/g
841
+ })
788
842
  let detailsList = row[specialDetailsKey] || []
789
843
 
790
844
  /** 简单处理下数据 */
@@ -807,7 +861,7 @@ class PrinterStore {
807
861
 
808
862
  return detailsList
809
863
  } catch (err) {
810
- return text
864
+ return templateText
811
865
  }
812
866
  }
813
867
 
@@ -841,8 +895,7 @@ class PrinterStore {
841
895
  const info = this.tablesInfo[name]
842
896
  if (!info?.body?.heights) return
843
897
 
844
- const rows =
845
- this.data._table[resolved] || this.data._table[dataKey] || []
898
+ const rows = this.data._table[resolved] || this.data._table[dataKey] || []
846
899
  const realCount = rows.filter(row => row && !row._isEmptyData).length
847
900
  if (info.body.heights.length > realCount) {
848
901
  info.body.heights = info.body.heights.slice(0, realCount)
@@ -877,18 +930,15 @@ class PrinterStore {
877
930
  return []
878
931
  }
879
932
 
880
- const sourceItems = flattenHorizontalPackedRows(
881
- sourceRows,
882
- sourceColNumber
883
- )
933
+ const sourceItems = flattenHorizontalPackedRows(sourceRows, sourceColNumber)
884
934
  const baseRowCount = sourceItems.length
885
935
  ? Math.max(1, Math.ceil(sourceItems.length / colNumber))
886
936
  : 0
887
937
  const packed = !baseRowCount
888
938
  ? []
889
939
  : isVertical
890
- ? packVerticalNewspaper(sourceItems, colNumber, baseRowCount, false)
891
- : packHorizontalRowMajor(sourceItems, colNumber)
940
+ ? packVerticalNewspaper(sourceItems, colNumber, baseRowCount, false)
941
+ : packHorizontalRowMajor(sourceItems, colNumber)
892
942
  this.data._table[dataKey] = packed
893
943
  return packed
894
944
  }
@@ -920,8 +970,8 @@ class PrinterStore {
920
970
  const sourceColNumber = isMultiTable(singleKey)
921
971
  ? getMultiNumber(singleKey)
922
972
  : isMultiTable(sourceKey)
923
- ? colNumber
924
- : 1
973
+ ? colNumber
974
+ : 1
925
975
  const sourceItems = flattenHorizontalPackedRows(
926
976
  sourceRows,
927
977
  sourceColNumber
@@ -952,8 +1002,8 @@ class PrinterStore {
952
1002
  emptyCount === 0
953
1003
  ? []
954
1004
  : emptyTable.length > 0
955
- ? emptyTable
956
- : this.getFilledTableData(table)
1005
+ ? emptyTable
1006
+ : this.getFilledTableData(table)
957
1007
  const withPartial = fillPartialLastRow(table, colNumber, this.fillIndex)
958
1008
  const lastKey = getMaxSerial(withPartial, colNumber) + 1
959
1009
  const sample = table[0]
@@ -169,7 +169,8 @@ class Table extends React.Component {
169
169
  range,
170
170
  pageIndex,
171
171
  printerStore,
172
- isSomeSubtotalTr
172
+ isSomeSubtotalTr,
173
+ isLastTablePage
173
174
  } = this.props
174
175
  // 数据
175
176
  dataKey = getDataKey(dataKey, arrange)
@@ -407,7 +408,8 @@ class Table extends React.Component {
407
408
  ? printerStore.templateSpecialDetails(
408
409
  col,
409
410
  dataKey,
410
- i
411
+ i,
412
+ config.specialConfig?.template_text
411
413
  )
412
414
  : printerStore
413
415
  .templateTable(col.text, dataKey, i, pageIndex)
@@ -441,6 +443,7 @@ class Table extends React.Component {
441
443
  range={range}
442
444
  config={config}
443
445
  printerStore={printerStore}
446
+ isLastTablePage={isLastTablePage}
444
447
  />
445
448
  <DiyOverallOrder
446
449
  range={range}
@@ -499,7 +502,12 @@ Table.propTypes = {
499
502
  pageIndex: PropTypes.number.isRequired,
500
503
  placeholder: PropTypes.string,
501
504
  printerStore: PropTypes.object,
502
- isSomeSubtotalTr: PropTypes.bool
505
+ isSomeSubtotalTr: PropTypes.bool,
506
+ isLastTablePage: PropTypes.bool
507
+ }
508
+
509
+ Table.defaultProps = {
510
+ isLastTablePage: true
503
511
  }
504
512
 
505
513
  export default Table
@@ -2,10 +2,9 @@ import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import _ from 'lodash'
4
4
  // import Big from 'big.js'
5
- import { coverDigit2Uppercase, getDataKey } from '../util'
5
+ import { coverDigit2Uppercase, getDataKey, maskedSum } from '../util'
6
6
  import { observer } from 'mobx-react'
7
7
  import classNames from 'classnames'
8
- import Big from 'big.js'
9
8
 
10
9
  const DiyOverallOrder = props => {
11
10
  const {
@@ -15,20 +14,14 @@ const DiyOverallOrder = props => {
15
14
  } = props
16
15
  const tableData = printerStore.data._table[getDataKey(dataKey)] || []
17
16
 
18
- // 计算合计
17
+ // 计算合计:任一渲染结果脱敏 '***' 则合计显 '***'(整格判定假设同 table_diy_summary_tr)
19
18
  const sumData = field => {
20
- return _.reduce(
21
- tableData,
22
- (a, b, i) => {
23
- let result = a
24
- const bRes = printerStore
25
- .templateTable(field, dataKey, i, pageIndex)
26
- .replace(/\(\)/g, '')
27
- result = a.plus(+bRes || 0)
28
- return result
29
- },
30
- Big(0)
31
- ).toFixed(2)
19
+ const values = _.map(tableData, (b, i) =>
20
+ printerStore
21
+ .templateTable(field, dataKey, i, pageIndex)
22
+ .replace(/\(\)/g, '')
23
+ )
24
+ return maskedSum(values)
32
25
  }
33
26
 
34
27
  if (!diyOverallOrder?.show || !printerStore?.ready) {
@@ -1,11 +1,15 @@
1
1
  import React from 'react'
2
2
  import PropTypes from 'prop-types'
3
3
  import _ from 'lodash'
4
- import { coverDigit2Uppercase, getDataKey, isMultiTable } from '../util'
4
+ import {
5
+ coverDigit2Uppercase,
6
+ getDataKey,
7
+ isMultiTable,
8
+ maskedSum
9
+ } from '../util'
5
10
  import { MULTI_SUFFIX, MULTI_SUFFIX3 } from '../config'
6
11
  import { observer } from 'mobx-react'
7
12
  import classNames from 'classnames'
8
- import Big from 'big.js'
9
13
 
10
14
  function buildTemplateField(fieldStr, suffix) {
11
15
  // 如果 field 是 "{{列.下单数}}",提取出 "下单数"
@@ -45,39 +49,18 @@ const DiySummary = props => {
45
49
 
46
50
  // 计算合计
47
51
  const sumData = field => {
48
- if (isMulti) {
49
- return _.reduce(
50
- tableData,
51
- (a, b, i) => {
52
- let result = a
53
- // 先通过 templateTable 获取原始字段的值
54
- const bRes = getRes(field, i)
55
- result = a.plus(+bRes || 0)
56
-
57
- // 双栏
58
- const multiField = buildTemplateField(field, MULTI_SUFFIX)
59
- result = result.plus(+getRes(multiField, i) || 0)
60
-
61
- // 三栏
62
- const multiField3 = buildTemplateField(field, MULTI_SUFFIX3)
63
- result = result.plus(+getRes(multiField3, i) || 0)
64
-
65
- return result
66
- },
67
- Big(0)
68
- ).toFixed(2)
69
- }
70
-
71
- return _.reduce(
72
- tableData,
73
- (a, b, i) => {
74
- let result = a
75
- const bRes = getRes(field, i)
76
- result = a.plus(+bRes || 0)
77
- return result
78
- },
79
- Big(0)
80
- ).toFixed(2)
52
+ // 收集本列渲染结果(含多栏后缀列),任一脱敏 '***' 则合计显 '***'
53
+ // 注意:基于渲染后字符串判定,假设模板整格就是脱敏值;带前后缀的模板(如 '{{列.金额}}元')无法识别
54
+ const values = []
55
+ _.each(tableData, (b, i) => {
56
+ values.push(getRes(field, i))
57
+ if (isMulti) {
58
+ // 双栏/三栏取后缀字段
59
+ values.push(getRes(buildTemplateField(field, MULTI_SUFFIX), i))
60
+ values.push(getRes(buildTemplateField(field, MULTI_SUFFIX3), i))
61
+ }
62
+ })
63
+ return maskedSum(values)
81
64
 
82
65
  function getRes(field, i) {
83
66
  return printerStore