befly-admin-ui 1.49.0 → 1.50.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/layouts/1.vue CHANGED
@@ -3,3 +3,4 @@
3
3
  <RouterView />
4
4
  </div>
5
5
  </template>
6
+ <script setup></script>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "befly-admin-ui",
3
- "version": "1.49.0",
3
+ "version": "1.50.0",
4
4
  "gitHead": "071d17be177355cdd61f30659c6e4c5873f87d39",
5
5
  "private": false,
6
6
  "description": "Befly - 管理后台功能组件",
@@ -50,8 +50,8 @@
50
50
  "dependencies": {},
51
51
  "peerDependencies": {
52
52
  "tdesign-icons-vue-next": ">=0.4.0",
53
- "tdesign-vue-next": ">=1.20.2",
54
- "vue": ">=3.0.0",
53
+ "tdesign-vue-next": ">=1.20.3",
54
+ "vue": ">=3.5.39",
55
55
  "vue-router": ">=5.0.0"
56
56
  }
57
57
  }
@@ -1,60 +1,54 @@
1
1
  <template>
2
2
  <div class="page-project-stats">
3
3
  <div class="section-block">
4
- <div class="section-header">
5
- <ChartIcon />
6
- <h2>项目统计</h2>
4
+ <div class="section-header page-project-stats__header">
5
+ <div class="page-project-stats__header-title">
6
+ <ChartIcon />
7
+ <h2>项目统计</h2>
8
+ </div>
9
+
10
+ <div class="page-project-stats__header-actions">
11
+ <TRadioGroup v-model="$Data.layout" theme="button" variant="default-filled" size="small">
12
+ <TRadioButton value="list">列表</TRadioButton>
13
+ <TRadioButton value="card">卡片</TRadioButton>
14
+ </TRadioGroup>
15
+ </div>
7
16
  </div>
8
17
 
9
18
  <div class="section-content">
10
- <div class="project-row-list">
19
+ <div v-if="$Data.layout === 'list'" class="project-row-list">
11
20
  <div v-for="item in $Computed.productRows" :key="item.key" class="product-row">
12
21
  <div class="product-title">{{ $Method.formatProductTitle(item) }}</div>
13
22
 
14
23
  <t-row :gutter="[16, 16]">
15
- <t-col :xs="12" :sm="6" :md="4" :lg="2" class="metric-col">
16
- <div class="metric-card">
17
- <span class="metric-label">今日在线</span>
18
- <strong class="metric-value-daily">{{ item.today }}</strong>
19
- </div>
20
- </t-col>
21
-
22
- <t-col :xs="12" :sm="6" :md="4" :lg="2" class="metric-col">
23
- <div class="metric-card">
24
- <span class="metric-label">昨日在线</span>
25
- <strong class="metric-value-daily">{{ item.yesterday }}</strong>
26
- </div>
27
- </t-col>
28
-
29
- <t-col :xs="12" :sm="6" :md="4" :lg="2" class="metric-col">
30
- <div class="metric-card">
31
- <span class="metric-label">前天在线</span>
32
- <strong class="metric-value-daily">{{ item.dayBeforeYesterday }}</strong>
33
- </div>
34
- </t-col>
35
-
36
- <t-col :xs="12" :sm="6" :md="4" :lg="2" class="metric-col">
24
+ <t-col v-for="metric in $Const.metricList" :key="metric.key" :xs="12" :sm="6" :md="4" :lg="2" class="metric-col">
37
25
  <div class="metric-card">
38
- <span class="metric-label">近7天在线</span>
39
- <strong class="metric-value-daily">{{ item.recent7 }}</strong>
26
+ <span class="metric-label">{{ metric.label }}</span>
27
+ <strong class="metric-value-daily">{{ item[metric.key] }}</strong>
40
28
  </div>
41
29
  </t-col>
30
+ </t-row>
31
+ </div>
32
+ </div>
42
33
 
43
- <t-col :xs="12" :sm="6" :md="4" :lg="2" class="metric-col">
44
- <div class="metric-card">
45
- <span class="metric-label">近30天在线</span>
46
- <strong class="metric-value-daily">{{ item.recent30 }}</strong>
34
+ <div v-else class="project-card-grid">
35
+ <t-row :gutter="[16, 16]">
36
+ <t-col v-for="item in $Computed.productRows" :key="item.key" :xs="12" :sm="6" :md="4" :lg="2" class="product-card-col">
37
+ <div class="product-card">
38
+ <div class="product-card__title">
39
+ <span>{{ item.productName }}</span>
40
+ <span>{{ item.productCode }}</span>
47
41
  </div>
