n20-common-lib 2.22.75 → 2.22.77
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
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
<template>
|
|
9
9
|
<!-- 金额类型(默认) -->
|
|
10
10
|
<InputNumber v-model="money" type="money" />
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
<!-- 比率类型 -->
|
|
13
13
|
<InputNumber v-model="rate" type="rate" />
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
<!-- 纯数字类型 -->
|
|
16
16
|
<InputNumber v-model="num" type="number" />
|
|
17
17
|
</template>
|
|
@@ -19,23 +19,24 @@
|
|
|
19
19
|
|
|
20
20
|
## 属性说明
|
|
21
21
|
|
|
22
|
-
| 属性名
|
|
23
|
-
| ------------ | ------------- | ----------------- |
|
|
24
|
-
| value | Number/String | undefined | 绑定值
|
|
25
|
-
| stringMode | Boolean | false | 高精度模式,非空绑定值和 input/change 事件值使用字符串
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
|
36
|
-
|
|
|
37
|
-
|
|
|
38
|
-
|
|
|
22
|
+
| 属性名 | 类型 | 默认值 | 说明 |
|
|
23
|
+
| ------------ | ------------- | ----------------- | ----------------------------------------------------------------------------------------------------- |
|
|
24
|
+
| value | Number/String | undefined | 绑定值 |
|
|
25
|
+
| stringMode | Boolean | false | 高精度模式,非空绑定值和 input/change 事件值使用字符串 |
|
|
26
|
+
| isString | Boolean | false | stringMode 兼容别名;小数位超过15位时自动按 true 处理 |
|
|
27
|
+
| type | String | 'money' | 输入框类型,可选值:'money'、'rate'、'number' |
|
|
28
|
+
| maxlength | Number | 16 | 最大输入长度 |
|
|
29
|
+
| min | Number/String | -9999999999999.99 | 最小值限制;高精度模式可传字符串 |
|
|
30
|
+
| max | Number/String | 9999999999999.99 | 最大值限制;高精度模式可传字符串 |
|
|
31
|
+
| step | Number/String | 1 | 步进值;高精度模式可传字符串 |
|
|
32
|
+
| stepStrictly | Boolean | false | 是否严格按步进值递增/递减 |
|
|
33
|
+
| disabled | Boolean | undefined | 是否禁用 |
|
|
34
|
+
| isClearable | Boolean | false | 是否可清空 |
|
|
35
|
+
| placeholder | String | '请输入' | 占位提示文本 |
|
|
36
|
+
| dNum | Number | undefined | 小数位数,优先级低于format;有效小数位超过15位时以字符串保持精度;显式字符串模式下与format、rangeAuto同时使用时表示最大小数位数 |
|
|
37
|
+
| format | String | undefined | 格式化字符串,如'0.00'表示保留2位小数;仅在显式字符串模式与dNum、rangeAuto同时使用时表示最少展示的小数位数 |
|
|
38
|
+
| suffix | String | '%' | 后缀文本,仅在type='rate'时有效 |
|
|
39
|
+
| rangeAuto | Boolean | false | 是否自动处理范围值 |
|
|
39
40
|
|
|
40
41
|
## 类型说明
|
|
41
42
|
|
|
@@ -61,18 +62,22 @@
|
|
|
61
62
|
|
|
62
63
|
## 事件
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
|
69
|
-
|
|
|
65
|
+
当有效小数位设置超过 15 位时,组件会自动使用字符串模式,`input` 和 `change` 回传字符串,避免 JavaScript `Number` 丢失精度。设置 `stringMode` 或 `isString` 为 `true` 后,无论小数位数多少,`input` 和 `change` 都回传字符串;清空时保持原有行为,回传 `undefined`。
|
|
66
|
+
|
|
67
|
+
当显式开启 `stringMode` 或 `isString`,且 `rangeAuto=true`、同时配置 `format` 和更大的 `dNum` 时,`format` 表示最少展示的小数位数,`dNum` 表示最多保留的小数位数。例如 `isString=true`、`format="0.000000"`、`dNum=20` 时,输入 `0.2` 显示为 `0.200000`,输入 7 至 20 位小数按实际位数显示,超过 20 位时按 20 位四舍五入。未显式开启字符串模式时,`format` 继续按历史规则强制模板精度。
|
|
68
|
+
|
|
69
|
+
| 事件名 | 说明 | 回调参数 |
|
|
70
|
+
| ------ | ---------------------- | -------- |
|
|
71
|
+
| input | 值改变时触发 | 当前值 |
|
|
72
|
+
| change | 值改变且失去焦点时触发 | 当前值 |
|
|
73
|
+
| blur | 失去焦点时触发 | - |
|
|
74
|
+
| clear | 清空时触发 | - |
|
|
70
75
|
|
|
71
76
|
## 方法
|
|
72
77
|
|
|
73
|
-
| 方法名
|
|
74
|
-
|
|
|
75
|
-
| focus
|
|
78
|
+
| 方法名 | 说明 |
|
|
79
|
+
| ------ | ---------------- |
|
|
80
|
+
| focus | 使输入框获得焦点 |
|
|
76
81
|
|
|
77
82
|
## 使用示例
|
|
78
83
|
|
|
@@ -113,7 +118,7 @@
|
|
|
113
118
|
|
|
114
119
|
### 20 位小数汇率
|
|
115
120
|
|
|
116
|
-
`stringMode`
|
|
121
|
+
`stringMode` 和 `isString` 默认关闭,原有金额/利率的精度、数值事件保持原样。任一配置开启,或按原有优先级计算出的有效小数位超过 15 位时,组件会进入高精度字符串模式。输入、回显、步进、范围比较和变更事件使用高精度十进制处理。
|
|
117
122
|
|
|
118
123
|
下面 `cl-*` 是默认注册前缀;业务项目按自己的 `Vue.use(n20, { prefix })` 替换标签。
|
|
119
124
|
|
|
@@ -141,9 +146,9 @@ export default {
|
|
|
141
146
|
</script>
|
|
142
147
|
```
|
|
143
148
|
|
|
144
|
-
- `stringMode` 不改变 `dNum`、`format` 和 `maxlength` 默认值。`format` 仍优先于 `dNum`;有旧 `format`
|
|
149
|
+
- `stringMode` / `isString` 不改变 `dNum`、`format` 和 `maxlength` 默认值。`format` 仍优先于 `dNum`;有旧 `format` 配置时需同步调整。小数位超过 15 位时即使两个开关都为 `false`,也会自动使用字符串模式。
|
|
145
150
|
- `maxlength` 统计全部字符,默认 16。20 位小数加上 `0.` 至少需要 22;按整数位、负号和小数点配置总长度。示例的 35 可容纳默认范围的 13 位整数、负号、小数点和 20 位小数。
|
|
146
|
-
-
|
|
151
|
+
- 默认按十进制四舍五入到配置位数并移除尾部 `0`;显式字符串模式同时配置 `rangeAuto + format + 更大的 dNum` 时,按“最少 `format`、最多 `dNum`”处理并保留展示所需的尾零。
|
|
147
152
|
- `min`、`max`、`step` 的字符串形式用于高精度模式;普通模式继续传 Number。`step` 使用正值。`stepStrictly` 的中点方向与原有 `Math.round` 一致。
|
|
148
153
|
- 可粘贴科学计数法,提交展开为普通十进制字符串。空值、NaN、Infinity、非十进制输入不作为有效数字。
|
|
149
154
|
- 按上下箭头改变输入框内容,提交时机与旧模式相同,在 change/blur 时同步绑定值。
|
|
@@ -36,6 +36,7 @@ import { $lc } from '../../utils/i18n/index'
|
|
|
36
36
|
import N from '../../utils/numberPor'
|
|
37
37
|
import { Decimal, parseDecimal } from '../../utils/decimal'
|
|
38
38
|
|
|
39
|
+
const MAX_SAFE_DECIMAL_PLACES = 15
|
|
39
40
|
|
|
40
41
|
export default {
|
|
41
42
|
name: 'InputNumber',
|
|
@@ -50,6 +51,11 @@ export default {
|
|
|
50
51
|
type: Boolean,
|
|
51
52
|
default: false
|
|
52
53
|
},
|
|
54
|
+
// isString 是 stringMode 的兼容别名;超过安全小数位时会自动生效。
|
|
55
|
+
isString: {
|
|
56
|
+
type: Boolean,
|
|
57
|
+
default: false
|
|
58
|
+
},
|
|
53
59
|
/**
|
|
54
60
|
* 输入框类型
|
|
55
61
|
* - money: 金额类型,默认保留2位小数,启用千分位格式化
|
|
@@ -162,7 +168,7 @@ export default {
|
|
|
162
168
|
watch: {
|
|
163
169
|
value: {
|
|
164
170
|
handler(val) {
|
|
165
|
-
if (this.
|
|
171
|
+
if (this.isStringMode()) {
|
|
166
172
|
this.setStringDisplay(val)
|
|
167
173
|
return
|
|
168
174
|
}
|
|
@@ -199,21 +205,52 @@ export default {
|
|
|
199
205
|
immediate: true
|
|
200
206
|
},
|
|
201
207
|
fNum() {
|
|
202
|
-
if (this.
|
|
208
|
+
if (this.isStringMode()) this.setStringDisplay(this.value)
|
|
203
209
|
}
|
|
204
210
|
},
|
|
205
211
|
methods: {
|
|
212
|
+
isAdaptivePrecision() {
|
|
213
|
+
return (this.stringMode || this.isString) &&
|
|
214
|
+
this.rangeAuto &&
|
|
215
|
+
this.format &&
|
|
216
|
+
(this.dNum || this.dNum === 0) &&
|
|
217
|
+
this.dNum > this.fNum
|
|
218
|
+
},
|
|
219
|
+
maxDecimalPlaces() {
|
|
220
|
+
return this.isAdaptivePrecision()
|
|
221
|
+
? Math.max(this.fNum, this.dNum)
|
|
222
|
+
: this.fNum
|
|
223
|
+
},
|
|
224
|
+
isStringMode() {
|
|
225
|
+
return this.stringMode || this.isString || this.fNum > MAX_SAFE_DECIMAL_PLACES
|
|
226
|
+
},
|
|
206
227
|
// rangeAuto 允许已有小数位超过配置值,其余情况按配置位数四舍五入。
|
|
207
228
|
formatStringValue(value, originalValue = value) {
|
|
208
229
|
const decimal = parseDecimal(value)
|
|
209
230
|
if (!decimal) return ''
|
|
210
231
|
// Decimal 会省略尾零,rangeAuto 额外保留普通十进制输入中的原始小数长度。
|
|
211
|
-
const fraction = String(originalValue).trim().match(/\.(\d+)$/)
|
|
232
|
+
const fraction = String(originalValue).replace(/,/g, '').trim().match(/\.(\d+)$/)
|
|
233
|
+
const originalPlaces = Math.max(decimal.decimalPlaces(), fraction ? fraction[1].length : 0)
|
|
212
234
|
const places = this.rangeAuto
|
|
213
|
-
? Math.max(
|
|
235
|
+
? Math.max(
|
|
236
|
+
this.fNum,
|
|
237
|
+
this.isAdaptivePrecision() ? Math.min(originalPlaces, this.maxDecimalPlaces()) : originalPlaces
|
|
238
|
+
)
|
|
214
239
|
: this.fNum
|
|
215
|
-
//
|
|
216
|
-
|
|
240
|
+
// 先按目标位数四舍五入,避免转成 Number 后丢失精度。
|
|
241
|
+
const fixedValue = decimal.toDecimalPlaces(places).toFixed(places)
|
|
242
|
+
// format + dNum + rangeAuto 场景中,format 是最少位数,dNum 是最多位数。
|
|
243
|
+
// 保留补齐后的尾零,使回显和用户输入的小数位一致。
|
|
244
|
+
if (this.isAdaptivePrecision()) {
|
|
245
|
+
return decimal.toDecimalPlaces(places).isZero()
|
|
246
|
+
? new Decimal(0).toFixed(places)
|
|
247
|
+
: fixedValue
|
|
248
|
+
}
|
|
249
|
+
// 其他高精度场景保留当前分支的规范化逻辑:移除尾部 0。
|
|
250
|
+
const trimmedValue = fixedValue
|
|
251
|
+
.replace(/(\.\d*?[1-9])0+$/, '$1')
|
|
252
|
+
.replace(/\.0+$/, '')
|
|
253
|
+
return trimmedValue === '-0' ? '0' : trimmedValue
|
|
217
254
|
},
|
|
218
255
|
setStringDisplay(value) {
|
|
219
256
|
const text = this.formatStringValue(value)
|
|
@@ -266,7 +303,7 @@ export default {
|
|
|
266
303
|
},
|
|
267
304
|
stepFn(ev) {
|
|
268
305
|
if ((ev.code === 'ArrowUp' || ev.code === 'ArrowDown') && !this.disabled) {
|
|
269
|
-
if (this.
|
|
306
|
+
if (this.isStringMode()) {
|
|
270
307
|
const value = parseDecimal(this.valueStr)
|
|
271
308
|
const step = parseDecimal(this.step)
|
|
272
309
|
if (value && step && step.gt(0)) {
|
|
@@ -296,7 +333,7 @@ export default {
|
|
|
296
333
|
}
|
|
297
334
|
},
|
|
298
335
|
inputFn(valStr) {
|
|
299
|
-
if (this.
|
|
336
|
+
if (this.isStringMode()) {
|
|
300
337
|
// 编辑中的符号和小数点暂时保留,完整值在失焦时统一规范化。
|
|
301
338
|
if (['', '-', '+', '.', '-.', '+.'].includes(valStr) || parseDecimal(valStr)) {
|
|
302
339
|
this.preValue = valStr
|
|
@@ -318,7 +355,7 @@ export default {
|
|
|
318
355
|
this.changeIng = false
|
|
319
356
|
})
|
|
320
357
|
|
|
321
|
-
if (this.
|
|
358
|
+
if (this.isStringMode()) {
|
|
322
359
|
this.changeStringValue(valStr)
|
|
323
360
|
return
|
|
324
361
|
}
|
|
@@ -1,13 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div>
|
|
3
3
|
<div v-if="size !== 'mini'" class="flex-box p-t-ss p-b-ss">
|
|
4
|
-
<statisItem
|
|
5
|
-
:type="(label + '合计') | $lc"
|
|
6
|
-
:list="pageList"
|
|
7
|
-
:show-w="showW"
|
|
8
|
-
:show-u="showU"
|
|
9
|
-
:count-label="countLabel"
|
|
10
|
-
/>
|
|
4
|
+
<statisItem :type="pageTotalLabel" :list="pageList" :show-w="showW" :show-u="showU" :count-label="countLabel" />
|
|
11
5
|
<statisItem
|
|
12
6
|
:type="'全部合计' | $lc"
|
|
13
7
|
:list="totalList"
|
|
@@ -18,7 +12,7 @@
|
|
|
18
12
|
</div>
|
|
19
13
|
<div v-else class="n20-statis p-t-ss p-b-ss">
|
|
20
14
|
<span class="m-r">
|
|
21
|
-
{{
|
|
15
|
+
{{ label + ':' }}<span class="n20-primary"> {{ pageSum }}</span> {{ '条' | $lc }}
|
|
22
16
|
</span>
|
|
23
17
|
<span class="m-r">
|
|
24
18
|
{{ '全部:' | $lc }}<span class="n20-primary"> {{ totalSun }}</span> {{ '条' | $lc }}
|
|
@@ -28,9 +22,10 @@
|
|
|
28
22
|
</template>
|
|
29
23
|
|
|
30
24
|
<script>
|
|
31
|
-
import { $lc } from '../../utils/i18n/index'
|
|
32
25
|
import statisItem from './statisItem.vue'
|
|
33
26
|
|
|
27
|
+
import { $lc } from '../../utils/i18n/index'
|
|
28
|
+
|
|
34
29
|
export default {
|
|
35
30
|
name: 'Statis',
|
|
36
31
|
components: {
|
|
@@ -71,15 +66,19 @@ export default {
|
|
|
71
66
|
},
|
|
72
67
|
label: {
|
|
73
68
|
type: String,
|
|
74
|
-
default: $lc(
|
|
69
|
+
default: $lc('已选')
|
|
75
70
|
}
|
|
76
71
|
},
|
|
77
72
|
computed: {
|
|
73
|
+
pageTotalLabel() {
|
|
74
|
+
const separator = ['zh', 'ja', 'th'].includes(this._lang || 'zh') ? '' : ' '
|
|
75
|
+
return this.label + separator + $lc('合计')
|
|
76
|
+
},
|
|
78
77
|
unitAs() {
|
|
79
78
|
if (!this.showU) {
|
|
80
79
|
return undefined
|
|
81
80
|
} else if (this.showU === true) {
|
|
82
|
-
return $lc(
|
|
81
|
+
return $lc('元')
|
|
83
82
|
} else {
|
|
84
83
|
return this.showU
|
|
85
84
|
}
|
|
@@ -87,29 +86,29 @@ export default {
|
|
|
87
86
|
pageList() {
|
|
88
87
|
if (this.pageAmount !== undefined) {
|
|
89
88
|
return [
|
|
90
|
-
{ label: $lc(
|
|
89
|
+
{ label: $lc('笔数'), value: this.pageSum },
|
|
91
90
|
{
|
|
92
|
-
label: $lc(
|
|
91
|
+
label: $lc('金额'),
|
|
93
92
|
value: this.pageAmount,
|
|
94
93
|
unit: this.unitAs
|
|
95
94
|
}
|
|
96
95
|
]
|
|
97
96
|
} else {
|
|
98
|
-
return [{ label: $lc(
|
|
97
|
+
return [{ label: $lc('笔数'), value: this.pageSum }]
|
|
99
98
|
}
|
|
100
99
|
},
|
|
101
100
|
totalList() {
|
|
102
101
|
if (this.totalAmount !== undefined) {
|
|
103
102
|
return [
|
|
104
|
-
{ label: $lc(
|
|
103
|
+
{ label: $lc('笔数'), value: this.totalSun },
|
|
105
104
|
{
|
|
106
|
-
label: $lc(
|
|
105
|
+
label: $lc('金额'),
|
|
107
106
|
value: this.totalAmount,
|
|
108
107
|
unit: this.unitAs
|
|
109
108
|
}
|
|
110
109
|
]
|
|
111
110
|
} else {
|
|
112
|
-
return [{ label: $lc(
|
|
111
|
+
return [{ label: $lc('笔数'), value: this.totalSun }]
|
|
113
112
|
}
|
|
114
113
|
}
|
|
115
114
|
}
|
|
@@ -1,19 +1,144 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<vxe-column :field="$attrs.prop" :title="$attrs.label" v-bind="
|
|
2
|
+
<vxe-column :field="$attrs.prop" :title="$attrs.label" v-bind="resolvedColumnAttrs">
|
|
3
3
|
<OperateBtns slot-scope="{ row, $index }" :btn-list="btnList" :row="row" @command="(c) => $emit(c, row, $index)" />
|
|
4
4
|
</vxe-column>
|
|
5
5
|
</template>
|
|
6
6
|
<script>
|
|
7
7
|
import OperateBtns from './OperateBtns.vue'
|
|
8
8
|
|
|
9
|
+
const DEFAULT_OPERATE_COLUMN_WIDTH = 180
|
|
10
|
+
|
|
9
11
|
export default {
|
|
10
12
|
name: 'TableProOperateColumn',
|
|
11
13
|
components: { OperateBtns },
|
|
14
|
+
inject: {
|
|
15
|
+
n20TableProContext: {
|
|
16
|
+
default: null
|
|
17
|
+
}
|
|
18
|
+
},
|
|
12
19
|
props: {
|
|
13
20
|
btnList: {
|
|
14
21
|
type: Array,
|
|
15
22
|
default: () => []
|
|
16
23
|
}
|
|
24
|
+
},
|
|
25
|
+
computed: {
|
|
26
|
+
resolvedColumnAttrs() {
|
|
27
|
+
const attrs = { ...this.$attrs }
|
|
28
|
+
const hasWidth =
|
|
29
|
+
Object.prototype.hasOwnProperty.call(attrs, 'width') &&
|
|
30
|
+
attrs.width !== null &&
|
|
31
|
+
attrs.width !== undefined &&
|
|
32
|
+
attrs.width !== ''
|
|
33
|
+
if (hasWidth) {
|
|
34
|
+
return attrs
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const minWidthKey = ['minWidth', 'min-width'].find((key) => {
|
|
38
|
+
const value = attrs[key]
|
|
39
|
+
return Object.prototype.hasOwnProperty.call(attrs, key) && value !== null && value !== undefined && value !== ''
|
|
40
|
+
})
|
|
41
|
+
const calculatedWidth = this.calcOperateColumnWidth()
|
|
42
|
+
if (minWidthKey) {
|
|
43
|
+
const minWidth = this.parsePixelWidth(attrs[minWidthKey])
|
|
44
|
+
if (minWidth !== null) {
|
|
45
|
+
attrs[minWidthKey] = Math.max(calculatedWidth, minWidth)
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
attrs.width = calculatedWidth
|
|
49
|
+
}
|
|
50
|
+
return attrs
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
methods: {
|
|
54
|
+
measureOperateText(text) {
|
|
55
|
+
const normalizedText = text === undefined || text === null ? '' : String(text)
|
|
56
|
+
if (!normalizedText) return 0
|
|
57
|
+
|
|
58
|
+
const fallbackWidth = Array.from(normalizedText).reduce(
|
|
59
|
+
(width, char) => width + (/[⺀-鿿]/.test(char) ? 14 : 8),
|
|
60
|
+
0
|
|
61
|
+
)
|
|
62
|
+
if (typeof document === 'undefined') return fallbackWidth
|
|
63
|
+
|
|
64
|
+
const canvas = document.createElement('canvas')
|
|
65
|
+
const context = canvas.getContext('2d')
|
|
66
|
+
if (!context) return fallbackWidth
|
|
67
|
+
|
|
68
|
+
context.font = '14px PingFang SC, Microsoft YaHei, sans-serif'
|
|
69
|
+
return Math.max(context.measureText(normalizedText).width, fallbackWidth)
|
|
70
|
+
},
|
|
71
|
+
parsePixelWidth(value) {
|
|
72
|
+
if (typeof value === 'number') {
|
|
73
|
+
return Number.isFinite(value) && value >= 0 ? value : null
|
|
74
|
+
}
|
|
75
|
+
if (typeof value !== 'string') return null
|
|
76
|
+
|
|
77
|
+
const normalizedValue = value.trim()
|
|
78
|
+
if (!/^\d+(\.\d+)?(px)?$/.test(normalizedValue)) return null
|
|
79
|
+
const parsedValue = Number.parseFloat(normalizedValue)
|
|
80
|
+
return Number.isFinite(parsedValue) ? parsedValue : null
|
|
81
|
+
},
|
|
82
|
+
calcOperateColumnWidth() {
|
|
83
|
+
const CELL_HORIZONTAL_PADDING = 14
|
|
84
|
+
const BUTTON_GAP = 6
|
|
85
|
+
const CHILDREN_ARROW_WIDTH = 20
|
|
86
|
+
const MORE_BUTTON_WIDTH = 16
|
|
87
|
+
const buttons = (this.btnList || []).filter((button) => button && button.isHas !== false)
|
|
88
|
+
const getButtonWidth = (button) => {
|
|
89
|
+
let width = this.measureOperateText(button.label)
|
|
90
|
+
if (button.children && button.children.length > 0) {
|
|
91
|
+
width += CHILDREN_ARROW_WIDTH
|
|
92
|
+
}
|
|
93
|
+
return width
|
|
94
|
+
}
|
|
95
|
+
const buttonWidths = buttons.map(getButtonWidth)
|
|
96
|
+
|
|
97
|
+
if (buttonWidths.length === 0) {
|
|
98
|
+
return DEFAULT_OPERATE_COLUMN_WIDTH
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const calcLayoutWidth = (inlineWidths, hasMoreButton = false) => {
|
|
102
|
+
const itemCount = inlineWidths.length + (hasMoreButton ? 1 : 0)
|
|
103
|
+
const contentWidth = inlineWidths.reduce((total, width) => total + width, 0)
|
|
104
|
+
const moreButtonWidth = hasMoreButton ? MORE_BUTTON_WIDTH : 0
|
|
105
|
+
const gapWidth = Math.max(itemCount - 1, 0) * BUTTON_GAP
|
|
106
|
+
return contentWidth + moreButtonWidth + gapWidth + CELL_HORIZONTAL_PADDING
|
|
107
|
+
}
|
|
108
|
+
const rows = this.n20TableProContext?.getData?.() || []
|
|
109
|
+
if (rows.length > 0) {
|
|
110
|
+
const maxRowWidth = rows.reduce((maxWidth, row) => {
|
|
111
|
+
const visibleButtonWidths = buttons
|
|
112
|
+
.filter((button) => this.hasButton(button.isHas, row))
|
|
113
|
+
.map(getButtonWidth)
|
|
114
|
+
const rowWidth = visibleButtonWidths.length > 3
|
|
115
|
+
? calcLayoutWidth(visibleButtonWidths.slice(0, 2), true)
|
|
116
|
+
: calcLayoutWidth(visibleButtonWidths)
|
|
117
|
+
return Math.max(maxWidth, rowWidth)
|
|
118
|
+
}, 0)
|
|
119
|
+
return Math.max(DEFAULT_OPERATE_COLUMN_WIDTH, Math.ceil(maxRowWidth))
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const sortedButtonWidths = [...buttonWidths].sort((a, b) => b - a)
|
|
123
|
+
const directButtonsWidth = calcLayoutWidth(sortedButtonWidths.slice(0, 3))
|
|
124
|
+
const collapsedButtonsWidth =
|
|
125
|
+
sortedButtonWidths.length > 3 ? calcLayoutWidth(sortedButtonWidths.slice(0, 2), true) : 0
|
|
126
|
+
|
|
127
|
+
return Math.max(
|
|
128
|
+
DEFAULT_OPERATE_COLUMN_WIDTH,
|
|
129
|
+
Math.ceil(directButtonsWidth),
|
|
130
|
+
Math.ceil(collapsedButtonsWidth)
|
|
131
|
+
)
|
|
132
|
+
},
|
|
133
|
+
hasButton(isHas, row) {
|
|
134
|
+
if (isHas === undefined || isHas === null) return true
|
|
135
|
+
if (typeof isHas === 'boolean') return isHas
|
|
136
|
+
if (typeof isHas === 'function') return isHas(row)
|
|
137
|
+
if (typeof isHas === 'string' || Array.isArray(isHas)) {
|
|
138
|
+
return typeof this.$has === 'function' ? this.$has(isHas) : true
|
|
139
|
+
}
|
|
140
|
+
return false
|
|
141
|
+
}
|
|
17
142
|
}
|
|
18
143
|
}
|
|
19
144
|
</script>
|