n20-common-lib 1.2.7 → 1.2.8
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 +1 -1
- package/src/components/FileExportAsync/index.vue +174 -0
- package/src/components/Layout/AsideNav/index.vue +55 -134
- package/src/components/Layout/AsideNav/menuItem.vue +34 -0
- package/src/components/Layout/AsideNav/submenuTitle.vue +26 -0
- package/src/directives/VTitle/index.js +8 -0
- package/src/index.js +8 -1
package/package.json
CHANGED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div style="display: none">
|
|
3
|
+
<el-dialog
|
|
4
|
+
v-drag
|
|
5
|
+
:visible.sync="pgsV"
|
|
6
|
+
title="文件导出"
|
|
7
|
+
width="432px"
|
|
8
|
+
top="calc(50vh - 92px)"
|
|
9
|
+
append-to-body
|
|
10
|
+
:close-on-click-modal="false"
|
|
11
|
+
:close-on-press-escape="false"
|
|
12
|
+
:before-close="exportCancel"
|
|
13
|
+
>
|
|
14
|
+
<div class="flex-box m-b">
|
|
15
|
+
<span class="m-r">导出文件</span>
|
|
16
|
+
<span class="flex-item">{{ fileName }}</span>
|
|
17
|
+
</div>
|
|
18
|
+
<div class="flex-box m-b">
|
|
19
|
+
<span class="m-r">导出进度</span>
|
|
20
|
+
<el-progress
|
|
21
|
+
class="flex-item"
|
|
22
|
+
:percentage="pgsVal"
|
|
23
|
+
:status="pgsStatus"
|
|
24
|
+
style="margin-right: -10px"
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
27
|
+
<span slot="footer">
|
|
28
|
+
<el-button plain @click="exportCancel">取消</el-button>
|
|
29
|
+
</span>
|
|
30
|
+
</el-dialog>
|
|
31
|
+
</div>
|
|
32
|
+
</template>
|
|
33
|
+
|
|
34
|
+
<script>
|
|
35
|
+
import downloadBlob from '../../utils/downloadBlob'
|
|
36
|
+
export default {
|
|
37
|
+
name: 'FileExportAsync',
|
|
38
|
+
props: {
|
|
39
|
+
fileName: {
|
|
40
|
+
type: String,
|
|
41
|
+
default: undefined
|
|
42
|
+
},
|
|
43
|
+
stepTime: {
|
|
44
|
+
type: Number,
|
|
45
|
+
default: 1000
|
|
46
|
+
},
|
|
47
|
+
waitTime: {
|
|
48
|
+
type: Number,
|
|
49
|
+
default: 10000
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
data() {
|
|
53
|
+
return {
|
|
54
|
+
pgsV: false,
|
|
55
|
+
pgsVal: 0,
|
|
56
|
+
status: undefined, //init progress success error
|
|
57
|
+
timer: undefined,
|
|
58
|
+
elapsedTimeout: 0,
|
|
59
|
+
waitPopV: false
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
computed: {
|
|
63
|
+
pgsStatus() {
|
|
64
|
+
if (this.status === 'error') {
|
|
65
|
+
return 'exception'
|
|
66
|
+
} else {
|
|
67
|
+
return undefined
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
methods: {
|
|
72
|
+
export() {
|
|
73
|
+
this.pgsVal = 0
|
|
74
|
+
this.status = 'init'
|
|
75
|
+
clearTimeout(this.timer)
|
|
76
|
+
this.elapsedTimeout = 0
|
|
77
|
+
this.waitPopV = false
|
|
78
|
+
|
|
79
|
+
this.pgsV = true
|
|
80
|
+
this.exportReq()
|
|
81
|
+
},
|
|
82
|
+
// 导出请求
|
|
83
|
+
exportReq() {
|
|
84
|
+
this.status = 'progress'
|
|
85
|
+
|
|
86
|
+
this.$emit('export-req', this.exportPgs)
|
|
87
|
+
},
|
|
88
|
+
// 导出进度
|
|
89
|
+
exportPgs() {
|
|
90
|
+
if (this.status !== 'progress') return
|
|
91
|
+
|
|
92
|
+
this.$emit('export-pgs', (pgs, error) => {
|
|
93
|
+
if (error) {
|
|
94
|
+
this.status = 'error'
|
|
95
|
+
console.error('导出失败')
|
|
96
|
+
return
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (pgs < 100) {
|
|
100
|
+
this.pgsVal = parseInt(pgs)
|
|
101
|
+
this.status = 'progress'
|
|
102
|
+
|
|
103
|
+
clearTimeout(this.timer)
|
|
104
|
+
this.timer = setTimeout(() => {
|
|
105
|
+
this.elapsedTimeout = this.elapsedTimeout + this.stepTime
|
|
106
|
+
this.exportPgs()
|
|
107
|
+
}, this.stepTime)
|
|
108
|
+
} else {
|
|
109
|
+
this.pgsVal = parseInt(pgs)
|
|
110
|
+
this.status = 'success'
|
|
111
|
+
|
|
112
|
+
this.exportRes()
|
|
113
|
+
}
|
|
114
|
+
this.waitPop()
|
|
115
|
+
})
|
|
116
|
+
},
|
|
117
|
+
// 导出响应
|
|
118
|
+
exportRes() {
|
|
119
|
+
this.$emit('export-res', (data, error) => {
|
|
120
|
+
if (error) {
|
|
121
|
+
this.status = 'error'
|
|
122
|
+
console.error('导出失败')
|
|
123
|
+
return
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this.status = 'success'
|
|
127
|
+
this.pgsVal = 100
|
|
128
|
+
|
|
129
|
+
downloadBlob(data, this.fileName)
|
|
130
|
+
this.pgsV = false
|
|
131
|
+
})
|
|
132
|
+
},
|
|
133
|
+
// 导出取消
|
|
134
|
+
exportCancel() {
|
|
135
|
+
if (this.status === 'error') {
|
|
136
|
+
this.pgsV = false
|
|
137
|
+
return
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
this.$msgboxPor({
|
|
141
|
+
title: '确定取消',
|
|
142
|
+
message: '取消后,数据导出将中断,是否确定取消导出?',
|
|
143
|
+
type: 'warning',
|
|
144
|
+
customClass: 'question',
|
|
145
|
+
confirmButtonText: '确定',
|
|
146
|
+
cancelButtonText: '取消'
|
|
147
|
+
}).then(() => {
|
|
148
|
+
clearTimeout(this.timer)
|
|
149
|
+
this.pgsV = false
|
|
150
|
+
this.$emit('export-cancel')
|
|
151
|
+
})
|
|
152
|
+
},
|
|
153
|
+
// 时间太长提示
|
|
154
|
+
waitPop() {
|
|
155
|
+
if (!this.waitPopV && this.elapsedTimeout > this.waitTime) {
|
|
156
|
+
this.waitPopV = true
|
|
157
|
+
|
|
158
|
+
this.$msgboxPor({
|
|
159
|
+
title: '提示',
|
|
160
|
+
message: '您的数据导出时间可能会比较长,是否继续导出?',
|
|
161
|
+
type: 'warning',
|
|
162
|
+
customClass: 'question',
|
|
163
|
+
confirmButtonText: '继续导出',
|
|
164
|
+
cancelButtonText: '取消'
|
|
165
|
+
}).catch(() => {
|
|
166
|
+
clearTimeout(this.timer)
|
|
167
|
+
this.pgsV = false
|
|
168
|
+
this.$emit('export-cancel')
|
|
169
|
+
})
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
</script>
|
|
@@ -1,143 +1,65 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<el-menu
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
class="layout-aside flex-column"
|
|
4
|
+
:collapse="collapse"
|
|
5
|
+
:default-active="activeNav"
|
|
6
|
+
background-color="#3d4b6a"
|
|
7
|
+
text-color="#fefefea6"
|
|
8
|
+
active-text-color="#ffffff"
|
|
9
9
|
>
|
|
10
10
|
<template v-for="omenus in menus">
|
|
11
|
-
<template v-for="
|
|
11
|
+
<template v-for="itemA in omenus.menu">
|
|
12
12
|
<!-- 一级菜单 -->
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
<i
|
|
20
|
-
v-if="item.iconUrl"
|
|
21
|
-
class="el-icon- icon-url"
|
|
22
|
-
:style="{ backgroundImage: `url(${item.iconUrl})` }"
|
|
23
|
-
></i>
|
|
24
|
-
<i v-else :class="item.iconClass"></i>
|
|
25
|
-
<span v-if="!item.href" slot="title">{{ item | titleF }}</span>
|
|
26
|
-
<a
|
|
27
|
-
v-else
|
|
28
|
-
slot="title"
|
|
29
|
-
:href="item.href"
|
|
30
|
-
target="_blank"
|
|
31
|
-
:rel="/^\//.test(item.href) ? 'opener' : undefined"
|
|
32
|
-
>{{ item | titleF }}</a
|
|
33
|
-
>
|
|
34
|
-
</el-menu-item>
|
|
13
|
+
<MenuItem
|
|
14
|
+
v-if="!itemA.children"
|
|
15
|
+
:key="itemA.title"
|
|
16
|
+
:item="itemA"
|
|
17
|
+
@click="linkFn"
|
|
18
|
+
/>
|
|
35
19
|
<el-submenu
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
20
|
+
v-else
|
|
21
|
+
:key="itemA.title"
|
|
22
|
+
:index="itemA.title"
|
|
23
|
+
popper-class="nav-menu-pop"
|
|
40
24
|
>
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
v-if="item.iconUrl"
|
|
44
|
-
class="el-icon- icon-url"
|
|
45
|
-
:style="{ backgroundImage: `url(${item.iconUrl})` }"
|
|
46
|
-
></i>
|
|
47
|
-
<i v-else :class="item.iconClass"></i>
|
|
48
|
-
<span>{{ item | titleF }}</span>
|
|
49
|
-
</template>
|
|
50
|
-
<template v-for="itemc in item.children">
|
|
25
|
+
<SubmenuTitle slot="title" :item="itemA" />
|
|
26
|
+
<template v-for="itemB in itemA.children">
|
|
51
27
|
<!-- 二级菜单 -->
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
<i
|
|
59
|
-
v-if="itemc.iconUrl"
|
|
60
|
-
class="el-icon- icon-url"
|
|
61
|
-
:style="{ backgroundImage: `url(${itemc.iconUrl})` }"
|
|
62
|
-
></i>
|
|
63
|
-
<i v-else :class="itemc.iconClass"></i>
|
|
64
|
-
<span slot="title">{{ itemc | titleF }}</span>
|
|
65
|
-
</el-menu-item>
|
|
28
|
+
<MenuItem
|
|
29
|
+
v-if="!itemB.children"
|
|
30
|
+
:key="itemB.title"
|
|
31
|
+
:item="itemB"
|
|
32
|
+
@click="linkFn"
|
|
33
|
+
/>
|
|
66
34
|
<el-submenu
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
35
|
+
v-else
|
|
36
|
+
:key="itemB.title"
|
|
37
|
+
:index="itemB.title"
|
|
38
|
+
popper-class="nav-menu-pop"
|
|
71
39
|
>
|
|
72
|
-
<
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
<template v-for="itemcc in itemc.children">
|
|
82
|
-
<!-- 三级菜单
|
|
83
|
-
<el-menu-item
|
|
84
|
-
:key="itemcc.title"
|
|
85
|
-
:index="itemcc.uuid"
|
|
86
|
-
@click="linkFn(itemcc)"
|
|
87
|
-
>
|
|
88
|
-
<i
|
|
89
|
-
v-if="itemcc.iconUrl"
|
|
90
|
-
class="el-icon- icon-url"
|
|
91
|
-
:style="{ backgroundImage: `url(${itemcc.iconUrl})` }"
|
|
92
|
-
></i>
|
|
93
|
-
<i v-else :class="itemcc.iconClass"></i>
|
|
94
|
-
<span slot="title">{{ itemcc | titleF }}</span>
|
|
95
|
-
</el-menu-item> -->
|
|
96
|
-
<!-- 二级菜单 -->
|
|
97
|
-
<el-menu-item
|
|
98
|
-
v-if="!itemc.children"
|
|
99
|
-
:key="itemcc.title"
|
|
100
|
-
:index="itemcc.uuid"
|
|
101
|
-
@click="linkFn(itemcc)"
|
|
102
|
-
>
|
|
103
|
-
<i
|
|
104
|
-
v-if="itemcc.iconUrl"
|
|
105
|
-
class="el-icon- icon-url"
|
|
106
|
-
:style="{ backgroundImage: `url(${itemcc.iconUrl})` }"
|
|
107
|
-
></i>
|
|
108
|
-
<i v-else :class="itemcc.iconClass"></i>
|
|
109
|
-
<span slot="title">{{ itemcc | titleF }}</span>
|
|
110
|
-
</el-menu-item>
|
|
40
|
+
<SubmenuTitle slot="title" :item="itemB" />
|
|
41
|
+
<template v-for="itemC in itemB.children">
|
|
42
|
+
<!-- 三级菜单 -->
|
|
43
|
+
<MenuItem
|
|
44
|
+
v-if="!itemC.children"
|
|
45
|
+
:key="itemC.title"
|
|
46
|
+
:item="itemC"
|
|
47
|
+
@click="linkFn"
|
|
48
|
+
/>
|
|
111
49
|
<el-submenu
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
50
|
+
v-else
|
|
51
|
+
:key="itemC.title"
|
|
52
|
+
:index="itemC.title"
|
|
53
|
+
popper-class="nav-menu-pop"
|
|
116
54
|
>
|
|
117
|
-
<
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
</template>
|
|
126
|
-
<template v-for="itemccc in itemcc.children">
|
|
127
|
-
<!-- 三级菜单 -->
|
|
128
|
-
<el-menu-item
|
|
129
|
-
:key="itemccc.title"
|
|
130
|
-
:index="itemccc.uuid"
|
|
131
|
-
@click="linkFn(itemccc)"
|
|
132
|
-
>
|
|
133
|
-
<i
|
|
134
|
-
v-if="itemccc.iconUrl"
|
|
135
|
-
class="el-icon- icon-url"
|
|
136
|
-
:style="{ backgroundImage: `url(${itemccc.iconUrl})` }"
|
|
137
|
-
></i>
|
|
138
|
-
<i v-else :class="itemccc.iconClass"></i>
|
|
139
|
-
<span slot="title">{{ itemccc | titleF }}</span>
|
|
140
|
-
</el-menu-item>
|
|
55
|
+
<SubmenuTitle slot="title" :item="itemC" />
|
|
56
|
+
<template v-for="itemD in itemC.children">
|
|
57
|
+
<!-- 四级菜单 -->
|
|
58
|
+
<MenuItem
|
|
59
|
+
:key="itemD.title"
|
|
60
|
+
:item="itemD"
|
|
61
|
+
@click="linkFn"
|
|
62
|
+
/>
|
|
141
63
|
</template>
|
|
142
64
|
</el-submenu>
|
|
143
65
|
</template>
|
|
@@ -149,23 +71,22 @@
|
|
|
149
71
|
<span class="flex-item"></span>
|
|
150
72
|
<div class="open-collapsed-btn">
|
|
151
73
|
<span
|
|
152
|
-
|
|
74
|
+
:class="
|
|
153
75
|
collapse
|
|
154
76
|
? 'n20-icon-caidanshouqi f-s-l rotate-icon'
|
|
155
77
|
: 'n20-icon-caidanshouqi f-s-l'
|
|
156
78
|
"
|
|
157
|
-
|
|
79
|
+
@click="setCollapse"
|
|
158
80
|
></span>
|
|
159
81
|
</div>
|
|
160
82
|
</el-menu>
|
|
161
83
|
</template>
|
|
162
84
|
|
|
163
85
|
<script>
|
|
164
|
-
import
|
|
86
|
+
import MenuItem from './menuItem.vue'
|
|
87
|
+
import SubmenuTitle from './submenuTitle.vue'
|
|
165
88
|
export default {
|
|
166
|
-
|
|
167
|
-
titleF: labelF
|
|
168
|
-
},
|
|
89
|
+
components: { MenuItem, SubmenuTitle },
|
|
169
90
|
props: {
|
|
170
91
|
menus: {
|
|
171
92
|
type: Array,
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<el-menu-item :index="item.uuid" @click="$emit('click', item)">
|
|
3
|
+
<i
|
|
4
|
+
v-if="item.iconUrl"
|
|
5
|
+
class="el-icon- icon-url"
|
|
6
|
+
:style="{ backgroundImage: `url(${item.iconUrl})` }"
|
|
7
|
+
></i>
|
|
8
|
+
<i v-else :class="item.iconClass"></i>
|
|
9
|
+
<span v-if="!item.href" slot="title">{{ item | titleF }}</span>
|
|
10
|
+
<a
|
|
11
|
+
v-else
|
|
12
|
+
slot="title"
|
|
13
|
+
:href="item.href"
|
|
14
|
+
target="_blank"
|
|
15
|
+
:rel="/^\//.test(item.href) ? 'opener' : undefined"
|
|
16
|
+
>{{ item | titleF }}</a
|
|
17
|
+
>
|
|
18
|
+
</el-menu-item>
|
|
19
|
+
</template>
|
|
20
|
+
|
|
21
|
+
<script>
|
|
22
|
+
import { labelF } from '../utils'
|
|
23
|
+
export default {
|
|
24
|
+
filters: {
|
|
25
|
+
titleF: labelF
|
|
26
|
+
},
|
|
27
|
+
props: {
|
|
28
|
+
item: {
|
|
29
|
+
type: Object,
|
|
30
|
+
default: () => ({})
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
</script>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<component :is="'slot'">
|
|
3
|
+
<i
|
|
4
|
+
v-if="item.iconUrl"
|
|
5
|
+
class="el-icon- icon-url"
|
|
6
|
+
:style="{ backgroundImage: `url(${item.iconUrl})` }"
|
|
7
|
+
></i>
|
|
8
|
+
<i v-else :class="item.iconClass"></i>
|
|
9
|
+
<span>{{ item | titleF }}</span>
|
|
10
|
+
</component>
|
|
11
|
+
</template>
|
|
12
|
+
|
|
13
|
+
<script>
|
|
14
|
+
import { labelF } from '../utils'
|
|
15
|
+
export default {
|
|
16
|
+
filters: {
|
|
17
|
+
titleF: labelF
|
|
18
|
+
},
|
|
19
|
+
props: {
|
|
20
|
+
item: {
|
|
21
|
+
type: Object,
|
|
22
|
+
default: () => ({})
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
</script>
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import Tooltip from './tooltip.vue'
|
|
2
2
|
|
|
3
|
+
let timer = undefined
|
|
4
|
+
|
|
3
5
|
function tipShow(el, tip) {
|
|
4
6
|
if (el.$tooltipTitle) {
|
|
5
7
|
if (!el.$tooltipTitleOverflow || el.clientWidth < el.scrollWidth) {
|
|
@@ -8,6 +10,12 @@ function tipShow(el, tip) {
|
|
|
8
10
|
tip.$refs['title-pop'].doDestroy()
|
|
9
11
|
tip.$nextTick(() => {
|
|
10
12
|
tip.visible = true
|
|
13
|
+
timer = setInterval(() => {
|
|
14
|
+
if (tip.visible && !el.scrollWidth) {
|
|
15
|
+
tipHide(el, tip)
|
|
16
|
+
clearInterval(timer)
|
|
17
|
+
}
|
|
18
|
+
}, 1000)
|
|
11
19
|
})
|
|
12
20
|
}
|
|
13
21
|
}
|
package/src/index.js
CHANGED
|
@@ -44,6 +44,7 @@ import Anchor from './components/Anchor/index.vue'
|
|
|
44
44
|
import AnchorItem from './components/Anchor/AnchorItem.vue'
|
|
45
45
|
import FlowStep from './components/FlowStep/index.vue'
|
|
46
46
|
import CascaderArea from './components/CascaderArea/index.vue'
|
|
47
|
+
import FileExportAsync from './components/FileExportAsync/index.vue'
|
|
47
48
|
/* old */
|
|
48
49
|
import TableO from './components/Table/indexO.vue'
|
|
49
50
|
import FiltersO from './components/Filters/indexO.vue'
|
|
@@ -59,6 +60,8 @@ import VClickOutside from './directives/VClickOutside/index.js'
|
|
|
59
60
|
import VHas from './directives/VHas/index.js'
|
|
60
61
|
|
|
61
62
|
/** 注入方法 */
|
|
63
|
+
import dayjs from 'dayjs'
|
|
64
|
+
import numerify from 'numerify'
|
|
62
65
|
import axios from './utils/axios.js'
|
|
63
66
|
import auth from './utils/auth.js'
|
|
64
67
|
import { msgPor, msgboxPor } from './utils/msgboxPor.js'
|
|
@@ -121,6 +124,7 @@ const components = [
|
|
|
121
124
|
AnchorItem,
|
|
122
125
|
FlowStep,
|
|
123
126
|
CascaderArea,
|
|
127
|
+
FileExportAsync,
|
|
124
128
|
/* old */
|
|
125
129
|
TableO,
|
|
126
130
|
FiltersO,
|
|
@@ -211,8 +215,11 @@ export {
|
|
|
211
215
|
AnchorItem,
|
|
212
216
|
FlowStep,
|
|
213
217
|
CascaderArea,
|
|
218
|
+
FileExportAsync,
|
|
214
219
|
repairEl,
|
|
215
220
|
linkPush,
|
|
216
221
|
linkGo,
|
|
217
|
-
isHas
|
|
222
|
+
isHas,
|
|
223
|
+
dayjs,
|
|
224
|
+
numerify
|
|
218
225
|
}
|