gm-printer 10.38.7 → 10.38.8-beta.2

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/package.json +1 -1
  3. package/src/common/component.js +3 -2
  4. package/src/common/editor_edit_field.js +14 -8
  5. package/src/common/editor_page_border.js +84 -0
  6. package/src/common/editor_store.js +128 -46
  7. package/src/common/hoc_with_store.js +9 -1
  8. package/src/common/page_border.js +102 -0
  9. package/src/editor/context_menu.js +1 -0
  10. package/src/editor/context_menu_config.js +1 -0
  11. package/src/editor/editor.js +2 -0
  12. package/src/editor/editor_menu_config.js +2 -0
  13. package/src/editor_account/context_menu.js +1 -0
  14. package/src/editor_account/editor.js +2 -0
  15. package/src/editor_account_statement/context_menu.js +1 -0
  16. package/src/editor_account_statement/editor.js +2 -0
  17. package/src/editor_box_label/context_menu.js +1 -0
  18. package/src/editor_box_label/editor.js +5 -0
  19. package/src/editor_purchase/context_menu.js +1 -0
  20. package/src/editor_purchase/editor.js +2 -0
  21. package/src/editor_salemenus/context_menu.js +1 -0
  22. package/src/editor_salemenus/editor.js +2 -0
  23. package/src/editor_settle/context_menu.js +1 -0
  24. package/src/editor_settle/editor.js +2 -0
  25. package/src/editor_statement/context_menu.js +1 -0
  26. package/src/editor_statement/editor.js +2 -0
  27. package/src/editor_stockin/context_menu.js +1 -0
  28. package/src/editor_stockin/editor.js +2 -0
  29. package/src/editor_stockout/context_menu.js +1 -0
  30. package/src/editor_stockout/editor.js +2 -0
  31. package/src/examining_report_editor/context_menu.js +1 -0
  32. package/src/examining_report_editor/editor.js +2 -0
  33. package/src/examining_report_editor/store.js +2 -2
  34. package/src/printer/merge_page.js +12 -0
  35. package/src/printer/page.js +11 -1
  36. package/src/printer/printer.js +16 -3
  37. package/src/printer/store.js +9 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gm-printer",
3
- "version": "10.38.7",
3
+ "version": "10.38.8-beta.2",
4
4
  "description": "diy printer",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -72,12 +72,13 @@ class Text extends React.Component {
72
72
  }
73
73
 
