minitest2.0 0.0.4 → 0.0.5

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.
@@ -1,28 +1,349 @@
1
+ <script setup lang="ts">
2
+ import {
3
+ buildOpeningReserveEstimatePayload,
4
+ queryOpeningReserveEstimate,
5
+ type OpeningReserveEstimateBody,
6
+ } from '@/api/opening-reserve-estimate'
7
+ import { showAppToast } from '@/utils/toast'
8
+
9
+ defineOptions({ name: 'OpeningReserveEstimatePage' })
10
+
11
+ type ResultItem = {
12
+ key: keyof OpeningReserveEstimateBody
13
+ label: string
14
+ icon: string
15
+ }
16
+
17
+ const estimateDetail = ref<OpeningReserveEstimateBody | null>(null)
18
+ const querying = ref(false)
19
+
20
+ const resultConfig: ResultItem[] = [
21
+ { key: 'rhAmt', label: '人行时点头寸(元)', icon: 'balance-o' },
22
+ { key: 'unverifyAmtOut', label: '预报未核销支出(元)', icon: 'card' },
23
+ { key: 'unverifyAmtIn', label: '预报未核销收入(元)', icon: 'gold-coin-o' },
24
+ { key: 'pdAmt', label: '总分行铺底资金之和(元)', icon: 'paid' },
25
+ { key: 'fzAmt', label: '法定准备金(元)', icon: 'shield-o' },
26
+ { key: 'preAmt', label: '日初备款(元)', icon: 'chart-trending-o' },
27
+ ]
28
+
29
+ const resultItems = computed(() =>
30
+ resultConfig.map((item) => ({
31
+ ...item,
32
+ value: formatYuanAmount(estimateDetail.value?.[item.key]),
33
+ })),
34
+ )
35
+
36
+ onMounted(() => {
37
+ void handleQuery({ showSuccessToast: false })
38
+ })
39
+
40
+ function handleRefresh() {
41
+ void handleQuery()
42
+ }
43
+
44
+ async function handleQuery(options: { showSuccessToast?: boolean } = {}) {
45
+ if (querying.value) return
46
+
47
+ querying.value = true
48
+ const payload = buildOpeningReserveEstimatePayload()
49
+ console.log('[日初备款数匡算入参]', payload)
50
+
51
+ try {
52
+ const response = await queryOpeningReserveEstimate(payload)
53
+ estimateDetail.value = response.body || {}
54
+ if (options.showSuccessToast !== false) {
55
+ showAppToast('刷新完成')
56
+ }
57
+ } catch (error) {
58
+ console.error('[日初备款数匡算失败]', error)
59
+ showAppToast(getErrorMessage(error, '查询失败,请重试'))
60
+ } finally {
61
+ querying.value = false
62
+ }
63
+ }
64
+
65
+ function formatYuanAmount(value?: string) {
66
+ const text = value?.trim()
67
+
68
+ if (!text) return '-'
69
+
70
+ const normalizedText = text.replaceAll(',', '')
71
+
72
+ if (!/^[-+]?\d+(\.\d+)?$/.test(normalizedText)) {
73
+ return '-'
74
+ }
75
+
76
+ const sign = normalizedText.startsWith('-') ? '-' : ''
77
+ const unsignedText =
78
+ normalizedText.startsWith('-') || normalizedText.startsWith('+')
79
+ ? normalizedText.slice(1)
80
+ : normalizedText
81
+ const [rawInteger = '0', rawDecimal = ''] = unsignedText.split('.')
82
+ let integer = rawInteger.replace(/^0+(?=\d)/, '') || '0'
83
+ let decimal = `${rawDecimal}00`.slice(0, 2)
84
+
85
+ if (Number(rawDecimal[2] || '0') >= 5) {
86
+ const roundedAmount = addOneCent(integer, decimal)
87
+ integer = roundedAmount.integer
88
+ decimal = roundedAmount.decimal
89
+ }
90
+
91
+ return `${sign}${integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',')}.${decimal}`
92
+ }
93
+
94
+ function addOneCent(integer: string, decimal: string) {
95
+ const centAmount = Number(decimal) + 1
96
+
97
+ if (centAmount < 100) {
98
+ return {
99
+ integer,
100
+ decimal: String(centAmount).padStart(2, '0'),
101
+ }
102
+ }
103
+
104
+ return {
105
+ integer: incrementIntegerText(integer),
106
+ decimal: '00',
107
+ }
108
+ }
109
+
110
+ function incrementIntegerText(value: string) {
111
+ const digits = value.split('')
112
+
113
+ for (let index = digits.length - 1; index >= 0; index -= 1) {
114
+ if (digits[index] !== '9') {
115
+ digits[index] = String(Number(digits[index]) + 1)
116
+ return digits.join('')
117
+ }
118
+
119
+ digits[index] = '0'
120
+ }
121
+
122
+ return `1${digits.join('')}`
123
+ }
124
+
125
+ function getErrorMessage(error: unknown, fallback: string) {
126
+ return error instanceof Error && error.message ? error.message : fallback
127
+ }
128
+ </script>
129
+
1
130
  <template>
