gm-printer 10.33.7 → 10.34.0

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.33.7",
3
+ "version": "10.34.0",
4
4
  "description": "diy printer",
5
5
  "main": "src/index.js",
6
6
  "scripts": {
@@ -149,6 +149,17 @@ class CommonContextMenu extends React.Component {
149
149
  })
150
150
  }
151
151
 
152
+ handleAddContentWithConfig = (diff, type, tableConfig) => {
153
+ const { editStore } = this.props
154
+ const { name } = this.state
155
+
156
+ editStore.addContentByDiff(name, diff, type, tableConfig)
157
+
158
+ this.setState({
159
+ name: null
160
+ })
161
+ }
162
+
152
163
  handleInsertImage = imgURL => {
153
164
  this.handleInsertBlock('image', imgURL)
154
165
  }
@@ -240,7 +251,6 @@ class CommonContextMenu extends React.Component {
240
251
  <Hr />
241
252
  </>
242
253
  )}
243
-
244
254
  <div onClick={this.handleAddContent.bind(this, 0, '')}>
245
255
  {i18next.t('向上插入区域块')}
246
256
  </div>
@@ -296,7 +306,7 @@ class CommonContextMenu extends React.Component {
296
306
  }
297
307
 
298
308
  renderPanel = () => {
299
- let { insertBlockList } = this.props
309
+ let { insertBlockList, customTableConfigs } = this.props
300
310
  const { name } = this.state
301
311
  const arr = name.split('.')
302
312
  const type = arr[0]
@@ -328,6 +338,21 @@ class CommonContextMenu extends React.Component {
328
338
  )
329
339
  })}
330
340
 
