@bdsoft/element 1.1.0 → 1.1.2
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 +3 -3
- package/src/assets/css/element.scss +101 -84
- package/src/components/countup/countUp.js +2 -2
- package/src/components/countup/index.vue +12 -10
- package/src/components/notice/NoticeList.vue +1 -1
- package/src/components/notice/NoticeListPaging.vue +1 -1
- package/src/components/notice/NoticeView.vue +1 -1
- package/src/components/pagination/index.vue +1 -1
- package/src/components/screenfull/package.json +1 -1
- package/src/index.js +6 -0
- package/src/xm_components/HeadSearch/readme.md +2 -2
- package/src/xm_components/MultiStatisticalCard/image.png +0 -0
- package/src/xm_components/MultiStatisticalCard/index.vue +114 -0
- package/src/xm_components/MultiStatisticalCard/readme.md +29 -0
- package/src/xm_components/StatisticalCard/image.png +0 -0
- package/src/xm_components/StatisticalCard/index.vue +196 -0
- package/src/xm_components/StatisticalCard/readme.md +41 -0
- package/utils/message.js +15 -17
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bdsoft/element",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
"preview": "vite preview"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@element-plus/icons-vue": "^2.3.
|
|
14
|
-
"element-plus": "
|
|
13
|
+
"@element-plus/icons-vue": "^2.3.2",
|
|
14
|
+
"element-plus": "2.13.1",
|
|
15
15
|
"splitpanes": "4.0.4"
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -27,106 +27,123 @@
|
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
// tab样式重写--圆滑风格
|
|
30
|
-
.bdtabs
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
30
|
+
.bdtabs.el-tabs {
|
|
31
|
+
& > .el-tabs__header {
|
|
32
|
+
margin: 0px !important;
|
|
33
|
+
height: 34px !important;
|
|
34
|
+
.el-tabs__nav-wrap {
|
|
35
|
+
margin-bottom: -3px;
|
|
36
|
+
}
|
|
37
|
+
.el-tabs__nav {
|
|
38
|
+
border: 0px !important;
|
|
39
|
+
}
|
|
40
|
+
.el-tabs__item {
|
|
41
|
+
padding: 0 10px;
|
|
42
|
+
height: 30px !important;
|
|
43
|
+
border-style: solid;
|
|
44
|
+
border-color: transparent !important;
|
|
45
|
+
}
|
|
46
|
+
.is-active {
|
|
47
|
+
background: #e5eeff !important;
|
|
48
|
+
z-index: 1;
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
center top;
|
|
60
|
-
-webkit-mask-repeat: no-repeat;
|
|
61
|
-
.el-dropdown span {
|
|
62
|
-
color: #0256ff !important;
|
|
63
|
-
margin-left: 10px;
|
|
50
|
+
-webkit-mask-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzAiIGhlaWdodD0iNzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSI+PHBhdGggZD0iTTEwMC4yMzYgOTkuODgzQzQ1LjAwOCAxMDAuMDEyLjEzMiA1NS4zNDQuMDAzLjExN2wuMjMzIDEwMCAxMDAtLjIzNHoiIG9wYWNpdHk9InVuZGVmaW5lZCIgc3Ryb2tlPSJudWxsIiBmaWxsPSIjRjhFQUU3Ii8+PHBhdGggZD0iTS0uNjM4IDcuMzEyYy4xMiAwIC4yMTguMDU4LjQ3Ny4xMi4yMzIuMDU0LjI3My4wMzQuMzU4LjExOS4wODQuMDg0LjM1NyAwIC40NzYgMGguMzU4TTI4LjkyMSA2OS4wNTJ2LjU5Nk0yOC45MjEgNjguNDU3aC4xMTl2MS43ODhoLS4xMTl6TTM2LjY2OSA1MS4yOTNoMTkuMDd2NC44ODdoLTE5LjA3eiIgc3Ryb2tlPSJudWxsIi8+PC9zdmc+),
|
|
51
|
+
url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNzAiIGhlaWdodD0iNzAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgZmlsbD0ibm9uZSI+PHBhdGggc3Ryb2tlPSJudWxsIiBmaWxsPSIjRjhFQUU3IiBkPSJNNjkuOTU0LjE0Yy0uMjI5IDU1LjIyOC00NS4xODYgOTkuODE0LTEwMC40MTMgOTkuNTg1bDk5Ljk5OS40MTRMNjkuOTU0LjE0eiIgY2xpcC1ydWxlPSJldmVub2RkIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiLz48cGF0aCBkPSJNLS42MzggNy4zMTJjLjEyIDAgLjIxOC4wNTguNDc3LjEyLjIzMi4wNTQuMjczLjAzNC4zNTguMTE5LjA4NC4wODQuMzU3IDAgLjQ3NiAwaC4zNThNMjguOTIxIDY5LjA1MnYuNTk2TTI4LjkyMSA2OC40NTdoLjExOXYxLjc4OGgtLjExOXpNMzYuNjY5IDUxLjI5M2gxOS4wN3Y0Ljg4N2gtMTkuMDd6IiBzdHJva2U9Im51bGwiLz48L3N2Zz4=),
|
|
52
|
+
url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHJ4PSI4IiB3aWR0aD0iMTAwJSIgaGVpZ2h0PSIxMDAlIiBmaWxsPSIjRjhFQUU3Ii8+PC9zdmc+);
|
|
53
|
+
-webkit-mask-size: 18px 30px, 20px 30px, calc(100% - 30px) calc(100% + 17px);
|
|
54
|
+
-webkit-mask-position: right bottom, left bottom, center top;
|
|
55
|
+
-webkit-mask-repeat: no-repeat;
|
|
56
|
+
.el-dropdown span {
|
|
57
|
+
color: #0256ff !important;
|
|
58
|
+
margin-left: 10px;
|
|
59
|
+
}
|
|
64
60
|
}
|
|
65
61
|
}
|
|
66
62
|
}
|
|
67
63
|
// tab样式重写--卡片风格
|
|
68
|
-
.bdtabs2
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
64
|
+
.bdtabs2.el-tabs {
|
|
65
|
+
& > .el-tabs__header {
|
|
66
|
+
margin: 0px !important;
|
|
67
|
+
height: 34px !important;
|
|
68
|
+
.el-tabs__nav-wrap {
|
|
69
|
+
margin-bottom: -3px;
|
|
70
|
+
}
|
|
71
|
+
.el-tabs__nav {
|
|
72
|
+
border: 0px !important;
|
|
73
|
+
}
|
|
74
|
+
.el-tabs__item {
|
|
75
|
+
padding: 0 10px;
|
|
76
|
+
height: 28px !important;
|
|
77
|
+
border: 1px solid #d9d9d9;
|
|
78
|
+
margin-left: 4px;
|
|
79
|
+
margin-top: 2px;
|
|
80
|
+
margin-bottom: 2px;
|
|
81
|
+
// border-color: transparent !important;
|
|
82
|
+
}
|
|
83
|
+
.is-active {
|
|
84
|
+
background: #e5eeff !important;
|
|
85
|
+
z-index: 1;
|
|
89
86
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
.el-dropdown span {
|
|
88
|
+
color: #0256ff !important;
|
|
89
|
+
margin-left: 10px;
|
|
90
|
+
}
|
|
94
91
|
}
|
|
95
92
|
}
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
// tab样式重写--灵动风格
|
|
99
|
-
.bdtabs3
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
96
|
+
.bdtabs3.el-tabs {
|
|
97
|
+
& > .el-tabs__header {
|
|
98
|
+
margin: 0px !important;
|
|
99
|
+
height: 34px !important;
|
|
100
|
+
.el-tabs__nav-wrap {
|
|
101
|
+
margin-bottom: -3px;
|
|
102
|
+
}
|
|
103
|
+
.el-tabs__nav {
|
|
104
|
+
border: 0px !important;
|
|
105
|
+
}
|
|
106
|
+
.el-tabs__item {
|
|
107
|
+
padding: 0 10px;
|
|
108
|
+
height: 28px !important;
|
|
109
|
+
border: 0px solid #d9d9d9;
|
|
110
|
+
// margin-left: 4px;
|
|
111
|
+
// margin-top:2px;
|
|
112
|
+
// margin-bottom:2px;
|
|
113
|
+
// border-color: transparent !important;
|
|
114
|
+
}
|
|
115
|
+
.is-active {
|
|
116
|
+
background: #e5eeff !important;
|
|
117
|
+
z-index: 1;
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
.el-dropdown span {
|
|
120
|
+
color: #0256ff !important;
|
|
121
|
+
margin-left: 10px;
|
|
122
|
+
}
|
|
125
123
|
}
|
|
126
124
|
}
|
|
127
125
|
}
|
|
126
|
+
// tab样式重写--顶部线条风格
|
|
127
|
+
.bdtabs4.el-tabs {
|
|
128
|
+
& > .el-tabs__header {
|
|
129
|
+
border-bottom: 1px solid #e4e7ed !important;
|
|
130
|
+
.el-tabs__nav {
|
|
131
|
+
border-right: 1px solid #fff;
|
|
132
|
+
border-left: 1px solid #fff;
|
|
133
|
+
}
|
|
128
134
|
|
|
129
|
-
|
|
135
|
+
.el-tabs__item {
|
|
136
|
+
border-top: 1px solid #fff;
|
|
137
|
+
border-left: 1px solid #fff;
|
|
138
|
+
border-right: 1px solid #fff;
|
|
139
|
+
}
|
|
140
|
+
.is-active {
|
|
141
|
+
border-top: 2px solid #409eff !important;
|
|
142
|
+
border-left: 1px solid #e4e7ed !important;
|
|
143
|
+
border-right: 1px solid #e4e7ed !important;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
130
147
|
// 分割线样式
|
|
131
148
|
.bddivider > .el-drawer__body > .el-divider--horizontal {
|
|
132
149
|
border-top: 1px solid #e5eeff !important;
|
|
@@ -95,9 +95,9 @@ var CountUp = function (target, startVal, endVal, decimals, duration, options) {
|
|
|
95
95
|
self.printValue = function (value) {
|
|
96
96
|
var result = self.formattingFn(value)
|
|
97
97
|
|
|
98
|
-
if (self.d
|
|
98
|
+
if (self.d?.tagName === 'INPUT') {
|
|
99
99
|
this.d.value = result
|
|
100
|
-
} else if (self.d
|
|
100
|
+
} else if (self.d?.tagName === 'text' || self.d?.tagName === 'tspan') {
|
|
101
101
|
this.d.textContent = result
|
|
102
102
|
} else {
|
|
103
103
|
this.d.innerHTML = result
|
|
@@ -8,12 +8,16 @@
|
|
|
8
8
|
<script setup>
|
|
9
9
|
import { ref, reactive, nextTick, watch, onMounted } from "vue";
|
|
10
10
|
import { CountUp } from './countUp.js'
|
|
11
|
-
|
|
12
11
|
const props = defineProps({
|
|
13
12
|
idName: {
|
|
14
13
|
type: String,
|
|
15
14
|
default: ''
|
|
16
15
|
},
|
|
16
|
+
// 标题显示
|
|
17
|
+
title: {
|
|
18
|
+
type: String,
|
|
19
|
+
default: ''
|
|
20
|
+
},
|
|
17
21
|
startVal: {
|
|
18
22
|
type: Number,
|
|
19
23
|
default: 0
|
|
@@ -28,7 +32,7 @@ const props = defineProps({
|
|
|
28
32
|
},
|
|
29
33
|
color: {
|
|
30
34
|
type: String,
|
|
31
|
-
default: '#
|
|
35
|
+
default: '#3b3a3a' // D9524E
|
|
32
36
|
},
|
|
33
37
|
introText: {
|
|
34
38
|
type: String,
|
|
@@ -51,9 +55,7 @@ const props = defineProps({
|
|
|
51
55
|
default: 500
|
|
52
56
|
}
|
|
53
57
|
})
|
|
54
|
-
const className= ref('')
|
|
55
|
-
// const countUpRef = ref(null)
|
|
56
|
-
// const countUp = new CountUp(countUpRef.value, props.endVal
|
|
58
|
+
const className = ref('')
|
|
57
59
|
|
|
58
60
|
function transformValue (val) {
|
|
59
61
|
let endVal = 0
|
|
@@ -88,7 +90,7 @@ onMounted(() => {
|
|
|
88
90
|
|
|
89
91
|
const res = transformValue(props.endVal)
|
|
90
92
|
const endVal = props.endVal // res.val
|
|
91
|
-
|
|
93
|
+
let idname = props.idName
|
|
92
94
|
demo = new CountUp(props.idName, props.startVal, endVal, props.decimals, props.duration, props.options)
|
|
93
95
|
if (!demo.error) {
|
|
94
96
|
demo.start()
|
|
@@ -100,13 +102,13 @@ onMounted(() => {
|
|
|
100
102
|
</script>
|
|
101
103
|
<template>
|
|
102
104
|
<div>
|
|
103
|
-
<div
|
|
105
|
+
<div v-if="title" style="color: #606266;">{{ title }}</div>
|
|
106
|
+
<div :class="className"
|
|
107
|
+
:style="{ textAlign: 'center', color: color, fontSize: countSize, fontWeight: countWeight, fontFamily: 'PingFang SC' }">
|
|
104
108
|
<span v-cloak :id="idName">{{ startVal }}</span>
|
|
105
109
|
</div>
|
|
106
110
|
<slot name="intro"></slot>
|
|
107
111
|
</div>
|
|
108
112
|
</template>
|
|
109
113
|
|
|
110
|
-
<style lang="scss" scoped>
|
|
111
|
-
|
|
112
|
-
</style>
|
|
114
|
+
<style lang="scss" scoped></style>
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @LastEditTime: 最后更新时间
|
|
7
7
|
-->
|
|
8
8
|
<script setup>
|
|
9
|
-
import { ref, computed, watch, onMounted,
|
|
9
|
+
import { ref, computed, watch, onMounted, nextTick } from 'vue'
|
|
10
10
|
const emits = defineEmits(['liClick'])
|
|
11
11
|
const props = defineProps({
|
|
12
12
|
imgNum: {
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* @LastEditTime: 最后更新时间
|
|
7
7
|
-->
|
|
8
8
|
<script setup>
|
|
9
|
-
import { ref, computed, watch, onMounted
|
|
9
|
+
import { ref, computed, watch, onMounted } from 'vue'
|
|
10
10
|
import { parseTime } from '../../utils/index.js'
|
|
11
11
|
const emits = defineEmits(['liClick', 'liRightClick', 'pageChange', 'titleSearch', 'addNew'])
|
|
12
12
|
const props = defineProps({
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
</div>
|
|
42
42
|
</template>
|
|
43
43
|
<script setup>
|
|
44
|
-
import { defineComponent, ref, reactive, computed, watch, onMounted, inject, nextTick, onBeforeMount, onUnmounted
|
|
44
|
+
import { defineComponent, ref, reactive, computed, watch, onMounted, inject, nextTick, onBeforeMount, onUnmounted } from 'vue'
|
|
45
45
|
const emits = defineEmits([])
|
|
46
46
|
const props = defineProps({
|
|
47
47
|
bdsdk: {
|
package/src/index.js
CHANGED
|
@@ -13,6 +13,10 @@ import BdLayout4 from './components/layout/layout4.vue'
|
|
|
13
13
|
import HeadSearch from './xm_components/HeadSearch/index.vue'
|
|
14
14
|
// 里程碑组件
|
|
15
15
|
import Milestone from './xm_components/Milestone/index.vue'
|
|
16
|
+
// 多维数据统计组件
|
|
17
|
+
import StatisticalCard from './xm_components/StatisticalCard/index.vue'
|
|
18
|
+
// 多数据指标统计
|
|
19
|
+
import MultiStatisticalCard from './xm_components/MultiStatisticalCard/index.vue'
|
|
16
20
|
import BDCarousel from './components/carousel/index.vue'
|
|
17
21
|
import BdFormItem from './components/form/FormItem.vue'
|
|
18
22
|
import BdForm from './components/form/Form.vue'
|
|
@@ -65,6 +69,8 @@ export {
|
|
|
65
69
|
BdLayout4,
|
|
66
70
|
HeadSearch,
|
|
67
71
|
Milestone,
|
|
72
|
+
StatisticalCard,
|
|
73
|
+
MultiStatisticalCard,
|
|
68
74
|
BdEmpty,
|
|
69
75
|
BdInvalid,
|
|
70
76
|
BDCarousel,
|
|
Binary file
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* @FileDescription: 核心指标统计组件
|
|
3
|
+
* @Author: 李兵泉
|
|
4
|
+
* @Date: 2025-11-26
|
|
5
|
+
* @LastEditors: 最后更新作者
|
|
6
|
+
* @LastEditTime: 最后更新时间
|
|
7
|
+
-->
|
|
8
|
+
<template>
|
|
9
|
+
<el-row :gutter="0" class="basicwarp" :style="{ height: height }">
|
|
10
|
+
<!-- 动态渲染指标项 valueColor-->
|
|
11
|
+
<el-col
|
|
12
|
+
v-for="(item, index) in indicators"
|
|
13
|
+
:key="index"
|
|
14
|
+
@click="handleIndicatorClick(item, index)"
|
|
15
|
+
:md="item.colSize || 4"
|
|
16
|
+
class="text-center mb-4"
|
|
17
|
+
style="cursor: pointer"
|
|
18
|
+
>
|
|
19
|
+
<BdCountUp
|
|
20
|
+
class="infor-intro-num user-created-count"
|
|
21
|
+
:title="item.title"
|
|
22
|
+
:id-name="item.key"
|
|
23
|
+
|
|
24
|
+
:endVal="item.value"
|
|
25
|
+
countSize="30px"
|
|
26
|
+
:color="item.valueColor || ''"
|
|
27
|
+
:countWeight="700"
|
|
28
|
+
@click="handleItemClick(item, index)"
|
|
29
|
+
>
|
|
30
|
+
</BdCountUp>
|
|
31
|
+
</el-col>
|
|
32
|
+
</el-row>
|
|
33
|
+
</template>
|
|
34
|
+
<script setup>
|
|
35
|
+
import { ref, watch, onMounted, onUnmounted, nextTick } from 'vue'
|
|
36
|
+
// import { useTransition } from '@vueuse/core'
|
|
37
|
+
import BdCountUp from '../../components/countup/index.vue'
|
|
38
|
+
|
|
39
|
+
// 定义自定义事件,用于向父组件传递点击信息
|
|
40
|
+
const emit = defineEmits(['indicator-click'])
|
|
41
|
+
// 存储每个指标的过渡值
|
|
42
|
+
const indicatorValues = ref({})
|
|
43
|
+
// 组件props定义
|
|
44
|
+
const props = defineProps({
|
|
45
|
+
height: {
|
|
46
|
+
type: String,
|
|
47
|
+
default: '200px'
|
|
48
|
+
},
|
|
49
|
+
// 指标数据列表
|
|
50
|
+
indicators: {
|
|
51
|
+
type: Array,
|
|
52
|
+
default: () => []
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
const handleItemClick = (item, index) => {
|
|
57
|
+
// 触发自定义事件,传递点击的指标项数据和索引
|
|
58
|
+
if (item.onClick) {
|
|
59
|
+
item.onClick(item, index)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 处理指标项点击事件
|
|
63
|
+
const handleIndicatorClick = (item, index) => {
|
|
64
|
+
// 触发自定义事件,传递点击的指标项数据和索引
|
|
65
|
+
emit('indicator-click', {
|
|
66
|
+
item, // 点击的指标项完整数据
|
|
67
|
+
index // 点击的指标项索引
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
watch(
|
|
72
|
+
() => props.indicators,
|
|
73
|
+
(newIndicators) => {
|
|
74
|
+
if (newIndicators && newIndicators.length > 0) {
|
|
75
|
+
// nextTick(() => {
|
|
76
|
+
// props.indicators.forEach(item => {
|
|
77
|
+
// indicatorValues.value[item.key] = useNumberTransition(ref(0), {
|
|
78
|
+
// duration: item.duration || 1000,
|
|
79
|
+
// })
|
|
80
|
+
// })
|
|
81
|
+
// });
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
immediate: true
|
|
86
|
+
}
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
// 初始化过渡动画
|
|
90
|
+
onMounted(() => {})
|
|
91
|
+
</script>
|
|
92
|
+
|
|
93
|
+
<style lang="scss" scoped>
|
|
94
|
+
.basicwarp {
|
|
95
|
+
display: flex;
|
|
96
|
+
align-items: center;
|
|
97
|
+
height: 100%;
|
|
98
|
+
width: 100%;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
:deep(.el-statistic__head) {
|
|
102
|
+
font-size: 17px;
|
|
103
|
+
text-align: center;
|
|
104
|
+
color: #737070 !important;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
:deep(.el-statistic__content) {
|
|
108
|
+
font-size: 28px;
|
|
109
|
+
text-align: center;
|
|
110
|
+
font-weight: 600;
|
|
111
|
+
color: #737070 !important;
|
|
112
|
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## 多指标显示组件
|
|
2
|
+
|
|
3
|
+
<template>
|
|
4
|
+
<MultiStatisticalCard :indicators="indicators" ></MultiStatisticalCard>
|
|
5
|
+
</template>
|
|
6
|
+
<script setup>
|
|
7
|
+
import { ref, reactive, computed, watch, onMounted } from "vue";
|
|
8
|
+
import { MultiStatisticalCard } from '@bdsoft/element'
|
|
9
|
+
|
|
10
|
+
const indicators = [
|
|
11
|
+
{ key: 'oil_prod_cum', title: '累计油量(t)', valueColor:'red',value: 5656 },
|
|
12
|
+
{ key: 'bncl', title: '本年产量(t)', valueColor:'red',value: 16 },
|
|
13
|
+
{ key: 'sncl', title: '上年产量(t)',valueColor:'red', value: 116 },
|
|
14
|
+
// { key: 'sncl2', title: '上年产量(t)', valueColor:'red',value: 116 },
|
|
15
|
+
{ key: 'zrcl', title: '昨日产量(t)',valueColor:'red', value: 2346 }
|
|
16
|
+
]
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
### 触发点击事件
|
|
20
|
+
|
|
21
|
+
<MultiStatisticalCard :indicators="indicators" @indicator-click="handleClick"></MultiStatisticalCard>
|
|
22
|
+
|
|
23
|
+
<script setup>
|
|
24
|
+
const handleClick = (data) => {
|
|
25
|
+
console.log('点击了指标项:', data.item);
|
|
26
|
+
console.log('指标项索引:', data.index);
|
|
27
|
+
// 处理点击逻辑
|
|
28
|
+
};
|
|
29
|
+
</script>
|
|
Binary file
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
* @FileDescription: 统计组件
|
|
3
|
+
* @Author: 李兵泉
|
|
4
|
+
* @Date: 2025-11-26
|
|
5
|
+
* @LastEditors: 最后更新作者
|
|
6
|
+
* @LastEditTime: 最后更新时间
|
|
7
|
+
-->
|
|
8
|
+
<template>
|
|
9
|
+
<!-- 投资总额卡片容器 -->
|
|
10
|
+
<div
|
|
11
|
+
class="investment-card"
|
|
12
|
+
:style="{ width: width }"
|
|
13
|
+
v-if="_datas && _datas != ''"
|
|
14
|
+
>
|
|
15
|
+
<!-- 循环渲染数据项(空数据则不显示) -->
|
|
16
|
+
<div class="data-item">
|
|
17
|
+
<!-- 标题行(带提示图标) -->
|
|
18
|
+
<div class="title-row">
|
|
19
|
+
<span class="title">{{ _datas[0]?.title }}</span>
|
|
20
|
+
<el-tooltip v-if="tip" :content="tip" placement="top">
|
|
21
|
+
<el-icon size="16px" class="info-icon"><question-filled /></el-icon>
|
|
22
|
+
</el-tooltip>
|
|
23
|
+
</div>
|
|
24
|
+
<!-- 数值行 -->
|
|
25
|
+
<div
|
|
26
|
+
class="value"
|
|
27
|
+
:style="{
|
|
28
|
+
color: _datas[0]?.valueColor || '#000',
|
|
29
|
+
cursor: _datas[0]?.onClick ? 'pointer' : 'default',
|
|
30
|
+
}"
|
|
31
|
+
@click="handleItemClick(_datas[0], 0)"
|
|
32
|
+
>
|
|
33
|
+
{{ _datas[0]?.value }}
|
|
34
|
+
</div>
|
|
35
|
+
</div>
|
|
36
|
+
<div style="display: flex" @click="handleItemClick(_datas[1], 1)">
|
|
37
|
+
<!-- 数组 up2 -->
|
|
38
|
+
<div v-if="_datas[1]" class="extra-row">
|
|
39
|
+
<span class="extra-item">
|
|
40
|
+
{{ _datas[1]?.title }}
|
|
41
|
+
<span :class="['trend', _datas[1]?.trend === 'up' ? 'up' : 'down']">
|
|
42
|
+
{{ _datas[1]?.value }}
|
|
43
|
+
<el-icon class="trend-icon">
|
|
44
|
+
<component
|
|
45
|
+
:is="_datas[1]?.trend === 'up' ? 'caret-top' : 'caret-bottom'"
|
|
46
|
+
/>
|
|
47
|
+
</el-icon>
|
|
48
|
+
</span>
|
|
49
|
+
</span>
|
|
50
|
+
</div>
|
|
51
|
+
<!-- 数组 down3 -->
|
|
52
|
+
<div
|
|
53
|
+
v-if="_datas[2]"
|
|
54
|
+
class="extra-row"
|
|
55
|
+
style="margin-left: 10%"
|
|
56
|
+
@click="handleItemClick(_datas[2], 2)"
|
|
57
|
+
>
|
|
58
|
+
<span class="extra-item">
|
|
59
|
+
{{ _datas[2]?.title }}
|
|
60
|
+
<span :class="['trend', _datas[2]?.trend === 'up' ? 'up' : 'down']">
|
|
61
|
+
{{ _datas[2]?.value }}
|
|
62
|
+
<el-icon class="trend-icon">
|
|
63
|
+
<component
|
|
64
|
+
:is="_datas[2]?.trend === 'up' ? 'caret-top' : 'caret-bottom'"
|
|
65
|
+
/>
|
|
66
|
+
</el-icon>
|
|
67
|
+
</span>
|
|
68
|
+
</span>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
<el-divider style="margin: 10px 0" />
|
|
72
|
+
<div
|
|
73
|
+
v-if="_datas[3]"
|
|
74
|
+
class="extra-row"
|
|
75
|
+
@click="handleItemClick(_datas[3], 3)"
|
|
76
|
+
>
|
|
77
|
+
<span class="extra-item" style="color: #595858">
|
|
78
|
+
{{ _datas[3]?.title }}
|
|
79
|
+
<span class="trend">
|
|
80
|
+
{{ _datas[3]?.value }}
|
|
81
|
+
</span>
|
|
82
|
+
</span>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</template>
|
|
86
|
+
|
|
87
|
+
<script setup>
|
|
88
|
+
import { ref, watch } from "vue";
|
|
89
|
+
|
|
90
|
+
const _datas = ref([]);
|
|
91
|
+
// 接收父组件传入的4组数据(数组,每个对象对应一组数据)
|
|
92
|
+
const props = defineProps({
|
|
93
|
+
// 组件默认宽度
|
|
94
|
+
width: {
|
|
95
|
+
type: String,
|
|
96
|
+
default: "350px",
|
|
97
|
+
},
|
|
98
|
+
// 右上角提示信息
|
|
99
|
+
tip: {
|
|
100
|
+
type: String,
|
|
101
|
+
default: "",
|
|
102
|
+
},
|
|
103
|
+
// 数据列表 格式参考readme
|
|
104
|
+
dataList: {
|
|
105
|
+
type: Array,
|
|
106
|
+
default: () => [],
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
const handleItemClick = (item, index) => {
|
|
110
|
+
// 触发自定义事件,传递点击的指标项数据和索引
|
|
111
|
+
if (item && item.onClick) {
|
|
112
|
+
item.onClick(item, index);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
watch(
|
|
116
|
+
() => props.dataList,
|
|
117
|
+
(newVal) => {
|
|
118
|
+
if (newVal && newVal.length > 0) {
|
|
119
|
+
_datas.value = newVal;
|
|
120
|
+
}
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
immediate: true,
|
|
124
|
+
}
|
|
125
|
+
);
|
|
126
|
+
</script>
|
|
127
|
+
|
|
128
|
+
<style scoped>
|
|
129
|
+
.investment-card {
|
|
130
|
+
background: #fff;
|
|
131
|
+
border-radius: 8px;
|
|
132
|
+
padding: 12px;
|
|
133
|
+
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.data-item {
|
|
137
|
+
margin-bottom: 12px;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.title-row {
|
|
141
|
+
display: flex;
|
|
142
|
+
justify-content: space-between;
|
|
143
|
+
align-items: center;
|
|
144
|
+
margin-bottom: 8px;
|
|
145
|
+
color: #666;
|
|
146
|
+
font-size: 14px;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.info-icon {
|
|
150
|
+
cursor: pointer;
|
|
151
|
+
color: #999;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.value {
|
|
155
|
+
font-size: 28px;
|
|
156
|
+
font-weight: bold;
|
|
157
|
+
margin-bottom: 8px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.extra-row {
|
|
161
|
+
display: flex;
|
|
162
|
+
gap: 16px;
|
|
163
|
+
margin-bottom: 8px;
|
|
164
|
+
font-size: 14px;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.extra-item {
|
|
168
|
+
display: flex;
|
|
169
|
+
align-items: center;
|
|
170
|
+
color: #999;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
.trend {
|
|
174
|
+
margin-left: 4px;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
.trend.up {
|
|
178
|
+
color: #f56c6c;
|
|
179
|
+
/* 红色-上升 */
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.trend.down {
|
|
183
|
+
color: #67c23a;
|
|
184
|
+
/* 绿色-下降 */
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.trend-icon {
|
|
188
|
+
font-size: 12px;
|
|
189
|
+
margin-left: 2px;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.additional {
|
|
193
|
+
font-size: 14px;
|
|
194
|
+
color: #666;
|
|
195
|
+
}
|
|
196
|
+
</style>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
## 统计数组组件
|
|
2
|
+
|
|
3
|
+
```
|
|
4
|
+
|
|
5
|
+
<template>
|
|
6
|
+
<StatisticalCard :dataList="dataList" tip="投资总额说明111"></StatisticalCard>
|
|
7
|
+
</template>
|
|
8
|
+
<script setup>
|
|
9
|
+
import { ref, reactive, computed, watch, onMounted } from "vue";
|
|
10
|
+
import { StatisticalCard } from '@bdsoft/element'
|
|
11
|
+
|
|
12
|
+
const dataList = ref([
|
|
13
|
+
{
|
|
14
|
+
title: '总用户数',
|
|
15
|
+
value: 1024,
|
|
16
|
+
valueColor:'red',
|
|
17
|
+
trend: '',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: '活跃用户数',
|
|
21
|
+
value: 768,
|
|
22
|
+
valueColor:'',
|
|
23
|
+
trend: 'up',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
title: '新增用户数',
|
|
27
|
+
value: 256,
|
|
28
|
+
valueColor:'',
|
|
29
|
+
trend: 'down',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
title: '付费用户数',
|
|
33
|
+
value: 128,
|
|
34
|
+
valueColor:'',
|
|
35
|
+
trend: ''
|
|
36
|
+
}
|
|
37
|
+
]);
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<style lang="scss" scoped></style>
|
|
41
|
+
```
|
package/utils/message.js
CHANGED
|
@@ -61,28 +61,23 @@ export function showconfirm(done, confirmtitle = '确认关闭?', showtext = { t
|
|
|
61
61
|
|
|
62
62
|
/**
|
|
63
63
|
* 信息提示框
|
|
64
|
-
* @param {*} msg
|
|
65
|
-
* @param {*} type
|
|
66
|
-
* @param {*} title
|
|
67
|
-
* @param {*} position
|
|
68
|
-
* @param {*} dangerouslyUseHTMLString
|
|
64
|
+
* @param {*} msg
|
|
65
|
+
* @param {*} type
|
|
66
|
+
* @param {*} title
|
|
67
|
+
* @param {*} position
|
|
68
|
+
* @param {*} dangerouslyUseHTMLString
|
|
69
69
|
*/
|
|
70
|
-
export function shownotiinfo(msg, type = 'info',title='提示',position='bottom-right',dangerouslyUseHTMLString=false) {
|
|
70
|
+
export function shownotiinfo(msg, type = 'info', title = '提示', position = 'bottom-right', dangerouslyUseHTMLString = false) {
|
|
71
71
|
ElNotification({
|
|
72
72
|
title: title,
|
|
73
73
|
position: position,
|
|
74
74
|
message: msg,
|
|
75
|
-
dangerouslyUseHTMLString:dangerouslyUseHTMLString,
|
|
75
|
+
dangerouslyUseHTMLString: dangerouslyUseHTMLString,
|
|
76
76
|
type: type
|
|
77
77
|
})
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
export function showconfirminfo(
|
|
81
|
-
msg = '确认删除?',
|
|
82
|
-
showtext = { type: '', position: 'bottom-right', title: '提示', dangerouslyUseHTMLString: true },
|
|
83
|
-
fn1,
|
|
84
|
-
fn2
|
|
85
|
-
) {
|
|
80
|
+
export function showconfirminfo(msg = '确认删除?', showtext = { type: '', position: 'bottom-right', title: '提示', dangerouslyUseHTMLString: true }, fn1, fn2) {
|
|
86
81
|
// 按钮
|
|
87
82
|
const btn1 = h(ElButton, {
|
|
88
83
|
innerText: '立即刷新',
|
|
@@ -138,7 +133,6 @@ export function confirm(confirmtitle = '确认关闭?') {
|
|
|
138
133
|
return ElMessageBox.confirm(confirmtitle)
|
|
139
134
|
}
|
|
140
135
|
|
|
141
|
-
|
|
142
136
|
export function showloading(msg, duration = 0, showClose = true) {
|
|
143
137
|
ElMessage({
|
|
144
138
|
// <svg viewBox="0 0 1024 1024" focusable="false" data-icon="loading" width="1em" height="1em" fill="currentColor" aria-hidden="true"><path d="M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z"></path></svg>
|
|
@@ -151,12 +145,16 @@ export function showloading(msg, duration = 0, showClose = true) {
|
|
|
151
145
|
|
|
152
146
|
// loading加载 closeLoading
|
|
153
147
|
let loadingObj = null
|
|
154
|
-
export function showLoading(msg) {
|
|
148
|
+
export function showLoading(msg, parm) {
|
|
149
|
+
let _parm = parm || {}
|
|
155
150
|
loadingObj = ElLoading.service({
|
|
151
|
+
// 默认配置
|
|
156
152
|
lock: true,
|
|
157
|
-
text:
|
|
153
|
+
text: '加载中...',
|
|
158
154
|
spinner: 'el-icon-loading',
|
|
159
|
-
background: 'rgba(0, 0, 0, 0.7)'
|
|
155
|
+
background: 'rgba(0, 0, 0, 0.7)',
|
|
156
|
+
// 展开 _parm,其属性会覆盖上面的默认配置
|
|
157
|
+
..._parm
|
|
160
158
|
})
|
|
161
159
|
}
|
|
162
160
|
|