gm-printer 10.41.0 → 10.41.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-printer",
3
- "version": "10.41.0",
3
+ "version": "10.41.1",
4
4
  "description": "diy printer",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -19,7 +19,7 @@ import {
19
19
  } from '../common/component'
20
20
  import { get, toJS } from 'mobx'
21
21
  import PropTypes from 'prop-types'
22
- import { subtotalRadioList, overallOrderRadioList } from './util'
22
+ import { subtotalRadioList } from './util'
23
23
  import { LONG_PRINT } from '../config'
24
24
  import _ from 'lodash'
25
25
 
@@ -529,7 +529,7 @@ class EditorField extends React.Component {
529
529
  {!isSomeSubtotalTr && (
530
530
  <div>
531
531
  <Flex>{i18next.t('合计栏打印金额')}:</Flex>
532
- <Flex style={{ marginLeft: 57 }} wrap>
532
+ <Flex style={{ marginLeft: 57 }}>
533
533
  {subtotalRadioList.map(fields => {
534
534
  // 兼容
535
535
  let subtotalFields = subtotal?.fields?.[0].valueField
@@ -627,14 +627,8 @@ class EditorField extends React.Component {
627
627
  onChange={this.handleOverallOrderStyleChange}
628
628
  />
629
629
  </Flex>
630
- <EditorSubtotalCheck
631
- subtotalCheckDisabled
632
- subtotalChecked={overallOrder?.showEachPage !== false}
633
- subtotalCheckOnChange={editStore.setOverallOrderShowEachPage}
634
- subtotalCheckText='每页展示'
635
- />
636
- <Flex style={{ marginLeft: 57 }} wrap>
637
- {overallOrderRadioList.map((fields, i) => {
630
+ <Flex style={{ marginLeft: 57 }}>
631
+ {subtotalRadioList.map((fields, i) => {
638
632
  return (
639
633
  <Radio
640
634
  style={{ marginLeft: 5 }}
@@ -773,10 +773,6 @@ class EditorStore {
773
773
  set(table.overallOrder, {
774
774
  show: !table.overallOrder.show
775
775
  })
776
- // 老模板补默认:每页展示默认勾选
777
- if (table.overallOrder.showEachPage === undefined) {
778
- set(table.overallOrder, { showEachPage: true })
779
- }
780
776
  table.overallOrder.fields[0].colSpan =
781
777
  colSpanLength - (table.overallOrder.fields?.[1]?.colSpan ?? 0)
782
778
  } else {
@@ -784,7 +780,6 @@ class EditorStore {
784
780
  set(table, {
785
781
  overallOrder: {
786
782
  show: true,
787
- showEachPage: true,
788
783
  fields: [
789
784
  {
790
785
  name: '整单合计:',
@@ -801,19 +796,6 @@ class EditorStore {
801
796
  this.config = toJS(this.config)
802
797
  }
803
798
 
804
- // 整单合计「每页展示」
805
- @action.bound
806
- setOverallOrderShowEachPage() {
807
- if (!this.selectedRegion) return
808
- const arr = this.selectedRegion.split('.')
809
- const table = this.config.contents[arr[2]]
810
- if (!table?.overallOrder) return
811
- this.overallOrderShow = !this.overallOrderShow
812
- const next = !(table.overallOrder.showEachPage !== false)
813
- set(table.overallOrder, { showEachPage: next })
814
- this.config = toJS(this.config)
815
- }
816
-
817
799
  @action
818
800
  setDiyOverallOrderShow(name) {
819
801
  const arr = name.split('.')
@@ -1837,7 +1819,6 @@ class EditorStore {
1837
1819
  set(table, {
1838
1820
  overallOrder: {
1839
1821
  show: true,
1840
- showEachPage: true,
1841
1822
  fields: [
1842
1823
  {
1843
1824
  name: '整单合计:',
@@ -1,9 +1,10 @@
1
1
  import i18next from '../../locales'
2
2
 
3
3
  /**
4
- * 每页合计金额单选
5
- * id 与 data_to_key 中文 key 对齐,用于对本页行求和,不要轻易改 id
4
+ * 每页合计设置单选按钮
5
+ * id的值是用来计算每页的金额总数,不要轻易随便改
6
6
  */
7
+ // 整单合计和每页合计栏都使用的这个
7
8
  const subtotalRadioList = [
8
9
  {
9
10
  value: i18next.t('下单金额'),
@@ -16,61 +17,6 @@ const subtotalRadioList = [
16
17
  {
17
18
  value: i18next.t('实际金额'),
18
19
  id: '实际金额'
19
- },
20
- {
21
- value: i18next.t('变化前金额'),
22
- id: '变化前金额'
23
- },
24
- {
25
- value: i18next.t('下单金额(不含税)'),
26
- id: '下单金额_不含税'
27
- },
28
- {
29
- value: i18next.t('实收金额'),
30
- id: '实收金额'
31
- },
32
- {
33
- value: i18next.t('实收金额(不含税)'),
34
- id: '实收金额_不含税'
35
- }
36
- ]
37
-
38
- /**
39
- * 整单合计金额单选(比每页合计多「出库金额(不含税)」)
40
- * id 与 data.common 中文 key 对齐,取订单已算金额,不重算
41
- */
42
- const overallOrderRadioList = [
43
- {
44
- value: i18next.t('下单金额'),
45
- id: '下单金额'
46
- },
47
- {
48
- value: i18next.t('出库金额'),
49
- id: '出库金额'
50
- },
51
- {
52
- value: i18next.t('实际金额'),
53
- id: '实际金额'
54
- },
55
- {
56
- value: i18next.t('变化前金额'),
57
- id: '变化前金额'
58
- },
59
- {
60
- value: i18next.t('下单金额(不含税)'),
61
- id: '下单金额_不含税'
62
- },
63
- {
64
- value: i18next.t('出库金额(不含税)'),
65
- id: '出库金额_不含税'
66
- },
67
- {
68
- value: i18next.t('实收金额'),
69
- id: '实收金额'
70
- },
71
- {
72
- value: i18next.t('实收金额(不含税)'),
73
- id: '实收金额_不含税'
74
20
  }
75
21
  ]
76
22
 
@@ -80,4 +26,4 @@ const accountRadioList = {
80
26
  实际金额: i18next.t('实际金额')
81
27
  }
82
28
 
83
- export { subtotalRadioList, overallOrderRadioList, accountRadioList }
29
+ export { subtotalRadioList, accountRadioList }
@@ -57,11 +57,8 @@ const detailSortOptionsForMerchant = [
57
57
  @observer
58
58
  class TableDetailEditor extends React.Component {
59
59
  handleDataKeyChange = dataKey => {
60
- const { editStore, addFields } = this.props
61
- editStore.setPurchaseTableKey(
62
- dataKey,
63
- addFields.specialTableConfig
64
- )
60
+ const { editStore } = this.props
61
+ editStore.setPurchaseTableKey(dataKey)
65
62
  }
66
63
 
67
64
  handlePurchaseSettingKeyChange = dataKey => {
@@ -77,7 +74,7 @@ class TableDetailEditor extends React.Component {
77
74
  }
78
75
 
79
76
  handleDetailAddField = ({ key, value }) => {
80
- const { editStore, config, addFields } = this.props
77
+ const { editStore, config } = this.props
81
78
  if (editStore.computedDataKey === 'purchase_detail_one_row') {
82
79
  // 序号 {{列.序号}}
83
80
  const transform = str => {
@@ -89,18 +86,12 @@ class TableDetailEditor extends React.Component {
89
86
  config.purchaseSettingKey === 'goods' &&
90
87
  config.dataKey !== 'purchase_independent_rol_sku'
91
88
  ) {
92
- editStore.setPurchaseTableKey(
93
- 'purchase_independent_rol_sku',
94
- addFields.specialTableConfig
95
- )
89
+ editStore.setPurchaseTableKey('purchase_independent_rol_sku')
96
90
  } else if (
97
91
  config.purchaseSettingKey === 'merchant' &&
98
92
  config.dataKey !== 'purchase_independent_rol_address'
99
93
  ) {
100
- editStore.setPurchaseTableKey(
101
- 'purchase_independent_rol_address',
102
- addFields.specialTableConfig
103
- )
94
+ editStore.setPurchaseTableKey('purchase_independent_rol_address')
104
95
  }
105
96
 
106
97
  editStore.addFieldToTable({ key, value: transform(value) })
@@ -122,7 +113,7 @@ class TableDetailEditor extends React.Component {
122
113
 
123
114
  render() {
124
115
  const {
125
- addFields: { detailFields, specialTableConfig = {} },
116
+ addFields: { detailFields },
126
117
  editStore
127
118
  } = this.props
128
119
  const {
@@ -132,28 +123,18 @@ class TableDetailEditor extends React.Component {
132
123
  specialConfig: { template_text, style }
133
124
  } = this.props.config
134
125
 
135
- const title = specialTableConfig.title || i18next.t('设置采购明细')
136
- const label = specialTableConfig.label || i18next.t('采购明细')
137
- // 外部可整体覆盖下拉选项(dataKeyList),否则按 hideDataKeys 过滤默认列表
138
- const baseDataKeyList = specialTableConfig.dataKeyList || dataKeyList
139
- const hideDataKeys = specialTableConfig.hideDataKeys || []
140
- const visibleDataKeyList = _.filter(
141
- baseDataKeyList,
142
- v => !hideDataKeys.includes(v.value)
143
- )
144
-
145
126
  return (
146
127
  <div>
147
- <Title title={title} />
128
+ <Title title={i18next.t('设置采购明细')} />
148
129
  <Gap />
149
130
  <Flex alignCenter className='gm-padding-top-5'>
150
- <div>{label}:</div>
131
+ <div>{i18next.t('采购明细')}:</div>
151
132
  <Select
152
133
  className='gm-printer-edit-select'
153
134
  value={editStore.computedDataKey}
154
135
  onChange={this.handleDataKeyChange}
155
136
  >
156
- {_.map(visibleDataKeyList, v => (
137
+ {_.map(dataKeyList, v => (
157
138
  <Option key={v.value} value={v.value}>
158
139
  {v.text}
159
140
  </Option>
@@ -13,7 +13,7 @@ class Store extends EditorStore {
13
13
 
14
14
  /* start---------设置采购明细相关--------- */
15
15
  @action.bound
16
- setPurchaseTableKey(dataKey, specialTableConfig) {
16
+ setPurchaseTableKey(dataKey) {
17
17
  // 先移除选中项,安全第一
18
18
  this.selected = null
19
19
  this.setTableDataKey(dataKey)
@@ -38,12 +38,9 @@ class Store extends EditorStore {
38
38
  separator: '+',
39
39
  // detailsType: 'purchase_last_col',
40
40
  specialDetailsKey: '__details',
41
- text:
42
- specialTableConfig && specialTableConfig.defaultDetailText !== undefined
43
- ? specialTableConfig.defaultDetailText
44
- : i18next.t(
45
- '{{采购数量_采购单位}}{{采购单位}}*{{商户名}}*{{商品备注}}'
46
- )
41
+ text: i18next.t(
42
+ '{{采购数量_采购单位}}{{采购单位}}*{{商户名}}*{{商品备注}}'
43
+ )
47
44
  })
48
45
  // 通过detailsType属性区分单列-总表最后一列的数据是否换行展示
49
46
  dataKey === 'purchase_last_col'
@@ -111,8 +111,7 @@ class Table extends React.Component {
111
111
  range,
112
112
  pageIndex,
113
113
  printerStore,
114
- isSomeSubtotalTr,
115
- isLastTablePage
114
+ isSomeSubtotalTr
116
115
  } = this.props
117
116
  // 数据
118
117
  dataKey = getDataKey(dataKey, arrange)
@@ -228,7 +227,6 @@ class Table extends React.Component {
228
227
  range={range}
229
228
  config={config}
230
229
  printerStore={printerStore}
231
- isLastTablePage={isLastTablePage}
232
230
  />
233
231
  <DiyOverallOrder
234
232
  range={range}
@@ -329,7 +327,6 @@ class Table extends React.Component {
329
327
  range={range}
330
328
  config={config}
331
329
  printerStore={printerStore}
332
- isLastTablePage={isLastTablePage}
333
330
  />
334
331
  <DiyOverallOrder
335
332
  range={range}
@@ -388,12 +385,7 @@ Table.propTypes = {
388
385
  pageIndex: PropTypes.number.isRequired,
389
386
  placeholder: PropTypes.string,
390
387
  printerStore: PropTypes.object,
391
- isSomeSubtotalTr: PropTypes.bool,
392
- isLastTablePage: PropTypes.bool
393
- }
394
-
395
- Table.defaultProps = {
396
- isLastTablePage: true
388
+ isSomeSubtotalTr: PropTypes.bool
397
389
  }
398
390
 
399
391
  export default Table
@@ -13,20 +13,6 @@ import MergePage from './merge_page'
13
13
  import { LONG_PRINT } from '../config'
14
14
  import Big from 'big.js'
15
15
 
16
- /** 当前 panel 是否为该表格 content 在全部分页中的最后一次出现 */
17
- const isLastTablePanel = (pages, pageIndex, panelIndexInPage, tableIndex) => {
18
- for (let pi = pages.length - 1; pi >= 0; pi--) {
19
- const page = pages[pi] || []
20
- for (let pji = page.length - 1; pji >= 0; pji--) {
21
- const p = page[pji]
22
- if (p?.type === 'table' && p.index === tableIndex) {
23
- return pi === pageIndex && pji === panelIndexInPage
24
- }
25
- }
26
- }
27
- return true
28
- }
29
-
30
16
  // Header Sign Footer 相对特殊,要单独处理
31
17
  const Header = props => (
32
18
  <Panel {...props} name='header' placeholder={i18next.t('页眉')} />
@@ -117,9 +103,7 @@ class Printer extends React.Component {
117
103
  componentDidMount() {
118
104
  const { printerStore, config, getremainpageHeight } = this.props
119
105
  const batchPrintConfig = config.batchPrintConfig
120
- // didMount 代表第一次渲染完成
121
- printerStore.setReady(true)
122
- // 连续打印不需要分页计算
106
+ // didMount 代表第一次渲染完成,先分页再 ready,避免空 pages 触发 renderPage
123
107
  if (batchPrintConfig !== 2) {
124
108
  printerStore.computedPages()
125
109
  if (config.autoFillConfig?.checked) {
@@ -131,11 +115,10 @@ class Printer extends React.Component {
131
115
  )
132
116
  printerStore.changeTableData()
133
117
  }
134
- // 开始计算,获取各种数据
135
- // 如果是自适应要先计算高度,在算出行数 不是自适应就先计算行数 在计算高度
136
118
  // 获取剩余空白高度,传到editor
137
119
  getremainpageHeight && getremainpageHeight(printerStore.remainPageHeight)
138
120
  }
121
+ printerStore.setReady(true)
139
122
 
140
123
  // Printer 不是立马就呈现出最终样式,有个过程。这个过程需要时间,什么 ready,不太清楚,估借 setState 来获取过程结束时刻
141
124
  this.setState({}, () => {
@@ -289,12 +272,6 @@ class Printer extends React.Component {
289
272
  placeholder={`${i18next.t('区域')} ${panel.index}`}
290
273
  pageIndex={i}
291
274
  isSomeSubtotalTr={isSomeSubtotalTr}
292
- isLastTablePage={isLastTablePanel(
293
- printerStore.pages,
294
- i,
295
- ii,
296
- panel.index
297
- )}
298
275
  />
299
276
  )
300
277
 
@@ -12,6 +12,18 @@ import Big from 'big.js'
12
12
  import { Tip } from '../components'
13
13
 
14
14
  export const TR_BASE_HEIGHT = 23
15
+
16
+ /** 分页高度运算:像素精度足够,避免热路径中 Big.js 开销 */
17
+ const roundHeight = n => Math.round(n * 100) / 100
18
+
19
+ /** 判断行是否含可拆分的采购明细(普通长文本列不可拆分) */
20
+ const canSplitRowDetails = (dataKey, row) => {
21
+ if (!row || dataKey.includes('noLineBreak')) return false
22
+ const details = row.__details
23
+ const detailsMulti = row.__details_MULTI_SUFFIX
24
+ return !!(details?.length || detailsMulti?.length)
25
+ }
26
+
15
27
  const price = (n, f = 2) => {
16
28
  if (isNaN(n)) return null
17
29
  return Big(n || 0).toFixed(f)
@@ -262,17 +274,26 @@ class PrinterStore {
262
274
 
263
275
  @action
264
276
  computedPages() {
265
- this.setIsSave(false)
266
- // 每次先初始化置空
267
- this.pages = []
277
+ // 快照 observable,避免热路径反复触发 MobX依赖追踪
278
+ const pageHeight = this.pageHeight
279
+ const heightMap = { ...this.height }
280
+ const contents = this.config.contents
281
+ const contentsLength = contents.length
282
+ const tablesInfo = this.tablesInfo
283
+ const tableDataMap = this.data._table
284
+
285
+ // 使用本地数组累积分页结果,避免循环中反复触发 observable 更新
286
+ const pages = []
268
287
  // 每页必有 页眉header, 页脚footer , 签名
269
- const allPagesHaveThisHeight = this.height.header + this.height.footer
288
+ const allPagesHaveThisHeight = heightMap.header + heightMap.footer
270
289
  // 退出计算! 因为页眉 + 页脚 > currentPageHeight,页面装不下其他东西
271
- if (allPagesHaveThisHeight > this.pageHeight) {
290
+ if (allPagesHaveThisHeight > pageHeight) {
291
+ this.pages = []
292
+ this.isSave = true
293
+ this.config.isSave = true
272
294
  Tip.warning(
273
295
  i18next.t('检测到当前页面高度不足,无法完整渲染,请重新设置页面高度!')
274
296
  )
275
- this.setIsSave(true)
276
297
  return
277
298
  }
278
299
 
@@ -285,15 +306,19 @@ class PrinterStore {
285
306
  /** 处理配送单有多个表格的情况 */
286
307
  let tableCount = 0
287
308
  /* --- 遍历 contents,将内容动态分配到page --- */
288
- while (index < this.config.contents.length) {
289
- const content = this.config.contents[index]
309
+ while (index < contentsLength) {
310
+ const content = contents[index]
290
311
 
291
312
  /* 表格内容处理 */
292
313
  if (content.type === 'table') {
293
314
  // 是表格就++
294
315
  tableCount++
295
316
  // 表格原始的高度和宽度信息
296
- const table = this.tablesInfo[`contents.table.${index}`]
317
+ const table = tablesInfo[`contents.table.${index}`]
318
+ if (!table?.body?.heights) {
319
+ index++
320
+ continue
321
+ }
297
322
  const {
298
323
  subtotal,
299
324
  dataKey,
@@ -330,13 +355,14 @@ class PrinterStore {
330
355
  const currentPageMinimumHeight =
331
356
  allPagesHaveThisHeight + allTableHaveThisHeight
332
357
  /** 当前page可容纳的table高度 */
333
- let pageAccomodateTableHeight = +new Big(this.pageHeight)
334
- .minus(currentPageHeight)
335
- .toFixed(2)
336
- const heights = this.getNormalTableBodyHeights(
337
- table.body.heights,
338
- dataKey
358
+ let pageAccomodateTableHeight = roundHeight(
359
+ pageHeight - currentPageHeight
339
360
  )
361
+ // 拷贝一份行高数组,避免 splice 触发 observable 副作用
362
+ const heights = [
363
+ ...this.getNormalTableBodyHeights(table.body.heights, dataKey)
364
+ ]
365
+ const tableData = tableDataMap[dataKey] || []
340
366
  // 表格行的索引,用于table.slice(begin, end), 分割到不同页面中
341
367
  let begin = 0
342
368
  let end = 0
@@ -352,27 +378,41 @@ class PrinterStore {
352
378
  let currentRemainTableHeight = 0
353
379
  /** 去最小的tr高度,用于下面的计算compare,(避免特殊情况:一般来说最小tr——height = 23, 比23还小的不考虑计算) */
354
380
  const minHeight = Math.max(getArrayMid(heights), 23)
381
+ // 安全阈值:防止极端情况下内层 while 迭代失控
382
+ const maxIterations = heights.length * 10 + 100
383
+ let loopCount = 0
355
384
  /* 遍历表格每一行,填充表格内容 */
356
385
  while (end < heights.length) {
357
- currentTableHeight += heights[end]
386
+ if (++loopCount > maxIterations) {
387
+ console.warn(
388
+ '[gm-printer] computedPages: iteration limit exceeded, force break'
389
+ )
390
+ break
391
+ }
392
+
393
+ const rowHeight = heights[end]
394
+ currentTableHeight += rowHeight
358
395
  // 用于计算最后一页有footer情况的高度
359
- currentPageHeight += heights[end]
396
+ currentPageHeight += rowHeight
360
397
  // 当前页没有多余空间
361
398
  if (currentTableHeight > pageAccomodateTableHeight) {
362
- currentRemainTableHeight = +Big(pageAccomodateTableHeight)
363
- .minus(currentTableHeight)
364
- .plus(heights[end])
399
+ currentRemainTableHeight = roundHeight(
400
+ pageAccomodateTableHeight - currentTableHeight + rowHeight
401
+ )
402
+
403
+ const row = tableData[end]
404
+ const isRowOversized = rowHeight > pageAccomodateTableHeight
405
+ const shouldTrySplitDetails =
406
+ canSplitRowDetails(dataKey, row) &&
407
+ ((currentRemainTableHeight / minHeight > 1.5 &&
408
+ rowHeight / currentRemainTableHeight > 1) ||
409
+ isRowOversized)
365
410
 
366
411
  /**
367
- * 说明: 1. currentRemainTableHeight至少要是minHeight的 2倍,不然每次到这都进入if,同时留下一点空白距离
368
- * 2. heights[end]至少要是currentRemainTableHeight的 1倍,怕出现打印时最后一行文字显示一半的情况
369
- * 3. heights[end] 高度超过了 pageAccomodateTableHeight
412
+ * 仅对含 __details 的采购明细行尝试拆分;
413
+ * 普通长文本列(如规格)超高时直接整行换页,避免无效 computedData 调用
370
414
  */
371
- if (
372
- (currentRemainTableHeight / minHeight > 1.5 &&
373
- heights[end] / currentRemainTableHeight > 1) ||
374
- heights[end] > pageAccomodateTableHeight
375
- ) {
415
+ if (shouldTrySplitDetails) {
376
416
  const detailsPageHeight = this.computedData(
377
417
  dataKey,
378
418
  table,
@@ -380,7 +420,7 @@ class PrinterStore {
380
420
  currentRemainTableHeight
381
421
  )
382
422
 
383
- // 拆分明细后,同时也要更新body.heights 不能影响后续计算
423
+ // 拆分明细后,同时也要更新 heights 不能影响后续计算
384
424
  if (detailsPageHeight.length > 0) {
385
425
  // 比较剩余高度和minHeight的大小,取最大(防止剩余一条明细时,第二页撑开的高度远大于一条明细的高度)
386
426
  detailsPageHeight[1] = Math.max(
@@ -395,7 +435,8 @@ class PrinterStore {
395
435
  if (begin === 0 && end === 0 && index === 0) {
396
436
  index++
397
437
  this.pages = []
398
- this.setIsSave(true)
438
+ this.isSave = true
439
+ this.config.isSave = true
399
440
  Tip.warning(
400
441
  i18next.t(
401
442
  '检测到当前页面高度不足,无法完整渲染,请重新设置页面高度!'
@@ -403,7 +444,7 @@ class PrinterStore {
403
444
  )
404
445
  break
405
446
  }
406
- // 修复 OOM:某行高度本身超过单页可容纳的表格高度时,end 无法推进会导致 while 死循环
447
+ // 行无法拆分(普通长文本列)或拆分失败时,强制推进 end 防止死循环
407
448
  if (end === begin) {
408
449
  end = end + 1
409
450
  }
@@ -416,27 +457,27 @@ class PrinterStore {
416
457
  end
417
458
  })
418
459
  // 此页完成任务
419
- this.pages.push(page)
460
+ pages.push(page)
420
461
  page = []
421
462
  }
422
463
  // 页面有多个表格时,当同一页的第二个表格的第一行高度加上第一个表格的高度大于页面的高度,需要生成新的一页
423
464
  // 因为是第二个表格,重新走了遍历,end重置0,没有进入到上面的判断(end !== 0),不会生成新的一页
424
465
  if (tableCount > 1 && end === 0) {
425
- this.pages.push(page)
466
+ pages.push(page)
426
467
  page = []
427
468
  }
428
469
 
429
470
  begin = end
430
471
  // 开启新一页,重置页面高度
431
- pageAccomodateTableHeight = +new Big(this.pageHeight).minus(
432
- allPagesHaveThisHeight
472
+ pageAccomodateTableHeight = roundHeight(
473
+ pageHeight - allPagesHaveThisHeight
433
474
  )
434
475
  currentTableHeight = allTableHaveThisHeight
435
476
  currentPageHeight = currentPageMinimumHeight
436
477
  } else {
437
478
  // 有空间,继续做下行
438
479
  end++
439
- // 最后一行,把信息加入 page,并轮下一个contents
480
+ // 最后一行,把信息加入 page
440
481
  if (end === heights.length) {
441
482
  page.push({
442
483
  type: 'table',
@@ -444,27 +485,35 @@ class PrinterStore {
444
485
  begin,
445
486
  end
446
487
  })
447
- index++
448
488
  }
449
489
  }
450
490
  }
491
+ // 最后一行换页时走 if 分支,内层不会 index++,此处统一推进
492
+ if (end >= heights.length) {
493
+ index++
494
+ } else {
495
+ console.warn(
496
+ '[gm-printer] computedPages: table pagination incomplete, force advance'
497
+ )
498
+ index++
499
+ }
451
500
  }
452
501
  /* 非表格内容处理 */
453
502
  } else {
454
- const panelHeight = this.height[`contents.panel.${index}`]
503
+ const panelHeight = heightMap[`contents.panel.${index}`]
455
504
  currentPageHeight += panelHeight
456
505
 
457
506
  // 当 panel + allPagesHaveThisHeight > 页高度, 停止. 避免死循环
458
- if (panelHeight + allPagesHaveThisHeight > this.pageHeight) {
507
+ if (panelHeight + allPagesHaveThisHeight > pageHeight) {
459
508
  break
460
509
  }
461
510
 
462
511
  // 如果是最后一页,必须要加上sign的高度,否则会重叠
463
- if (index === this.config.contents.length - 1) {
464
- currentPageHeight += this.height?.sign
512
+ if (index === contentsLength - 1) {
513
+ currentPageHeight += heightMap?.sign || 0
465
514
  }
466
515
 
467
- if (currentPageHeight <= this.pageHeight) {
516
+ if (currentPageHeight <= pageHeight) {
468
517
  // 空间充足,把信息加入 page,并轮下一个contents
469
518
  page.push({
470
519
  type: 'panel',
@@ -474,7 +523,7 @@ class PrinterStore {
474
523
  index++
475
524
  } else {
476
525
  // 此页空间不足,此页完成任务
477
- this.pages.push(page)
526
+ pages.push(page)
478
527
 
479
528
  // 为下一页做准备
480
529
  page = []
@@ -482,8 +531,11 @@ class PrinterStore {
482
531
  }
483
532
  }
484
533
  }
485
- this.pages.push(page)
486
- this.remainPageHeight = +Big(this.pageHeight - currentPageHeight).toFixed(0)
534
+ pages.push(page)
535
+ this.pages = pages
536
+ this.remainPageHeight = Math.round(pageHeight - currentPageHeight)
537
+ this.isSave = false
538
+ this.config.isSave = false
487
539
  }
488
540
 
489
541
  @action
@@ -169,8 +169,7 @@ class Table extends React.Component {
169
169
  range,
170
170
  pageIndex,
171
171
  printerStore,
172
- isSomeSubtotalTr,
173
- isLastTablePage
172
+ isSomeSubtotalTr
174
173
  } = this.props
175
174
  // 数据
176
175
  dataKey = getDataKey(dataKey, arrange)
@@ -446,7 +445,6 @@ class Table extends React.Component {
446
445
  range={range}
447
446
  config={config}
448
447
  printerStore={printerStore}
449
- isLastTablePage={isLastTablePage}
450
448
  />
451
449
  <DiyOverallOrder
452
450
  range={range}
@@ -505,12 +503,7 @@ Table.propTypes = {
505
503
  pageIndex: PropTypes.number.isRequired,
506
504
  placeholder: PropTypes.string,
507
505
  printerStore: PropTypes.object,
508
- isSomeSubtotalTr: PropTypes.bool,
509
- isLastTablePage: PropTypes.bool
510
- }
511
-
512
- Table.defaultProps = {
513
- isLastTablePage: true
506
+ isSomeSubtotalTr: PropTypes.bool
514
507
  }
515
508
 
516
509
  export default Table