Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
Y
yd-csf-h5
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
1
Merge Requests
1
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
jianan
yd-csf-h5
Commits
ff73e600
Commit
ff73e600
authored
Nov 03, 2026
by
yuzhenWang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'wyz' into 'test'
优化样式发布测试 See merge request
!6
parents
a18c7ba3
a343cb81
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
95 additions
and
47 deletions
+95
-47
src/App.vue
+4
-3
src/components/common/Modal.vue
+47
-3
src/components/feature/StatementDetail.vue
+39
-37
src/views/PoliciesView.vue
+1
-1
tailwind.config.js
+4
-3
No files found.
src/App.vue
View file @
ff73e600
...
...
@@ -49,7 +49,7 @@ function isActive(path: string): boolean {
<div
class=
"h-[3px] bg-brand-600"
></div>
<header
class=
"sticky top-0 z-20 border-b border-silver-200/70 bg-white/80 backdrop-blur-lg"
>
<div
class=
"mx-auto flex max-w-3xl items-center justify-between px-4 py-3"
>
<div
class=
"text-
[18px]
font-semibold tracking-tight text-brand-700"
>
{{
t
(
'app.title'
)
}}
</div>
<div
class=
"text-
lg
font-semibold tracking-tight text-brand-700"
>
{{
t
(
'app.title'
)
}}
</div>
<LoginBadge
/>
</div>
</header>
...
...
@@ -69,13 +69,14 @@ function isActive(path: string): boolean {
v-for=
"tab in tabs"
:key=
"tab.name"
:to=
"tab.path"
class=
"flex flex-col items-center rounded-xl py-2 text-
xs
font-medium transition-colors"
class=
"flex flex-col items-center rounded-xl py-2 text-
sm
font-medium transition-colors"
:class=
"isActive(tab.path) ? 'text-brand-700' : 'text-silver-500 hover:text-silver-700'"
>
<span
class=
"rounded-full px-3 py-1 transition-colors"
:class=
"isActive(tab.path) ? 'bg-brand-50' : 'bg-transparent'"
>
{{
t
(
tab
.
labelKey
)
}}
</span>
>
{{
t
(
tab
.
labelKey
)
}}
</span
>
</RouterLink>
</div>
</nav>
...
...
src/components/common/Modal.vue
View file @
ff73e600
<
script
setup
lang=
"ts"
>
<
!-- <
script setup lang="ts">
import { Dialog, DialogPanel, DialogTitle } from '@headlessui/vue'
defineProps<{
...
...
@@ -21,4 +21,49 @@ const emit = defineEmits<{
</DialogPanel>
</div>
</Dialog>
</
template
>
\ No newline at end of file
</template> -->
<
script
setup
lang=
"ts"
>
import
{
computed
}
from
'vue'
import
{
Dialog
,
DialogPanel
,
DialogTitle
}
from
'@headlessui/vue'
type
Position
=
'auto'
|
'bottom'
|
'center'
|
'top'
const
props
=
withDefaults
(
defineProps
<
{
open
:
boolean
title
?:
string
/** 弹窗位置:auto = 移动端底部/桌面居中(原默认行为);其余为强制指定 */
position
?:
Position
}
>
(),
{
position
:
'auto'
}
)
const
emit
=
defineEmits
<
{
(
e
:
'close'
):
void
}
>
()
const
alignClass
=
computed
(
()
=>
({
auto
:
'items-end sm:items-center'
,
bottom
:
'items-end'
,
center
:
'items-center'
,
top
:
'items-start'
})[
props
.
position
]
)
</
script
>
<
template
>
<Dialog
:open=
"open"
class=
"relative z-50"
@
close=
"emit('close')"
>
<div
class=
"fixed inset-0 bg-black/30"
aria-hidden=
"true"
></div>
<div
class=
"fixed inset-0 flex justify-center p-4"
:class=
"alignClass"
>
<DialogPanel
class=
"w-full max-w-md rounded-3xl bg-white p-5 shadow-soft sm:rounded-2xl"
>
<DialogTitle
v-if=
"title"
class=
"tnum mb-3 text-lg font-semibold tracking-tight"
>
{{
title
}}
</DialogTitle>
<slot
/>
</DialogPanel>
</div>
</Dialog>
</
template
>
src/components/feature/StatementDetail.vue
View file @
ff73e600
...
...
@@ -3,12 +3,9 @@ import { computed } from 'vue'
import
{
useI18n
}
from
'vue-i18n'
import
{
formatDetailMoney
,
formatHkd
}
from
'@/utils/money'
import
{
formatPercent
}
from
'@/utils/number'
import
{
calcPremiumTotals
}
from
'@/utils/premium'
import
type
{
PaymentFrequency
,
StatementDetail
as
StatementDetailType
,
StatementItem
}
from
'@/api/types'
// import { calcPremiumTotals } from '@/utils/premium'
// PaymentFrequency,StatementItem
import
type
{
StatementDetail
as
StatementDetailType
}
from
'@/api/types'
const
props
=
defineProps
<
{
detail
:
StatementDetailType
...
...
@@ -25,37 +22,41 @@ const adjustment = computed<number | null>(() => props.detail.adjustmentAmount ?
const
hasAdjustment
=
computed
(()
=>
adjustment
.
value
!==
null
&&
adjustment
.
value
!==
0
)
const
adjustmentText
=
computed
(()
=>
formatHkd
(
adjustment
.
value
??
0
))
function
frequencyLabel
(
value
:
PaymentFrequency
):
string
{
return
t
(
`frequency.
${
value
}
`
)
}
//
function frequencyLabel(value: PaymentFrequency): string {
//
return t(`frequency.${value}`)
//
}
/** 期交保费 × 缴费年期;季缴/月缴先按每年 4/12 期年化,避免总额算少 */
function
premiumText
(
item
:
StatementItem
):
string
{
if
(
!
item
.
periodPremium
)
return
''
const
{
periods
,
annualized
,
total
}
=
calcPremiumTotals
(
item
.
periodPremium
,
item
.
paymentFrequency
,
item
.
paymentTerm
)
const
perPeriod
=
`
${
formatDetailMoney
(
item
.
periodPremium
,
item
.
originalCurrency
)}
/
${
frequencyLabel
(
item
.
paymentFrequency
)}
`
if
(
total
===
null
)
{
// 年期缺失或终身缴费:只给年化金额,不臆造总额
return
`
${
perPeriod
}
·
${
t
(
'statement.annualized'
)}
${
formatDetailMoney
(
annualized
,
item
.
originalCurrency
)}
`
}
const
perYear
=
periods
>
1
?
` ×
${
periods
}
${
t
(
'statement.periodsPerYear'
)}
`
:
''
return
`
${
perPeriod
}${
perYear
}
×
${
item
.
paymentTerm
}
${
t
(
'statement.years'
)}
=
${
formatDetailMoney
(
total
,
item
.
originalCurrency
)}
`
}
//
function premiumText(item: StatementItem): string {
//
if (!item.periodPremium) return ''
//
const { periods, annualized, total } = calcPremiumTotals(
//
item.periodPremium,
//
item.paymentFrequency,
//
item.paymentTerm
//
)
//
const perPeriod = `${formatDetailMoney(item.periodPremium, item.originalCurrency)} / ${frequencyLabel(
//
item.paymentFrequency
//
)}`
//
if (total === null) {
//
// 年期缺失或终身缴费:只给年化金额,不臆造总额
//
return `${perPeriod} · ${t('statement.annualized')} ${formatDetailMoney(
//
annualized,
//
item.originalCurrency
//
)}`
//
}
//
const perYear = periods > 1 ? ` × ${periods} ${t('statement.periodsPerYear')}` : ''
//
return `${perPeriod}${perYear} × ${item.paymentTerm} ${t('statement.years')} = ${formatDetailMoney(
//
total,
//
item.originalCurrency
//
)}`
//
}
// function rateText(rate: number): string {
// return rate > 0 ? rate.toFixed(4) : '—'
// }
function
rateText
(
rate
:
number
):
string
{
return
rate
>
0
?
rate
.
toFixed
(
4
)
:
'—'
if
(
!
(
rate
>
0
))
return
'—'
return
Number
.
isInteger
(
rate
)
?
rate
.
toFixed
(
2
)
:
rate
.
toFixed
(
4
)
}
</
script
>
...
...
@@ -74,13 +75,13 @@ function rateText(rate: number): string {
<div
class=
"mt-4 grid grid-cols-2 gap-3"
>
<div
class=
"rounded-xl bg-brand-50 px-3 py-3"
>
<div
class=
"text-xs text-brand-700/80"
>
{{
t
(
'statement.gross'
)
}}
</div>
<div
class=
"tnum mt-1 text-
xl
font-semibold leading-tight text-brand-700"
>
<div
class=
"tnum mt-1 text-
lg
font-semibold leading-tight text-brand-700"
>
{{
formatHkd
(
detail
.
grossAmount
)
}}
</div>
</div>
<div
class=
"rounded-xl bg-silver-50 px-3 py-3"
>
<div
class=
"text-xs text-silver-600"
>
{{
t
(
'statement.net'
)
}}
</div>
<div
class=
"tnum mt-1 text-
xl
font-semibold leading-tight text-silver-700"
>
<div
class=
"tnum mt-1 text-
lg
font-semibold leading-tight text-silver-700"
>
{{
formatHkd
(
detail
.
netAmount
)
}}
</div>
</div>
...
...
@@ -211,10 +212,11 @@ function rateText(rate: number): string {
<dt
class=
"shrink-0 text-silver-500"
>
{{
t
(
'statement.policyRate'
)
}}
</dt>
<dd
class=
"tnum text-silver-700"
>
{{
rateText
(
item
.
exchangeRate
)
}}
</dd>
</div>
<div
v-if=
"item.periodPremium"
class=
"col-span-2 flex gap-1.5"
>
<!--
<div
v-if=
"item.periodPremium"
class=
"col-span-2 flex gap-1.5"
>
1111
<dt
class=
"shrink-0 text-silver-500"
>
{{
t
(
'statement.premiumTerm'
)
}}
</dt>
<dd
class=
"tnum text-silver-700"
>
{{
premiumText
(
item
)
}}
</dd>
</div>
</div>
-->
<div
v-if=
"item.remark"
class=
"col-span-2 flex gap-1.5"
>
<dt
class=
"shrink-0 text-silver-500"
>
{{
t
(
'statement.itemRemark'
)
}}
</dt>
...
...
src/views/PoliciesView.vue
View file @
ff73e600
...
...
@@ -96,7 +96,7 @@ onMounted(load)
</div>
</ApiLoader>
<Modal
:open=
"modalOpen"
:title=
"selectedPolicyNo"
@
close=
"modalOpen = false"
>
<Modal
:open=
"modalOpen"
position=
"center"
:title=
"selectedPolicyNo"
@
close=
"modalOpen = false"
>
<ApiLoader
:loading=
"modalLoading"
:error=
"modalError"
...
...
tailwind.config.js
View file @
ff73e600
...
...
@@ -49,9 +49,10 @@ export default {
'2xl'
:
'1rem'
},
fontSize
:
{
xs
:
[
'.9375rem'
,
{
lineHeight
:
'1.25rem'
}],
// 13px + 20px 行高
sm
:
[
'1.125rem'
],
lg
:
[
'1.25rem'
,
{
lineHeight
:
'1.25rem'
}]
// 13px + 20px 行高
xs
:
[
'.75rem'
,
{
lineHeight
:
'1.25rem'
}],
// 13px + 20px 行高
sm
:
[
'.875rem'
],
lg
:
[
'1rem'
,
{
lineHeight
:
'1.25rem'
}]
// 13px + 20px 行高
}
}
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment