t20-common-lib 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="statis-card flex-box">
|
|
3
|
+
<div class="card-item flex-column" v-for="(item, index) in cardList" :key="item.id" :style="{
|
|
4
|
+
'--bg': cardConfig[index].background,
|
|
5
|
+
'--flex': cardConfig[index].flex
|
|
6
|
+
}">
|
|
7
|
+
<div class="header flex-box flex-lr">
|
|
8
|
+
<!-- 动态判断:如果是图片路径则用 img,否则用 iconfont -->
|
|
9
|
+
<div class="flex-box flex-v">
|
|
10
|
+
<img
|
|
11
|
+
class="icon"
|
|
12
|
+
v-if="isImagePath(item.icon)"
|
|
13
|
+
:src="resolveImagePath(item.icon)"
|
|
14
|
+
alt="icon"
|
|
15
|
+
>
|
|
16
|
+
<i class="icon" v-else :class="item.icon"></i>
|
|
17
|
+
<div class="title">{{ item.title }}</div>
|
|
18
|
+
<div class="slot-dropdown">
|
|
19
|
+
<slot :name="item.slotName" :item="item"></slot>
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="slot-tab">
|
|
23
|
+
<slot :name="item.slotTabName" :item="item"></slot>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="content flex-box">
|
|
27
|
+
<template v-for="(conItem, index) in item.subList">
|
|
28
|
+
<div class="content-item" :key="conItem.subId">
|
|
29
|
+
<div class="content-item-title">{{ conItem.title }}
|
|
30
|
+
<i v-if="conItem.tips" v-title="conItem.tips" class="n20-icon-xinxitishi"></i>
|
|
31
|
+
</div>
|
|
32
|
+
<div v-if="conItem.amountFormat" class="content-item-val" @click="$emit('click', conItem)">{{ conItem.value | cardFormatAmount('value') }}<span class="content-item-unit">{{ conItem.value | cardFormatAmount('unit') }}</span></div>
|
|
33
|
+
<div v-else class="content-item-val" @click="$emit('click', conItem)">{{ conItem.value }}<span class="content-item-unit">{{ conItem.unit }}</span></div>
|
|
34
|
+
</div>
|
|
35
|
+
<div
|
|
36
|
+
v-if="index !== item.subList.length - 1"
|
|
37
|
+
class="divider"
|
|
38
|
+
:key="'divider-' + conItem.subId">
|
|
39
|
+
</div>
|
|
40
|
+
</template>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script>
|
|
47
|
+
export default {
|
|
48
|
+
name: 'StatisCard',
|
|
49
|
+
props: {
|
|
50
|
+
cardList: {
|
|
51
|
+
type: Array,
|
|
52
|
+
default: () => []
|
|
53
|
+
},
|
|
54
|
+
cardConfig: {
|
|
55
|
+
type: Array,
|
|
56
|
+
default: () => []
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
filters: {
|
|
60
|
+
/**
|
|
61
|
+
* 格式化金额或返回原始值
|
|
62
|
+
* @param {Number|String} value - 原始值
|
|
63
|
+
* @param {String} type - 'value' 或 'unit'
|
|
64
|
+
* @param {Boolean} isAmount - 是否作为金额处理
|
|
65
|
+
*/
|
|
66
|
+
cardFormatAmount(value, type = 'value') {
|
|
67
|
+
const language = localStorage.getItem('pageLang')
|
|
68
|
+
const unitMap = {
|
|
69
|
+
'en': {
|
|
70
|
+
'thousand': 'K',
|
|
71
|
+
'million': 'M',
|
|
72
|
+
},
|
|
73
|
+
'zh': {
|
|
74
|
+
'thousand': '万元',
|
|
75
|
+
'million': '亿元',
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 非数字直接返回原值(单位返回空字符串)
|
|
80
|
+
if (typeof value !== 'number' || isNaN(value)) {
|
|
81
|
+
return type === 'value' ? value || 0 : unitMap[language].thousand;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const amountInTenThousand = value / 10000;
|
|
85
|
+
|
|
86
|
+
if (type === 'value') {
|
|
87
|
+
// 返回格式化后的数值
|
|
88
|
+
return amountInTenThousand >= 1000
|
|
89
|
+
? parseFloat((amountInTenThousand / 10000).toFixed(2))
|
|
90
|
+
: parseFloat(amountInTenThousand.toFixed(2));
|
|
91
|
+
} else {
|
|
92
|
+
// 返回单位
|
|
93
|
+
return amountInTenThousand >= 1000 ? unitMap[language].million : unitMap[language].thousand;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
data() {
|
|
98
|
+
return {
|
|
99
|
+
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
methods: {
|
|
103
|
+
isImagePath(icon) {
|
|
104
|
+
return typeof icon === 'string' &&
|
|
105
|
+
(icon.endsWith('.png') || icon.endsWith('.jpg') || icon.startsWith('@/') || icon.endsWith('.svg'));
|
|
106
|
+
},
|
|
107
|
+
// 解析Webpack别名路径(需配合require或import)
|
|
108
|
+
resolveImagePath(path) {
|
|
109
|
+
try {
|
|
110
|
+
return require(`@/assets/${path}`);
|
|
111
|
+
} catch (e) {
|
|
112
|
+
console.warn('图片加载失败', path);
|
|
113
|
+
return '';
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
</script>
|
|
119
|
+
|
|
120
|
+
<style lang="scss" scoped>
|
|
121
|
+
.statis-card {
|
|
122
|
+
width: 100%;
|
|
123
|
+
gap: 10px;
|
|
124
|
+
.card-item {
|
|
125
|
+
padding: 16px;
|
|
126
|
+
border-radius: 4px;
|
|
127
|
+
position: relative;
|
|
128
|
+
box-sizing: border-box;
|
|
129
|
+
overflow: hidden;
|
|
130
|
+
flex: var(--flex);
|
|
131
|
+
background: var(--bg);
|
|
132
|
+
.header {
|
|
133
|
+
display: flex;
|
|
134
|
+
align-items: center;
|
|
135
|
+
margin-bottom: 16px;
|
|
136
|
+
|
|
137
|
+
.icon {
|
|
138
|
+
width: 14px;
|
|
139
|
+
height: 14px;
|
|
140
|
+
margin-right: 8px;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.title {
|
|
144
|
+
font-size: 16px;
|
|
145
|
+
color: #fff;
|
|
146
|
+
white-space: nowrap;
|
|
147
|
+
}
|
|
148
|
+
.slot-dropdown {
|
|
149
|
+
white-space: nowrap;
|
|
150
|
+
cursor: pointer;
|
|
151
|
+
::v-deep .el-dropdown {
|
|
152
|
+
font-size: 12px !important;
|
|
153
|
+
color: #fff !important;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.content {
|
|
160
|
+
padding: 0 22px;
|
|
161
|
+
color: #fff;
|
|
162
|
+
.content-item {
|
|
163
|
+
&-title {
|
|
164
|
+
font-size: 14px;
|
|
165
|
+
margin-block: 8px;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
&-val {
|
|
169
|
+
cursor: pointer;
|
|
170
|
+
font-size: 20px;
|
|
171
|
+
text-align: center;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
&-unit {
|
|
175
|
+
font-size: 14px;
|
|
176
|
+
margin-left: 4px;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
.divider {
|
|
180
|
+
height: 32px;
|
|
181
|
+
width: 1px;;
|
|
182
|
+
background-color: #fff;
|
|
183
|
+
margin: auto;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
.n20-icon-xinxitishi {
|
|
188
|
+
color: #fff;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
</style>
|
package/src/index.js
CHANGED
|
@@ -6,13 +6,14 @@ import { getColumnWidth, getCellAlign } from './utils/tableCellUtils'
|
|
|
6
6
|
import MainPage from '../packages/main-page/index.js'
|
|
7
7
|
import TablePage from '../packages/table-page/index.js'
|
|
8
8
|
import TabPane from '../packages/tab-pane/index.js'
|
|
9
|
-
|
|
9
|
+
import StatisCard from '../packages/statis-card/index.js'
|
|
10
10
|
|
|
11
11
|
// 存储组件列表
|
|
12
12
|
const components = [
|
|
13
13
|
MainPage,
|
|
14
14
|
TablePage,
|
|
15
|
-
TabPane
|
|
15
|
+
TabPane,
|
|
16
|
+
StatisCard
|
|
16
17
|
]
|
|
17
18
|
|
|
18
19
|
// 定义 install 方法,接收 Vue 作为参数
|
|
@@ -43,6 +44,8 @@ export {
|
|
|
43
44
|
// 以下是具体的组件列表
|
|
44
45
|
MainPage,
|
|
45
46
|
TablePage,
|
|
47
|
+
StatisCard,
|
|
48
|
+
TabPane,
|
|
46
49
|
repairEl,
|
|
47
50
|
getColumnWidth,
|
|
48
51
|
getCellAlign
|