imeik-bizui 2.8.2 → 2.8.4

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.
@@ -7,19 +7,17 @@
7
7
  <div v-loading="bootLoading" :class="['pbd', `pbd--${variant}`]">
8
8
  <div v-if="bootError" class="pbd-error">{{ bootError }}</div>
9
9
  <template v-else-if="overview">
10
- <div :class="['pbd-state', stateClass]">{{ stateText }}</div>
11
-
12
10
  <section class="pbd-stats" aria-label="预算汇总">
13
11
  <div class="pbd-stat">
14
- <div class="pbd-stat__value num">{{ formatMoney(overview.budgetAmount) }}</div>
12
+ <div class="pbd-stat__value num">{{ formatMoneyYuan(overview.budgetAmount) }}</div>
15
13
  <div class="pbd-stat__label">总预算</div>
16
14
  </div>
17
15
  <div class="pbd-stat" :class="{ 'is-used-danger': isForbid }">
18
- <div class="pbd-stat__value num">{{ formatMoney(overview.usedAmount) }}</div>
16
+ <div class="pbd-stat__value num">{{ formatMoneyYuan(overview.usedAmount) }}</div>
19
17
  <div class="pbd-stat__label">已使用</div>
20
18
  </div>
21
19
  <div class="pbd-stat" :class="{ 'is-remain-danger': remainDanger }">
22
- <div class="pbd-stat__value num">{{ formatMoney(overview.remainingAmountWithCurrent) }}</div>
20
+ <div class="pbd-stat__value num">{{ formatMoneyYuan(overview.remainingAmountWithCurrent) }}</div>
23
21
  <div class="pbd-stat__label">剩余可用</div>
24
22
  </div>
25
23
  </section>
@@ -109,7 +107,7 @@
109
107
  </div>
110
108
  <div class="pbd-total pbd-total--usage">
111
109
  <span>{{ usageTotalLabel }}</span>
112
- <strong>¥{{ formatMoneyPlain(usageTotalAmount) }}</strong>
110
+ <strong>{{ formatMoneyYuan(usageTotalAmount) }}</strong>
113
111
  </div>
114
112
  </section>
115
113
 
@@ -194,7 +192,7 @@
194
192
  </div>
195
193
  <div class="pbd-total pbd-total--perf">
196
194
  <span>{{ performanceTotalLabel }}</span>
197
- <strong>¥{{ formatMoneyPlain(performanceTotalAmount) }}</strong>
195
+ <strong>{{ formatMoneyYuan(performanceTotalAmount) }}</strong>
198
196
  </div>
199
197
  </section>
200
198
  </div>
@@ -212,8 +210,8 @@
212
210
  import {
213
211
  BUDGET_STATUS,
214
212
  formatDateTime,
215
- formatMoney,
216
213
  formatMoneyPlain,
214
+ formatMoneyYuan,
217
215
  normalizeBudgetStatus,
218
216
  parseAmount
219
217
  } from './format'