74
74
  render() {
75
- const { value, placeholder, style, className, ...rest } = this.props
75
+ const { value, placeholder, style, className, onChange, ...rest } =
76
+ this.props
76
77
  return (
77
78
  <input
78
79
  className={classNames('gm-printer-edit-input', className)}
79
80
  type='text'
80
- value={value}
81
+ value={value == null || typeof value === 'object' ? '' : value}
81
82
  placeholder={placeholder}
82
83
  onChange={this.handleChange}
83
84
  style={style}
@@ -22,6 +22,7 @@ import PropTypes from 'prop-types'
22
22
  import { subtotalRadioList } from './util'
23
23
  import { LONG_PRINT } from '../config'
24
24
  import _ from 'lodash'
25
+ import EditorPageBorder from './editor_page_border'
25
26
 
26
27
  @inject('editStore')
27
28
  @observer
@@ -247,7 +248,7 @@ class EditorField extends React.Component {
247
248
  false
248
249
  // 每页合计样式
249
250
  const overallOrderStyle =
250
- (overallOrder && overallOrder?.fields[0].style) || {}
251
+ (overallOrder && overallOrder?.fields?.[0]?.style) || {}
251
252
  // 每页合计自定义单元格
252
253
  const subtotalUpperCustomCell =
253
254
  (editStore.computedTableSpecialConfig?.subtotal &&
@@ -282,7 +283,7 @@ class EditorField extends React.Component {
282
283
  false
283
284
  // 自定义整单合计样式
284
285
  const diyOverallOrderStyle =
285
- (diyOverallOrder && diyOverallOrder?.fields[0].style) || {}
286
+ (diyOverallOrder && diyOverallOrder?.fields?.[0]?.style) || {}
286
287
 
287
288
  // 自定义整单合计是否大写
288
289
  const diyOverallOrderNeedUpperCase =
@@ -303,7 +304,7 @@ class EditorField extends React.Component {
303
304
 
304
305
  const diyOverallOrderValueField =
305
306
  editStore.computedTableSpecialConfig?.diyOverallOrder?.fields?.[0]
306
- .valueField
307
+ ?.valueField
307
308
 
308
309
  // 分类/标签小计 是否需要大写
309
310
  const classificationAndLabelTallyNeedUpperCase =
@@ -532,12 +533,12 @@ class EditorField extends React.Component {
532
533
  <Flex style={{ marginLeft: 57 }}>
533
534
  {subtotalRadioList.map(fields => {
534
535
  // 兼容
535
- let subtotalFields = subtotal?.fields?.[0].valueField
536
+ let subtotalFields = subtotal?.fields?.[0]?.valueField
536
537
  if (subtotalFields === 'total_item_price')
537
538
  subtotalFields = '下单金额'
538
539
  if (
539
540
  subtotalFields === 'real_item_price' ||
540
- !subtotal?.fields?.[0].valueField
541
+ !subtotal?.fields?.[0]?.valueField
541
542
  )
542
543
  subtotalFields = '出库金额'
543
544
  return (
@@ -597,8 +598,8 @@ class EditorField extends React.Component {
597
598
  // 只有自定义单元格的valueField值是空的,以后自每页合计,记得加type,之前没加,都无法区分
598
599
  value={
599
600
  subtotal && subtotal?.fields?.length > 1
600
- ? _.find(subtotal?.fields, item => !item.valueField)?.name ??
601
- ''
601
+ ? _.find(subtotal?.fields, item => item && !item.valueField)
602
+ ?.name ?? ''
602
603
  : ''
603
604
  }
604
605
  onChange={editStore.setSubtotalFields}
@@ -971,7 +972,12 @@ class EditorField extends React.Component {
971
972
  const { editStore } = this.props
972
973
 
973
974
  let content = null
974
- if (editStore.computedIsSelectBlock) {
975
+ if (
976
+ editStore.enablePageBorder &&
977
+ editStore.selectedRegion === 'border'
978
+ ) {
979
+ content = <EditorPageBorder />
980
+ } else if (editStore.computedIsSelectBlock) {
975
981
  content = this.renderBlocks()
976
982
  } else if (editStore.computedIsSelectTable) {
977
983
  content = this.renderTable()
@@ -0,0 +1,84 @@
1
+ import i18next from '../../locales'
2
+ import React from 'react'
3
+ import PropTypes from 'prop-types'
4
+ import { observer, inject } from 'mobx-react'
5
+ import { Gap, Title } from './component'
6
+ import { Flex } from '../components'
7
+
8
+ @inject('editStore')
9
+ @observer
10
+ class EditorPageBorder extends React.Component {
11
+ handleSelect = id => {
12
+ this.props.editStore.setPageBorderId(id)
13
+ }
14
+
15
+ render() {
16
+ const { editStore } = this.props
17
+ const { borderId } = editStore.config.page || {}
18
+ const list = editStore.computedAvailablePageBorders
19
+
20
+ return (
21
+ <div>
22
+ <Title title={i18next.t('编辑边框')} />
23
+ <Gap />
24
+ {!list.length ? (
25
+ <div className='gm-text-desc'>{i18next.t('暂无可用边框')}</div>
26
+ ) : (
27
+ <Flex wrap>
28
+ {list.map(item => {
29
+ const active = borderId === item.id
30
+ return (
31
+ <div
32
+ key={item.id}
33
+ onClick={() => this.handleSelect(item.id)}
34
+ style={{
35
+ width: 88,
36
+ margin: '0 8px 8px 0',
37
+ padding: 4,
38
+ cursor: 'pointer',
39
+ border: active ? '2px solid #56a3f2' : '1px solid #eee',
40
+ textAlign: 'center'
41
+ }}
42
+ >
43
+ <img
44
+ src={item.imageUrl}
45
+ alt={item.name}
46
+ style={{
47
+ width: '100%',
48
+ height: 64,
49
+ objectFit: 'contain',
50
+ display: 'block'
51
+ }}
52
+ />
53
+ <div style={{ marginTop: 4, fontSize: 12 }}>{item.name}</div>
54
+ </div>
55
+ )
56
+ })}
57
+ <div
58
+ onClick={() => this.handleSelect(null)}
59
+ style={{
60
+ width: 88,
61
+ margin: '0 8px 8px 0',
62
+ padding: 4,
63
+ cursor: 'pointer',
64
+ border: !borderId ? '2px solid #56a3f2' : '1px dashed #ccc',
65
+ textAlign: 'center',
66
+ lineHeight: '64px',
67
+ fontSize: 12,
68
+ color: '#999'
69
+ }}
70
+ >
71
+ {i18next.t('无边框')}
72
+ </div>
73
+ </Flex>
74
+ )}
75
+ </div>
76
+ )
77
+ }
78
+ }
79
+
80
+ EditorPageBorder.propTypes = {
81
+ editStore: PropTypes.object
82
+ }
83
+
84
+ export default EditorPageBorder
@@ -6,6 +6,12 @@ import { dispatchMsg, getBlockName, exchange, getColSpanLength } from '../util'
6
6
  import { accountRadioList } from './util'
7
7
  import React from 'react'
8
8
  import { createDiySummaryStoreMethods } from './diy_summary_helper'
9
+ import {
10
+ filterPageBorderTypes,
11
+ isPageBorderCompatible,
12
+ resolvePageGapForBorder,
13
+ getPageBorderGap
14
+ } from './page_border'
9
15
 
10
16
  class EditorStore {
11
17
  @observable
@@ -47,6 +53,9 @@ class EditorStore {
47
53
  @observable
48
54
  selectedRegion = null
49
55
 
56
+ @observable
57
+ enablePageBorder = false
58
+
50
59
  @observable
51
60
  insertPanel = 'header'
52
61
 
@@ -99,20 +108,27 @@ class EditorStore {
99
108
 
100
109
  const colSpanLength = getColSpanLength(table)
101
110
  if (!table.subtotal.fields?.length) {
102
- set(table.subtotal, {
103
- fields: [
104
- {
105
- name: '每页合计:',
106
- valueField: 'real_item_price',
107
- colSpan: colSpanLength
108
- }
109
- ]
110
- })
111
+ const fields = [
112
+ {
113
+ name: '每页合计:',
114
+ valueField: 'real_item_price',
115
+ colSpan: colSpanLength
116
+ }
117
+ ]
118
+ if (table.subtotal.isCustomCells) {
119
+ const customCellField = { ...this.subtotalConfigFields }
120
+ fields[0].colSpan = colSpanLength - customCellField.colSpan
121
+ fields.push(customCellField)
122
+ }
123
+ set(table.subtotal, { fields })
111
124
  return
112
125
  }
113
126
 
114
127
  const subtotalLength = table.subtotal.fields.length
115
- table.subtotal.fields[subtotalLength - 1].colSpan += 1
128
+ const lastField = table.subtotal.fields[subtotalLength - 1]
129
+ if (lastField) {
130
+ lastField.colSpan += 1
131
+ }
116
132
  }
117
133
 
118
134
  @action
@@ -292,7 +308,7 @@ class EditorStore {
292
308
  }
293
309
 
294
310
  @action
295
- init(config, data) {
311
+ init(config, data, options = {}) {
296
312
  // batchPrintConfig: 1 不连续打印(一张采购单不出现多供应商)2 连续打印(一张采购单可能出现多个供应商)
297
313
  this.config = Object.assign(
298
314
  { batchPrintConfig: 1, isFixLastFooter: true },
@@ -310,6 +326,7 @@ class EditorStore {
310
326
 
311
327
  this.taxFreeProductRateDisplay =
312
328
  config?.specialControlConfig?.taxFreeProductRateDisplay || ''
329
+ this.enablePageBorder = !!options.enablePageBorder
313
330
  }
314
331
 
315
332
  @action
@@ -358,18 +375,50 @@ class EditorStore {
358
375
  const contentRegions = this.config.contents.map((v, i) => {
359
376
  if (v.type === 'table') {
360
377
  return { value: `contents.table.${i}`, text: i18next.t('区域') + i }
361
- } else {
362
- return { value: `contents.panel.${i}`, text: i18next.t('区域') + i }
363
378
  }
379
+ return { value: `contents.panel.${i}`, text: i18next.t('区域') + i }
364
380
  })
365
381
 
366
- return [
382
+ const list = [
367
383
  { value: 'all', text: i18next.t('请选择区域') },
368
384
  { value: 'header', text: i18next.t('页眉') },
369
385
  ...contentRegions,
370
386
  { value: 'sign', text: i18next.t('签名') },
371
387
  { value: 'footer', text: i18next.t('页脚') }
372
388
  ]
389
+ if (this.enablePageBorder) {
390
+ list.push({ value: 'border', text: i18next.t('边框') })
391
+ }
392
+ return list
393
+ }
394
+
395
+ @computed
396
+ get computedAvailablePageBorders() {
397
+ const types = this.config?.pageBorderTypes
398
+ const pageType = this.config?.page?.type
399
+ return filterPageBorderTypes(types, pageType)
400
+ }
401
+
402
+ @action
403
+ setEnablePageBorder(enable) {
404
+ this.enablePageBorder = !!enable
405
+ }
406
+
407
+ @action
408
+ setPageBorderId(borderId) {
409
+ if (!this.config?.page) return
410
+ const nextBorderId = borderId || null
411
+ const nextGap = resolvePageGapForBorder({
412
+ pageBorderTypes: this.config.pageBorderTypes,
413
+ borderId: nextBorderId,
414
+ pageType: this.config.page.type,
415
+ currentGap: this.config.page.gap
416
+ })
417
+ const patch = { borderId: nextBorderId }
418
+ if (nextGap) {
419
+ patch.gap = nextGap
420
+ }
421
+ set(this.config.page, patch)
373
422
  }
374
423
 
375
424
  @action
@@ -431,6 +480,23 @@ class EditorStore {
431
480
  gap,
432
481
  name
433
482
  }
483
+
484
+ const borderId = this.config.page.borderId
485
+ if (
486
+ borderId &&
487
+ !isPageBorderCompatible(this.config.pageBorderTypes, borderId, type)
488
+ ) {
489
+ set(this.config.page, { borderId: null })
490
+ } else if (borderId) {
491
+ // 纸张切换后仍匹配:仅当边框配置了 gap 时覆盖
492
+ const borderGap = getPageBorderGap(
493
+ this.config.pageBorderTypes,
494
+ borderId
495
+ )
496
+ if (borderGap) {
497
+ set(this.config.page, { gap: borderGap })
498
+ }
499
+ }
434
500
  }
435
501
 
436
502
  @action
@@ -442,6 +508,9 @@ class EditorStore {
442
508
  @computed
443
509
  get computedSelectedRegionTip() {
444
510
  if (!this.selectedRegion) return ''
511
+ if (this.selectedRegion === 'border') {
512
+ return i18next.t('说明:边框铺满整页,内容区仍保留页边距')
513
+ }
445
514
  return /(contents)|(sign)/g.test(this.selectedRegion) ? (
446
515
  <>
447
516
  <div>{i18next.t('说明:所选区域的内容仅打印一次')}</div>
@@ -1659,8 +1728,8 @@ class EditorStore {
1659
1728
  // fields添加自定义单元格
1660
1729
  subtotalConfig.fields = [
1661
1730
  subtotalConfig.fields[0],
1662
- this.subtotalAccountConfigFields,
1663
- subtotalConfig.fields[1]
1731
+ { ...this.subtotalAccountConfigFields },
1732
+ { ...subtotalConfig.fields[1] }
1664
1733
  ]
1665
1734
  // 重新计算合并单元格的个数
1666
1735
  subtotalConfig.fields[0].colSpan = Math.floor(colSpanLength / 3)
@@ -1673,7 +1742,7 @@ class EditorStore {
1673
1742
  // fields添加自定义单元格
1674
1743
  subtotalConfig.fields = [
1675
1744
  subtotalConfig.fields[0],
1676
- this.subtotalAccountConfigFields
1745
+ { ...this.subtotalAccountConfigFields }
1677
1746
  ]
1678
1747
  // 重新计算合并单元格的个数
1679
1748
  subtotalConfig.fields[0].colSpan =
@@ -1685,7 +1754,7 @@ class EditorStore {
1685
1754
  if (subtotalConfig?.fields?.length === 3) {
1686
1755
  subtotalConfig.fields = [
1687
1756
  subtotalConfig.fields[0],
1688
- this.subtotalConfigFields
1757
+ { ...this.subtotalConfigFields }
1689
1758
  ]
1690
1759
  // 重新计算合并单元格的个数
1691
1760
  subtotalConfig.fields[0].colSpan =
@@ -1719,7 +1788,7 @@ class EditorStore {
1719
1788
  isCustomCells: !oldCustomCells
1720
1789
  })
1721
1790
  // 兼容已经存在后端的模板,每页合计直接是显示的,导致每页合计配置没有fields,isCustomCells,手动添加上
1722
- if (oldCustomCells === undefined && !subtotalConfig.fields) {
1791
+ if (!subtotalConfig.fields?.length) {
1723
1792
  set(subtotalConfig, {
1724
1793
  fields: [
1725
1794
  {
@@ -1730,15 +1799,16 @@ class EditorStore {
1730
1799
  ]
1731
1800
  })
1732
1801
  }
1733
- // 开启自定义单元格
1802
+ // 开启自定义单元格(必须拷贝,禁止共用 store 上的模板对象,否则 toJS/多次开关后 fields 会错乱)
1734
1803
  if (subtotalConfig?.isCustomCells) {
1735
- // 同时还开启了自定义单元格选项
1804
+ const customCellField = { ...this.subtotalConfigFields }
1805
+ // 同时还开启了打印账户总计金额
1736
1806
  if (subtotalConfig?.fields?.length === 2) {
1737
- // fields添加自定义单元格
1807
+ const accountField = { ...this.subtotalAccountConfigFields }
1738
1808
  subtotalConfig.fields = [
1739
1809
  subtotalConfig.fields[0],
1740
- this.subtotalAccountConfigFields,
1741
- this.subtotalConfigFields
1810
+ accountField,
1811
+ customCellField
1742
1812
  ]
1743
1813
  // 重新计算合并单元格的个数
1744
1814
  subtotalConfig.fields[0].colSpan = Math.floor(colSpanLength / 3)
@@ -1748,11 +1818,7 @@ class EditorStore {
1748
1818
  subtotalConfig.fields[0].colSpan -
1749
1819
  subtotalConfig.fields[1].colSpan
1750
1820
  } else {
1751
- // fields添加自定义单元格
1752
- subtotalConfig.fields = [
1753
- subtotalConfig.fields[0],
1754
- this.subtotalConfigFields
1755
- ]
1821
+ subtotalConfig.fields = [subtotalConfig.fields[0], customCellField]
1756
1822
  // 重新计算合并单元格的个数
1757
1823
  subtotalConfig.fields[0].colSpan =
1758
1824
  colSpanLength - subtotalConfig.fields[1].colSpan
@@ -1763,7 +1829,7 @@ class EditorStore {
1763
1829
  if (subtotalConfig?.fields?.length === 3) {
1764
1830
  subtotalConfig.fields = [
1765
1831
  subtotalConfig.fields[0],
1766
- this.subtotalAccountConfigFields
1832
+ { ...this.subtotalAccountConfigFields }
1767
1833
  ]
1768
1834
  // 重新计算合并单元格的个数
1769
1835
  subtotalConfig.fields[0].colSpan =
@@ -1781,17 +1847,30 @@ class EditorStore {
1781
1847
  // 每页合计自定义单元格文本输入
1782
1848
  @action.bound
1783
1849
  setSubtotalFields(value) {
1784
- if (this.selectedRegion) {
1785
- const arr = this.selectedRegion.split('.')
1786
- const table = this.config.contents[arr[2]]
1787
- const subtotalConfig = table?.subtotal
1850
+ if (!this.selectedRegion) return
1851
+ // Text 组件应传入 string;防护误传 React 事件对象
1852
+ if (typeof value !== 'string') return
1788
1853
 
1789
- if (subtotalConfig.isCustomCells) {
1790
- const subtotalConfig = table?.subtotal.fields
1791
- subtotalConfig.length === 3
1792
- ? (subtotalConfig[2].name = value)
1793
- : (subtotalConfig[1].name = value)
1794
- }
1854
+ const arr = this.selectedRegion.split('.')
1855
+ const table = this.config.contents[arr[2]]
1856
+ const subtotalConfig = table?.subtotal
1857
+ if (!subtotalConfig?.isCustomCells) return
1858
+
1859
+ const fields = subtotalConfig.fields
1860
+ if (!fields?.length) return
1861
+
1862
+ // 自定义单元格的 valueField 为空(与编辑面板展示逻辑一致)
1863
+ const customField = _.find(fields, item => item && !item.valueField)
1864
+ if (customField) {
1865
+ customField.name = value
1866
+ return
1867
+ }
1868
+
1869
+ // 兼容:按位置写入(开启打印账户时自定义单元格在末位)
1870
+ const target =
1871
+ fields.length >= 3 ? fields[2] : fields.length >= 2 ? fields[1] : null
1872
+ if (target) {
1873
+ target.name = value
1795
1874
  }
1796
1875
  }
1797
1876
 
@@ -1927,13 +2006,16 @@ class EditorStore {
1927
2006
  // 整单合计自定义单元格文本输入
1928
2007
  @action.bound
1929
2008
  setOverallOrderFields(value) {
1930
- if (this.selectedRegion) {
1931
- const arr = this.selectedRegion.split('.')
1932
- const table = this.config.contents[arr[2]]
1933
- const overallOrderConfig = table?.overallOrder
2009
+ if (!this.selectedRegion) return
2010
+ if (typeof value !== 'string') return
2011
+
2012
+ const arr = this.selectedRegion.split('.')
2013
+ const table = this.config.contents[arr[2]]
2014
+ const overallOrderConfig = table?.overallOrder
1934
2015
 
1935
- if (overallOrderConfig.isCustomCells) {
1936
- const overallOrderConfigFields = table?.overallOrder.fields
2016
+ if (overallOrderConfig?.isCustomCells) {
2017
+ const overallOrderConfigFields = table?.overallOrder.fields
2018
+ if (overallOrderConfigFields?.[1]) {
1937
2019
  overallOrderConfigFields[1].name = value
1938
2020
  }
1939
2021
  }
@@ -7,7 +7,15 @@ const withStore = store => WrapComponent =>
7
7
  constructor(props) {
8
8
  super(props)
9
9
  this.store = store
10
- this.store.init(props.config, props.mockData)
10
+ this.store.init(props.config, props.mockData, {
11
+ enablePageBorder: props.enablePageBorder
12
+ })
13
+ }
14
+
15
+ componentDidUpdate(prevProps) {
16
+ if (prevProps.enablePageBorder !== this.props.enablePageBorder) {
17
+ this.store.setEnablePageBorder(this.props.enablePageBorder)
18
+ }
11
19
  }
12
20
 
13
21
  componentDidMount() {
@@ -0,0 +1,102 @@
1
+ import _ from 'lodash'
2
+ import { pageTypeMap } from '../config'
3
+
4
+ /**
5
+ * @param {Array<{id:string,name:string,imageUrl:string,pageTypes:string[],gap?:object}>} types
6
+ * @param {string} pageType
7
+ */
8
+ export function filterPageBorderTypes(types, pageType) {
9
+ if (!types || !types.length || !pageType) return []
10
+ return types.filter(
11
+ item => item && _.includes(item.pageTypes || [], pageType)
12
+ )
13
+ }
14
+
15
+ export function findPageBorderType(types, borderId) {
16
+ if (!borderId || !types) return null
17
+ return types.find(item => item && item.id === borderId) || null
18
+ }
19
+
20
+ /**
21
+ * 当前 borderId 是否仍适用于 pageType;不适用则应清空
22
+ */
23
+ export function isPageBorderCompatible(types, borderId, pageType) {
24
+ if (!borderId) return true
25
+ return !!filterPageBorderTypes(types, pageType).find(
26
+ item => item.id === borderId
27
+ )
28
+ }
29
+
30
+ /**
31
+ * 取边框自带边距;无配置则返回 null(表示不覆盖 page.gap)
32
+ */
33
+ export function getPageBorderGap(types, borderId) {
34
+ const item = findPageBorderType(types, borderId)
35
+ if (!item || !item.gap) return null
36
+ const { paddingTop, paddingRight, paddingBottom, paddingLeft } = item.gap
37
+ if (
38
+ paddingTop == null &&
39
+ paddingRight == null &&
40
+ paddingBottom == null &&
41
+ paddingLeft == null
42
+ ) {
43
+ return null
44
+ }
45
+ return {
46
+ paddingTop: paddingTop || '0mm',
47
+ paddingRight: paddingRight || '0mm',
48
+ paddingBottom: paddingBottom || '0mm',
49
+ paddingLeft: paddingLeft || '0mm'
50
+ }
51
+ }
52
+
53
+ /**
54
+ * 选中边框:有 gap 则用边框 gap,无 gap 则保持 currentGap
55
+ * 清空边框:回退纸张默认 gap
56
+ */
57
+ export function resolvePageGapForBorder({
58
+ pageBorderTypes,
59
+ borderId,
60
+ pageType,
61
+ currentGap
62
+ }) {
63
+ if (borderId) {
64
+ const borderGap = getPageBorderGap(pageBorderTypes, borderId)
65
+ if (borderGap) return borderGap
66
+ return currentGap ? { ...currentGap } : null
67
+ }
68
+ const defaultGap = pageTypeMap[pageType]?.gap
69
+ if (defaultGap) {
70
+ return { ...defaultGap }
71
+ }
72
+ return currentGap ? { ...currentGap } : null
73
+ }
74
+
75
+ /**
76
+ * 生成要合并进 .gm-printer-page 的边框背景 style
77
+ * 不满足条件时返回 {}
78
+ */
79
+ export function getPageBorderBackgroundStyle({
80
+ enablePageBorder,
81
+ borderId,
82
+ pageBorderTypes
83
+ }) {
84
+ if (!enablePageBorder || !borderId) return {}
85
+ const item = findPageBorderType(pageBorderTypes, borderId)
86
+ if (!item || !item.imageUrl) return {}
87
+ return {
88
+ backgroundImage: `url(${item.imageUrl})`,
89
+ backgroundSize: '100% 100%',
90
+ backgroundRepeat: 'no-repeat'
91
+ }
92
+ }
93
+
94
+ /**
95
+ * pageStyle 在前,边框 background* 覆盖其上
96
+ */
97
+ export function mergePageStyleWithBorder(pageStyle, borderStyle) {
98
+ return {
99
+ ...(pageStyle || {}),
100
+ ...(borderStyle || {})
101
+ }
102
+ }
@@ -292,6 +292,7 @@ class ContextMenu extends React.Component {
292
292
  key={editStore.computedPrinterKey}
293
293
  selected={editStore.selected}
294
294
  selectedRegion={editStore.selectedRegion}
295
+ enablePageBorder={editStore.enablePageBorder}
295
296
  isAutoFilling={editStore.isAutoFilling}
296
297
  fillIndex={editStore.fillIndex}
297
298
  lineheight={editStore.computedTableCustomerRowHeight}
@@ -311,6 +311,7 @@ class ContextMenu extends React.Component {
311
311
  key={editStore.computedPrinterKey}
312
312
  selected={editStore.selected}
313
313
  selectedRegion={editStore.selectedRegion}
314
+ enablePageBorder={editStore.enablePageBorder}
314
315
  isAutoFilling={editStore.isAutoFilling}
315
316
  fillIndex={editStore.fillIndex}
316
317
  lineheight={editStore.computedTableCustomerRowHeight}
@@ -115,6 +115,7 @@ class Editor extends React.Component {
115
115
  }
116
116
 
117
117
  Editor.propTypes = {
118
+ enablePageBorder: PropTypes.bool,
118
119
  config: PropTypes.object.isRequired,
119
120
  onSave: PropTypes.func,
120
121
  showEditor: PropTypes.bool,
@@ -126,6 +127,7 @@ Editor.propTypes = {
126
127
  }
127
128
 
128
129
  Editor.defaultProps = {
130
+ enablePageBorder: false,
129
131
  onSave: _.noop,
130
132
  showNewDate: false
131
133
  }
@@ -118,6 +118,7 @@ class Editor extends React.Component {
118
118
  }
119
119
 
120
120
  Editor.propTypes = {
121
+ enablePageBorder: PropTypes.bool,
121
122
  config: PropTypes.object.isRequired,
122
123
  onSave: PropTypes.func,
123
124
  showEditor: PropTypes.bool,
@@ -133,6 +134,7 @@ Editor.propTypes = {
133
134
  }
134
135
 
135
136
  Editor.defaultProps = {
137
+ enablePageBorder: false,
136
138
  onSave: _.noop,
137
139
  showNewDate: false
138
140
  }
@@ -136,6 +136,7 @@ class ContextMenu extends React.Component {
136
136
  key={editStore.computedPrinterKey}
137
137
  selected={editStore.selected}
138
138
  selectedRegion={editStore.selectedRegion}
139
+ enablePageBorder={editStore.enablePageBorder}
139
140
  isAutoFilling={editStore.isAutoFilling}
140
141
  config={editStore.config}
141
142
  data={editStore.mockData}
@@ -77,6 +77,7 @@ class Editor extends React.Component {
77
77
  }
78
78
 
79
79
  Editor.propTypes = {
80
+ enablePageBorder: PropTypes.bool,
80
81
  config: PropTypes.object.isRequired,
81
82
  onSave: PropTypes.func,
82
83
  showEditor: PropTypes.bool,
@@ -86,6 +87,7 @@ Editor.propTypes = {
86
87
  }
87
88
 
88
89
  Editor.defaultProps = {
90
+ enablePageBorder: false,
89
91
  onSave: _.noop,
90
92
  showNewDate: false
91
93
  }