2
- <main class="page">
3
- <section class="page-body">
4
- <p class="placeholder">页面建设中…</p>
131
+ <main class="opening-reserve-page">
132
+ <section class="result-section" aria-label="日初备款数匡算查询结果">
133
+ <div class="section-heading">
134
+ <span class="section-heading__mark" aria-hidden="true"></span>
135
+ <h2>查询结果</h2>
136
+ </div>
137
+
138
+ <div class="result-stack">
139
+ <dl class="result-list">
140
+ <div v-for="item in resultItems" :key="item.key" class="result-row">
141
+ <dt>
142
+ <span class="result-icon" aria-hidden="true">
143
+ <van-icon :name="item.icon" />
144
+ </span>
145
+ <span class="result-label">{{ item.label }}</span>
146
+ </dt>
147
+ <dd>{{ item.value }}</dd>
148
+ </div>
149
+ </dl>
150
+ </div>
5
151
  </section>
152
+
153
+ <nav class="action-bar" aria-label="日初备款数匡算操作">
154
+ <button class="query-button" type="button" :disabled="querying" @click="handleRefresh">
155
+ <span>{{ querying ? '刷新中' : '刷新' }}</span>
156
+ </button>
157
+ </nav>
6
158
  </main>
7
159
  </template>
8
160
 
9
161
  <style scoped>
