sh-view 2.9.21 → 2.9.23
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 +5 -5
- package/packages/components/sh-calendar/index.vue +1 -1
- package/packages/components/sh-date/index.vue +2 -2
- package/packages/components/sh-form/query.vue +1 -1
- package/packages/components/sh-progress/index.vue +7 -3
- package/packages/components/sh-table/components/importModal.vue +5 -5
- package/packages/components/sh-table/css/index.scss +1 -1
- package/packages/components/sh-table/js/useTable.js +4 -4
- package/packages/components/sh-table/table.vue +3 -0
- package/packages/components/sh-tabs/index.vue +9 -3
- package/packages/components/sh-toolbar/index.vue +32 -71
- package/packages/components/sh-tree/components/table-tree.vue +30 -27
- package/packages/components/sh-tree/index.vue +1 -1
- package/packages/components/sh-upload/index.vue +3 -3
- package/packages/css/main.scss +32 -0
- package/packages/mixin/index.js +7 -51
- package/packages/other/sh-preview/components/sh-excel.vue +1 -0
- package/packages/other/sh-preview/components/sh-image.vue +19 -0
- package/packages/other/sh-preview/index.vue +17 -8
- package/packages/vxeTable/css/index.scss +13 -9
- package/packages/vxeTable/index.js +61 -2
- package/packages/vxeTable/render/cell/vxe-render-goption.vue +2 -3
- package/packages/vxeTable/render/cell/vxe-render-input.vue +19 -2
- package/packages/vxeTable/render/cell/vxe-render-money.vue +11 -3
- package/packages/vxeTable/render/cell/vxe-render-progress.vue +1 -1
- package/packages/vxeTable/render/cell/vxe-render-textarea.vue +1 -1
- package/packages/vxeTable/render/cell/vxe-render-time.vue +1 -1
- package/packages/vxeTable/render/globalRenders.jsx +7 -7
- package/packages/vxeTable/render/mixin/cell-hooks.js +8 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sh-view",
|
|
3
|
-
"version": "2.9.
|
|
3
|
+
"version": "2.9.23",
|
|
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",
|
|
@@ -28,9 +28,9 @@
|
|
|
28
28
|
"babel-polyfill": "^6.26.0",
|
|
29
29
|
"codemirror": "^6.0.2",
|
|
30
30
|
"core-js": "^3.32.2",
|
|
31
|
-
"countup.js": "^2.
|
|
31
|
+
"countup.js": "^2.9.0",
|
|
32
32
|
"cron-parser": "^4.8.1",
|
|
33
|
-
"docx-preview": "^0.1.
|
|
33
|
+
"docx-preview": "^0.1.20",
|
|
34
34
|
"exceljs": "^4.4.0",
|
|
35
35
|
"jspdf": "^3.0.4",
|
|
36
36
|
"jszip": "^3.10.1",
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"vue": "^3.5.20",
|
|
41
41
|
"vue-masonry": "^0.16.0",
|
|
42
42
|
"vue-router": "^4.5.1",
|
|
43
|
-
"vxe-pc-ui": "^4.
|
|
44
|
-
"vxe-table": "^4.
|
|
43
|
+
"vxe-pc-ui": "^4.11.24",
|
|
44
|
+
"vxe-table": "^4.17.36"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
</vxe-pulldown>
|
|
22
22
|
</template>
|
|
23
23
|
<template v-else>
|
|
24
|
-
<vxe-
|
|
24
|
+
<vxe-date-picker
|
|
25
25
|
v-model="inputValue"
|
|
26
26
|
v-bind="inputConfig"
|
|
27
27
|
@input="dispatch('input', $event)"
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
@suffix-click="dispatch('suffix-click', $event)"
|
|
39
39
|
@date-prev="dispatch('date-prev', $event)"
|
|
40
40
|
@date-today="dispatch('date-today', $event)"
|
|
41
|
-
@date-next="dispatch('date-next', $event)"></vxe-
|
|
41
|
+
@date-next="dispatch('date-next', $event)"></vxe-date-picker>
|
|
42
42
|
</template>
|
|
43
43
|
</div>
|
|
44
44
|
</template>
|
|
@@ -33,7 +33,7 @@ import useForm from './js/useForm'
|
|
|
33
33
|
export default defineComponent({
|
|
34
34
|
name: 'ShQuery',
|
|
35
35
|
props: props,
|
|
36
|
-
emits: ['submit', 'reset', 'edit-closed', 'submit-invalid', 'collapse', 'prefix-click', 'suffix-click'],
|
|
36
|
+
emits: ['submit', 'reset', 'edit-closed', 'submit-invalid', 'collapse', 'prefix-click', 'suffix-click', 'collapsed'],
|
|
37
37
|
setup(props, context) {
|
|
38
38
|
const { proxy } = getCurrentInstance()
|
|
39
39
|
const useFormHooks = useForm(props, context, proxy)
|
|
@@ -31,6 +31,10 @@ export default defineComponent({
|
|
|
31
31
|
type: Number,
|
|
32
32
|
default: 0
|
|
33
33
|
},
|
|
34
|
+
successAuto: {
|
|
35
|
+
type: Boolean,
|
|
36
|
+
default: true
|
|
37
|
+
},
|
|
34
38
|
status: {
|
|
35
39
|
type: String,
|
|
36
40
|
default: 'normal' // normal', 'active', 'wrong', 'success'
|
|
@@ -97,11 +101,11 @@ export default defineComponent({
|
|
|
97
101
|
if (isDown) {
|
|
98
102
|
currentStatus.value = 'normal'
|
|
99
103
|
emit('status-change', 'normal')
|
|
100
|
-
} else {
|
|
101
|
-
if (
|
|
104
|
+
} else if (parseInt(props.percent, 10) === 100) {
|
|
105
|
+
if (props.successAuto) {
|
|
102
106
|
currentStatus.value = 'success'
|
|
103
|
-
emit('status-change', 'success')
|
|
104
107
|
}
|
|
108
|
+
emit('status-change', 'success')
|
|
105
109
|
}
|
|
106
110
|
}
|
|
107
111
|
|
|
@@ -136,13 +136,13 @@ export default defineComponent({
|
|
|
136
136
|
const handleImportDataBtn = async (type = 'all') => {
|
|
137
137
|
let importData = type === 'all' ? importTableData.value : shtable.value.getSelectionData()
|
|
138
138
|
if (!importData || !Array.isArray(importData) || importData.length < 1) {
|
|
139
|
-
proxy.
|
|
139
|
+
proxy.$vMessage.info('未导入数据')
|
|
140
140
|
return false
|
|
141
141
|
}
|
|
142
142
|
if (props.needValidate) {
|
|
143
143
|
let validateErrMap = await handleImportDataValidate(importData)
|
|
144
144
|
if (validateErrMap) {
|
|
145
|
-
proxy.
|
|
145
|
+
proxy.$vMessage.error('导入校验失败,请检查数据')
|
|
146
146
|
return validateErrMap
|
|
147
147
|
}
|
|
148
148
|
}
|
|
@@ -180,7 +180,7 @@ export default defineComponent({
|
|
|
180
180
|
if (typeof props.downloadTemplateFinished === 'function') {
|
|
181
181
|
props.downloadTemplateFinished(options)
|
|
182
182
|
}
|
|
183
|
-
proxy.
|
|
183
|
+
proxy.$vMessage.success('下载模板完成!')
|
|
184
184
|
}
|
|
185
185
|
// 选择导入文件按钮
|
|
186
186
|
const handleImportFileBtn = async () => {
|
|
@@ -201,9 +201,9 @@ export default defineComponent({
|
|
|
201
201
|
if (typeof props.importFileFinished === 'function') {
|
|
202
202
|
props.importFileFinished(options)
|
|
203
203
|
}
|
|
204
|
-
proxy.
|
|
204
|
+
proxy.$vMessage.success('导入完成!')
|
|
205
205
|
} catch (e) {
|
|
206
|
-
proxy.
|
|
206
|
+
proxy.$vMessage.error(e.message || e)
|
|
207
207
|
}
|
|
208
208
|
}
|
|
209
209
|
// 读取文件
|
|
@@ -150,7 +150,7 @@ export default function (props, context, proxy, isGrid) {
|
|
|
150
150
|
return Object.assign({ seqMethod: obj => seqMethod(obj, pagerConfig) }, props.seqConfig)
|
|
151
151
|
})
|
|
152
152
|
const tableMoneyConfig = computed(() => {
|
|
153
|
-
return Object.assign({ style: { width: '
|
|
153
|
+
return Object.assign({ style: { width: '70px' } }, $vTableSetup.moneyConfig, props.moneyConfig, tableVmConfig.value)
|
|
154
154
|
})
|
|
155
155
|
const tableExportConfig = computed(() =>
|
|
156
156
|
Object.assign(
|
|
@@ -582,7 +582,7 @@ export default function (props, context, proxy, isGrid) {
|
|
|
582
582
|
// 自定义操作列点击事件
|
|
583
583
|
const handleGoptionClick = async (btnObj, dataObj) => {
|
|
584
584
|
if (btnObj.code === 'delete' || btnObj.idConfirm) {
|
|
585
|
-
await proxy.
|
|
585
|
+
await proxy.$vMessage.confirm({ content: btnObj.ConfirmContent || `确定${btnObj.content}吗?` })
|
|
586
586
|
}
|
|
587
587
|
emit('globaloption', btnObj, dataObj)
|
|
588
588
|
}
|
|
@@ -611,11 +611,11 @@ export default function (props, context, proxy, isGrid) {
|
|
|
611
611
|
if (isTool) {
|
|
612
612
|
let selectedRows = getSelectionData()
|
|
613
613
|
if (selectedRows.length < 1) {
|
|
614
|
-
proxy.
|
|
614
|
+
proxy.$vMessage.warning('请选择要删除的行!')
|
|
615
615
|
return
|
|
616
616
|
}
|
|
617
617
|
deleteRows = selectedRows
|
|
618
|
-
await proxy.
|
|
618
|
+
await proxy.$vMessage.confirm({ content: `确定删除吗?` })
|
|
619
619
|
} else if (typeof props.onToolbarBtnDeleteBefore === 'function') {
|
|
620
620
|
let result = await props.onToolbarBtnDeleteBefore(deleteRows)
|
|
621
621
|
if (!result) return
|
|
@@ -165,6 +165,9 @@ export default defineComponent({
|
|
|
165
165
|
slotRefs.forEach(slotRef => {
|
|
166
166
|
otherHeight += slotRef.value?.offsetHeight || 0
|
|
167
167
|
})
|
|
168
|
+
if (useTableHooks.zoomStatus.value) {
|
|
169
|
+
otherHeight += 16
|
|
170
|
+
}
|
|
168
171
|
tableHeight.value = parentHeight - otherHeight
|
|
169
172
|
}
|
|
170
173
|
|
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
<template v-for="(tab, tabIndex) in tabList" :key="tabIndex">
|
|
12
12
|
<div v-bind="getTabItemBind(tab, tabIndex)" @click="handleChange(tab)">
|
|
13
13
|
<slot name="tabItem" v-bind="{ ...tab, isActive: tab[labelKey] === activeKey }">
|
|
14
|
-
<div v-if="tab.icon" class="sh-tab-icon"><sh-icon :type="tab.icon"></sh-icon></div>
|
|
14
|
+
<div v-if="tab.icon" class="sh-tab-icon"><sh-icon :type="tab.icon" :size="iconSize"></sh-icon></div>
|
|
15
15
|
<div v-if="tab[labelField]" class="sh-tab-label">{{ tab[labelField] }}</div>
|
|
16
|
-
<div v-if="getTabIsClosable(tab)" class="sh-tab-close" @click.stop="handleClose(tab)"><sh-icon type="ios-close"></sh-icon></div>
|
|
16
|
+
<div v-if="getTabIsClosable(tab)" class="sh-tab-close" @click.stop="handleClose(tab)"><sh-icon type="ios-close" :size="iconSize"></sh-icon></div>
|
|
17
17
|
</slot>
|
|
18
18
|
</div>
|
|
19
19
|
</template>
|
|
@@ -108,6 +108,10 @@ export default defineComponent({
|
|
|
108
108
|
const isHorizontal = computed(() => ['left', 'right'].includes(props.placement))
|
|
109
109
|
const hasContent = computed(() => props.isContent && activeKey.value && props.options.map(item => item[props.labelKey]).includes(activeKey.value))
|
|
110
110
|
const vmSize = computed(() => props.size || $vUiSetup.size)
|
|
111
|
+
const iconSize = computed(() => {
|
|
112
|
+
if (['small', 'mini'].includes(vmSize.value)) return 12
|
|
113
|
+
return 14
|
|
114
|
+
})
|
|
111
115
|
const tabClass = computed(() => {
|
|
112
116
|
return {
|
|
113
117
|
'sh-tabs-card': props.type === 'card',
|
|
@@ -269,6 +273,7 @@ export default defineComponent({
|
|
|
269
273
|
activeKey,
|
|
270
274
|
hasContent,
|
|
271
275
|
contentStyle,
|
|
276
|
+
iconSize,
|
|
272
277
|
scrollPrev,
|
|
273
278
|
scrollNext,
|
|
274
279
|
handleScroll,
|
|
@@ -287,7 +292,7 @@ export default defineComponent({
|
|
|
287
292
|
width: 100%;
|
|
288
293
|
position: relative;
|
|
289
294
|
display: flex;
|
|
290
|
-
line-height: 2.
|
|
295
|
+
line-height: 2.4em;
|
|
291
296
|
&-size {
|
|
292
297
|
&-medium {
|
|
293
298
|
font-size: 1.25em;
|
|
@@ -303,6 +308,7 @@ export default defineComponent({
|
|
|
303
308
|
display: inline-flex;
|
|
304
309
|
align-items: center;
|
|
305
310
|
font-size: 1.4em;
|
|
311
|
+
padding: 0 0.1em;
|
|
306
312
|
&:hover {
|
|
307
313
|
background-color: rgba(0, 0, 0, 0.1);
|
|
308
314
|
}
|
|
@@ -2,14 +2,9 @@
|
|
|
2
2
|
<div class="sh-vxe-toolbar">
|
|
3
3
|
<div class="toolbar-left">
|
|
4
4
|
<slot name="left"></slot>
|
|
5
|
-
<
|
|
6
|
-
<template v-for="(toolBtn, toolBtnIndex) in toolBtns" :key="toolBtnIndex">
|
|
7
|
-
<vxe-button :size="vmSize" v-bind="toolBtn" @click="handleToolBtn(toolBtn)"></vxe-button>
|
|
8
|
-
</template>
|
|
9
|
-
</template>
|
|
10
|
-
<vxe-radio-group v-else v-model="leftActive" @change="handleLeftBtn">
|
|
5
|
+
<vxe-radio-group v-model="leftActive" @change="handleLeftBtn">
|
|
11
6
|
<template v-for="(leftBtn, leftBtnIndex) in leftBtns" :key="leftBtnIndex">
|
|
12
|
-
<vxe-radio-button :size="vmSize" v-bind="leftBtn" :label="leftBtn
|
|
7
|
+
<vxe-radio-button :size="vmSize" v-bind="leftBtn" :label="leftBtn[leftKey]"></vxe-radio-button>
|
|
13
8
|
</template>
|
|
14
9
|
</vxe-radio-group>
|
|
15
10
|
<slot name="leftr"></slot>
|
|
@@ -17,7 +12,7 @@
|
|
|
17
12
|
<div class="toolbar-right">
|
|
18
13
|
<slot name="rightl"></slot>
|
|
19
14
|
<template v-for="(rightBtn, rightBtnIndex) in rightBtns" :key="rightBtnIndex">
|
|
20
|
-
<vxe-button :size="vmSize" v-bind="rightBtn" @click="handleRightBtn(rightBtn)"></vxe-button>
|
|
15
|
+
<vxe-button :size="vmSize" :round="round" v-bind="rightBtn" @click="handleRightBtn(rightBtn)"></vxe-button>
|
|
21
16
|
</template>
|
|
22
17
|
<slot name="right"></slot>
|
|
23
18
|
</div>
|
|
@@ -35,58 +30,30 @@ export default defineComponent({
|
|
|
35
30
|
relation: {
|
|
36
31
|
type: Boolean
|
|
37
32
|
},
|
|
38
|
-
|
|
39
|
-
type:
|
|
40
|
-
default() {
|
|
41
|
-
return []
|
|
42
|
-
}
|
|
33
|
+
round: {
|
|
34
|
+
type: Boolean
|
|
43
35
|
},
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
default
|
|
47
|
-
return [
|
|
48
|
-
{ value: '1', code: 'wss', content: '未送审' },
|
|
49
|
-
{ value: '2', code: 'bth', content: '被退回' },
|
|
50
|
-
{ value: '3', code: 'yss', content: '已送审' },
|
|
51
|
-
{ value: '4', code: 'ygd', content: '已归档' },
|
|
52
|
-
{ value: '5', code: 'qb', content: '全部' },
|
|
53
|
-
{ value: '6', code: 'dsh', content: '待审核' },
|
|
54
|
-
{ value: '7', code: 'ysh', content: '已审核' }
|
|
55
|
-
]
|
|
56
|
-
}
|
|
36
|
+
leftKey: {
|
|
37
|
+
String,
|
|
38
|
+
default: 'value'
|
|
57
39
|
},
|
|
58
|
-
|
|
40
|
+
leftContain: {
|
|
59
41
|
type: Array,
|
|
60
42
|
default() {
|
|
61
43
|
return []
|
|
62
44
|
}
|
|
63
45
|
},
|
|
64
|
-
|
|
65
|
-
type:
|
|
46
|
+
leftConfig: {
|
|
47
|
+
type: Array
|
|
66
48
|
},
|
|
67
|
-
|
|
49
|
+
rightContain: {
|
|
68
50
|
type: Array,
|
|
69
51
|
default() {
|
|
70
52
|
return []
|
|
71
53
|
}
|
|
72
54
|
},
|
|
73
|
-
|
|
74
|
-
type: Array
|
|
75
|
-
default() {
|
|
76
|
-
return [
|
|
77
|
-
{ code: 'add', content: '新增', status: 'primary', icon: 'vxe-icon-add' },
|
|
78
|
-
{ code: 'edit', content: '修改', status: 'warning', icon: 'vxe-icon-edit' },
|
|
79
|
-
{ code: 'delete', content: '删除', status: 'danger', icon: 'vxe-icon-delete' },
|
|
80
|
-
{ code: 'detail', content: '查看', status: '', icon: 'vxe-icon-information' },
|
|
81
|
-
{ code: 'export', content: '导出', status: 'success', icon: 'vxe-icon-download' },
|
|
82
|
-
{ code: 'import', content: '导入', status: 'primary', icon: 'vxe-icon-upload' },
|
|
83
|
-
{ code: 'print', content: '打印', status: 'warning', icon: 'vxe-icon-print' },
|
|
84
|
-
{ code: 'batch-add', content: '批量新增', status: 'primary', icon: 'vxe-icon-add' },
|
|
85
|
-
{ code: 'batch-edit', content: '批量修改', status: 'warning', icon: 'vxe-icon-edit' },
|
|
86
|
-
{ code: 'batch-delete', content: '批量删除', status: 'danger', icon: 'vxe-icon-delete' },
|
|
87
|
-
{ code: 'batch-detail', content: '查看', status: '', icon: 'vxe-icon-information' }
|
|
88
|
-
]
|
|
89
|
-
}
|
|
55
|
+
rightConfig: {
|
|
56
|
+
type: Array
|
|
90
57
|
},
|
|
91
58
|
size: {
|
|
92
59
|
type: String,
|
|
@@ -102,42 +69,35 @@ export default defineComponent({
|
|
|
102
69
|
const leftActive = ref(props.modelValue)
|
|
103
70
|
|
|
104
71
|
const vmSize = computed(() => props.size || $vUiSetup.size)
|
|
72
|
+
const leftConfigBtns = computed(() => props.leftConfig || $vUiSetup.toolbarLeftConfig)
|
|
73
|
+
const rightConfigBtns = computed(() => props.rightConfig || $vUiSetup.toolbarRightConfig)
|
|
105
74
|
const leftBtns = computed(() => {
|
|
106
75
|
let lBtns = []
|
|
107
|
-
if (props.leftContain && Array.isArray(props.leftContain)) {
|
|
108
|
-
lBtns = props.leftContain.map(item =>
|
|
76
|
+
if (props.leftContain && Array.isArray(props.leftContain) && props.leftContain.length > 0) {
|
|
77
|
+
lBtns = props.leftContain.map(item => leftConfigBtns.value.find(btn => btn.code === item))
|
|
109
78
|
}
|
|
110
|
-
return lBtns
|
|
79
|
+
return lBtns.filter(item => !!item)
|
|
111
80
|
})
|
|
112
81
|
const rightBtns = computed(() => {
|
|
113
82
|
let rBtns = []
|
|
114
|
-
if (props.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return rBtns
|
|
122
|
-
})
|
|
123
|
-
const toolBtns = computed(() => {
|
|
124
|
-
let toolBtns = []
|
|
125
|
-
if (props.toolsContain && Array.isArray(props.toolsContain)) {
|
|
126
|
-
toolBtns = props.toolsContain.map(item => props.toolsConfig.find(btn => btn.code === item))
|
|
83
|
+
if (props.relation) {
|
|
84
|
+
let leftBtn = leftBtns.value.find(btn => btn.value === leftActive.value)
|
|
85
|
+
if (leftBtn) {
|
|
86
|
+
rBtns = (leftBtn.buttons || []).map(item => rightConfigBtns.value.find(btn => btn.code === item))
|
|
87
|
+
}
|
|
88
|
+
} else if (props.rightContain && Array.isArray(props.rightContain) && props.rightContain.length > 0) {
|
|
89
|
+
rBtns = props.rightContain.map(item => rightConfigBtns.value.find(btn => btn.code === item))
|
|
127
90
|
}
|
|
128
|
-
return
|
|
91
|
+
return rBtns.filter(item => !!item)
|
|
129
92
|
})
|
|
130
93
|
|
|
131
94
|
const handleLeftBtn = ({ label }) => {
|
|
132
|
-
let btnObj = props.leftConfig.find(item => item.
|
|
95
|
+
let btnObj = props.leftConfig.find(item => item[props.leftKey] === label)
|
|
133
96
|
emitValue(btnObj)
|
|
134
97
|
emit('left', label, btnObj)
|
|
135
98
|
}
|
|
136
99
|
const handleRightBtn = btn => {
|
|
137
|
-
emit('right', btn
|
|
138
|
-
}
|
|
139
|
-
const handleToolBtn = btn => {
|
|
140
|
-
emit('tool', btn)
|
|
100
|
+
emit('right', btn)
|
|
141
101
|
}
|
|
142
102
|
const emitValue = btnObj => {
|
|
143
103
|
emit('input', leftActive.value, btnObj)
|
|
@@ -153,10 +113,9 @@ export default defineComponent({
|
|
|
153
113
|
|
|
154
114
|
return {
|
|
155
115
|
leftActive,
|
|
156
|
-
|
|
116
|
+
vmSize,
|
|
157
117
|
leftBtns,
|
|
158
118
|
rightBtns,
|
|
159
|
-
handleToolBtn,
|
|
160
119
|
handleLeftBtn,
|
|
161
120
|
handleRightBtn
|
|
162
121
|
}
|
|
@@ -175,6 +134,7 @@ export default defineComponent({
|
|
|
175
134
|
width: 100%;
|
|
176
135
|
.toolbar-left {
|
|
177
136
|
flex: 1;
|
|
137
|
+
white-space: nowrap;
|
|
178
138
|
.vxe-radio-button > input:checked + .vxe-radio--label {
|
|
179
139
|
border-color: var(--primary-color);
|
|
180
140
|
background: linear-gradient(-10deg, var(--primary-color), var(--primary-lighten-color));
|
|
@@ -183,6 +143,7 @@ export default defineComponent({
|
|
|
183
143
|
.toolbar-right {
|
|
184
144
|
flex: 0;
|
|
185
145
|
white-space: nowrap;
|
|
146
|
+
margin-left: 20px;
|
|
186
147
|
}
|
|
187
148
|
}
|
|
188
149
|
</style>
|
|
@@ -90,34 +90,36 @@ export default defineComponent({
|
|
|
90
90
|
return Object.assign(resultConfig, tableProps.value)
|
|
91
91
|
})
|
|
92
92
|
|
|
93
|
-
const initSelection =
|
|
94
|
-
let { modelValue, multiple } = props
|
|
93
|
+
const initSelection = async isForce => {
|
|
94
|
+
let { modelValue, multiple, isSelect } = props
|
|
95
95
|
let nodeKey = props.nodeKey || 'id'
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (checkRows.length > 0) {
|
|
107
|
-
let expendNode = checkRows[0]
|
|
108
|
-
let checkParent = $vUtils.findTree(tableFullData, item => item[nodeKey] === expendNode[nodeKey])
|
|
109
|
-
let parentNodes = checkParent.nodes.filter(item => item[nodeKey] !== expendNode[nodeKey])
|
|
110
|
-
tableRef.value.setTreeExpand(parentNodes, true)
|
|
111
|
-
if (multiple) {
|
|
112
|
-
tableRef.value.setCheckboxRow(checkRows, true)
|
|
113
|
-
} else {
|
|
114
|
-
tableRef.value.setRadioRow(checkRows[0])
|
|
115
|
-
}
|
|
96
|
+
if (!tableRef.value) return
|
|
97
|
+
if (!isForce && $vUtils.isEqual(modelValue, treeValue.value)) {
|
|
98
|
+
// 非强制更新,如果两次值相等,返回
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
let tableFullData = tableRef.value.getTableData().fullData
|
|
102
|
+
let checkRows = []
|
|
103
|
+
$vUtils.eachTree(tableFullData, item => {
|
|
104
|
+
if (props.modelValue.includes(item[nodeKey])) {
|
|
105
|
+
checkRows.push(item)
|
|
116
106
|
}
|
|
117
|
-
setTimeout(() => {
|
|
118
|
-
tableRef.value.scrollToRow({ [nodeKey]: modelValue[0] })
|
|
119
|
-
})
|
|
120
107
|
})
|
|
108
|
+
// 找到第一个选中节点的所有父级,进行展开
|
|
109
|
+
if (checkRows.length > 0) {
|
|
110
|
+
let expendNode = checkRows[0]
|
|
111
|
+
let checkParent = $vUtils.findTree(tableFullData, item => item[nodeKey] === expendNode[nodeKey])
|
|
112
|
+
let parentNodes = checkParent.nodes.filter(item => item[nodeKey] !== expendNode[nodeKey])
|
|
113
|
+
await tableRef.value.setTreeExpand(parentNodes, true)
|
|
114
|
+
await tableRef.value.scrollToRow(checkRows[0])
|
|
115
|
+
if (multiple) {
|
|
116
|
+
await tableRef.value.setCheckboxRow(checkRows, true)
|
|
117
|
+
} else {
|
|
118
|
+
await tableRef.value.setRadioRow(checkRows[0])
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
await tableRef.value.clearAll()
|
|
122
|
+
}
|
|
121
123
|
}
|
|
122
124
|
// 单选框变化
|
|
123
125
|
const onRadioChange = obj => {
|
|
@@ -198,13 +200,14 @@ export default defineComponent({
|
|
|
198
200
|
})
|
|
199
201
|
}
|
|
200
202
|
|
|
201
|
-
const
|
|
203
|
+
const initChangeDebounce = $vUtils.debounce(initSelection, 100)
|
|
204
|
+
const filterChangeDebounce = $vUtils.debounce(handleMyTableFilter, 300)
|
|
202
205
|
const offetChangeDebounce = $vUtils.debounce(handleOffsetChange, tableConfigIn.value.resizeConfig?.refreshDelay || 100)
|
|
203
206
|
|
|
204
207
|
watch(
|
|
205
208
|
() => props.modelValue,
|
|
206
209
|
() => {
|
|
207
|
-
|
|
210
|
+
initChangeDebounce()
|
|
208
211
|
}
|
|
209
212
|
)
|
|
210
213
|
watch(
|
|
@@ -367,18 +367,18 @@ export default defineComponent({
|
|
|
367
367
|
const checked = fileFormat.value.some(item => item.toLocaleLowerCase() === _file_format)
|
|
368
368
|
if (!checked) {
|
|
369
369
|
let errorMsg = `格式不正确,请上传 ${fileFormat.value.join(' ')} 格式文件`
|
|
370
|
-
props.onFormatError ? props.onFormatError(file, errorMsg, fileList.value) : proxy.
|
|
370
|
+
props.onFormatError ? props.onFormatError(file, errorMsg, fileList.value) : proxy.$vMessage.info(errorMsg)
|
|
371
371
|
return
|
|
372
372
|
}
|
|
373
373
|
}
|
|
374
374
|
// check maxSize
|
|
375
375
|
if (maxSize && file.size > maxSize * 1024) {
|
|
376
376
|
let errorMsg = `文件大小不能超过 ${maxSize / 1024} M`
|
|
377
|
-
props.onExceededSize ? props.onExceededSize(file, errorMsg, fileList.value) : proxy.
|
|
377
|
+
props.onExceededSize ? props.onExceededSize(file, errorMsg, fileList.value) : proxy.$vMessage.info(errorMsg)
|
|
378
378
|
return
|
|
379
379
|
}
|
|
380
380
|
if (!action) {
|
|
381
|
-
proxy.
|
|
381
|
+
proxy.$vMessage.info('上传地址不能为空')
|
|
382
382
|
return
|
|
383
383
|
}
|
|
384
384
|
return true
|
package/packages/css/main.scss
CHANGED
|
@@ -205,3 +205,35 @@ input[type="number"]{ -moz-appearance: textfield; }
|
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
// 全局通用提醒个性化样式
|
|
209
|
+
.sh-message-box{
|
|
210
|
+
&.type--confirm{
|
|
211
|
+
.vxe-modal--box{
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
&.status--success{
|
|
215
|
+
.vxe-modal--box{
|
|
216
|
+
background-color: #edfff3;
|
|
217
|
+
border-color: var(--success-color);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
&.status--warning{
|
|
221
|
+
.vxe-modal--box{
|
|
222
|
+
background-color: #fff9e6;
|
|
223
|
+
border-color: var(--warning-color);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
&.status--error{
|
|
227
|
+
.vxe-modal--box{
|
|
228
|
+
background-color: #ffefe6;
|
|
229
|
+
border-color: var(--danger-color);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
&.status--info{
|
|
233
|
+
.vxe-modal--box{
|
|
234
|
+
background-color: #f0faff;
|
|
235
|
+
border-color: var(--info-color);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
package/packages/mixin/index.js
CHANGED
|
@@ -1,41 +1,5 @@
|
|
|
1
|
-
const msgDefault = {
|
|
2
|
-
title: '',
|
|
3
|
-
className: 'globalMessageBox',
|
|
4
|
-
draggable: false
|
|
5
|
-
}
|
|
6
|
-
|
|
7
1
|
const mixin = {
|
|
8
2
|
methods: {
|
|
9
|
-
// 全局msg提示方法
|
|
10
|
-
msg(options) {
|
|
11
|
-
return this.$vTable.modal.message(options)
|
|
12
|
-
},
|
|
13
|
-
msginfo(options) {
|
|
14
|
-
let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'info' } : options)
|
|
15
|
-
return this.msg(opts)
|
|
16
|
-
},
|
|
17
|
-
msgsuccess(options) {
|
|
18
|
-
let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'success' } : options)
|
|
19
|
-
return this.msg(opts)
|
|
20
|
-
},
|
|
21
|
-
msgwarning(options) {
|
|
22
|
-
let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'warning' } : options)
|
|
23
|
-
return this.msg(opts)
|
|
24
|
-
},
|
|
25
|
-
msgerror(options) {
|
|
26
|
-
let opts = Object.assign({}, msgDefault, typeof options === 'string' ? { content: options, status: 'error' } : options)
|
|
27
|
-
return this.msg(opts)
|
|
28
|
-
},
|
|
29
|
-
msgconfirm(options) {
|
|
30
|
-
return new Promise(async resolve => {
|
|
31
|
-
let opts = Object.assign({}, typeof options === 'string' ? { content: options } : options)
|
|
32
|
-
let type = await this.$vTable.modal.confirm({
|
|
33
|
-
showHeader: Boolean(opts.title),
|
|
34
|
-
...opts
|
|
35
|
-
})
|
|
36
|
-
if (type === 'confirm') resolve(type)
|
|
37
|
-
})
|
|
38
|
-
},
|
|
39
3
|
// 全局路由跳
|
|
40
4
|
routerTo(route) {
|
|
41
5
|
let { name, params, query } = {}
|
|
@@ -45,8 +9,11 @@ const mixin = {
|
|
|
45
9
|
params = route.params
|
|
46
10
|
query = route.query
|
|
47
11
|
}
|
|
48
|
-
if (name.
|
|
49
|
-
window.open(name
|
|
12
|
+
if (String(name).startsWith('http')) {
|
|
13
|
+
window.open(name)
|
|
14
|
+
return
|
|
15
|
+
} else if (String(name).startsWith('href:')) {
|
|
16
|
+
window.open(String(name).replace('href:', ''))
|
|
50
17
|
return
|
|
51
18
|
}
|
|
52
19
|
try {
|
|
@@ -56,24 +23,13 @@ const mixin = {
|
|
|
56
23
|
}
|
|
57
24
|
},
|
|
58
25
|
// 全局路由返回上一页
|
|
59
|
-
|
|
60
|
-
this.$router.back()
|
|
26
|
+
routerBack() {
|
|
27
|
+
return this.$router.back()
|
|
61
28
|
},
|
|
62
29
|
// 全局判断是否有子节点
|
|
63
30
|
hasChildren(item, name = 'children') {
|
|
64
31
|
return item && item[name] && Array.isArray(item[name]) && item[name].length > 0
|
|
65
32
|
},
|
|
66
|
-
// 全局格式化名称
|
|
67
|
-
formatTitle(item) {
|
|
68
|
-
let { title, __titleIsFunction__ } = item.meta || {}
|
|
69
|
-
if (!title) return false
|
|
70
|
-
if (this.$config.useI18n) {
|
|
71
|
-
if (title.includes('{{') && title.includes('}}')) title = title.replace(/({{[\s\S]+?}})/, (m, str) => str.replace(/{{([\s\S]*)}}/, (m, _) => this.$t(_.trim())))
|
|
72
|
-
else if (__titleIsFunction__) title = item.meta.title
|
|
73
|
-
else title = this.$t(item.name)
|
|
74
|
-
} else title = (item.meta && item.meta.title) || item.name
|
|
75
|
-
return title
|
|
76
|
-
},
|
|
77
33
|
// 配置继承方法
|
|
78
34
|
getExtendConfig(config = {}, name, module) {
|
|
79
35
|
let moduleConfig = config[module] || config.default || {}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script>
|
|
2
|
+
import { defineComponent, computed, getCurrentInstance } from 'vue'
|
|
3
|
+
import dataProps from '../js/data-props'
|
|
4
|
+
export default defineComponent({
|
|
5
|
+
name: 'ShImage',
|
|
6
|
+
props: dataProps,
|
|
7
|
+
emits: ['rendered', 'error'],
|
|
8
|
+
setup(props, context) {
|
|
9
|
+
const { proxy } = getCurrentInstance()
|
|
10
|
+
return {}
|
|
11
|
+
}
|
|
12
|
+
})
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<template>
|
|
16
|
+
<vxe-image ref="rootRef" :src="src" v-bind="options"></vxe-image>
|
|
17
|
+
</template>
|
|
18
|
+
|
|
19
|
+
<style lang="scss" scoped></style>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="sh-preview">
|
|
3
|
-
<component :is="componentName" v-bind="componentProps"
|
|
2
|
+
<div class="sh-preview" :style="styles">
|
|
3
|
+
<component :is="componentName" v-bind="componentProps" @rendered="onRendered" @error="onError" />
|
|
4
4
|
</div>
|
|
5
5
|
</template>
|
|
6
6
|
|
|
@@ -41,6 +41,8 @@ export default defineComponent({
|
|
|
41
41
|
const componentName = computed(() => {
|
|
42
42
|
if (!props.url || !previewType.value) {
|
|
43
43
|
return 'div'
|
|
44
|
+
} else if (['jpg', 'jpeg', 'jpe', 'png', 'gif'].includes(previewType.value)) {
|
|
45
|
+
return defineAsyncComponent(() => import('./components/sh-image.vue'))
|
|
44
46
|
} else if (['word', 'doc', 'docx'].includes(previewType.value)) {
|
|
45
47
|
return defineAsyncComponent(() => import('./components/sh-word.vue'))
|
|
46
48
|
} else if (['excel', 'xlsx'].includes(previewType.value)) {
|
|
@@ -51,19 +53,25 @@ export default defineComponent({
|
|
|
51
53
|
const componentProps = computed(() => {
|
|
52
54
|
let srcPrefix = props.base || ''
|
|
53
55
|
let srcProps = {
|
|
54
|
-
src: srcPrefix + props.url
|
|
55
|
-
frameborder: 0
|
|
56
|
+
src: srcPrefix + props.url
|
|
56
57
|
}
|
|
57
58
|
if (componentName.value === 'iframe') {
|
|
59
|
+
srcProps.frameborder = 0
|
|
60
|
+
srcProps.width = props.width
|
|
61
|
+
srcProps.height = props.height
|
|
58
62
|
srcProps.src += '#scrollbars=0&toolbar=0&statusbar=0'
|
|
59
63
|
}
|
|
60
64
|
return srcProps
|
|
61
65
|
})
|
|
62
|
-
const
|
|
63
|
-
|
|
66
|
+
const styles = computed(() => {
|
|
67
|
+
let resultStyle = {
|
|
64
68
|
width: props.width,
|
|
65
|
-
|
|
69
|
+
maxWidth: '100%'
|
|
66
70
|
}
|
|
71
|
+
if (componentName.value !== 'iframe') {
|
|
72
|
+
resultStyle.height = props.height
|
|
73
|
+
}
|
|
74
|
+
return resultStyle
|
|
67
75
|
})
|
|
68
76
|
|
|
69
77
|
const onRendered = data => {
|
|
@@ -74,9 +82,9 @@ export default defineComponent({
|
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
return {
|
|
85
|
+
styles,
|
|
77
86
|
componentName,
|
|
78
87
|
componentProps,
|
|
79
|
-
componentStyles,
|
|
80
88
|
onRendered,
|
|
81
89
|
onError
|
|
82
90
|
}
|
|
@@ -88,5 +96,6 @@ export default defineComponent({
|
|
|
88
96
|
.sh-preview {
|
|
89
97
|
position: relative;
|
|
90
98
|
overflow: auto;
|
|
99
|
+
max-width: 100%;
|
|
91
100
|
}
|
|
92
101
|
</style>
|
|
@@ -94,6 +94,12 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
|
|
|
94
94
|
.vxe-modal--wrapper{
|
|
95
95
|
width: calc(100%);
|
|
96
96
|
height: calc(100%);
|
|
97
|
+
.vxe-modal--box{
|
|
98
|
+
.vxe-modal--footer{
|
|
99
|
+
border-top: 1px solid var(--border-color);
|
|
100
|
+
padding: 0.6em;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
97
103
|
&.vxe-modal--preview{
|
|
98
104
|
.vxe-modal--box{
|
|
99
105
|
.vxe-modal--content{
|
|
@@ -102,20 +108,18 @@ button:focus, .vxe-button.type--button:not(.is--disabled):focus{
|
|
|
102
108
|
}
|
|
103
109
|
}
|
|
104
110
|
&.type--modal {
|
|
105
|
-
.vxe-modal--
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
border-top: 1px solid var(--border-color);
|
|
110
|
-
padding-top: 0.5rem;
|
|
111
|
-
padding-bottom: 0.5em;
|
|
111
|
+
.vxe-modal--box{
|
|
112
|
+
.vxe-modal--header{
|
|
113
|
+
background-color: var(--primary-weak-color);
|
|
114
|
+
}
|
|
112
115
|
}
|
|
113
116
|
}
|
|
114
117
|
&.type--confirm {
|
|
115
118
|
.vxe-modal--box{
|
|
116
|
-
width:
|
|
119
|
+
width: 340px;
|
|
120
|
+
min-height: 130px;
|
|
121
|
+
max-width: 96%;
|
|
117
122
|
.vxe-modal--body{
|
|
118
|
-
padding: 10px;
|
|
119
123
|
}
|
|
120
124
|
}
|
|
121
125
|
}
|
|
@@ -74,7 +74,40 @@ let uiOptions = {
|
|
|
74
74
|
loading: {
|
|
75
75
|
icon: 'vxe-icon-spinner roll',
|
|
76
76
|
text: '加载中...'
|
|
77
|
-
}
|
|
77
|
+
},
|
|
78
|
+
message: { title: '', className: 'sh-message-box', draggable: false },
|
|
79
|
+
toolbarLeftConfig: [
|
|
80
|
+
{ value: '1', code: 'wss', content: '未送审' },
|
|
81
|
+
{ value: '2', code: 'bth', content: '被退回' },
|
|
82
|
+
{ value: '3', code: 'yss', content: '已送审' },
|
|
83
|
+
{ value: '4', code: 'ygd', content: '已归档' },
|
|
84
|
+
{ value: '5', code: 'qb', content: '全部' },
|
|
85
|
+
{ value: '6', code: 'dsh', content: '待审核' },
|
|
86
|
+
{ value: '7', code: 'ysh', content: '已审核' }
|
|
87
|
+
],
|
|
88
|
+
toolbarRightConfig: [
|
|
89
|
+
{ code: 'add', content: '新增', status: 'primary', icon: 'vxe-icon-add' },
|
|
90
|
+
{ code: 'edit', content: '修改', status: 'warning', icon: 'vxe-icon-edit' },
|
|
91
|
+
{ code: 'delete', content: '删除', status: 'danger', icon: 'vxe-icon-delete' },
|
|
92
|
+
{ code: 'detail', content: '查看', status: '', icon: 'vxe-icon-information' },
|
|
93
|
+
{ code: 'export', content: '导出', status: 'success', icon: 'vxe-icon-download' },
|
|
94
|
+
{ code: 'import', content: '导入', status: 'primary', icon: 'vxe-icon-upload' },
|
|
95
|
+
{ code: 'print', content: '打印', status: 'warning', icon: 'vxe-icon-print' },
|
|
96
|
+
{ code: 'batch-add', content: '批量新增', status: 'primary', icon: 'vxe-icon-add' },
|
|
97
|
+
{ code: 'batch-edit', content: '批量修改', status: 'warning', icon: 'vxe-icon-edit' },
|
|
98
|
+
{ code: 'batch-delete', content: '批量删除', status: 'danger', icon: 'vxe-icon-delete' },
|
|
99
|
+
{ code: 'batch-detail', content: '查看', status: '', icon: 'vxe-icon-information' },
|
|
100
|
+
{ code: 'audit-push', content: '送审', status: 'success', icon: '' },
|
|
101
|
+
{ code: 'audit-withdraw', content: '撤销', status: 'danger', icon: '' },
|
|
102
|
+
{ code: 'audit-back', content: '退回', status: 'warning', icon: '' },
|
|
103
|
+
{ code: 'audit-back-insert', content: '退回到录入', status: 'warning', icon: '' },
|
|
104
|
+
{ code: 'audit-pass', content: '审核', status: 'success', icon: '' },
|
|
105
|
+
{ code: 'batch-audit-push', content: '批量送审', status: 'success', icon: '' },
|
|
106
|
+
{ code: 'batch-audit-withdraw', content: '批量撤销', status: 'danger', icon: '' },
|
|
107
|
+
{ code: 'batch-audit-back', content: '批量退回', status: 'warning', icon: '' },
|
|
108
|
+
{ code: 'batch-audit-back-insert', content: '批量退回到录入', status: 'warning', icon: '' },
|
|
109
|
+
{ code: 'batch-audit-pass', content: '批量审核', status: 'success', icon: '' }
|
|
110
|
+
]
|
|
78
111
|
}
|
|
79
112
|
|
|
80
113
|
let tableOptions = {
|
|
@@ -250,6 +283,30 @@ VXETable.renderer.mixin(publicRenders)
|
|
|
250
283
|
VXETable.renderer.mixin(extraRenders)
|
|
251
284
|
VXETable.renderer.mixin(filterRenders)
|
|
252
285
|
|
|
286
|
+
// 便捷化全局提示
|
|
287
|
+
const statusList = ['info', 'success', 'warning', 'error']
|
|
288
|
+
const vModal = VXEUI.modal
|
|
289
|
+
let vMessage = {
|
|
290
|
+
confirm: options => {
|
|
291
|
+
return new Promise(async resolve => {
|
|
292
|
+
let opts = Object.assign({}, uiOptions.message, typeof options === 'string' ? { content: options } : options)
|
|
293
|
+
let type = await vModal.confirm({ showHeader: Boolean(opts.title), ...opts })
|
|
294
|
+
if (type === 'confirm') resolve(type)
|
|
295
|
+
})
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
let vNotice = {}
|
|
299
|
+
statusList.forEach(status => {
|
|
300
|
+
vMessage[status] = options => {
|
|
301
|
+
let opts = Object.assign({ status }, uiOptions.message, typeof options === 'string' ? { content: options } : options)
|
|
302
|
+
return vModal.message(opts)
|
|
303
|
+
}
|
|
304
|
+
vNotice[status] = options => {
|
|
305
|
+
let opts = Object.assign({ status }, uiOptions.message, typeof options === 'string' ? { content: options } : options)
|
|
306
|
+
return vModal.notification(opts)
|
|
307
|
+
}
|
|
308
|
+
})
|
|
309
|
+
|
|
253
310
|
const index = {
|
|
254
311
|
install(Vue, { uiOption, tableOption, pdfOption, xlsxOption, menuOption, editorOption }) {
|
|
255
312
|
let vuiOption = utils.merge(uiOptions, uiOption)
|
|
@@ -268,7 +325,9 @@ const index = {
|
|
|
268
325
|
Vue.use(VXETable)
|
|
269
326
|
|
|
270
327
|
Vue.config.globalProperties.$vUtils = utils
|
|
271
|
-
Vue.config.globalProperties.$vModal =
|
|
328
|
+
Vue.config.globalProperties.$vModal = vModal
|
|
329
|
+
Vue.config.globalProperties.$vMessage = vMessage
|
|
330
|
+
Vue.config.globalProperties.$vNotice = vNotice
|
|
272
331
|
Vue.config.globalProperties.$vUi = VXEUI
|
|
273
332
|
Vue.config.globalProperties.$vTable = VXETable
|
|
274
333
|
Vue.config.globalProperties.$vUiSetup = vuiOption
|
|
@@ -3,8 +3,7 @@
|
|
|
3
3
|
<template v-for="renderBtn in renderBtns" :key="renderBtn.code">
|
|
4
4
|
<vxe-button
|
|
5
5
|
v-if="isBtnRender(renderBtn)"
|
|
6
|
-
|
|
7
|
-
:type="rprops.type"
|
|
6
|
+
:mode="rprops.type"
|
|
8
7
|
:size="rsize"
|
|
9
8
|
:icon="getBtnContent(renderBtn).icon"
|
|
10
9
|
:status="getBtnContent(renderBtn).status"
|
|
@@ -47,7 +46,7 @@ export default defineComponent({
|
|
|
47
46
|
const isBtnRender = renderBtn => {
|
|
48
47
|
if ($vUtils.has(renderBtn, 'condition')) {
|
|
49
48
|
let condition = $vUtils.get(renderBtn, 'condition')
|
|
50
|
-
return $vUtils.calculate(condition,
|
|
49
|
+
return $vUtils.calculate(condition, useCell.rdata.value)
|
|
51
50
|
}
|
|
52
51
|
return true
|
|
53
52
|
}
|
|
@@ -6,7 +6,15 @@
|
|
|
6
6
|
<span v-else @click="vxeInputPrefixClick">{{ rprops.prefixText }}</span>
|
|
7
7
|
</span>
|
|
8
8
|
<span v-else-if="controlButton" class="control-btn before" @click="vxeControlClick(false)">-</span>
|
|
9
|
-
<
|
|
9
|
+
<component
|
|
10
|
+
:is="inputComponent"
|
|
11
|
+
v-model="renderValue"
|
|
12
|
+
v-bind="rprops"
|
|
13
|
+
:size="rsize"
|
|
14
|
+
:immediate="false"
|
|
15
|
+
@change="vxeInputChange"
|
|
16
|
+
@blur="vxeBlurCallback"
|
|
17
|
+
@clear="vxeClearCallback"></component>
|
|
10
18
|
<span v-if="rprops.suffixText && rform" class="suffix">
|
|
11
19
|
<vxe-button v-if="suffixButton" v-bind="psButtonConfig" @click="vxeInputSuffixClick">{{ rprops.suffixText }}</vxe-button>
|
|
12
20
|
<span v-else @click="vxeInputSuffixClick">{{ rprops.suffixText }}</span>
|
|
@@ -33,7 +41,14 @@ export default defineComponent({
|
|
|
33
41
|
const { $vUtils } = proxy
|
|
34
42
|
const useCell = cellHooks(props, context, proxy)
|
|
35
43
|
|
|
36
|
-
const
|
|
44
|
+
const isNumberInput = computed(() => ['number', 'float', 'integer'].includes(useCell.rprops.value.type))
|
|
45
|
+
const inputComponent = computed(() => {
|
|
46
|
+
if (isNumberInput.value) {
|
|
47
|
+
return 'vxe-number-input'
|
|
48
|
+
}
|
|
49
|
+
return 'vxe-input'
|
|
50
|
+
})
|
|
51
|
+
const controlButton = computed(() => useCell.rprops.value.control && isNumberInput.value)
|
|
37
52
|
|
|
38
53
|
// 输入框数字加减控制
|
|
39
54
|
const vxeControlClick = bol => {
|
|
@@ -45,6 +60,8 @@ export default defineComponent({
|
|
|
45
60
|
|
|
46
61
|
return {
|
|
47
62
|
...useCell,
|
|
63
|
+
isNumberInput,
|
|
64
|
+
inputComponent,
|
|
48
65
|
controlButton,
|
|
49
66
|
vxeControlClick
|
|
50
67
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<span class="vxe-render--inner" :class="{ 'form-render': rform, 'td-render': !rform, 'td-all': rprops.bill }">
|
|
3
3
|
<template v-if="redit || isEditAll">
|
|
4
|
-
<vxe-number-input v-model="renderText" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @
|
|
4
|
+
<vxe-number-input v-model="renderText" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @blur="vxeMoneyBlur" @clear="vxeMoneyClear" />
|
|
5
5
|
</template>
|
|
6
6
|
<template v-else-if="rprops.bill">
|
|
7
7
|
<template v-for="(bil, bilindex) in billGroups" :key="bilindex">
|
|
@@ -34,15 +34,23 @@ export default defineComponent({
|
|
|
34
34
|
return cellValue
|
|
35
35
|
})
|
|
36
36
|
|
|
37
|
-
const
|
|
37
|
+
const vxeMoneyBlur = async ({ value, $event }) => {
|
|
38
38
|
let cellValue = $vUtils.multiply(value, useCell.rprops.value.moneyUnit || 1)
|
|
39
39
|
useCell.setRenderValue(cellValue)
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
+
const vxeMoneyClear = async ({ value, $event }) => {
|
|
43
|
+
let cellValue = $vUtils.multiply(value, useCell.rprops.value.moneyUnit || 1)
|
|
44
|
+
setTimeout(() => {
|
|
45
|
+
useCell.setRenderValue(cellValue)
|
|
46
|
+
}, 50)
|
|
47
|
+
}
|
|
48
|
+
|
|
42
49
|
return {
|
|
43
50
|
...useCell,
|
|
44
51
|
cellFormatValue,
|
|
45
|
-
|
|
52
|
+
vxeMoneyBlur,
|
|
53
|
+
vxeMoneyClear
|
|
46
54
|
}
|
|
47
55
|
}
|
|
48
56
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<template v-if="redit || isEditAll">
|
|
3
|
-
<vxe-input v-model="renderValue" type="number" v-bind="rprops" :size="rsize" @change="vxeInputChange" @
|
|
3
|
+
<vxe-input v-model="renderValue" type="number" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @blur="vxeBlurCallback" @clear="vxeClearCallback" />
|
|
4
4
|
</template>
|
|
5
5
|
<template v-else>
|
|
6
6
|
<sh-progress :percent="renderText" v-bind="rprops" />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<template v-if="redit || isEditAll">
|
|
3
|
-
<vxe-textarea v-model="renderValue" v-bind="rprops" :size="rsize" @change="vxeInputChange" @
|
|
3
|
+
<vxe-textarea v-model="renderValue" v-bind="rprops" :size="rsize" :immediate="false" @change="vxeInputChange" @blur="vxeBlurCallback" @clear="vxeClearCallback" />
|
|
4
4
|
</template>
|
|
5
5
|
<template v-else>
|
|
6
6
|
<span>{{ renderText }}</span>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<template v-if="redit || isEditAll">
|
|
3
|
-
<sh-date v-model="renderValue" v-bind="rprops" :size="rsize" :disabled-method="vxeDisabledMethod" @
|
|
3
|
+
<sh-date v-model="renderValue" v-bind="rprops" :size="rsize" :disabled-method="vxeDisabledMethod" @change="vxeChangeCallBack" @clear="vxeChangeCallBack"></sh-date>
|
|
4
4
|
</template>
|
|
5
5
|
<template v-else>
|
|
6
6
|
<span v-html="renderText"></span>
|
|
@@ -34,7 +34,7 @@ import vxeFilterComplex from './filters/vxe-filter-complex.vue'
|
|
|
34
34
|
// 全局渲染器
|
|
35
35
|
const publicRenders = {
|
|
36
36
|
$vInput: {
|
|
37
|
-
autofocus: '.
|
|
37
|
+
autofocus: '.vxe-input--inner, .vxe-number-input--input',
|
|
38
38
|
autoselect: true,
|
|
39
39
|
renderCell(renderOpts, params) {
|
|
40
40
|
return [<vxeRenderInput rparams={params} roptions={renderOpts} />]
|
|
@@ -50,7 +50,7 @@ const publicRenders = {
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
$vTextArea: {
|
|
53
|
-
autofocus: '.
|
|
53
|
+
autofocus: '.vxe-textarea--inner',
|
|
54
54
|
autoselect: true,
|
|
55
55
|
renderCell(renderOpts, params) {
|
|
56
56
|
return [<vxeRenderTextarea rparams={params} roptions={renderOpts} />]
|
|
@@ -63,7 +63,7 @@ const publicRenders = {
|
|
|
63
63
|
}
|
|
64
64
|
},
|
|
65
65
|
$vSelect: {
|
|
66
|
-
autofocus: '.
|
|
66
|
+
autofocus: '.vxe-input--inner',
|
|
67
67
|
autoselect: true,
|
|
68
68
|
renderCell(renderOpts, params) {
|
|
69
69
|
return [<vxeRenderSelect rparams={params} roptions={renderOpts} />]
|
|
@@ -76,7 +76,7 @@ const publicRenders = {
|
|
|
76
76
|
}
|
|
77
77
|
},
|
|
78
78
|
$vTree: {
|
|
79
|
-
autofocus: '.
|
|
79
|
+
autofocus: '.vxe-input--inner',
|
|
80
80
|
autoselect: true,
|
|
81
81
|
renderCell(renderOpts, params) {
|
|
82
82
|
return [<vxeRenderTree rparams={params} roptions={renderOpts} />]
|
|
@@ -89,7 +89,7 @@ const publicRenders = {
|
|
|
89
89
|
}
|
|
90
90
|
},
|
|
91
91
|
$vTime: {
|
|
92
|
-
autofocus: '.
|
|
92
|
+
autofocus: '.vxe-date-picker--inner',
|
|
93
93
|
autoselect: true,
|
|
94
94
|
renderCell(renderOpts, params) {
|
|
95
95
|
return [<vxeRenderTime rparams={params} roptions={renderOpts} />]
|
|
@@ -102,7 +102,7 @@ const publicRenders = {
|
|
|
102
102
|
}
|
|
103
103
|
},
|
|
104
104
|
$vProgress: {
|
|
105
|
-
autofocus: '.
|
|
105
|
+
autofocus: '.vxe-input--inner',
|
|
106
106
|
autoselect: true,
|
|
107
107
|
renderCell(renderOpts, params) {
|
|
108
108
|
return [<vxeRenderProgress rparams={params} roptions={renderOpts} />]
|
|
@@ -130,7 +130,7 @@ const publicRenders = {
|
|
|
130
130
|
}
|
|
131
131
|
},
|
|
132
132
|
$vMoney: {
|
|
133
|
-
autofocus: '.
|
|
133
|
+
autofocus: '.vxe-number-input--input',
|
|
134
134
|
autoselect: true,
|
|
135
135
|
renderCell(renderOpts, params) {
|
|
136
136
|
return [<vxeRenderMoney rparams={params} roptions={renderOpts} />]
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { computed, ref, watch } from 'vue'
|
|
1
|
+
import { computed, ref, watch, nextTick } from 'vue'
|
|
2
2
|
|
|
3
3
|
export default function (props, context, proxy) {
|
|
4
4
|
const { $vUtils, $vTableSetup } = proxy
|
|
@@ -73,6 +73,12 @@ export default function (props, context, proxy) {
|
|
|
73
73
|
const vxeBlurCallback = async ({ value, $event }) => {
|
|
74
74
|
setRenderValue(value)
|
|
75
75
|
}
|
|
76
|
+
// 输入框失去焦点回调
|
|
77
|
+
const vxeClearCallback = async ({ value, $event }) => {
|
|
78
|
+
setTimeout(() => {
|
|
79
|
+
setRenderValue(value)
|
|
80
|
+
}, 50)
|
|
81
|
+
}
|
|
76
82
|
// 回调赋值
|
|
77
83
|
const setRenderValue = value => {
|
|
78
84
|
let cellValue = !$vUtils.isNone(value) ? value : renderValue.value
|
|
@@ -147,6 +153,7 @@ export default function (props, context, proxy) {
|
|
|
147
153
|
vxeRadioCallBack,
|
|
148
154
|
vxeCheckCallBack,
|
|
149
155
|
vxeBlurCallback,
|
|
156
|
+
vxeClearCallback,
|
|
150
157
|
getBillClass,
|
|
151
158
|
getBillValue,
|
|
152
159
|
setRenderValue
|