sh-view 2.8.4 → 2.8.6
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/.eslintrc.js +3 -2
- package/package.json +8 -8
- package/packages/components/sh-form/js/useForm.js +9 -28
- package/packages/components/sh-noticebar/index.vue +33 -35
- package/packages/components/sh-table/css/index.scss +0 -2
- package/packages/components/sh-table/grid.vue +1 -0
- package/packages/components/sh-table/js/props.js +8 -6
- package/packages/components/sh-table/js/tableMethods.js +46 -50
- package/packages/components/sh-table/js/useTable.js +56 -67
- package/packages/components/sh-table/table.vue +1 -19
- package/packages/components/sh-tabs/index.vue +11 -7
- package/packages/vxeTable/css/variable.scss +1 -1
- package/packages/vxeTable/index.js +36 -9
- package/packages/vxeTable/render/footer/vxe-footer-input.vue +1 -1
- package/packages/vxeTable/render/footer/vxe-footer-money.vue +1 -1
- package/packages/vxeTable/render/globalRenders.jsx +12 -5
- package/packages/vxeTable/render/header/vxe-header-money.vue +1 -1
- package/packages/vxeTable/render/mixin/cell-hooks.js +21 -71
- package/types/alert.ts +30 -30
- package/types/component.d.ts +1 -1
package/.eslintrc.js
CHANGED
|
@@ -3,10 +3,11 @@ module.exports = {
|
|
|
3
3
|
env: {
|
|
4
4
|
node: true
|
|
5
5
|
},
|
|
6
|
-
extends: ['plugin:vue/vue3-essential', '
|
|
6
|
+
extends: ['plugin:vue/vue3-essential', 'plugin:prettier/recommended'], // 开启typescript 需要加入 '@vue/typescript/recommended'
|
|
7
7
|
plugins: ['vue', 'prettier'],
|
|
8
8
|
parserOptions: {
|
|
9
|
-
|
|
9
|
+
parser: '@babel/eslint-parser'
|
|
10
|
+
// ecmaVersion: 2020
|
|
10
11
|
},
|
|
11
12
|
rules: {
|
|
12
13
|
'prettier/prettier': 'error',
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sh-view",
|
|
3
|
-
"version": "2.8.
|
|
3
|
+
"version": "2.8.6",
|
|
4
4
|
"description": "基于vxe-table二次封装,更包含Alert,Badge,Card,CodeEditor,Col,Corner,CountTo,Drawer,Empty,Form,Header,Icon,List,Loading,Modal,Noticebar,Poptip,Progress,PullRefresh,Query,Result,Row,Split,Grid,Table,Tabs,Tag,Toolbar,Tree,Upload,WaterFall,WaterMark等丰富组件库",
|
|
5
5
|
"main": "packages/index.js",
|
|
6
6
|
"typings": "types/index.d.ts",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
"author": "神秘的sh",
|
|
16
16
|
"license": "ISC",
|
|
17
17
|
"dependencies": {
|
|
18
|
+
"@babel/eslint-parser": "^7.23.10",
|
|
18
19
|
"@codemirror/lang-javascript": "^6.1.9",
|
|
19
20
|
"@codemirror/lang-json": "^6.0.1",
|
|
20
21
|
"@codemirror/lang-sql": "^6.5.2",
|
|
@@ -26,21 +27,20 @@
|
|
|
26
27
|
"countup.js": "^2.8.0",
|
|
27
28
|
"cron-parser": "^4.8.1",
|
|
28
29
|
"docx-preview": "^0.1.18",
|
|
29
|
-
"exceljs": "^4.
|
|
30
|
+
"exceljs": "^4.4.0",
|
|
30
31
|
"jspdf": "^2.5.1",
|
|
31
32
|
"jszip": "^3.10.1",
|
|
32
33
|
"lunar-typescript": "^1.6.10",
|
|
33
34
|
"popper.js": "^1.16.1",
|
|
34
|
-
"sh-tools": "^2.2.
|
|
35
|
+
"sh-tools": "^2.2.7",
|
|
35
36
|
"tinymce": "^5.10.5",
|
|
36
37
|
"vue": "^3.3.4",
|
|
37
38
|
"vue-masonry": "^0.16.0",
|
|
38
39
|
"vue-router": "^4.2.4",
|
|
39
|
-
"vxe-table": "^4.5.
|
|
40
|
-
"vxe-table-plugin-export-pdf": "^
|
|
41
|
-
"vxe-table-plugin-export-xlsx": "^
|
|
42
|
-
"xe-clipboard": "^1.10.2"
|
|
43
|
-
"xe-utils": "^3.5.13"
|
|
40
|
+
"vxe-table": "^4.5.20",
|
|
41
|
+
"vxe-table-plugin-export-pdf": "^4.0.1",
|
|
42
|
+
"vxe-table-plugin-export-xlsx": "^4.0.1",
|
|
43
|
+
"xe-clipboard": "^1.10.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { computed, onBeforeMount, ref, watch } from 'vue'
|
|
2
|
-
import {
|
|
2
|
+
import { getFieldRules } from '../../sh-table/js/tableMethods'
|
|
3
3
|
|
|
4
4
|
// 表单默认配置
|
|
5
5
|
const formConfigDefault = {
|
|
@@ -86,24 +86,12 @@ export default function (props, context, proxy, isForm) {
|
|
|
86
86
|
const validate = callback => {
|
|
87
87
|
return formRef.value.validate(callback)
|
|
88
88
|
}
|
|
89
|
-
// 初始化表单字段
|
|
90
|
-
const initFormData = () => {
|
|
91
|
-
let initItems = isForm ? props.items : props.items.filter(item => item.search && item.search !== '0')
|
|
92
|
-
$vUtils.eachTree(initItems, item => {
|
|
93
|
-
let renderProps = item.renderProps || item.itemRender?.props || {}
|
|
94
|
-
if (!$vUtils.isNone(renderProps?.defaultValue) && $vUtils.isNone($vUtils.get(props.data, item.field))) {
|
|
95
|
-
$vUtils.set(props.data, item.field, renderProps.defaultValue)
|
|
96
|
-
}
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
89
|
// 初始化表单项
|
|
100
90
|
const initFormItems = () => {
|
|
101
|
-
let rules = getFieldsRules(props.items)
|
|
102
|
-
initEditRules(rules)
|
|
103
|
-
|
|
104
91
|
let formItemsArr = props.items
|
|
105
92
|
if (props.transformitem) {
|
|
106
|
-
let { groupItemsArr, flatItemsArr } = generateFormItem(formItemsArr)
|
|
93
|
+
let { groupItemsArr, flatItemsArr, rules } = generateFormItem(formItemsArr)
|
|
94
|
+
initEditRules(rules)
|
|
107
95
|
// 表单支持分组 搜索组件不需要分组
|
|
108
96
|
formItemsArr = isForm ? groupItemsArr : flatItemsArr
|
|
109
97
|
}
|
|
@@ -124,7 +112,6 @@ export default function (props, context, proxy, isForm) {
|
|
|
124
112
|
// tag: vxe-form在 item监听时数据length为0时没有刷新视图补充
|
|
125
113
|
refreshRender()
|
|
126
114
|
}
|
|
127
|
-
initFormData()
|
|
128
115
|
}
|
|
129
116
|
// 初始化验证规则
|
|
130
117
|
const initEditRules = rules => {
|
|
@@ -151,6 +138,7 @@ export default function (props, context, proxy, isForm) {
|
|
|
151
138
|
let notRenderName = ['seq', 'checkbox', 'radio', '$vImg', '$vHref', '$vGlobalOption']
|
|
152
139
|
let renderItems = $vUtils.searchTree(items, item => !((item.renderName && notRenderName.includes(item.renderName)) || notRenderName.includes(item.type)))
|
|
153
140
|
let flatItemsArr = []
|
|
141
|
+
let rules = {}
|
|
154
142
|
let groupItemsArr = $vUtils.mapTree(renderItems, ori => {
|
|
155
143
|
let tar = Object.assign({}, ori)
|
|
156
144
|
if (ori.children && ori.children.length > 0) {
|
|
@@ -161,6 +149,8 @@ export default function (props, context, proxy, isForm) {
|
|
|
161
149
|
name: ori.renderName || '$vInput',
|
|
162
150
|
props: Object.assign({}, ori.renderProps || {})
|
|
163
151
|
}
|
|
152
|
+
// 首先提取校验配置
|
|
153
|
+
getFieldRules(ori, rules)
|
|
164
154
|
if (readonly || disabled) {
|
|
165
155
|
renderConfig.props.disabled = true
|
|
166
156
|
}
|
|
@@ -168,7 +158,7 @@ export default function (props, context, proxy, isForm) {
|
|
|
168
158
|
flatItemsArr.push(tar)
|
|
169
159
|
return tar
|
|
170
160
|
})
|
|
171
|
-
return { groupItemsArr, flatItemsArr }
|
|
161
|
+
return { groupItemsArr, flatItemsArr, rules }
|
|
172
162
|
}
|
|
173
163
|
|
|
174
164
|
watch(
|
|
@@ -177,15 +167,6 @@ export default function (props, context, proxy, isForm) {
|
|
|
177
167
|
initFormItems()
|
|
178
168
|
}
|
|
179
169
|
)
|
|
180
|
-
watch(
|
|
181
|
-
() => props.data,
|
|
182
|
-
() => {
|
|
183
|
-
initFormData()
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
immediate: true
|
|
187
|
-
}
|
|
188
|
-
)
|
|
189
170
|
watch(
|
|
190
171
|
() => props.items,
|
|
191
172
|
nv => {
|
|
@@ -198,8 +179,8 @@ export default function (props, context, proxy, isForm) {
|
|
|
198
179
|
)
|
|
199
180
|
watch(
|
|
200
181
|
() => props.rules,
|
|
201
|
-
|
|
202
|
-
initEditRules(
|
|
182
|
+
value => {
|
|
183
|
+
initEditRules(value)
|
|
203
184
|
},
|
|
204
185
|
{
|
|
205
186
|
deep: true,
|
|
@@ -84,7 +84,7 @@ export default defineComponent({
|
|
|
84
84
|
const styles = computed(() => {
|
|
85
85
|
return {
|
|
86
86
|
color: props.color,
|
|
87
|
-
backgroundColor: $vUtils.fade(props.color,
|
|
87
|
+
backgroundColor: $vUtils.fade(props.color, 20)
|
|
88
88
|
}
|
|
89
89
|
})
|
|
90
90
|
const animateStyles = computed(() => {
|
|
@@ -164,44 +164,42 @@ export default defineComponent({
|
|
|
164
164
|
z-index: 15;
|
|
165
165
|
padding: 10px 0 10px 15px;
|
|
166
166
|
box-sizing: border-box;
|
|
167
|
-
|
|
167
|
+
&-round {
|
|
168
168
|
border-radius: 6px;
|
|
169
169
|
}
|
|
170
|
-
|
|
171
|
-
|
|
170
|
+
&-left,
|
|
171
|
+
&-right {
|
|
172
|
+
display: flex;
|
|
173
|
+
align-items: center;
|
|
172
174
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
line-height: 1.5;
|
|
199
|
-
white-space: normal;
|
|
175
|
+
&-left {
|
|
176
|
+
padding-right: 10px;
|
|
177
|
+
}
|
|
178
|
+
&-right {
|
|
179
|
+
padding: 0 10px;
|
|
180
|
+
}
|
|
181
|
+
&-empty {
|
|
182
|
+
padding-right: 0;
|
|
183
|
+
}
|
|
184
|
+
&-content {
|
|
185
|
+
flex: 1;
|
|
186
|
+
margin: auto;
|
|
187
|
+
width: auto;
|
|
188
|
+
white-space: nowrap;
|
|
189
|
+
overflow: hidden;
|
|
190
|
+
&-multi-content {
|
|
191
|
+
padding: 0;
|
|
192
|
+
line-height: 1.5;
|
|
193
|
+
white-space: normal;
|
|
194
|
+
}
|
|
195
|
+
&-animate {
|
|
196
|
+
padding-left: 100%;
|
|
197
|
+
display: inline-block;
|
|
198
|
+
animation: sh-notice-bar-animation linear 30s infinite both;
|
|
199
|
+
}
|
|
200
200
|
}
|
|
201
|
-
.sh-notice-
|
|
202
|
-
|
|
203
|
-
display: inline-block;
|
|
204
|
-
animation: sh-notice-bar-animation linear 30s infinite both;
|
|
201
|
+
.sh-notice-icon {
|
|
202
|
+
cursor: pointer;
|
|
205
203
|
}
|
|
206
204
|
}
|
|
207
205
|
@keyframes sh-notice-bar-animation {
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
<div v-if="slots.toolbarRight" class="sh-table-toolbar-item">
|
|
58
58
|
<slot name="toolbarRight"></slot>
|
|
59
59
|
</div>
|
|
60
|
+
<div v-if="tableMoneyConfig.enabled" class="sh-table-toolbar-item">单位:<sh-select v-model="tableMoneyUnit" v-bind="tableMoneyConfig" /></div>
|
|
60
61
|
<div v-if="tableGlobalConfig.zoom" class="sh-table-toolbar-item">
|
|
61
62
|
<vxe-button v-if="!tableIsFullscreen" v-ripple :size="size" icon="vxe-icon-zoom-out" @click="handleTableZoomBtn(true)">全屏</vxe-button>
|
|
62
63
|
<vxe-button v-else v-ripple :size="size" icon="vxe-icon-zoom-in" @click="handleTableZoomBtn(false)">退出全屏</vxe-button>
|
|
@@ -112,8 +112,7 @@ export default {
|
|
|
112
112
|
type: [Function]
|
|
113
113
|
},
|
|
114
114
|
keepSource: {
|
|
115
|
-
type: Boolean
|
|
116
|
-
default: true
|
|
115
|
+
type: Boolean
|
|
117
116
|
},
|
|
118
117
|
emptyIcon: {
|
|
119
118
|
type: String
|
|
@@ -193,10 +192,7 @@ export default {
|
|
|
193
192
|
}
|
|
194
193
|
},
|
|
195
194
|
mouseConfig: {
|
|
196
|
-
type: Object
|
|
197
|
-
default() {
|
|
198
|
-
return {}
|
|
199
|
-
}
|
|
195
|
+
type: Object
|
|
200
196
|
},
|
|
201
197
|
customConfig: {
|
|
202
198
|
type: Object,
|
|
@@ -269,6 +265,12 @@ export default {
|
|
|
269
265
|
return {}
|
|
270
266
|
}
|
|
271
267
|
},
|
|
268
|
+
moneyConfig: {
|
|
269
|
+
type: Object,
|
|
270
|
+
default() {
|
|
271
|
+
return {}
|
|
272
|
+
}
|
|
273
|
+
},
|
|
272
274
|
footerCalculate: {
|
|
273
275
|
type: Object,
|
|
274
276
|
default() {
|
|
@@ -32,11 +32,9 @@ export const columnDefaultFilterMethod = ({ column, $columnIndex }) => {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// 默认求底部计算方法(已改用footer渲染器,其他需要自行计算)
|
|
35
|
-
export const tableFooterCompute = (columns,
|
|
36
|
-
|
|
37
|
-
let computeName =
|
|
38
|
-
let computeData = typeObj.data || {}
|
|
39
|
-
let textIndex = 0
|
|
35
|
+
export const tableFooterCompute = (columns, fullData, computeType, typeObj = {}) => {
|
|
36
|
+
const { emptyText = '', name, data = {} } = typeObj
|
|
37
|
+
let computeName = name || ''
|
|
40
38
|
if (!computeName) {
|
|
41
39
|
switch (computeType) {
|
|
42
40
|
case 'subTotal':
|
|
@@ -52,16 +50,20 @@ export const tableFooterCompute = (columns, data, computeType, typeObj = {}) =>
|
|
|
52
50
|
}
|
|
53
51
|
}
|
|
54
52
|
return columns.map((column, columnIndex) => {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
53
|
+
if (['seq', 'total'].includes(column.type)) {
|
|
54
|
+
return computeName
|
|
55
|
+
}
|
|
56
|
+
let renderName = column.editRender?.name || column.cellRender?.name
|
|
57
|
+
let renderProps = column.editRender?.props || column.cellRender?.props
|
|
58
|
+
let footerValue = data[column.property] || emptyText
|
|
59
|
+
if (renderName === '$vMoney' || renderProps.calculate) {
|
|
60
|
+
if (computeType === 'subTotal') {
|
|
61
|
+
footerValue = $vUtils.sum(fullData, column.property)
|
|
62
|
+
} else if (computeType === 'mean') {
|
|
63
|
+
footerValue = $vUtils.mean(fullData, column.property)
|
|
64
|
+
}
|
|
63
65
|
}
|
|
64
|
-
return
|
|
66
|
+
return footerValue
|
|
65
67
|
})
|
|
66
68
|
}
|
|
67
69
|
// 转化表头过滤配置
|
|
@@ -84,28 +86,25 @@ export const turnColumnItemFilters = (column, props) => {
|
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
// 转换表头校验规则
|
|
87
|
-
export const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
if (
|
|
92
|
-
|
|
93
|
-
if (column['requireProps'] && Array.isArray(column['requireProps']) && column['requireProps'].length > 0) {
|
|
94
|
-
rules[column['field']] = column['requireProps']
|
|
95
|
-
} else {
|
|
96
|
-
let dataType = 'string'
|
|
97
|
-
let arrayType = ['$vCheckgroup', '$vUpload', '$vTable']
|
|
98
|
-
if (arrayType.includes(column['renderName']) || ((column['renderName'] === '$vSelect' || column['renderName'] === '$vTree') && isTrue(column.renderProps?.multiple))) {
|
|
99
|
-
dataType = 'array'
|
|
100
|
-
}
|
|
101
|
-
rules[column['field']] = [{ required: true, message: getDefaultMessage(column['renderName'], column['title']), type: dataType }]
|
|
102
|
-
}
|
|
89
|
+
export const getFieldRules = (ori, rules) => {
|
|
90
|
+
if (isTrue(ori['renderRequire'])) {
|
|
91
|
+
let dataType = 'string'
|
|
92
|
+
let arrayType = ['$vCheckgroup', '$vUpload', '$vTable']
|
|
93
|
+
if (arrayType.includes(ori['renderName']) || (['$vSelect', '$vTree'].includes(ori['renderName']) && isTrue(ori.renderProps?.multiple))) {
|
|
94
|
+
dataType = 'array'
|
|
103
95
|
}
|
|
104
|
-
|
|
105
|
-
|
|
96
|
+
let defaultRuleOption = { message: getDefaultMessage(ori['renderName'], ori['title']), type: dataType, trigger: 'blur' }
|
|
97
|
+
let fieldRules = [{ required: true, ...defaultRuleOption }]
|
|
98
|
+
// 若配置了校验参数则走校验参数,没配置则给默认校验条件
|
|
99
|
+
if (ori['requireProps'] && Array.isArray(ori['requireProps']) && ori['requireProps'].length > 0) {
|
|
100
|
+
fieldRules = ori['requireProps'].map(rule => ({ ...defaultRuleOption, ...rule }))
|
|
101
|
+
}
|
|
102
|
+
rules[ori['field']] = fieldRules
|
|
103
|
+
}
|
|
106
104
|
}
|
|
107
105
|
// 转换生成新表头数据
|
|
108
106
|
export const getTransfarFields = (oriArr = [], columnObj, isSearch) => {
|
|
107
|
+
let rules = {}
|
|
109
108
|
let columnsFlatArr = []
|
|
110
109
|
let formItemsArr = []
|
|
111
110
|
let columnsArr = $vUtils.mapTree(oriArr, ori => {
|
|
@@ -116,41 +115,38 @@ export const getTransfarFields = (oriArr = [], columnObj, isSearch) => {
|
|
|
116
115
|
} else {
|
|
117
116
|
let renderConfig = {
|
|
118
117
|
name: ori.renderName || '$vInput',
|
|
119
|
-
props: Object.assign({}, ori.renderProps
|
|
118
|
+
props: Object.assign({}, ori.renderProps)
|
|
120
119
|
}
|
|
120
|
+
// 首先提取校验配置
|
|
121
|
+
getFieldRules(ori, rules)
|
|
122
|
+
// 初始化排序条件
|
|
123
|
+
if (Number(tar.sortable) === 0 || tar.sortable === 'false') tar.sortable = false
|
|
121
124
|
// 个性化设置
|
|
122
125
|
if (tar.renderName === '$vGlobalOption' || ['$vImg', '$vHref', '$vUpload'].includes(tar.renderName)) {
|
|
123
|
-
tar
|
|
124
|
-
tar.sortable = false
|
|
126
|
+
Object.assign(tar, { filter: false, sortable: false })
|
|
125
127
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
if (tar.renderName === '$vMoney' || ['number', 'float', 'integer'].includes(renderConfig.props.type)) {
|
|
128
|
+
|
|
129
|
+
if (tar.renderName === '$vGlobalOption') tar.resizable = false
|
|
130
|
+
if (tar.renderName === '$vMoney' || ['number', 'float', 'integer'].includes(ori.renderProps?.type)) {
|
|
130
131
|
tar.cellType = 'number'
|
|
131
132
|
}
|
|
132
|
-
if (tar.renderName === '$vMoney' &&
|
|
133
|
+
if (tar.renderName === '$vMoney' && ori.renderProps?.bill) {
|
|
133
134
|
tar.filter = false
|
|
134
135
|
tar.headerClassName += ' header-bill-cell'
|
|
135
136
|
}
|
|
136
|
-
// 初始化排序条件
|
|
137
|
-
if (Number(tar.sortable) === 0 || tar.sortable === 'false') {
|
|
138
|
-
tar.sortable = false
|
|
139
|
-
}
|
|
140
137
|
// 判断单元格是否可编辑
|
|
141
138
|
if (ori.readonly || ori.slots?.default || (!ori.renderName && !(tar.editRender && tar.editRender.name))) {
|
|
142
|
-
tar.cellRender = Object.assign(
|
|
139
|
+
tar.cellRender = Object.assign(renderConfig, tar.cellRender)
|
|
143
140
|
} else {
|
|
144
|
-
tar.editRender = Object.assign(
|
|
141
|
+
tar.editRender = Object.assign(renderConfig, tar.editRender)
|
|
145
142
|
}
|
|
146
143
|
// 初始化表单查询配置
|
|
147
144
|
if (isSearch) {
|
|
148
145
|
let editFixedNames = ['$vImg', '$vHref', '$vUpload']
|
|
149
|
-
let formItem =
|
|
150
|
-
formItem.itemRender = Object.assign({}, renderConfig, tar.editRender
|
|
146
|
+
let formItem = { ...tar }
|
|
147
|
+
formItem.itemRender = Object.assign({ name: '$vInput' }, renderConfig, tar.editRender, tar.itemRender)
|
|
151
148
|
delete formItem.cellRender
|
|
152
149
|
delete formItem.editRender
|
|
153
|
-
formItem.itemRender.name = formItem.itemRender.name || '$vInput'
|
|
154
150
|
// 此处修正, 对其不进行默认渲染
|
|
155
151
|
if (formItem.search && formItem.search !== '0' && !editFixedNames.includes(formItem.itemRender.name)) {
|
|
156
152
|
formItemsArr.push(formItem)
|
|
@@ -164,5 +160,5 @@ export const getTransfarFields = (oriArr = [], columnObj, isSearch) => {
|
|
|
164
160
|
columnsFlatArr.push(tar)
|
|
165
161
|
return tar
|
|
166
162
|
})
|
|
167
|
-
return { columnsArr, columnsFlatArr, formItemsArr }
|
|
163
|
+
return { columnsArr, columnsFlatArr, formItemsArr, rules }
|
|
168
164
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { computed, reactive, ref, watch } from 'vue'
|
|
2
|
-
import { columnDefaultFilterMethod, tableFooterCompute, getTransfarFields
|
|
1
|
+
import { computed, onMounted, reactive, ref, watch } from 'vue'
|
|
2
|
+
import { columnDefaultFilterMethod, tableFooterCompute, getTransfarFields } from './tableMethods'
|
|
3
3
|
|
|
4
4
|
// 记录自定义参数,传给vxe要过滤掉
|
|
5
5
|
let omitProps = [
|
|
@@ -58,7 +58,7 @@ const columnsMapDefault = {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export default function (props, context, proxy, isGrid) {
|
|
61
|
-
const { $vUtils, $vxePluginNames } = proxy
|
|
61
|
+
const { $vUtils, $vTableSetup, $vxePluginNames } = proxy
|
|
62
62
|
const { emit, slots } = context
|
|
63
63
|
|
|
64
64
|
const tableRef = ref()
|
|
@@ -66,6 +66,7 @@ export default function (props, context, proxy, isGrid) {
|
|
|
66
66
|
const selectedRowKeys = ref([]) // table选中keys
|
|
67
67
|
const selectionRows = ref([]) // table选中records
|
|
68
68
|
const tableColumnsFixed = ref([]) // 表格格式化后表头
|
|
69
|
+
const tableMoneyUnit = ref(props.moneyConfig?.defaultValue || 1) // 表格金额单位
|
|
69
70
|
const tableFilterData = ref(null) // 表格全表搜索数据
|
|
70
71
|
const tableColumnsFlat = ref([]) // 多层转一维后表头
|
|
71
72
|
const tableFormItems = ref([]) // 根据表格表头生成表单项配置
|
|
@@ -120,6 +121,9 @@ export default function (props, context, proxy, isGrid) {
|
|
|
120
121
|
}
|
|
121
122
|
}
|
|
122
123
|
})
|
|
124
|
+
const tableMoneyConfig = computed(() => {
|
|
125
|
+
return Object.assign({ enabled: true, options: $vTableSetup.moneyUnitConstants, style: { width: '60px' } }, props.moneyConfig, tableVmConfig.value)
|
|
126
|
+
})
|
|
123
127
|
const tableExportConfig = computed(() =>
|
|
124
128
|
Object.assign(
|
|
125
129
|
{
|
|
@@ -148,10 +152,17 @@ export default function (props, context, proxy, isGrid) {
|
|
|
148
152
|
Object.assign({ enabled: !props.disabled, showStatus: !props.disabled, showUpdateStatus: !props.disabled, showInsertStatus: !props.disabled }, props.editConfig)
|
|
149
153
|
)
|
|
150
154
|
const tableQueryConfig = computed(() => {
|
|
151
|
-
let otherConfig = isGrid ? { transformitem: false, items: tableFormItems.value } : { items: props.columns }
|
|
152
155
|
return Object.assign(
|
|
153
|
-
{
|
|
154
|
-
|
|
156
|
+
{
|
|
157
|
+
data: props.queryData,
|
|
158
|
+
rules: tableEditRules.value,
|
|
159
|
+
validConfig: props.validConfig,
|
|
160
|
+
globalConfig: tableGlobalConfig.value,
|
|
161
|
+
items: tableFormItems.value,
|
|
162
|
+
transformitem: false,
|
|
163
|
+
valid: false,
|
|
164
|
+
footer: true
|
|
165
|
+
},
|
|
155
166
|
tableVmConfig.value
|
|
156
167
|
)
|
|
157
168
|
})
|
|
@@ -162,9 +173,7 @@ export default function (props, context, proxy, isGrid) {
|
|
|
162
173
|
})
|
|
163
174
|
const tableBindConfig = computed(() => {
|
|
164
175
|
let defaultProps = { footerMethod: tableFooterMethod, footerSpanMethod: tableFooterSpanMethod }
|
|
165
|
-
let tableProps = $vUtils.omit(props, (val, key) =>
|
|
166
|
-
return omitProps.includes(key) || $vUtils.isNone(val)
|
|
167
|
-
})
|
|
176
|
+
let tableProps = $vUtils.omit(props, (val, key) => omitProps.includes(key) || $vUtils.isNone(val))
|
|
168
177
|
let shProps = {
|
|
169
178
|
data: tableViewData.value,
|
|
170
179
|
stripe: props.stripe && !tableTreeConfig.value,
|
|
@@ -175,7 +184,9 @@ export default function (props, context, proxy, isGrid) {
|
|
|
175
184
|
editConfig: tableEditConfig.value,
|
|
176
185
|
editRules: tableEditRules.value,
|
|
177
186
|
exportConfig: tableExportConfig.value,
|
|
178
|
-
printConfig: tablePrintConfig.value
|
|
187
|
+
printConfig: tablePrintConfig.value,
|
|
188
|
+
moneyConfig: tableMoneyConfig.value,
|
|
189
|
+
moneyUnit: tableMoneyUnit.value
|
|
179
190
|
}
|
|
180
191
|
return Object.assign(defaultProps, tableProps, shProps)
|
|
181
192
|
})
|
|
@@ -220,12 +231,13 @@ export default function (props, context, proxy, isGrid) {
|
|
|
220
231
|
}
|
|
221
232
|
|
|
222
233
|
// 默认求底部绑定方法vxe
|
|
223
|
-
const tableFooterMethod = ({ columns
|
|
234
|
+
const tableFooterMethod = ({ columns }) => {
|
|
224
235
|
const { footerCalculate } = props
|
|
236
|
+
const fullData = getFullData()
|
|
225
237
|
let footerData = []
|
|
226
238
|
let footerCalculateList = footerCalculate.calculate || []
|
|
227
|
-
footerCalculateList.forEach(
|
|
228
|
-
footerData.push(tableFooterCompute(columns,
|
|
239
|
+
footerCalculateList.forEach(computeType => {
|
|
240
|
+
footerData.push(tableFooterCompute(columns, fullData, computeType, footerCalculate[computeType]))
|
|
229
241
|
})
|
|
230
242
|
return footerData
|
|
231
243
|
}
|
|
@@ -238,6 +250,15 @@ export default function (props, context, proxy, isGrid) {
|
|
|
238
250
|
}
|
|
239
251
|
return { rowspan: 1, colspan: 1 }
|
|
240
252
|
}
|
|
253
|
+
const updateSelection = rows => {
|
|
254
|
+
let selections = []
|
|
255
|
+
let radioRecord = tableRef.value && tableRef.value.getRadioRecord()
|
|
256
|
+
let checkRecords = tableRef.value && tableRef.value.getCheckboxRecords()
|
|
257
|
+
if (rows) selections = rows
|
|
258
|
+
else if (tableGlobalConfig.value.selectType === 'radio' && radioRecord) selections = [radioRecord]
|
|
259
|
+
else if (tableGlobalConfig.value.selectType === 'checkbox' && checkRecords) selections = checkRecords
|
|
260
|
+
selectionRows.value = selections
|
|
261
|
+
}
|
|
241
262
|
|
|
242
263
|
// -------- 表格
|
|
243
264
|
// 当前行变化
|
|
@@ -247,7 +268,7 @@ export default function (props, context, proxy, isGrid) {
|
|
|
247
268
|
}
|
|
248
269
|
// 单选框变化
|
|
249
270
|
const onRadioChange = params => {
|
|
250
|
-
|
|
271
|
+
updateSelection([params.row])
|
|
251
272
|
emit('radio-change', selectionRows.value, params)
|
|
252
273
|
}
|
|
253
274
|
// 复选框变化
|
|
@@ -266,7 +287,7 @@ export default function (props, context, proxy, isGrid) {
|
|
|
266
287
|
})
|
|
267
288
|
records = records.filter(row => !childRowsKeys.includes(row[keyField]))
|
|
268
289
|
}
|
|
269
|
-
|
|
290
|
+
updateSelection(records)
|
|
270
291
|
emit('selection-change', selectionRows.value, params)
|
|
271
292
|
}
|
|
272
293
|
// 单元格点击事件
|
|
@@ -328,7 +349,7 @@ export default function (props, context, proxy, isGrid) {
|
|
|
328
349
|
}
|
|
329
350
|
// 分页变化触发
|
|
330
351
|
const onPageChange = params => {
|
|
331
|
-
|
|
352
|
+
updateSelection([])
|
|
332
353
|
emit('page-change', params)
|
|
333
354
|
}
|
|
334
355
|
|
|
@@ -372,14 +393,14 @@ export default function (props, context, proxy, isGrid) {
|
|
|
372
393
|
}
|
|
373
394
|
|
|
374
395
|
// 初始化生成新表头数据
|
|
375
|
-
const initTableColumns = (
|
|
376
|
-
let
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
396
|
+
const initTableColumns = () => {
|
|
397
|
+
let transResult = getTransfarFields(props.columns, tableColumnObjConfig.value, tableGlobalConfig.value.search)
|
|
398
|
+
tableColumnsFlat.value = transResult.columnsFlatArr
|
|
399
|
+
tableFormItems.value = transResult.formItemsArr
|
|
400
|
+
tableColumnsFixed.value = transResult.columnsArr
|
|
401
|
+
initEditRules(transResult.rules)
|
|
402
|
+
if (!isGrid) {
|
|
403
|
+
tableRef.value.loadColumn(tableColumns.value)
|
|
383
404
|
}
|
|
384
405
|
}
|
|
385
406
|
// 初始化验证规则
|
|
@@ -394,39 +415,6 @@ export default function (props, context, proxy, isGrid) {
|
|
|
394
415
|
})
|
|
395
416
|
}
|
|
396
417
|
}
|
|
397
|
-
// 初始化表头配置默认值
|
|
398
|
-
const initColsDefaultValue = () => {
|
|
399
|
-
let colsDefaultValue = {}
|
|
400
|
-
let colsFormulaValue = {}
|
|
401
|
-
$vUtils.eachTree(props.columns, item => {
|
|
402
|
-
let columnProps = item.renderProps || item.editRender?.props || item.cellRender?.props || {}
|
|
403
|
-
if (!$vUtils.isNone(columnProps.defaultValue)) {
|
|
404
|
-
colsDefaultValue[item.field] = columnProps.defaultValue
|
|
405
|
-
}
|
|
406
|
-
if (!$vUtils.isNone(columnProps.formula)) {
|
|
407
|
-
colsFormulaValue[item.field] = columnProps.formula
|
|
408
|
-
}
|
|
409
|
-
})
|
|
410
|
-
tableRowDefaultData.value = colsDefaultValue
|
|
411
|
-
if (Array.isArray(props.dataSourse)) {
|
|
412
|
-
props.dataSourse.forEach(row => {
|
|
413
|
-
if (Object.keys(colsDefaultValue).length > 0) {
|
|
414
|
-
Object.keys(colsDefaultValue).forEach(defaultKey => {
|
|
415
|
-
if ($vUtils.isNone($vUtils.get(row, defaultKey))) {
|
|
416
|
-
$vUtils.set(row, defaultKey, colsDefaultValue[defaultKey])
|
|
417
|
-
}
|
|
418
|
-
})
|
|
419
|
-
}
|
|
420
|
-
if (Object.keys(colsFormulaValue).length > 0) {
|
|
421
|
-
Object.keys(colsFormulaValue).forEach(formulaKey => {
|
|
422
|
-
let formulaValue = $vUtils.calculate(colsFormulaValue[formulaKey], row)
|
|
423
|
-
$vUtils.set(row, formulaKey, formulaValue)
|
|
424
|
-
})
|
|
425
|
-
}
|
|
426
|
-
})
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
418
|
// 全局搜索输入框事件
|
|
431
419
|
const handleTableFilter = obj => {
|
|
432
420
|
let filterText = tableFilterText.value
|
|
@@ -543,28 +531,27 @@ export default function (props, context, proxy, isGrid) {
|
|
|
543
531
|
if (!result) return
|
|
544
532
|
}
|
|
545
533
|
await tableRef.value.remove(deleteRows)
|
|
546
|
-
|
|
547
|
-
let keyField = props.rowConfig.keyField || proxy.$vTableSetup.table.rowConfig.keyField
|
|
548
|
-
selectionRows.value = selectionRows.value.filter(sr => !deleteRows.find(dr => dr[keyField] === sr[keyField]))
|
|
549
|
-
}
|
|
534
|
+
updateSelection()
|
|
550
535
|
if (isTool) emit('toolbaroption', 'delete', deleteRows, tableRef.value)
|
|
551
536
|
}
|
|
552
537
|
|
|
538
|
+
onMounted(() => {
|
|
539
|
+
initTableColumns()
|
|
540
|
+
})
|
|
541
|
+
|
|
553
542
|
watch(
|
|
554
543
|
() => props.columns,
|
|
555
544
|
value => {
|
|
556
|
-
initTableColumns(
|
|
545
|
+
initTableColumns()
|
|
557
546
|
},
|
|
558
547
|
{
|
|
559
|
-
deep: true
|
|
560
|
-
immediate: true
|
|
548
|
+
deep: true
|
|
561
549
|
}
|
|
562
550
|
)
|
|
563
551
|
watch(
|
|
564
552
|
() => props.dataSourse,
|
|
565
553
|
value => {
|
|
566
|
-
|
|
567
|
-
selectionRows.value = []
|
|
554
|
+
updateSelection([])
|
|
568
555
|
},
|
|
569
556
|
{
|
|
570
557
|
immediate: true
|
|
@@ -600,6 +587,8 @@ export default function (props, context, proxy, isGrid) {
|
|
|
600
587
|
selectionRows,
|
|
601
588
|
tableBindConfig,
|
|
602
589
|
importBindConfig,
|
|
590
|
+
tableMoneyUnit,
|
|
591
|
+
tableMoneyConfig,
|
|
603
592
|
onCurrentChange,
|
|
604
593
|
onRadioChange,
|
|
605
594
|
onSelectionChange,
|
|
@@ -631,6 +620,6 @@ export default function (props, context, proxy, isGrid) {
|
|
|
631
620
|
getFullData,
|
|
632
621
|
handleTableAddRow,
|
|
633
622
|
handleTableDeleteRow,
|
|
634
|
-
|
|
623
|
+
initTableColumns
|
|
635
624
|
}
|
|
636
625
|
}
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
<div v-if="slots.toolbarRight" class="sh-table-toolbar-item">
|
|
32
32
|
<slot name="toolbarRight"></slot>
|
|
33
33
|
</div>
|
|
34
|
+
<div v-if="tableMoneyConfig.enabled" @click.stop class="sh-table-toolbar-item">单位:<sh-select v-model="tableMoneyUnit" v-bind="tableMoneyConfig" /></div>
|
|
34
35
|
<template v-for="(tool, toolIndex) in tableTools" :key="toolIndex">
|
|
35
36
|
<div class="sh-table-toolbar-item">
|
|
36
37
|
<vxe-button v-ripple :size="size" v-bind="tool" @click="handleTableTool(tool)"></vxe-button>
|
|
@@ -70,14 +71,6 @@
|
|
|
70
71
|
<template v-if="customLayout">
|
|
71
72
|
<slot></slot>
|
|
72
73
|
</template>
|
|
73
|
-
<template v-else>
|
|
74
|
-
<template v-for="(column, columnIndex) in tablePrevColumns" :key="columnIndex">
|
|
75
|
-
<vxe-column v-bind="column"></vxe-column>
|
|
76
|
-
</template>
|
|
77
|
-
<template v-for="(column, columnIndex) in columns" :key="columnIndex">
|
|
78
|
-
<sh-column :column="column"></sh-column>
|
|
79
|
-
</template>
|
|
80
|
-
</template>
|
|
81
74
|
<template #empty>
|
|
82
75
|
<sh-empty :icon="emptyIcon" :content="emptyText"></sh-empty>
|
|
83
76
|
</template>
|
|
@@ -107,13 +100,11 @@ import { computed, defineComponent, getCurrentInstance, provide, ref, reactive }
|
|
|
107
100
|
import './css/index.scss'
|
|
108
101
|
|
|
109
102
|
import props from './js/props'
|
|
110
|
-
import shColumn from './components/sh-column.vue'
|
|
111
103
|
import importModal from './components/importModal.vue'
|
|
112
104
|
import useTable from './js/useTable'
|
|
113
105
|
export default defineComponent({
|
|
114
106
|
name: 'ShTable',
|
|
115
107
|
components: {
|
|
116
|
-
shColumn,
|
|
117
108
|
importModal
|
|
118
109
|
},
|
|
119
110
|
props: {
|
|
@@ -172,15 +163,6 @@ export default defineComponent({
|
|
|
172
163
|
const isPagerSlot = computed(() => useTableHooks.tablePagerConfig.value.enabled)
|
|
173
164
|
const isBottomSlot = computed(() => Boolean(slots.bottom))
|
|
174
165
|
|
|
175
|
-
provide(
|
|
176
|
-
'ShTableInstance',
|
|
177
|
-
reactive({
|
|
178
|
-
columnObjConfig: useTableHooks.tableColumnObjConfig,
|
|
179
|
-
turnColumnItemFilters: useTableHooks.turnColumnItemFilters,
|
|
180
|
-
slots: useTableHooks.slots
|
|
181
|
-
})
|
|
182
|
-
)
|
|
183
|
-
|
|
184
166
|
const handleResize = e => {
|
|
185
167
|
if (useTableHooks.wrapHeight.value === 'auto') return
|
|
186
168
|
let slotRefs = [topSlotRef, formSlotRef, toolbarSlotRef, headSlotRef, footSlotRef, pagerSlotRef, bottomSlotRef]
|
|
@@ -9,10 +9,7 @@
|
|
|
9
9
|
<div ref="navScrollRef" class="sh-tabs-nav-scroll" @DOMMouseScroll="handleScroll" @mousewheel="handleScroll">
|
|
10
10
|
<div ref="navRef" v-resize="handleResize" class="sh-tabs-nav-inner" :style="navStyle">
|
|
11
11
|
<template v-for="(tab, tabIndex) in tabList" :key="tabIndex">
|
|
12
|
-
<div
|
|
13
|
-
:class="{ 'sh-tab-item': true, 'sh-tab-item-disabled': tab.disabled, 'sh-tab-item-active': tab[labelKey] === activeKey }"
|
|
14
|
-
:style="getTabItemStyle(tab, tabIndex)"
|
|
15
|
-
@click="handleChange(tab)">
|
|
12
|
+
<div v-ripple v-bind="getTabItemBind(tab, tabIndex)" @click="handleChange(tab)">
|
|
16
13
|
<slot name="tabItem" v-bind="{ ...tab, isActive: tab[labelKey] === activeKey }">
|
|
17
14
|
<div v-if="tab.icon" class="sh-tab-icon"><sh-icon :type="tab.icon"></sh-icon></div>
|
|
18
15
|
<div class="sh-tab-label">{{ tab[labelField] }}</div>
|
|
@@ -161,14 +158,21 @@ export default defineComponent({
|
|
|
161
158
|
const getTabIsClosable = tab => {
|
|
162
159
|
return props.closable && !tab.disabled && !tab.unClosed
|
|
163
160
|
}
|
|
164
|
-
const
|
|
161
|
+
const getTabItemBind = (tab, tabIndex) => {
|
|
165
162
|
let itemStyle = {}
|
|
166
163
|
if (isHorizontal.value) {
|
|
167
164
|
itemStyle.marginTop = tabIndex ? `${props.gutter}px` : 0
|
|
168
165
|
} else {
|
|
169
166
|
itemStyle.marginLeft = tabIndex ? `${props.gutter}px` : 0
|
|
170
167
|
}
|
|
171
|
-
return
|
|
168
|
+
return {
|
|
169
|
+
style: itemStyle,
|
|
170
|
+
class: {
|
|
171
|
+
'sh-tab-item': true,
|
|
172
|
+
'sh-tab-item-disabled': tab.disabled,
|
|
173
|
+
'sh-tab-item-active': tab[props.labelKey] === activeKey.value
|
|
174
|
+
}
|
|
175
|
+
}
|
|
172
176
|
}
|
|
173
177
|
const handleResize = e => {
|
|
174
178
|
const navOffset = isHorizontal.value ? navRef.value.offsetHeight : navRef.value.offsetWidth
|
|
@@ -269,7 +273,7 @@ export default defineComponent({
|
|
|
269
273
|
handleChange,
|
|
270
274
|
handleClose,
|
|
271
275
|
getTabIsClosable,
|
|
272
|
-
|
|
276
|
+
getTabItemBind
|
|
273
277
|
}
|
|
274
278
|
}
|
|
275
279
|
})
|
|
@@ -2,6 +2,7 @@ import VXETable from 'vxe-table'
|
|
|
2
2
|
import './css/index.scss'
|
|
3
3
|
import VXETablePluginExportXLSX from './plugins/export'
|
|
4
4
|
import VXETablePluginExportPDF from 'vxe-table-plugin-export-pdf'
|
|
5
|
+
import { jsPDF } from 'jspdf'
|
|
5
6
|
import XEClipboard from 'xe-clipboard'
|
|
6
7
|
import ShValidators from 'sh-tools/packages/utils/validate'
|
|
7
8
|
import { publicRenders, extraRenders, filterRenders, publicRendersNames } from './render/globalRenders.jsx'
|
|
@@ -154,17 +155,43 @@ let vxeOptions = {
|
|
|
154
155
|
loading: {
|
|
155
156
|
icon: 'vxe-icon-spinner roll',
|
|
156
157
|
text: '加载中...'
|
|
157
|
-
}
|
|
158
|
+
},
|
|
159
|
+
moneyUnitConstants: [
|
|
160
|
+
{ value: 1, label: '元', digits: 2 },
|
|
161
|
+
{ value: 1000, label: '千元', digits: 4 },
|
|
162
|
+
{ value: 10000, label: '万元', digits: 6 }
|
|
163
|
+
],
|
|
164
|
+
cnGroups: [
|
|
165
|
+
{ shortText: '兆', fullText: '兆', value: '' },
|
|
166
|
+
{ shortText: '千', fullText: '千亿', value: '' },
|
|
167
|
+
{ shortText: '百', fullText: '百亿', value: '' },
|
|
168
|
+
{ shortText: '十', fullText: '十亿', value: '' },
|
|
169
|
+
{ shortText: '亿', fullText: '亿', value: '' },
|
|
170
|
+
{ shortText: '千', fullText: '千万', value: '' },
|
|
171
|
+
{ shortText: '百', fullText: '百万', value: '' },
|
|
172
|
+
{ shortText: '十', fullText: '十万', value: '' },
|
|
173
|
+
{ shortText: '万', fullText: '万', value: '' },
|
|
174
|
+
{ shortText: '千', fullText: '千', value: '' },
|
|
175
|
+
{ shortText: '百', fullText: '百', value: '' },
|
|
176
|
+
{ shortText: '十', fullText: '十', value: '' },
|
|
177
|
+
{ shortText: '元', fullText: '元', value: '' },
|
|
178
|
+
{ shortText: '角', fullText: '角', value: '' },
|
|
179
|
+
{ shortText: '分', fullText: '分', value: '' },
|
|
180
|
+
{ shortText: '毫', fullText: '毫', value: '' },
|
|
181
|
+
{ shortText: '厘', fullText: '厘', value: '' }
|
|
182
|
+
]
|
|
158
183
|
}
|
|
159
184
|
|
|
160
185
|
let vxePdfOptions = {
|
|
161
|
-
|
|
162
|
-
fontName: '
|
|
163
|
-
beforeMethod: ({ $pdf, options, columns, datas }) => {}
|
|
186
|
+
jsPDF,
|
|
187
|
+
fonts: [{ fontName: 'SourceHanSansNormal' }]
|
|
164
188
|
}
|
|
165
|
-
|
|
189
|
+
let vxeXlsxOptions = {}
|
|
166
190
|
Object.keys(ShValidators).forEach(key => {
|
|
167
191
|
VXETable.validators.add(key, {
|
|
192
|
+
itemValidatorMethod({ itemValue }) {
|
|
193
|
+
return ShValidators[key](itemValue)
|
|
194
|
+
},
|
|
168
195
|
cellValidatorMethod({ cellValue }) {
|
|
169
196
|
return ShValidators[key](cellValue)
|
|
170
197
|
}
|
|
@@ -174,15 +201,15 @@ Object.keys(ShValidators).forEach(key => {
|
|
|
174
201
|
VXETable.renderer.mixin(publicRenders)
|
|
175
202
|
VXETable.renderer.mixin(extraRenders)
|
|
176
203
|
VXETable.renderer.mixin(filterRenders)
|
|
177
|
-
VXETable.use(VXETablePluginExportXLSX)
|
|
178
|
-
VXETable.use(VXETablePluginExportPDF)
|
|
179
204
|
|
|
180
205
|
const index = {
|
|
181
|
-
install(Vue, { vxeOption = {}, vxePdfOption = {} }) {
|
|
206
|
+
install(Vue, { vxeOption = {}, vxePdfOption = {}, vxeXlsxOption }) {
|
|
182
207
|
let setupOption = Object.assign(vxeOptions, vxeOption)
|
|
208
|
+
let xlsxSetUpOption = Object.assign(vxeXlsxOptions, vxeXlsxOption)
|
|
183
209
|
let pdfSetUpOption = Object.assign(vxePdfOptions, vxePdfOption)
|
|
184
210
|
VXETable.setup(setupOption)
|
|
185
|
-
|
|
211
|
+
VXETable.use(VXETablePluginExportXLSX, xlsxSetUpOption)
|
|
212
|
+
VXETable.use(VXETablePluginExportPDF, pdfSetUpOption)
|
|
186
213
|
Vue.use(VXETable)
|
|
187
214
|
Vue.config.globalProperties.$vTable = VXETable
|
|
188
215
|
Vue.config.globalProperties.$vTableSetup = setupOption
|
|
@@ -39,7 +39,7 @@ let defaultPublicProps = {
|
|
|
39
39
|
|
|
40
40
|
// 渲染器个性化默认配置
|
|
41
41
|
let defaultProps = {
|
|
42
|
-
$vInput: { type: 'text', placeholder: '请输入', transfer: true, digits: 2, prefixType: 'text', suffixType: 'text' },
|
|
42
|
+
$vInput: { type: 'text', placeholder: '请输入', transfer: true, digits: 2, prefixType: 'text', suffixType: 'text', immediate: false },
|
|
43
43
|
$vTextArea: { placeholder: '请输入', rows: 2, transfer: true, resize: 'none', showWordCount: true },
|
|
44
44
|
$vSelect: { placeholder: '请选择', filterable: true, transfer: true, showType: 'text', tagColor: 'default', split: ',', options: [] },
|
|
45
45
|
$vTree: { placeholder: '请选择', transfer: true, split: ',', nodeKey: 'id', labelField: 'label' },
|
|
@@ -64,7 +64,7 @@ let defaultProps = {
|
|
|
64
64
|
// 统一处理传参boolean与配置String问题
|
|
65
65
|
const getFixedProp = (renderOpts, params) => {
|
|
66
66
|
let { name, props = {} } = renderOpts
|
|
67
|
-
let { column, $table } = params
|
|
67
|
+
let { column, $grid, $table } = params
|
|
68
68
|
let rturnProps = Object.assign({}, defaultPublicProps, defaultProps[name], props)
|
|
69
69
|
let transKeys = ['transfer', 'disabled', 'multiple', 'isLeaf', 'commafy', 'border', 'filterable', 'showWordCount', 'editable']
|
|
70
70
|
transKeys.forEach(key => {
|
|
@@ -72,6 +72,13 @@ const getFixedProp = (renderOpts, params) => {
|
|
|
72
72
|
rturnProps[key] = Boolean(+rturnProps[key])
|
|
73
73
|
}
|
|
74
74
|
})
|
|
75
|
+
const contextAttrs = $grid?.context?.attrs || $table?.context?.attrs || {}
|
|
76
|
+
if (['$vMoney'].includes(name) && contextAttrs.moneyConfig?.enabled && contextAttrs.moneyUnit && !rturnProps.bill && rturnProps.bill !== '0') {
|
|
77
|
+
let moneyOption = contextAttrs.moneyConfig?.options.find(item => item.value === contextAttrs.moneyUnit)
|
|
78
|
+
rturnProps.moneyUnit = contextAttrs.moneyUnit
|
|
79
|
+
rturnProps.moneyOption = moneyOption
|
|
80
|
+
if (moneyOption && moneyOption.digits) rturnProps.digits = moneyOption.digits
|
|
81
|
+
}
|
|
75
82
|
if (column) {
|
|
76
83
|
column.rname = name
|
|
77
84
|
column.rprops = rturnProps
|
|
@@ -106,7 +113,7 @@ const publicRenders = {
|
|
|
106
113
|
},
|
|
107
114
|
renderFooter(renderOpts, params) {
|
|
108
115
|
let props = getFixedProp(renderOpts, params)
|
|
109
|
-
return [<vxeFooterInput
|
|
116
|
+
return [<vxeFooterInput rparams={params} rname={renderOpts.name} rprops={props.rprops} rkey={props.rkey} />]
|
|
110
117
|
}
|
|
111
118
|
},
|
|
112
119
|
$vTextArea: {
|
|
@@ -252,11 +259,11 @@ const publicRenders = {
|
|
|
252
259
|
},
|
|
253
260
|
renderHeader(renderOpts, params) {
|
|
254
261
|
let props = getFixedProp(renderOpts, params)
|
|
255
|
-
return [<vxeHeaderMoney
|
|
262
|
+
return [<vxeHeaderMoney rparams={params} rname={renderOpts.name} rprops={props.rprops} rkey={props.rkey} />]
|
|
256
263
|
},
|
|
257
264
|
renderFooter(renderOpts, params) {
|
|
258
265
|
let props = getFixedProp(renderOpts, params)
|
|
259
|
-
return [<vxeFooterMoney
|
|
266
|
+
return [<vxeFooterMoney rparams={params} rname={renderOpts.name} rprops={props.rprops} rkey={props.rkey} />]
|
|
260
267
|
},
|
|
261
268
|
exportMethod({ row, column }) {
|
|
262
269
|
return utils.get(row, column.property)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<span>
|
|
3
3
|
{{ rparams.column.title }}
|
|
4
|
-
<span v-if="
|
|
4
|
+
<span v-if="rprops.moneyOption?.label && !rprops.bill" class="header-money-unit-text">({{ rprops.moneyOption?.label }})</span>
|
|
5
5
|
</span>
|
|
6
6
|
<div v-if="rprops.bill" class="header-bill-box">
|
|
7
7
|
<template v-for="(bil, bilindex) in billGroups" :key="bilindex">
|
|
@@ -1,32 +1,7 @@
|
|
|
1
1
|
import { computed, ref, watch } from 'vue'
|
|
2
2
|
|
|
3
|
-
let moneyUnitConstants = [
|
|
4
|
-
{ value: 1, label: '元' },
|
|
5
|
-
{ value: 1000, label: '千元' },
|
|
6
|
-
{ value: 10000, label: '万元' }
|
|
7
|
-
]
|
|
8
|
-
let cnGroups = [
|
|
9
|
-
{ shortText: '兆', fullText: '兆', value: '' },
|
|
10
|
-
{ shortText: '千', fullText: '千亿', value: '' },
|
|
11
|
-
{ shortText: '百', fullText: '百亿', value: '' },
|
|
12
|
-
{ shortText: '十', fullText: '十亿', value: '' },
|
|
13
|
-
{ shortText: '亿', fullText: '亿', value: '' },
|
|
14
|
-
{ shortText: '千', fullText: '千万', value: '' },
|
|
15
|
-
{ shortText: '百', fullText: '百万', value: '' },
|
|
16
|
-
{ shortText: '十', fullText: '十万', value: '' },
|
|
17
|
-
{ shortText: '万', fullText: '万', value: '' },
|
|
18
|
-
{ shortText: '千', fullText: '千', value: '' },
|
|
19
|
-
{ shortText: '百', fullText: '百', value: '' },
|
|
20
|
-
{ shortText: '十', fullText: '十', value: '' },
|
|
21
|
-
{ shortText: '元', fullText: '元', value: '' },
|
|
22
|
-
{ shortText: '角', fullText: '角', value: '' },
|
|
23
|
-
{ shortText: '分', fullText: '分', value: '' },
|
|
24
|
-
{ shortText: '毫', fullText: '毫', value: '' },
|
|
25
|
-
{ shortText: '厘', fullText: '厘', value: '' }
|
|
26
|
-
]
|
|
27
|
-
|
|
28
3
|
export default function (props, context, proxy) {
|
|
29
|
-
const { $vUtils } = proxy
|
|
4
|
+
const { $vUtils, $vTableSetup } = proxy
|
|
30
5
|
|
|
31
6
|
const renderValue = ref(null)
|
|
32
7
|
const renderText = ref('')
|
|
@@ -37,15 +12,11 @@ export default function (props, context, proxy) {
|
|
|
37
12
|
const isEditAll = computed(() => {
|
|
38
13
|
return props.rparams.$table?.props?.editConfig?.enabled && reditmode.value === 'all' && props.rparams.column.editRender
|
|
39
14
|
})
|
|
40
|
-
const moneyUnitText = computed(() => {
|
|
41
|
-
let moneyConstant = moneyUnitConstants.find(item => item.value === props.rprops.moneyUnit)
|
|
42
|
-
return moneyConstant && moneyConstant.label
|
|
43
|
-
})
|
|
44
15
|
const billGroups = computed(() => {
|
|
45
16
|
let { billStart = '分', billEnd = '亿' } = props.rprops
|
|
46
|
-
let startIndex = cnGroups.findIndex(cn => cn.fullText === billEnd)
|
|
47
|
-
let endIndex = cnGroups.findIndex(cn => cn.fullText === billStart)
|
|
48
|
-
return cnGroups.slice(startIndex, endIndex)
|
|
17
|
+
let startIndex = $vTableSetup.cnGroups.findIndex(cn => cn.fullText === billEnd)
|
|
18
|
+
let endIndex = $vTableSetup.cnGroups.findIndex(cn => cn.fullText === billStart)
|
|
19
|
+
return $vTableSetup.cnGroups.slice(startIndex, endIndex + 1)
|
|
49
20
|
})
|
|
50
21
|
const psButtonConfig = computed(() => {
|
|
51
22
|
return { disabled: props.rprops.disabled, size: props.rsize, status: 'primary' }
|
|
@@ -117,51 +88,28 @@ export default function (props, context, proxy) {
|
|
|
117
88
|
}
|
|
118
89
|
// 格式化值formatValue
|
|
119
90
|
const formatValueFun = (value, editable) => {
|
|
91
|
+
if (props.rparams.type === 'footer') {
|
|
92
|
+
const { items, itemIndex } = props.rparams
|
|
93
|
+
const { moneyUnit, digits } = props.rprops
|
|
94
|
+
let footerText = items[itemIndex]
|
|
95
|
+
if (props.rname === '$vMoney') footerText = $vUtils.truncate($vUtils.divide(items[itemIndex], moneyUnit), digits)
|
|
96
|
+
if (props.rprops.commafy) footerText = $vUtils.commafy(footerText, { digits })
|
|
97
|
+
renderValue.value = items[itemIndex]
|
|
98
|
+
renderText.value = footerText
|
|
99
|
+
return
|
|
100
|
+
}
|
|
120
101
|
let formatObj = $vUtils.formatRender(value, props.rkey, props.rdata, props.rname, props.rprops, proxy, editable)
|
|
121
102
|
renderValue.value = ['$vMoney'].includes(props.rname) ? formatObj.rtext : formatObj.rvalue
|
|
122
103
|
renderText.value = formatObj.rtext
|
|
123
104
|
return formatObj
|
|
124
105
|
}
|
|
125
|
-
// 格式化底部值
|
|
126
|
-
const getFooterData = (qianfen = true) => {
|
|
127
|
-
let { $table, items, itemIndex, column } = props.rparams
|
|
128
|
-
let tableData = $table.internalData.afterFullData
|
|
129
|
-
let { rname, rprops, rfooter, property } = column
|
|
130
|
-
let { digits, moneyUnit, commafy, type, calculate } = rprops
|
|
131
|
-
let footerValue = items[itemIndex]
|
|
132
|
-
if (rfooter) {
|
|
133
|
-
let caculateObj = rfooter[items[rfooter.index || 0]]
|
|
134
|
-
if (caculateObj && (rname === '$vMoney' || (['number', 'float', 'integer'].includes(type) && calculate))) {
|
|
135
|
-
let tableColumnData = $vUtils.mapTree(tableData, row => row[property])
|
|
136
|
-
let { computeType, result, typeObj } = caculateObj
|
|
137
|
-
switch (computeType) {
|
|
138
|
-
case 'subTotal':
|
|
139
|
-
footerValue = $vUtils.sum(tableColumnData)
|
|
140
|
-
break
|
|
141
|
-
case 'allTotal':
|
|
142
|
-
footerValue = typeObj[property] || result
|
|
143
|
-
break
|
|
144
|
-
case 'mean':
|
|
145
|
-
footerValue = $vUtils.mean(tableColumnData)
|
|
146
|
-
break
|
|
147
|
-
default:
|
|
148
|
-
footerValue = result
|
|
149
|
-
break
|
|
150
|
-
}
|
|
151
|
-
if (rname === '$vMoney') footerValue = $vUtils.truncate($vUtils.divide(footerValue, moneyUnit), digits)
|
|
152
|
-
if (qianfen && commafy) footerValue = $vUtils.commafy(footerValue, { digits })
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
return footerValue
|
|
156
|
-
}
|
|
157
106
|
const getBillClass = bil => {
|
|
158
107
|
return { basic: bil.fullText === '元', commafy: ['千', '百万', '十亿', '兆'].includes(bil.fullText) }
|
|
159
108
|
}
|
|
160
109
|
// 获取单据值
|
|
161
|
-
const getBillValue =
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
let fullValue = $vUtils.formatMoneyPad(value)
|
|
110
|
+
const getBillValue = index => {
|
|
111
|
+
if (!renderValue.value) return ''
|
|
112
|
+
let fullValue = $vUtils.formatMoneyPad(renderValue.value)
|
|
165
113
|
let fullList = fullValue.replace('.', '').split('')
|
|
166
114
|
return fullList[index]
|
|
167
115
|
}
|
|
@@ -171,6 +119,10 @@ export default function (props, context, proxy) {
|
|
|
171
119
|
() => initData(),
|
|
172
120
|
{ deep: true, immediate: true }
|
|
173
121
|
)
|
|
122
|
+
watch(
|
|
123
|
+
() => props.rprops,
|
|
124
|
+
() => initData()
|
|
125
|
+
)
|
|
174
126
|
|
|
175
127
|
return {
|
|
176
128
|
renderValue,
|
|
@@ -178,7 +130,6 @@ export default function (props, context, proxy) {
|
|
|
178
130
|
rsize,
|
|
179
131
|
rform,
|
|
180
132
|
isEditAll,
|
|
181
|
-
moneyUnitText,
|
|
182
133
|
billGroups,
|
|
183
134
|
psButtonConfig,
|
|
184
135
|
prefixButton,
|
|
@@ -190,7 +141,6 @@ export default function (props, context, proxy) {
|
|
|
190
141
|
vxeRadioCallBack,
|
|
191
142
|
vxeCheckCallBack,
|
|
192
143
|
vxeBlurCallback,
|
|
193
|
-
getFooterData,
|
|
194
144
|
getBillClass,
|
|
195
145
|
getBillValue,
|
|
196
146
|
setRenderValue
|
package/types/alert.ts
CHANGED
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { ShType } from './component'
|
|
2
|
-
|
|
3
|
-
export const alertProps = {
|
|
4
|
-
type: {
|
|
5
|
-
type: String as () => ShType,
|
|
6
|
-
default: 'info'
|
|
7
|
-
},
|
|
8
|
-
title: {
|
|
9
|
-
type: String
|
|
10
|
-
},
|
|
11
|
-
content: {
|
|
12
|
-
type: String
|
|
13
|
-
},
|
|
14
|
-
closable: {
|
|
15
|
-
type: Boolean,
|
|
16
|
-
default: false
|
|
17
|
-
},
|
|
18
|
-
showIcon: {
|
|
19
|
-
type: Boolean,
|
|
20
|
-
default: false
|
|
21
|
-
},
|
|
22
|
-
fade: {
|
|
23
|
-
type: Boolean,
|
|
24
|
-
default: true
|
|
25
|
-
},
|
|
26
|
-
block: {
|
|
27
|
-
type: Boolean,
|
|
28
|
-
default: false
|
|
29
|
-
}
|
|
30
|
-
}
|
|
1
|
+
import { ShType } from './component'
|
|
2
|
+
|
|
3
|
+
export const alertProps = {
|
|
4
|
+
type: {
|
|
5
|
+
type: String as () => ShType,
|
|
6
|
+
default: 'info'
|
|
7
|
+
},
|
|
8
|
+
title: {
|
|
9
|
+
type: String
|
|
10
|
+
},
|
|
11
|
+
content: {
|
|
12
|
+
type: String
|
|
13
|
+
},
|
|
14
|
+
closable: {
|
|
15
|
+
type: Boolean,
|
|
16
|
+
default: false
|
|
17
|
+
},
|
|
18
|
+
showIcon: {
|
|
19
|
+
type: Boolean,
|
|
20
|
+
default: false
|
|
21
|
+
},
|
|
22
|
+
fade: {
|
|
23
|
+
type: Boolean,
|
|
24
|
+
default: true
|
|
25
|
+
},
|
|
26
|
+
block: {
|
|
27
|
+
type: Boolean,
|
|
28
|
+
default: false
|
|
29
|
+
}
|
|
30
|
+
}
|
package/types/component.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export type ShType = 'info' | 'success' | 'warning' | 'error'
|
|
1
|
+
export type ShType = 'info' | 'success' | 'warning' | 'error'
|