10
- .page {
162
+ .opening-reserve-page {
163
+ width: 100%;
11
164
  max-width: 750px;
12
165
  min-height: var(--app-page-min-height, 100vh);
13
166
  margin: 0 auto;
14
- padding: 0 11px;
15
- background: #f7f8fa;
167
+ padding: 31px 15px calc(env(safe-area-inset-bottom, 0px) + 94px);
168
+ color: #171b20;
169
+ background: #ffffff;
170
+ box-sizing: border-box;
171
+ }
172
+
173
+ button {
174
+ border: 0;
175
+ padding: 0;
176
+ font: inherit;
177
+ background: transparent;
178
+ appearance: none;
179
+ }
180
+
181
+ .result-section {
182
+ display: block;
183
+ }
184
+
185
+ .section-heading {
186
+ display: flex;
187
+ align-items: center;
188
+ margin-bottom: 21px;
189
+ }
190
+
191
+ .section-heading__mark {
192
+ width: 7px;
193
+ height: 24px;
194
+ flex: 0 0 7px;
195
+ border-radius: 999px;
196
+ background: linear-gradient(180deg, #ff3b44 0%, #ff1f2d 100%);
197
+ box-shadow: 0 6px 12px rgba(255, 39, 48, 0.22);
198
+ }
199
+
200
+ .section-heading h2 {
201
+ margin: 0 0 0 13px;
202
+ color: #151922;
203
+ font-size: 20px;
204
+ font-weight: 760;
205
+ line-height: 1.2;
206
+ letter-spacing: 0;
207
+ }
208
+
209
+ .result-stack {
210
+ display: block;
211
+ }
212
+
213
+ .result-list {
214
+ display: flex;
215
+ flex-direction: column;
216
+ gap: 10px;
217
+ margin: 0;
218
+ padding: 0;
219
+ }
220
+
221
+ .result-row {
222
+ display: grid;
223
+ grid-template-columns: 34px minmax(0, 1fr);
224
+ grid-template-rows: auto auto;
225
+ align-items: center;
226
+ min-height: 74px;
227
+ padding: 13px 16px;
228
+ column-gap: 13px;
229
+ border: 1px solid #ffd9dd;
230
+ border-radius: 12px;
231
+ background:
232
+ linear-gradient(180deg, rgba(255, 255, 255, 0.99) 0%, rgba(255, 252, 252, 0.97) 100%), #ffffff;
233
+ box-shadow: 0 7px 18px rgba(255, 43, 50, 0.06);
234
+ box-sizing: border-box;
16
235
  }
17
236
 
18
- .page-body {
19
- padding: 24px 0;
237
+ .result-row dt {
238
+ display: contents;
239
+ margin: 0;
20
240
  }
21
241
 
22
- .placeholder {
23
- padding-top: 120px;
24
- color: #969799;
242
+ .result-icon {
243
+ display: inline-flex;
244
+ align-items: center;
245
+ justify-content: center;
246
+ grid-row: 1 / 3;
247
+ grid-column: 1;
248
+ width: 34px;
249
+ height: 34px;
250
+ border-radius: 50%;
251
+ color: #f52932;
252
+ font-size: 19px;
253
+ background:
254
+ radial-gradient(circle at 35% 24%, rgba(255, 255, 255, 0.9) 0%, rgba(255, 255, 255, 0) 42%),
255
+ linear-gradient(135deg, #fff2f3 0%, #ffe6e9 100%);
256
+ }
257
+
258
+ .result-label {
259
+ grid-row: 1;
260
+ grid-column: 2;
261
+ align-self: end;
262
+ min-width: 0;
263
+ margin: 0 0 5px;
264
+ color: #20242d;
25
265
  font-size: 14px;
26
- text-align: center;
266
+ font-weight: 500;
267
+ line-height: 1.25;
268
+ }
269
+
270
+ .result-row dd {
271
+ grid-row: 2;
272
+ grid-column: 2;
273
+ align-self: start;
274
+ min-width: 0;
275
+ margin: 0;
276
+ color: #f20f19;
277
+ font-size: 18px;
278
+ font-weight: 650;
279
+ line-height: 1.28;
280
+ text-align: left;
281
+ overflow-wrap: anywhere;
282
+ letter-spacing: 0;
283
+ }
284
+
285
+ .action-bar {
286
+ position: fixed;
287
+ right: 0;
288
+ bottom: calc(env(safe-area-inset-bottom, 0px) + 15px);
289
+ left: 50%;
290
+ z-index: 10;
291
+ width: 100%;
292
+ max-width: 750px;
293
+ padding: 0 15px;
294
+ transform: translateX(-50%);
295
+ box-sizing: border-box;
296
+ pointer-events: none;
297
+ }
298
+
299
+ .query-button {
300
+ display: inline-flex;
301
+ align-items: center;
302
+ justify-content: center;
303
+ width: 100%;
304
+ height: 48px;
305
+ border-radius: 14px;
306
+ color: #ffffff;
307
+ font-size: 18px;
308
+ font-weight: 680;
309
+ line-height: 1;
310
+ background: linear-gradient(135deg, #ff3d43 0%, #ff1825 100%);
311
+ box-shadow:
312
+ 0 13px 24px rgba(255, 35, 43, 0.24),
313
+ inset 0 1px 0 rgba(255, 255, 255, 0.28);
314
+ pointer-events: auto;
315
+ }
316
+
317
+ .query-button:disabled {
318
+ cursor: not-allowed;
319
+ opacity: 0.72;
320
+ }
321
+
322
+ @media (max-width: 360px) {
323
+ .opening-reserve-page {
324
+ padding-right: 15px;
325
+ padding-left: 15px;
326
+ }
327
+
328
+ .result-row {
329
+ grid-template-columns: 32px minmax(0, 1fr);
330
+ min-height: 70px;
331
+ padding: 12px 14px;
332
+ column-gap: 12px;
333
+ }
334
+
335
+ .result-icon {
336
+ width: 32px;
337
+ height: 32px;
338
+ font-size: 18px;
339
+ }
340
+
341
+ .result-label {
342
+ font-size: 13px;
343
+ }
344
+
345
+ .result-row dd {
346
+ font-size: 16px;
347
+ }
27
348
  }
28
349
  </style>
@@ -9,30 +9,50 @@ import { showAppToast } from '@/utils/toast'
9
9
 
10
10
  defineOptions({ name: 'PbcPositionPage' })
11
11
 
12
+ /** 页面信息行的展示模型,icon 对应 Vant Icon 的图标名称。 */
12
13
  type PositionItem = {
14
+ /** 字段中文名,直接渲染到左侧标题。 */
13
15
  label: string
16
+ /** 字段展示值,接口空值统一转换为占位符。 */
14
17
  value: string
18
+ /** Vant Icon 名称,用于增强字段识别度。 */
15
19
  icon: string
20
+ /** 是否按关键金额样式突出展示。 */
16
21
  highlight?: boolean
17
22
  }
18
23
 
24
+ /** 页面按业务含义分组展示字段,避免模板中直接堆业务判断。 */
19
25
  type PositionSection = {
26
+ /** 分组唯一标识,用于 v-for key。 */
20
27
  key: string
28
+ /** 当前分组下的信息行。 */
21
29
  items: PositionItem[]
22
30
  }
23
31
 
32
+ /** 当前申请或最终查询到的人行头寸余额明细。 */
24
33
  const balanceDetail = ref<PbcPositionBalance | null>(null)
34
+ /** “发送”按钮加载态,防止重复发起申请。 */
25
35
  const sending = ref(false)
36
+ /** “查询”按钮加载态,防止查询链路重复执行。 */
26
37
  const querying = ref(false)
27
38
 
39
+ /** 任一交易进行中时禁用底部操作按钮。 */
28
40
  const actionDisabled = computed(() => sending.value || querying.value)
41
+ /** 发送交易返回的申请平台流水号;存在该值时才展示“查询”按钮。 */
29
42
  const requestRefNo = computed(() => balanceDetail.value?.requestRefNo || '')
30
43
 
44
+ /**
45
+ * 将接口明细转换为页面展示分组。
46
+ *
47
+ * 发送成功但尚未查询时,balanceDetail 只包含申请流水号;其余字段会显示
48
+ * 占位符。查询成功后,列表字段和明细字段合并进同一个对象并刷新展示。
49
+ */
31
50
  const positionSections = computed<PositionSection[]>(() => {
32
51
  const detail = balanceDetail.value
33
52
 
34
53
  return [
35
54
  {
55
+ // 基础信息:流水号、账号、更新时间等用于定位本次查询结果的字段。
36
56
  key: 'basic',
37
57
  items: [
38
58
  { label: '清算账户账号', value: fieldText(detail?.settleBankNo), icon: 'manager' },
@@ -47,6 +67,7 @@ const positionSections = computed<PositionSection[]>(() => {
47
67
  ],
48
68
  },
49
69
  {
70
+ // 余额信息:接口返回单位为元,页面统一换算为亿元展示。
50
71
  key: 'balance',
51
72
  items: [
52
73
  {
@@ -64,6 +85,7 @@ const positionSections = computed<PositionSection[]>(() => {
64
85
  ],
65
86
  },
66
87
  {
88
+ // 排队和辖内非清算账户信息:由明细交易补充返回。
67
89
  key: 'queue',
68
90
  items: [
69
91
  {
@@ -87,7 +109,14 @@ const positionSections = computed<PositionSection[]>(() => {
87
109
  ]
88
110
  })
89
111
 
112
+ /**
113
+ * 发起人行头寸余额查询申请。
114
+ *
115
+ * 成功后仅能得到申请平台流水号,页面先保存该流水号并展示“查询”按钮;
116
+ * 最终余额数据需要用户继续点击“查询”触发列表加明细的组合查询。
117
+ */
90
118
  async function handleSend() {
119
+ // 交易进行中直接忽略重复点击,避免产生多笔申请或状态交叉覆盖。
91
120
  if (actionDisabled.value) return
92
121
 
93
122
  sending.value = true
@@ -98,6 +127,7 @@ async function handleSend() {
98
127
  const response = await sendPbcPositionRequest(payload)
99
128
  const refNo = response.body.refNo || ''
100
129
 
130
+ // 保存申请流水号作为下一步查询条件,同时让页面立即展示当前编号。
101
131
  balanceDetail.value = {
102
132
  requestRefNo: refNo,
103
133
  refNo,
@@ -111,7 +141,14 @@ async function handleSend() {
111
141
  }
112
142
  }
113
143
 
144
+ /**
145
+ * 根据发送返回的申请平台流水号查询人行头寸余额。
146
+ *
147
+ * queryPbcPositionBalance 内部会先查候选列表,再逐条查询明细并匹配
148
+ * requestRefNo;页面只负责校验是否已有申请编号和维护加载态。
149
+ */
114
150
  async function handleQuery() {
151
+ // 和发送共用禁用条件,避免发送、查询两个异步流程并发写入页面状态。
115
152
  if (actionDisabled.value) return
116
153
 
117
154
  if (!requestRefNo.value) {
@@ -136,11 +173,18 @@ async function handleQuery() {
136
173
  }
137
174
  }
138
175
 
176
+ /** 将接口字符串字段标准化为可展示文本,空值统一显示占位符。 */
139
177
  function fieldText(value?: string) {
140
178
  const text = value?.trim()
141
179
  return text || '-'
142
180
  }
143
181
 
182
+ /**
183
+ * 将接口返回的元级金额转换为亿元文本。
184
+ *
185
+ * 后端金额字段可能带千分位逗号;转换前先移除逗号,非法数字或空值
186
+ * 都按占位符展示,避免页面出现 NaN。
187
+ */
144
188
  function formatYuanToBillionText(value?: string) {
145
189
  if (!value?.trim()) return '-'
146
190
 
@@ -153,6 +197,7 @@ function formatYuanToBillionText(value?: string) {
153
197
  }).format(amount / 100000000)
154
198
  }
155
199
 
200
+ /** 从异常对象中提取可读错误信息,兜底展示当前操作的默认失败文案。 */
156
201
  function getErrorMessage(error: unknown, fallback: string) {
157
202
  return error instanceof Error && error.message ? error.message : fallback
158
203
  }
@@ -160,6 +205,7 @@ function getErrorMessage(error: unknown, fallback: string) {
160
205
 
161
206
  <template>
162
207
  <main class="pbc-page">
208
+ <!-- 余额信息区:发送前显示占位符,查询成功后展示真实余额和明细字段。 -->
163
209
  <section class="balance-card" aria-label="人行头寸余额">
164
210
  <div v-for="section in positionSections" :key="section.key" class="info-section">
165
211
  <dl class="info-list">
@@ -176,7 +222,8 @@ function getErrorMessage(error: unknown, fallback: string) {
176
222
  </div>
177
223
  </section>
178
224
 
179
- <nav class="action-bar" aria-label="人行头寸操作">
225
+ <!-- 底部操作区:未获得申请流水号时只展示“发送”,发送成功后再展示“查询”。 -->
226
+ <nav class="action-bar" :class="{ 'single-action': !requestRefNo }" aria-label="人行头寸操作">
180
227
  <button
181
228
  class="action-btn send-btn"
182
229
  type="button"
@@ -186,6 +233,7 @@ function getErrorMessage(error: unknown, fallback: string) {
186
233
  <span>{{ sending ? '发送中' : '发送' }}</span>
187
234
  </button>
188
235
  <button
236
+ v-if="requestRefNo"
189
237
  class="action-btn query-btn"
190
238
  type="button"
191
239
  :disabled="actionDisabled"
@@ -198,6 +246,7 @@ function getErrorMessage(error: unknown, fallback: string) {
198
246
  </template>
199
247
 
200
248
  <style scoped>
249
+ /* 页面主体宽度与移动端安全区留白,适配 750px 设计稿容器。 */
201
250
  .pbc-page {
202
251
  width: 100%;
203
252
  max-width: 750px;
@@ -208,6 +257,7 @@ function getErrorMessage(error: unknown, fallback: string) {
208
257
  box-sizing: border-box;
209
258
  }
210
259
 
260
+ /* 重置原生按钮样式,避免不同终端默认外观影响底部操作按钮。 */
211
261
  button {
212
262
  border: 0;
213
263
  padding: 0;
@@ -216,6 +266,7 @@ button {
216
266
  appearance: none;
217
267
  }
218
268
 
269
+ /* 信息卡片承载全部余额字段,多个业务分组用浅色分隔条区分。 */
219
270
  .balance-card {
220
271
  overflow: hidden;
221
272
  margin: 17px 13px 0;
@@ -229,6 +280,7 @@ button {
229
280
  border-top: 8px solid #f7f7f8;
230
281
  }
231
282
 
283
+ /* 字段列表使用 dl 语义结构,dt 为字段名,dd 为字段值。 */
232
284
  .info-list {
233
285
  margin: 0;
234
286
  padding: 8px 13px;
@@ -246,6 +298,7 @@ button {
246
298
  border-top: 1px solid #edf0f2;
247
299
  }
248
300
 
301
+ /* 字段图标和标题保持左侧固定结构,右侧值按内容宽度右对齐。 */
249
302
  .info-row dt {
250
303
  display: flex;
251
304
  align-items: center;
@@ -288,6 +341,7 @@ button {
288
341
  white-space: nowrap;
289
342
  }
290
343
 
344
+ /* 关键余额金额使用更高权重,便于柜员快速定位清算账户余额。 */
291
345
  .info-row dd.highlight {
292
346
  color: #c91b20;
293
347
  font-size: 22px;
@@ -295,6 +349,7 @@ button {
295
349
  letter-spacing: 0;
296
350
  }
297
351
 
352
+ /* 固定底部操作栏,pointer-events 只开放给按钮,避免遮挡页面其他区域点击。 */
298
353
  .action-bar {
299
354
  position: fixed;
300
355
  right: 0;
@@ -312,6 +367,12 @@ button {
312
367
  pointer-events: none;
313
368
  }
314
369
 
370
+ /* 未获取申请流水号时只有一个发送按钮,按钮占满整行。 */
371
+ .action-bar.single-action {
372
+ grid-template-columns: 1fr;
373
+ }
374
+
375
+ /* 发送和查询按钮共享基础尺寸,具体颜色由各自业务类控制。 */
315
376
  .action-btn {
316
377
  display: inline-flex;
317
378
  align-items: center;
@@ -329,6 +390,7 @@ button {
329
390
  opacity: 0.68;
330
391
  }
331
392
 
393
+ /* 发送是主操作,使用实心红色按钮。 */
332
394
  .send-btn {
333
395
  color: #ffffff;
334
396
  background: linear-gradient(135deg, #ff3338 0%, #ff232b 100%);
@@ -337,6 +399,7 @@ button {
337
399
  inset 0 1px 0 rgba(255, 255, 255, 0.22);
338
400
  }
339
401
 
402
+ /* 查询是发送后的次级操作,使用描边按钮以弱化视觉层级。 */
340
403
  .query-btn {
341
404
  border: 1px solid #ff3038;
342
405
  color: #ef252d;
@@ -344,6 +407,7 @@ button {
344
407
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
345
408
  }
346
409
 
410
+ /* 窄屏下压缩字段和值字号,避免长字段名与金额互相挤压。 */
347
411
  @media (max-width: 350px) {
348
412
  .field-label,
349
413
  .info-row dd {
@@ -6,6 +6,7 @@ import {
6
6
  } from '@/api/rmb-position'
7
7
  import {
8
8
  formatForecastAmountText,
9
+ formatForecastAmountYuanText,
9
10
  formatRmbForecastDate,
10
11
  resolveBusinessType,
11
12
  resolveClientType,
@@ -34,6 +35,7 @@ const loading = ref(false)
34
35
  const loadError = ref(false)
35
36
  const statusOption = computed(() => resolveForecastStatus(detail.value?.predStatus))
36
37
  const heroAmount = computed(() => formatForecastAmountText(detail.value?.predAmt))
38
+ const heroAmountYuan = computed(() => formatForecastAmountYuanText(detail.value?.predAmt))
37
39
  const heroDate = computed(() => formatRmbForecastDate(detail.value?.tranDate))
38
40
 
39
41
  const detailSections = computed<DetailSection[]>(() => {
@@ -145,6 +147,7 @@ function fieldText(value?: string) {
145
147
  <span class="hero-date">{{ heroDate }}</span>
146
148
  </div>
147
149
  <strong>{{ heroAmount }}</strong>
150
+ <span v-if="heroAmountYuan !== '-'" class="hero-amount-yuan">{{ heroAmountYuan }}</span>
148
151
  <p>{{ detail.predRefNo || predRefNo }}</p>
149
152
  </section>
150
153
 
@@ -224,9 +227,19 @@ button {
224
227
  line-height: 1.1;
225
228
  }
226
229
 
230
+ .hero-amount-yuan {
231
+ display: block;
232
+ margin-top: 7px;
233
+ color: rgba(255, 255, 255, 0.74);
234
+ font-size: 12px;
235
+ font-weight: 500;
236
+ line-height: 1.35;
237
+ overflow-wrap: anywhere;
238
+ }
239
+
227
240
  .hero-card p {
228
241
  overflow: hidden;
229
- margin: 12px 0 0;
242
+ margin: 10px 0 0;
230
243
  color: rgba(255, 255, 255, 0.82);
231
244
  font-size: 12px;
232
245
  line-height: 1.3;