341
+ {customTableConfigs &&
342
+ customTableConfigs.map(customConfig => (
343
+ <div
344
+ key={customConfig.label}
345
+ onClick={this.handleAddContentWithConfig.bind(
346
+ this,
347
+ 1,
348
+ 'table',
349
+ customConfig.tableConfig
350
+ )}
351
+ >
352
+ {customConfig.label}
353
+ </div>
354
+ ))}
355
+
331
356
  {arr[0] === 'contents' && (
332
357
  <>
333
358
  <Hr />
@@ -410,6 +435,7 @@ CommonContextMenu.propTypes = {
410
435
  editStore: PropTypes.object,
411
436
  insertBlockList: PropTypes.array.isRequired,
412
437
  renderTableAction: PropTypes.func,
438
+ customTableConfigs: PropTypes.array,
413
439
  children: PropTypes.element.isRequired
414
440
  }
415
441
 
@@ -72,7 +72,7 @@ class Text extends React.Component {
72
72
  }
73
73
 
74
74
  render() {
75
- const { value, placeholder, style, className } = this.props
75
+ const { value, placeholder, style, className, ...rest } = this.props
76
76
  return (
77
77
  <input
78
78
  className={classNames('gm-printer-edit-input', className)}
@@ -81,6 +81,7 @@ class Text extends React.Component {
81
81
  placeholder={placeholder}
82
82
  onChange={this.handleChange}
83
83
  style={style}
84
+ {...rest}
84
85
  />
85
86
  )
86
87
  }
@@ -3,6 +3,7 @@ import { inject, observer } from 'mobx-react'
3
3
  import PropTypes from 'prop-types'
4
4
  import React from 'react'
5
5
  import { Flex, Switch } from '../components'
6
+ import { Text } from './component'
6
7
 
7
8
  @inject('editStore')
8
9
  @observer
@@ -25,10 +26,47 @@ class EditorCutomizedConfig extends React.Component {
25
26
  editStore.setFillIndex(value)
26
27
  }
27
28
 
29
+ handleTaxFreeProductRateDisplay = e => {
30
+ const value = e.target.value
31
+
32
+ const { editStore } = this.props
33
+ // 限制10位以内,如果超过则截断
34
+ const trimmedValue = value.length > 10 ? value.slice(0, 10) : value
35
+ editStore.setTaxFreeProductRateDisplay(trimmedValue)
36
+
37
+ // 如果选中了表格,同时更新表格配置
38
+ if (editStore.selectedRegion && editStore.computedRegionIsTable) {
39
+ const arr = editStore.selectedRegion.split('.')
40
+ const tableConfig = editStore.config.contents[arr[2]]
41
+
42
+ const dataKey = tableConfig.dataKey
43
+ const tableData = editStore.mockData._table[dataKey]
44
+
45
+ if (tableData?.length) {
46
+ const list = tableData.map(item => {
47
+ if (item._origin && Number(item._origin?.tax_rate) === 0) {
48
+ if (String(value).length > 0) {
49
+ item['税率'] = value
50
+ } else {
51
+ item['税率'] = '0.00%'
52
+ }
53
+ }
54
+ return item
55
+ })
56
+ editStore.updateTableData(dataKey, list)
57
+ }
58
+ }
59
+ }
60
+
28
61
  render() {
29
62
  const {
30
63
  editStore,
31
- editStore: { isAutoFilling, isMultiDigitDecimal, fillIndex }
64
+ editStore: {
65
+ isAutoFilling,
66
+ isMultiDigitDecimal,
67
+ fillIndex,
68
+ taxFreeProductRateDisplay
69
+ }
32
70
  } = this.props
33
71
  // 是table
34
72
  if (editStore.computedRegionIsTable) {
@@ -58,6 +96,15 @@ class EditorCutomizedConfig extends React.Component {
58
96
  onChange={this.handleMultiDigitDecimal}
59
97
  />
60
98
  </Flex>
99
+ <Flex alignCenter className='gm-padding-top-5'>
100
+ <div>{i18next.t('免税产品税率显示')}:</div>
101
+ <Text
102
+ value={taxFreeProductRateDisplay || ''}
103
+ onChange={this.handleTaxFreeProductRateDisplay}
104
+ placeholder={i18next.t('请输入')}
105
+ maxLength={10}
106
+ />
107
+ </Flex>
61
108
  </>
62
109
  )
63
110
  } else {
@@ -57,6 +57,10 @@ class EditorStore {
57
57
  @observable
58
58
  isMultiDigitDecimal = false
59
59
 
60
+ /** 免税产品税率显示 */
61
+ @observable
62
+ taxFreeProductRateDisplay = ''
63
+
60
64
  defaultTableDataKey = 'orders'
61
65
 
62
66
  // 默认table的dataKey
@@ -101,11 +105,23 @@ class EditorStore {
101
105
  this.isMultiDigitDecimal = bool
102
106
  set(this.config, {
103
107
  specialControlConfig: {
108
+ ...this.config.specialControlConfig,
104
109
  multiDigitDecimal: bool
105
110
  }
106
111
  })
107
112
  }
108
113
 
114
+ @action
115
+ setTaxFreeProductRateDisplay(value) {
116
+ this.taxFreeProductRateDisplay = value
117
+ set(this.config, {
118
+ specialControlConfig: {
119
+ ...this.config.specialControlConfig,
120
+ taxFreeProductRateDisplay: value
121
+ }
122
+ })
123
+ }
124
+
109
125
  @observable
110
126
  overallOrderShow = false
111
127
 
@@ -257,6 +273,9 @@ class EditorStore {
257
273
  this.isAutoFilling = false
258
274
  this.fillIndex = false
259
275
  this.isMultiDigitDecimal = false
276
+
277
+ this.taxFreeProductRateDisplay =
278
+ config?.specialControlConfig?.taxFreeProductRateDisplay || ''
260
279
  }
261
280
 
262
281
  @action
@@ -479,6 +498,11 @@ class EditorStore {
479
498
  }
480
499
  }
481
500
 
501
+ @action.bound
502
+ updateTableData(dataKey, tableData) {
503
+ this.mockData._table[dataKey] = tableData
504
+ }
505
+
482
506
  @action
483
507
  clearAllTableEmptyData() {
484
508
  const tableData = this.mockData._table
@@ -1016,17 +1040,20 @@ class EditorStore {
1016
1040
  }
1017
1041
 
1018
1042
  @action
1019
- addContentByDiff(name, diff, type) {
1043
+ addContentByDiff(name, diff, type, tableConfig = null) {
1020
1044
  const arr = name.split('.')
1045
+
1021
1046
  if (arr.length === 3 && arr[0] === 'contents') {
1022
- this.addContent(name, ~~arr[2] + diff, type)
1047
+ this.addContent(name, ~~arr[2] + diff, type, tableConfig)
1023
1048
  } else if (arr.length === 5 && arr[3] === 'column') {
1024
- this.addContent(name, ~~arr[2] + diff, type)
1049
+ this.addContent(name, ~~arr[2] + diff, type, tableConfig)
1050
+ } else {
1051
+ console.warn('addContentByDiff: Invalid name format', name)
1025
1052
  }
1026
1053
  }
1027
1054
 
1028
1055
  @action.bound
1029
- addContent(name, index, type) {
1056
+ addContent(name, index, type, tableConfig = null) {
1030
1057
  const defaultTableDataKey = this.defaultTableDataKey
1031
1058
  const defaultTableSubtotal = this.defaultTableSubtotal
1032
1059
 
@@ -1036,27 +1063,89 @@ class EditorStore {
1036
1063
  if ((arr.length === 3 || arr.length === 5) && arr[0] === 'contents') {
1037
1064
  if (index >= 0 && index <= this.config.contents.length) {
1038
1065
  if (type === 'table') {
1039
- this.config.contents.splice(index, 0, {
1040
- type: 'table',
1041
- className: '',
1042
- specialConfig: { style: {} },
1043
- dataKey: defaultTableDataKey, // 默认
1044
- subtotal: defaultTableSubtotal, // 默认的每页合计配置
1045
- customerTag: false, // 特殊标记,用于提供用户干预功能标记
1046
- columns: [
1047
- {
1048
- head: i18next.t('表头'),
1049
- headStyle: {
1050
- textAlign: 'center',
1051
- minWidth: '30px'
1066
+ // 如果传入了自定义表格配置,使用自定义配置,否则使用默认配置
1067
+ const finalTableConfig = tableConfig
1068
+ ? {
1069
+ // 先展开自定义配置,支持传入其他配置项
1070
+ ...tableConfig,
1071
+ // 然后设置必需的属性,确保都有值
1072
+ type: 'table',
1073
+ className: tableConfig.className || '',
1074
+ specialConfig: tableConfig.specialConfig || {
1075
+ style: {}
1052
1076
  },
1053
- text: i18next.t('内容'),
1054
- style: {
1055
- textAlign: 'center'
1056
- }
1077
+ dataKey: tableConfig.dataKey || defaultTableDataKey,
1078
+ subtotal:
1079
+ tableConfig.subtotal !== undefined
1080
+ ? tableConfig.subtotal
1081
+ : defaultTableSubtotal,
1082
+ customerTag:
1083
+ tableConfig.customerTag !== undefined
1084
+ ? tableConfig.customerTag
1085
+ : false,
1086
+ columns: tableConfig.columns || [
1087
+ {
1088
+ head: i18next.t('表头'),
1089
+ headStyle: {
1090
+ textAlign: 'center',
1091
+ minWidth: '30px'
1092
+ },
1093
+ text: i18next.t('内容'),
1094
+ style: {
1095
+ textAlign: 'center'
1096
+ }
1097
+ }
1098
+ ]
1057
1099
  }
1058
- ]
1059
- })
1100
+ : {
1101
+ type: 'table',
1102
+ className: '',
1103
+ specialConfig: { style: {} },
1104
+ dataKey: defaultTableDataKey, // 默认
1105
+ subtotal: defaultTableSubtotal, // 默认的每页合计配置
1106
+ customerTag: false, // 特殊标记,用于提供用户干预功能标记
1107
+ columns: [
1108
+ {
1109
+ head: i18next.t('表头'),
1110
+ headStyle: {
1111
+ textAlign: 'center',
1112
+ minWidth: '30px'
1113
+ },
1114
+ text: i18next.t('内容'),
1115
+ style: {
1116
+ textAlign: 'center'
1117
+ }
1118
+ }
1119
+ ]
1120
+ }
1121
+
1122
+ // 确保数据源存在,如果不存在则初始化为空数组
1123
+ const dataKey = finalTableConfig.dataKey
1124
+ if (!this.mockData._table) {
1125
+ this.mockData._table = {}
1126
+ }
1127
+ if (!this.mockData._table[dataKey]) {
1128
+ this.mockData._table[dataKey] = []
1129
+ }
1130
+
1131
+ // 如果 dataKey 是 taxRateSales,并且有 head 为 custom_filed 的列,修改其 text
1132
+ if (
1133
+ finalTableConfig.dataKey === 'taxRateSales' &&
1134
+ finalTableConfig.columns &&
1135
+ this.mockData._table[dataKey] &&
1136
+ this.mockData._table[dataKey].length > 0
1137
+ ) {
1138
+ const firstRowData = this.mockData._table[dataKey][0]
1139
+
1140
+ finalTableConfig.columns.forEach(column => {
1141
+ if (column.head === 'custom_filed' && firstRowData.custom_filed) {
1142
+ // 将 text 设置为第一行的 custom_filed 值
1143
+ column.text = firstRowData.custom_filed
1144
+ }
1145
+ })
1146
+ }
1147
+
1148
+ this.config.contents.splice(index, 0, finalTableConfig)
1060
1149
  } else {
1061
1150
  this.config.contents.splice(index, 0, {
1062
1151
  blocks: [],
@@ -44,6 +44,12 @@ class ContextMenu extends React.Component {
44
44
  // 多位小数
45
45
  editStore.setMultiDigitDecimal(specialControlConfig?.multiDigitDecimal)
46
46
  }
47
+ if (specialControlConfig?.taxFreeProductRateDisplay !== undefined) {
48
+ // 免税产品税率显示
49
+ editStore.setTaxFreeProductRateDisplay(
50
+ specialControlConfig?.taxFreeProductRateDisplay || ''
51
+ )
52
+ }
47
53
  }
48
54
 
49
55
  /**
@@ -196,11 +202,12 @@ class ContextMenu extends React.Component {
196
202
  }
197
203
 
198
204
  render() {
199
- const { editStore } = this.props
205
+ const { editStore, customTableConfigs } = this.props
200
206
  return (
201
207
  <CommonContextMenu
202
208
  renderTableAction={this.renderOrderActionBtn}
203
209
  insertBlockList={blockTypeList}
210
+ customTableConfigs={customTableConfigs}
204
211
  >
205
212
  <Printer
206
213
  key={editStore.computedPrinterKey}
@@ -220,6 +227,7 @@ class ContextMenu extends React.Component {
220
227
  }
221
228
  ContextMenu.propTypes = {
222
229
  editStore: PropTypes.object,
223
- mockData: PropTypes.object
230
+ mockData: PropTypes.object,
231
+ customTableConfigs: PropTypes.array
224
232
  }
225
233
  export default ContextMenu
@@ -47,7 +47,8 @@ class Editor extends React.Component {
47
47
  addFields,
48
48
  showNewDate,
49
49
  mockData,
50
- mergeClassificationAndLabel
50
+ mergeClassificationAndLabel,
51
+ customTableConfigs
51
52
  } = this.props
52
53
 
53
54
  return (
@@ -106,7 +107,7 @@ class Editor extends React.Component {
106
107
  )}
107
108
 
108
109
  <div className='gm-printer-edit-wrap'>
109
- <ContextMenu />
110
+ <ContextMenu customTableConfigs={customTableConfigs} />
110
111
  </div>
111
112
  </div>
112
113
  )
@@ -120,7 +121,8 @@ Editor.propTypes = {
120
121
  mockData: PropTypes.object.isRequired,
121
122
  addFields: PropTypes.object.isRequired,
122
123
  showNewDate: PropTypes.bool,
123
- mergeClassificationAndLabel: PropTypes.bool
124
+ mergeClassificationAndLabel: PropTypes.bool,
125
+ customTableConfigs: PropTypes.array
124
126
  }
125
127
 
126
128
  Editor.defaultProps = {
@@ -15,9 +15,10 @@ const regExp = text => {
15
15
  * 每列统计
16
16
  * @param key
17
17
  * @param dataList
18
+ * @param summaryFieldsResultToNumber 需要转换为数字的汇总字段
18
19
  * @returns {*|string}
19
20
  */
20
- const sumCol = (key, dataList) => {
21
+ const sumCol = (key, dataList, summaryFieldsResultToNumber = []) => {
21
22
  let result
22
23
  try {
23
24
  result = dataList
@@ -26,6 +27,10 @@ const sumCol = (key, dataList) => {
26
27
  return acc
27
28
  }, Big(0))
28
29
  .toFixed(2)
30
+
31
+ if (summaryFieldsResultToNumber.includes(key)) {
32
+ result = Number(result)
33
+ }
29
34
  } catch (e) {
30
35
  result = ''
31
36
  }
@@ -53,6 +58,14 @@ const PageSummary = props => {
53
58
  const tableData = printerStore.data._table[_dataKey] || []
54
59
  const currentPageTableData = tableData.slice(range.begin, range.end)
55
60
 
61
+ // 需要转换为数字的汇总字段
62
+ let summaryFieldsResultToNumber =
63
+ printerStore.config?.summaryFieldsResultToNumber
64
+ if (summaryFieldsResultToNumber) {
65
+ summaryFieldsResultToNumber = summaryFieldsResultToNumber.map(item =>
66
+ regExp(item)
67
+ )
68
+ }
56
69
  return (
57
70
  <tr>
58
71
  {_.map(columns, (col, index) => {
@@ -66,7 +79,7 @@ const PageSummary = props => {
66
79
  summaryConfig.summaryColumns
67
80
  .map(text => regExp(text))
68
81
  .includes(key) && key
69
- ? sumCol(key, currentPageTableData)
82
+ ? sumCol(key, currentPageTableData, summaryFieldsResultToNumber)
70
83
  : ' '
71
84
  }
72
85
 
@@ -537,7 +537,8 @@ class PrinterStore {
537
537
  if (
538
538
  dataKey !== 'purchase_detail_one_row' &&
539
539
  dataKey !== 'purchase_independent_rol_sku' &&
540
- dataKey !== 'purchase_independent_rol_address'
540
+ dataKey !== 'purchase_independent_rol_address' &&
541
+ dataKey !== 'taxRateSales'
541
542
  ) {
542
543
  return null
543
544
  }
@@ -545,6 +546,7 @@ class PrinterStore {
545
546
 
546
547
  const interpolate = /{{([\s\S]+?)}}/g
547
548
  const match = interpolate.exec(text)
549
+ if (!match) return null
548
550
  // 显示在表格上的 th 名
549
551
  const showFiledText = match[1].split('.')[1]
550
552
 
@@ -555,7 +557,7 @@ class PrinterStore {
555
557
  let newPageCellRowSpan = 1
556
558
  for (let i = index - 1; i < list.length; i--) {
557
559
  const record = list[i]
558
- if (record._origin.rowSpan > 1) {
560
+ if (record && record._origin && record._origin.rowSpan > 1) {
559
561
  newPageCellRowSpan = record._origin.rowSpan - (index - i)
560
562
  break
561
563
  }
@@ -224,6 +224,16 @@ class Table extends React.Component {
224
224
  }
225
225
  return tdStyle
226
226
  }
227
+
228
+ const headText = col => {
229
+ if (dataKey === 'taxRateSales') {
230
+ return col.head === 'custom_field'
231
+ ? tableData?.[0]?.custom_field || ''
232
+ : col.headAlias
233
+ }
234
+ return col.head
235
+ }
236
+
227
237
  return (
228
238
  <table
229
239
  style={{
@@ -254,7 +264,7 @@ class Table extends React.Component {
254
264
  onDrop={this.handleDrop}
255
265
  onDragOver={this.handleDragOver}
256
266
  >
257
- {col.head}
267
+ {headText(col)}
258
268
  </th>
259
269
  ))}
260
270
  </tr>
@@ -264,10 +274,17 @@ class Table extends React.Component {
264
274
  {_.map(_.range(range.begin, range.end), i => {
265
275
  const _special = tableData[i] && tableData[i]._special
266
276
  const _specialText = tableData[i] && tableData[i]._specialText
277
+ const _customTr = tableData[i] && tableData[i]._customTr
278
+
267
279
  if (_specialText)
268
280
  return <CategoryTr key={i} config={config} data={_specialText} />
269
281
  if (_special)
270
282
  return <SpecialTr key={i} config={config} data={_special} />
283
+
284
+ if (_customTr) {
285
+ return <tr dangerouslySetInnerHTML={{ __html: _customTr }} />
286
+ }
287
+
271
288
  // 如果项为空对象展现一个占满一行的td
272
289
  const isItemNone = !_.keys(tableData[i]).length
273
290
  return (
@@ -308,7 +325,9 @@ class Table extends React.Component {
308
325
  ...getTdStyle(j, col.style),
309
326
  ...col.style
310
327
  }}
311
- {...(rowSpan > 1 && { rowSpan: rowSpan })}
328
+ {...(rowSpan > 1 && {
329
+ rowSpan: rowSpan
330
+ })}
312
331
  className={classNames({
313
332
  active:
314
333
  getTableColumnName(name, col.index) ===