48
- </t-col>
49
42
 
50
- <t-col :xs="12" :sm="6" :md="4" :lg="2" class="metric-col">
51
- <div class="metric-card">
52
- <span class="metric-label">本月在线</span>
53
- <strong class="metric-value-daily">{{ item.month }}</strong>
43
+ <div class="product-card__metrics">
44
+ <div v-for="metric in $Const.metricList" :key="metric.key" class="product-card__metric">
45
+ <span class="product-card__metric-label">{{ metric.label }}</span>
46
+ <strong class="product-card__metric-value">{{ item[metric.key] }}</strong>
47
+ </div>
54
48
  </div>
55
- </t-col>
56
- </t-row>
57
- </div>
49
+ </div>
50
+ </t-col>
51
+ </t-row>
58
52
  </div>
59
53
  </div>
60
54
  </div>
@@ -63,12 +57,24 @@
63
57
 
64
58
  <script setup>
65
59
  import { ChartIcon } from "tdesign-icons-vue-next";
66
- import { Col as TCol, Row as TRow } from "tdesign-vue-next";
60
+ import { Col as TCol, RadioButton as TRadioButton, RadioGroup as TRadioGroup, Row as TRow } from "tdesign-vue-next";
67
61
  import { computed, reactive } from "vue";
68
62
 
69
63
  import { $Http } from "@/plugins/http.js";
70
64
 
65
+ const $Const = {
66
+ metricList: [
67
+ { key: "today", label: "今日在线" },
68
+ { key: "yesterday", label: "昨日在线" },
69
+ { key: "dayBeforeYesterday", label: "前天在线" },
70
+ { key: "recent7", label: "近7天在线" },
71
+ { key: "recent30", label: "近30天在线" },
72
+ { key: "month", label: "本月在线" }
73
+ ]
74
+ };
75
+
71
76
  const $Data = reactive({
77
+ layout: "list",
72
78
  productState: {
73
79
  options: []
74
80
  }
@@ -127,12 +133,30 @@ $Method.fetchData();
127
133
  overflow-y: auto;
128
134
  overflow-x: hidden;
129
135
  padding: 4px 0 12px;
136
+
137
+ // 头部区域
138
+ &__header {
139
+ justify-content: space-between;
140
+ gap: 12px;
141
+ }
142
+
143
+ &__header-title {
144
+ display: flex;
145
+ align-items: center;
146
+ gap: 8px;
147
+ }
148
+
149
+ &__header-actions {
150
+ display: flex;
151
+ align-items: center;
152
+ }
130
153
  }
131
154
 
132
155
  .section-content {
133
156
  min-width: 0;
134
157
  }
135
158
 
159
+ // 列表布局
136
160
  .project-row-list {
137
161
  display: flex;
138
162
  flex-direction: column;
@@ -180,4 +204,64 @@ $Method.fetchData();
180
204
  justify-content: flex-start;
181
205
  padding: 12px;
182
206
  }
207
+
208
+ // 卡片布局
209
+ .project-card-grid {
210
+ min-width: 0;
211
+ }
212
+
213
+ .product-card-col {
214
+ min-width: 0;
215
+ }
216
+
217
+ .product-card {
218
+ display: flex;
219
+ flex-direction: column;
220
+
221
+ @include dashboardCard.dashboardCardShell();
222
+
223
+ justify-content: flex-start;
224
+ padding: 12px;
225
+
226
+ &__title {
227
+ display: flex;
228
+ align-items: center;
229
+ justify-content: space-between;
230
+ gap: 8px;
231
+ font-size: 14px;
232
+ font-weight: 700;
233
+ color: var(--text-primary);
234
+ line-height: 1.2;
235
+ margin-bottom: 12px;
236
+
237
+ span:last-child {
238
+ font-weight: 500;
239
+ color: var(--text-secondary);
240
+ }
241
+ }
242
+
243
+ &__metrics {
244
+ display: flex;
245
+ flex-direction: column;
246
+ gap: 8px;
247
+ }
248
+
249
+ &__metric {
250
+ display: flex;
251
+ align-items: center;
252
+ justify-content: space-between;
253
+ gap: 8px;
254
+ }
255
+
256
+ &__metric-label {
257
+ @include dashboardCard.dashboardCardLabel();
258
+ }
259
+
260
+ &__metric-value {
261
+ @include dashboardCard.dashboardCardNumericValue(var(--success-color));
262
+
263
+ font-size: 16px;
264
+ white-space: nowrap;
265
+ }
266
+ }
183
267
  </style>