@@ -290,21 +288,6 @@ export default {
290
288
  isForbid() {
291
289
  return this.status === BUDGET_STATUS.FORBID
292
290
  },
293
- stateClass() {
294
- if (this.status === BUDGET_STATUS.FORBID) return 'is-deny'
295
- if (this.status === BUDGET_STATUS.WARN) return 'is-warn'
296
- return 'is-pass'
297
- },
298
- stateText() {
299
- const remain = parseAmount(this.overview && this.overview.remainingAmountWithCurrent)
300
- if (this.status === BUDGET_STATUS.FORBID) {
301
- const over = Number.isFinite(remain) && remain < 0 ? ` · 超出 ${formatMoney(String(Math.abs(remain)))}` : ''
302
- return `已超预算${over}`
303
- }
304
- if (this.status === BUDGET_STATUS.WARN) return '预算预警 · 本年累计使用已超过预警值'
305
- if (this.status === BUDGET_STATUS.PASS) return '预算正常 · 本年累计使用未超过预警值'
306
- return (this.overview && this.overview.message) || '预算状态待确认'
307
- },
308
291
  remainDanger() {
309
292
  const n = parseAmount(this.overview && this.overview.remainingAmountWithCurrent)
310
293
  return Number.isFinite(n) && n < 0
@@ -365,7 +348,7 @@ export default {
365
348
  }
366
349
  },
367
350
  methods: {
368
- formatMoney,
351
+ formatMoneyYuan,
369
352
  formatMoneyPlain,
370
353
  formatDateTime,
371
354
  usageDateText(row) {
@@ -584,17 +567,6 @@ export default {
584
567
  color: #cf1322;
585
568
  font-size: 13px;
586
569
  }
587
- .pbd-state {
588
- padding: 7px 12px;
589
- margin-bottom: 12px;
590
- border-radius: 6px;
591
- font-size: 12px;
592
- line-height: 18px;
593
- word-break: break-word;
594
- &.is-pass { background: #f6ffed; color: #237804; }
595
- &.is-warn { background: #fffbe6; color: #d46b08; }
596
- &.is-deny { background: #fff1f0; color: #cf1322; }
597
- }
598
570
  .pbd-stats {
599
571
  display: grid;
600
572
  grid-template-columns: repeat(3, minmax(0, 1fr));
@@ -1,6 +1,6 @@
1
1
  <!--
2
- 个人预算概述看板 UI(对齐原型:通过/预警/禁止 + 进度条 + 查看详情)
3
- 移动端布局对齐费率 / 底价:标题行钉详情链、说明与金额独立成行、进度条可叠放
2
+ 个人预算概述看板 UI(对齐费率:状态+说明同行,金额+剩余chip同行,进度条右侧剩余%)
3
+ 移动端:标题行钉详情链,进度条满宽叠放;status 空值展示 '-'
4
4
  -->
5
5
  <template>
6
6
  <div class="person-budget-overview">
@@ -11,10 +11,12 @@
11
11
  <div :class="['pbo-head', { 'pbo-head--with-link': showDetailLink }]">
12
12
  <div class="pbo-head__main">
13
13
  <div class="pbo-head__row">
14
- <span class="pbo-icon">{{ statusMeta.icon }}</span>
15
- <span class="pbo-title">{{ statusMeta.title }}</span>
14
+ <span class="pbo-badge">
15
+ <span class="pbo-icon" aria-hidden="true">{{ statusMeta.icon }}</span>
16
+ <span class="pbo-title">{{ statusMeta.title }}</span>
17
+ </span>
18
+ <span v-if="statusDesc" class="pbo-desc">{{ statusDesc }}</span>
16
19
  </div>
17
- <p class="pbo-desc">{{ statusDesc }}</p>
18
20
  </div>
19
21
  <el-button
20
22
  v-if="showDetailLink"
@@ -29,16 +31,16 @@
29
31
  <div class="pbo-metrics">
30
32
  <div class="pbo-line2">
31
33
  <div class="pbo-line2__text">
32
- <span class="pbo-line2__label">本年累计使用(含本次)</span>
33
- <b class="pbo-money">{{ formatMoney(overview.usedAmount) }}</b>
34
+ <span class="pbo-line2__label">本年累计使用(含本次):</span>
35
+ <b class="pbo-money">{{ formatMoneyYuan(overview.usedAmount) }}</b>
34
36
  <span class="pbo-sep">/</span>
35
37
  <span class="pbo-line2__label">总预算</span>
36
- <b class="pbo-money">{{ formatMoney(overview.budgetAmount) }}</b>
38
+ <b class="pbo-money">{{ formatMoneyYuan(overview.budgetAmount) }}</b>
39
+ <span :class="['pbo-chip', remainingChipDanger ? 'is-danger' : '']">
40
+ 剩余 {{ formatMoneyYuan(overview.remainingAmountWithCurrent) }}
41
+ </span>
37
42
  </div>
38
43
  </div>
39
- <span :class="['pbo-chip', remainingChipDanger ? 'is-danger' : '']">
40
- 剩余 {{ formatMoney(overview.remainingAmountWithCurrent) }}
41
- </span>
42
44
 
43
45
  <div class="pbo-bar-row">
44
46
  <div class="pbo-bar-col">
@@ -48,14 +50,14 @@
48
50
  v-if="showWarnTick"
49
51
  class="pbo-bar__tick"
50
52
  :style="{ left: warnTickPercent + '%' }"
51
- :title="'预警值:' + formatMoney(warnAmount)"
53
+ :title="'预警值:' + formatMoneyYuan(warnAmount)"
52
54
  />
53
55
  </div>
54
56
  <div v-if="showWarnTick" class="pbo-scale">
55
57
  <span
56
58
  :class="['pbo-scale__sc', warnScaleClass]"
57
59
  :style="{ left: warnTickPercent + '%' }"
58
- >预警值:{{ formatMoney(warnAmount) }}</span>
60
+ >预警值:{{ formatMoneyYuan(warnAmount) }}</span>
59
61
  </div>
60
62
  </div>
61
63
  </div>
@@ -68,7 +70,7 @@
68
70
  <script>
69
71
  import {
70
72
  BUDGET_STATUS,
71
- formatMoney,
73
+ formatMoneyYuan,
72
74
  formatPercent,
73
75
  normalizeBudgetStatus,
74
76
  parseAmount
@@ -139,13 +141,16 @@ export default {
139
141
  budgetNum() {
140
142
  return parseAmount(this.overview && this.overview.budgetAmount)
141
143
  },
144
+ /** 有有效总预算才算占比;否则不展示假的 100% 剩余 */
145
+ hasBudgetRatio() {
146
+ return Number.isFinite(this.usedNum) && Number.isFinite(this.budgetNum) && this.budgetNum > 0
147
+ },
142
148
  usagePercent() {
143
- const used = this.usedNum
144
- const budget = this.budgetNum
145
- if (!Number.isFinite(used) || !Number.isFinite(budget) || budget <= 0) return 0
146
- return (used / budget) * 100
149
+ if (!this.hasBudgetRatio) return NaN
150
+ return (this.usedNum / this.budgetNum) * 100
147
151
  },
148
152
  fillWidth() {
153
+ if (!this.hasBudgetRatio) return '0'
149
154
  return Math.min(Math.max(this.usagePercent, 0), 100).toFixed(2)
150
155
  },
151
156
  warnAmount() {
@@ -169,13 +174,14 @@ export default {
169
174
  return 'is-mid'
170
175
  },
171
176
  barLabel() {
177
+ if (!this.hasBudgetRatio) return '剩余 —'
172
178
  const remain = 100 - this.usagePercent
173
179
  if (remain < 0) return `已超 ${formatPercent(this.usagePercent - 100)}`
174
180
  return `剩余 ${formatPercent(remain)}`
175
181
  }
176
182
  },
177
183
  methods: {
178
- formatMoney
184
+ formatMoneyYuan
179
185
  }
180
186
  }
181
187
  </script>
@@ -243,37 +249,54 @@ export default {
243
249
  display: flex;
244
250
  align-items: center;
245
251
  flex-wrap: wrap;
246
- gap: 8px;
252
+ gap: 8px 10px;
247
253
  min-width: 0;
248
254
  }
255
+ /* 对齐费率:图标 + 状态文案收成同一徽章,垂直居中 */
256
+ .pbo-badge {
257
+ display: inline-flex;
258
+ align-items: center;
259
+ flex: none;
260
+ gap: 6px;
261
+ min-height: 24px;
262
+ padding: 2px 10px 2px 8px;
263
+ border-radius: 12px;
264
+ box-sizing: border-box;
265
+ line-height: 1;
266
+ }
267
+ .is-pass .pbo-badge { background: #dcf5cf; }
268
+ .is-warn .pbo-badge { background: #ffefc2; }
269
+ .is-deny .pbo-badge { background: #ffd9d6; }
270
+ /* 对齐费率:小实心圆点,不放字符 */
249
271
  .pbo-icon {
250
- width: 22px;
251
- height: 22px;
272
+ width: 6px;
273
+ height: 6px;
252
274
  border-radius: 50%;
253
275
  flex: none;
254
- display: inline-flex;
255
- align-items: center;
256
- justify-content: center;
257
- color: #fff;
258
- font-size: 13px;
259
- font-weight: 700;
276
+ display: inline-block;
277
+ font-size: 0;
278
+ line-height: 0;
279
+ overflow: hidden;
280
+ color: transparent;
260
281
  }
261
282
  .is-pass .pbo-icon { background: #00b578; }
262
283
  .is-warn .pbo-icon { background: #ff8f1f; }
263
284
  .is-deny .pbo-icon { background: #fa5151; }
264
285
  .pbo-title {
265
- font-size: 15px;
286
+ font-size: 13px;
266
287
  font-weight: 600;
267
- line-height: 22px;
288
+ line-height: 16px;
268
289
  }
269
- .is-pass .pbo-title { color: #00b578; }
270
- .is-warn .pbo-title { color: #ff8f1f; }
271
- .is-deny .pbo-title { color: #fa5151; }
290
+ .is-pass .pbo-title { color: #237804; }
291
+ .is-warn .pbo-title { color: #d46b08; }
292
+ .is-deny .pbo-title { color: #cf1322; }
272
293
  .pbo-desc {
273
- margin: 6px 0 0;
294
+ margin: 0;
274
295
  font-size: 12px;
275
- line-height: 18px;
296
+ line-height: 24px;
276
297
  color: #646a73;
298
+ flex: 1 1 auto;
299
+ min-width: 0;
277
300
  word-break: break-word;
278
301
  overflow-wrap: anywhere;
279
302
  }
@@ -304,7 +327,7 @@ export default {
304
327
  max-width: 100%;
305
328
  }
306
329
  .pbo-line2 {
307
- grid-column: 1;
330
+ grid-column: 1 / -1;
308
331
  grid-row: 1;
309
332
  font-size: 13.5px;
310
333
  color: #1f2329;
@@ -314,8 +337,8 @@ export default {
314
337
  .pbo-line2__text {
315
338
  display: inline-flex;
316
339
  flex-wrap: wrap;
317
- align-items: baseline;
318
- gap: 4px 6px;
340
+ align-items: center;
341
+ gap: 4px 8px;
319
342
  min-width: 0;
320
343
  line-height: 1.65;
321
344
  word-break: break-word;
@@ -329,14 +352,13 @@ export default {
329
352
  font-variant-numeric: tabular-nums;
330
353
  white-space: nowrap;
331
354
  }
355
+ .is-pass .pbo-money { color: #00b578; }
356
+ .is-warn .pbo-money { color: #ff8f1f; }
357
+ .is-deny .pbo-money { color: #fa5151; }
332
358
  .pbo-sep {
333
359
  color: #8f959e;
334
360
  }
335
361
  .pbo-chip {
336
- grid-column: 2;
337
- grid-row: 1;
338
- justify-self: end;
339
- align-self: start;
340
362
  font-size: 12px;
341
363
  font-weight: 600;
342
364
  padding: 3px 10px;
@@ -435,10 +457,6 @@ export default {
435
457
  min-height: 22px;
436
458
  }
437
459
 
438
- .pbo-desc {
439
- margin-top: 4px;
440
- }
441
-
442
460
  .pbo-metrics {
443
461
  grid-template-columns: minmax(0, 1fr);
444
462
  grid-template-rows: auto;
@@ -448,7 +466,6 @@ export default {
448
466
  }
449
467
 
450
468
  .pbo-line2,
451
- .pbo-chip,
452
469
  .pbo-bar-row,
453
470
  .pbo-bar-label {
454
471
  grid-column: 1;
@@ -456,10 +473,6 @@ export default {
456
473
  justify-self: stretch;
457
474
  }
458
475
 
459
- .pbo-chip {
460
- justify-self: start;
461
- }
462
-
463
476
  .pbo-bar-label {
464
477
  justify-self: start;
465
478
  margin-top: 0;
@@ -32,12 +32,18 @@ function formatAmountFixed2(value) {
32
32
  return `${neg ? '-' : ''}${withComma}.${decPart}`
33
33
  }
34
34
 
35
- /** null/空展示 —;展示固定两位小数 */
35
+ /** null/空展示 —;展示固定两位小数,前缀 ¥ */
36
36
  export function formatMoney(value) {
37
37
  const formatted = formatAmountFixed2(value)
38
38
  return formatted == null ? '—' : `¥ ${formatted}`
39
39
  }
40
40
 
41
+ /** 对齐费率文案:248,601.00 元 */
42
+ export function formatMoneyYuan(value) {
43
+ const formatted = formatAmountFixed2(value)
44
+ return formatted == null ? '—' : `${formatted} 元`
45
+ }
46
+
41
47
  export function formatMoneyPlain(value) {
42
48
  const formatted = formatAmountFixed2(value)
43
49
  return formatted == null ? '—' : formatted