Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
X
xzzxzmj
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
qd01
xzzxzmj
Commits
b4da5cd7
Commit
b4da5cd7
authored
Feb 18, 2025
by
zhangsan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
1
parent
ba473afe
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
731 additions
and
376 deletions
+731
-376
components.d.ts
src/components.d.ts
+4
-0
payUp.vue
src/components/payUp.vue
+436
-0
generateRoutes.ts
src/utils/generateRoutes.ts
+1
-1
index.vue
src/views/user/index.vue
+7
-5
myapple.vue
src/views/user/myapple.vue
+189
-185
mybankCard.vue
src/views/user/mybankCard.vue
+86
-177
vite.config.ts
vite.config.ts
+8
-8
No files found.
src/components.d.ts
View file @
b4da5cd7
...
...
@@ -12,6 +12,7 @@ declare module 'vue' {
NewsCard
:
typeof
import
(
'
./components/NewsCard.vue
'
)[
'
default
'
]
Overlay
:
typeof
import
(
'
./components/overlay.vue
'
)[
'
default
'
]
PageLoading
:
typeof
import
(
'
./components/PageLoading.vue
'
)[
'
default
'
]
PayUp
:
typeof
import
(
'
./components/payUp.vue
'
)[
'
default
'
]
Progress
:
typeof
import
(
'
./components/progress.vue
'
)[
'
default
'
]
RouterLink
:
typeof
import
(
'
vue-router
'
)[
'
RouterLink
'
]
RouterView
:
typeof
import
(
'
vue-router
'
)[
'
RouterView
'
]
...
...
@@ -23,6 +24,9 @@ declare module 'vue' {
VanList
:
typeof
import
(
'
vant/es
'
)[
'
List
'
]
VanLoading
:
typeof
import
(
'
vant/es
'
)[
'
Loading
'
]
VanNavBar
:
typeof
import
(
'
vant/es
'
)[
'
NavBar
'
]
VanPopup
:
typeof
import
(
'
vant/es
'
)[
'
Popup
'
]
VanRadio
:
typeof
import
(
'
vant/es
'
)[
'
Radio
'
]
VanRadioGroup
:
typeof
import
(
'
vant/es
'
)[
'
RadioGroup
'
]
VanStep
:
typeof
import
(
'
vant/es
'
)[
'
Step
'
]
VanSteps
:
typeof
import
(
'
vant/es
'
)[
'
Steps
'
]
VanSwipe
:
typeof
import
(
'
vant/es
'
)[
'
Swipe
'
]
...
...
src/components/payUp.vue
0 → 100644
View file @
b4da5cd7
<
template
>
<van-popup
v-model:show=
"visible"
position=
"bottom"
round
class=
"pay-popup"
>
<div
class=
"pay-page"
>
<!-- 顶部标题栏 -->
<div
class=
"popup-header"
>
<div
class=
"title"
>
{{
payParams
.
payTitle
}}
</div>
<van-icon
name=
"cross"
@
click=
"handleClose"
/>
</div>
<!-- 主要内容区 -->
<div
class=
"pay-content"
>
<!-- 支付金额卡片 -->
<div
class=
"amount-card"
>
<div
class=
"amount-value"
>
<span
class=
"currency"
>
¥
</span>
<span
class=
"number"
>
{{
payParams
.
amount
}}
</span>
<span
class=
"currency"
>
元
</span>
</div>
</div>
<!-- 支付方式区域 -->
<div
class=
"payment-section"
>
<div
class=
"section-title"
>
选择支付方式
</div>
<van-radio-group
v-model=
"selectedMethod"
>
<div
class=
"method-list"
>
<div
v-for=
"method in availablePaymentMethods"
:key=
"method.value"
class=
"method-item"
:class=
"
{ active: selectedMethod === method.value }" @click="selectedMethod = method.value">
<div
class=
"method-content"
>
<img
:src=
"method.icon"
:alt=
"method.label"
class=
"method-icon"
>
<div
class=
"method-info"
>
<span
class=
"method-label"
>
{{
method
.
label
}}
</span>
<span
class=
"method-desc"
v-if=
"method.desc"
>
{{
method
.
desc
}}
</span>
</div>
</div>
<van-radio
:name=
"method.value"
/>
</div>
</div>
</van-radio-group>
</div>
<!--
<template
v-if=
"payParams.payType == 1"
>
<div
class=
"pay-title"
>
支付说明:
</div>
<div
class=
"pay-desc"
>
此费用仅用于习币用户自主开户预存账户作用,成功开户后即可进入习币交易所进行习币抛售及开启限时入仓免费提现业务!
(成功缴纳预存款开户后,可进入习币交易所申请退返预存款)
</div>
</
template
>
-->
</div>
<!-- 底部支付按钮 -->
<div
class=
"bottom-bar"
>
<div
class=
"amount-info"
>
<span
class=
"label"
>
实付金额:
</span>
<span
class=
"currency"
>
¥
</span>
<span
class=
"value"
>
{{ payParams.amount }}元
</span>
</div>
<van-button
type=
"primary"
class=
"pay-button"
:loading=
"loading"
:disabled=
"!selectedMethod || loading || isSubmitting"
@
click=
"handleSubmit"
>
<
template
v-if=
"isSubmitting"
>
提交确认,请勿退出(
{{
submitCountdown
}}
s)
</
template
>
<
template
v-else
>
确认支付
</
template
>
</van-button>
</div>
<!-- 密码输入弹窗 -->
<van-popup
v-model:show=
"showPasswordDialog"
round
position=
"bottom"
class=
"password-popup"
:close-on-click-overlay=
"false"
>
<div
class=
"password-content"
>
<div
class=
"popup-header"
>
<div
class=
"password-title"
>
请输入支付密码
</div>
<van-icon
name=
"cross"
@
click=
"showPasswordDialog = false"
/>
</div>
<var-input
v-model=
"password"
type=
"password"
maxlength=
"6"
:rules=
"[v => !!v || '请输入密码']"
class=
"password-input"
placeholder=
"请输入6位数字密码"
/>
<div
class=
"password-hint"
>
默认密码:123456
</div>
<van-button
block
round
type=
"primary"
class=
"confirm-button"
:disabled=
"!password || password.length < 6"
@
click=
"confirmPassword"
>
确认
</van-button>
</div>
</van-popup>
</div>
</van-popup>
</template>
<
script
setup
>
import
{
ref
,
computed
}
from
'
vue
'
import
{
showToast
}
from
'
vant
'
import
wxIcon
from
'
@/static/payup/wx.svg
'
import
aliIcon
from
'
@/static/payup/zfb.svg
'
import
ylIcon
from
'
@/static/payup/yinlian.svg
'
import
request
from
'
@/utils/request
'
// 状态管理
const
visible
=
ref
(
false
)
const
selectedMethod
=
ref
(
'
ali
'
)
const
loading
=
ref
(
false
)
const
showPasswordDialog
=
ref
(
false
)
const
password
=
ref
(
''
)
const
isSubmitting
=
ref
(
false
)
const
submitCountdown
=
ref
(
6
)
// 支付参数
const
payParams
=
ref
({
amount
:
0
,
payTitle
:
'
支付
'
,
payType
:
'
0
'
,
productId
:
'
0
'
,
needPassword
:
false
})
console
.
log
(
payParams
.
value
)
// 支付方式配置
const
methodsConfig
=
{
wechat
:
{
label
:
'
微信支付
'
,
icon
:
wxIcon
,
value
:
'
wechat
'
,
desc
:
'
微信快捷支付
'
},
ali
:
{
label
:
'
支付宝支付
'
,
icon
:
aliIcon
,
value
:
'
ali
'
,
desc
:
'
推荐使用支付宝支付
'
},
yl
:
{
label
:
'
云闪付
'
,
icon
:
ylIcon
,
value
:
'
yl
'
,
desc
:
'
银联安全支付
'
}
}
// 可用支付方式
const
availablePaymentMethods
=
computed
(()
=>
{
return
[
'
wechat
'
,
'
ali
'
,
'
yl
'
]
.
map
(
method
=>
methodsConfig
[
method
])
.
filter
(
Boolean
)
})
// 关闭弹窗
const
handleClose
=
()
=>
{
visible
.
value
=
false
// 重置状态
selectedMethod
.
value
=
'
ali
'
loading
.
value
=
false
showPasswordDialog
.
value
=
false
password
.
value
=
''
isSubmitting
.
value
=
false
submitCountdown
.
value
=
6
}
// 提交支付
const
handleSubmit
=
async
()
=>
{
if
(
!
selectedMethod
.
value
)
{
showToast
(
'
请选择支付方式
'
)
return
}
if
(
payParams
.
value
.
needPassword
)
{
showPasswordDialog
.
value
=
true
return
}
submitPay
()
}
// 提交支付请求
const
submitPay
=
async
()
=>
{
showToast
(
'
暂未开启支付...
'
)
return
false
try
{
isSubmitting
.
value
=
true
const
payData
=
{
remark
:
selectedMethod
.
value
,
balance
:
payParams
.
value
.
amount
,
type
:
payParams
.
value
.
payType
,
productId
:
payParams
.
value
.
productId
}
const
res
=
await
request
.
post
(
'
/ops/daybook
'
,
payData
)
if
(
res
.
code
===
200
)
{
const
payUrl
=
res
.
msg
// 根据环境跳转支付链接
if
(
navigator
.
userAgent
.
includes
(
'
APP
'
))
{
window
.
plus
?.
runtime
.
openURL
(
encodeURI
(
payUrl
))
}
else
{
window
.
location
.
href
=
payUrl
}
handleClose
()
}
else
{
throw
new
Error
(
res
.
msg
)
}
}
catch
(
error
)
{
showToast
({
message
:
error
.
message
||
'
支付失败
'
,
type
:
'
error
'
})
}
finally
{
isSubmitting
.
value
=
false
}
}
// 密码确认
const
confirmPassword
=
async
()
=>
{
if
(
password
.
value
!==
'
123456
'
)
{
showToast
(
'
支付密码错误,请重试
'
)
return
}
showPasswordDialog
.
value
=
false
password
.
value
=
''
submitPay
()
}
// 暴露打开方法
const
open
=
(
params
)
=>
{
payParams
.
value
=
{
...
payParams
.
value
,
...
params
}
visible
.
value
=
true
}
// 暴露方法给父组件
defineExpose
({
open
})
</
script
>
<
style
lang=
"scss"
scoped
>
.pay-popup
{
.pay-page
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
background
:
#f7f8fa
;
}
}
.popup-header
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
16px
;
background
:
#fff
;
border-bottom
:
1px
solid
#f5f5f5
;
.title
{
font-size
:
20px
;
font-weight
:
700
;
flex
:
1
;
text-align
:
center
;
}
.van-icon
{
font-size
:
20px
;
color
:
#999
;
}
}
.pay-content
{
flex
:
1
;
overflow-y
:
auto
;
padding
:
16px
;
}
.amount-card
{
background
:
#fff
;
border-radius
:
12px
;
padding
:
24px
;
text-align
:
center
;
margin-bottom
:
16px
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0
.04
);
.amount-value
{
.currency
{
font-size
:
24px
;
font-weight
:
500
;
color
:
#ff6b00
;
}
.number
{
font-size
:
36px
;
font-weight
:
600
;
color
:
#ff6b00
;
margin
:
0
4px
;
}
}
}
.payment-section
{
background
:
#fff
;
border-radius
:
12px
;
padding
:
16px
;
.section-title
{
font-size
:
15px
;
color
:
#333
;
margin-bottom
:
16px
;
font-weight
:
500
;
}
.method-list
{
.method-item
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
16px
;
border-bottom
:
1px
solid
#f5f5f5
;
&
:last-child
{
border-bottom
:
none
;
}
&
.active
{
background
:
#fff7e9
;
}
.method-content
{
display
:
flex
;
align-items
:
center
;
gap
:
12px
;
}
.method-icon
{
width
:
28px
;
height
:
28px
;
}
.method-info
{
display
:
flex
;
flex-direction
:
column
;
.method-label
{
font-size
:
15px
;
color
:
#333
;
margin-bottom
:
4px
;
}
.method-desc
{
font-size
:
12px
;
color
:
#999
;
}
}
}
}
}
.pay-title
{
font-size
:
15px
;
color
:
#333
;
margin
:
16px
0
8px
;
}
.pay-desc
{
font-size
:
12px
;
color
:
#666
;
line-height
:
1
.5
;
}
.bottom-bar
{
padding
:
8px
16px
;
background
:
#fff
;
border-top
:
1px
solid
#f5f5f5
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
.amount-info
{
.label
{
font-size
:
14px
;
color
:
#666
;
}
.currency
{
font-size
:
14px
;
color
:
#ff6b00
;
}
.value
{
font-size
:
20px
;
font-weight
:
600
;
color
:
#ff6b00
;
}
}
.pay-button
{
flex
:
none
;
width
:
120px
;
height
:
40px
;
font-size
:
15px
;
background
:
linear-gradient
(
to
right
,
#ff8f1f
,
#ff6b00
);
border
:
none
;
&
:
:
before
{
border
:
none
;
}
}
}
.password-popup
{
.password-content
{
padding
:
24px
16px
;
}
.password-title
{
text-align
:
center
;
font-size
:
18px
;
font-weight
:
500
;
margin-bottom
:
24px
;
}
.password-input
{
margin-bottom
:
16px
;
}
.password-hint
{
text-align
:
center
;
color
:
#999
;
font-size
:
14px
;
margin-bottom
:
24px
;
}
.confirm-button
{
height
:
44px
;
font-size
:
16px
;
}
}
</
style
>
\ No newline at end of file
src/utils/generateRoutes.ts
View file @
b4da5cd7
...
...
@@ -37,7 +37,7 @@ const titleMap: Record<string, string> = {
ddownload
:
"
APP下载
"
,
newsdetail
:
"
新闻详情
"
,
modify
:
"
修改资料
"
,
myapple
:
"
提现
记录
"
,
myapple
:
"
提现
"
,
};
// 处理路径转换为路由配置
...
...
src/views/user/index.vue
View file @
b4da5cd7
...
...
@@ -81,7 +81,7 @@ const renderList = [
{
title
:
"
邀请好友
"
,
icon
:
a5
,
path
:
"
/user/invite
"
},
{
title
:
"
修改资料
"
,
icon
:
a6
,
path
:
"
/user/modify
"
},
{
title
:
"
APP下载
"
,
icon
:
a7
,
path
:
"
/user/ddownload
"
},
{
title
:
"
提现记录
"
,
icon
:
a8
,
path
:
"
/user/myapple
"
},
//
{ title: "提现记录", icon: a8, path: "/user/myapple" },
];
const
handleClick
=
(
item
:
any
)
=>
{
if
(
item
.
title
==
"
实名认证
"
||
item
.
title
==
"
邀请好友
"
||
item
.
title
==
"
APP下载
"
||
item
.
title
==
"
我的团队
"
)
{
...
...
@@ -105,11 +105,13 @@ const tixian = (q1: string, type: number, title: string) => {
if
(
!
isEealNameAuthentication
())
{
return
false
}
if
(
q1
==
null
||
isNaN
(
Number
(
q1
))
||
Number
(
q1
)
<
1
)
{
showToast
(
"
余额不足
"
);
return
false
;
}
router
.
push
(
`/user/tixian?balance=
${
q1
}
&type=
${
type
}
&title=
${
title
}
`
);
}
router
.
push
(
"
/user/myapple
"
);
// router.push(`/user/tixian?balance=${q1}&type=${type}&title=${title}`);
};
// 明细
...
...
src/views/user/myapple.vue
View file @
b4da5cd7
<
template
>
<div
class=
"myapple-container"
>
<van-nav-bar
title=
"提现记录"
left-arrow
@
click-left=
"$router.back()"
fixed
/>
<div
class=
"content"
>
<van-list
v-model:loading=
"loading"
:finished=
"finished"
finished-text=
"没有更多了"
@
load=
"getList"
>
<div
v-for=
"(item, index) in list"
:key=
"index"
class=
"record-card"
>
<div
class=
"card-header"
>
<div
class=
"amount-info"
>
<span
class=
"label"
>
提现金额
</span>
<span
class=
"amount"
>
¥
{{
item
.
withdrawAmount
}}
</span>
<div
class=
"withdraw-page"
>
<!-- 银行卡信息 -->
<div
class=
"content-warp"
>
<div
class=
"bank-card"
>
<div
class=
"bank-card-item"
v-if=
"bankInfo.bankNum"
>
<div
class=
"bankName"
>
{{
bankInfo
.
bankName
}}
</div>
<div
class=
"bank-card-item-right-bottom"
>
<span
v-if=
"!isShow"
>
**** **** ****
{{
bankInfo
.
bankNum
.
slice
(
-
4
)
}}
</span>
<span
v-else
>
{{
bankInfo
.
bankNum
}}
</span>
<van-icon
name=
"eye-o"
v-if=
"!isShow"
@
click=
"isShow = true"
/>
<van-icon
name=
"closed-eye"
v-else
@
click=
"isShow = false"
/>
</div>
<van-tag
:type=
"getStatusType(item.status)"
round
class=
"status-tag"
>
{{
getStatusText
(
item
.
status
)
}}
</van-tag>
</div>
<div
class=
"progress-section"
>
<van-steps
:active=
"getStepByStatus(item.status)"
active-color=
"#07c160"
>
<van-step>
申请提现
</van-step>
<van-step>
缴纳手续费
</van-step>
<van-step>
解除风控
</van-step>
<van-step>
缴纳税费
</van-step>
<van-step>
到账成功
</van-step>
</van-steps>
<div
class=
"empty"
v-else
>
<van-empty
image-size=
"100"
description=
"暂未绑定银行卡"
/>
<var-button
type=
"primary"
size=
"large"
block
@
click=
"addBankCard"
>
前往添加银行卡
</var-button>
</div>
<div
class=
"card-footer"
>
<div
class=
"info-item"
>
<van-icon
name=
"clock-o"
/>
<span>
{{
item
.
createTime
}}
</span>
</div>
<div
class=
"info-item"
>
<van-icon
name=
"credit-pay"
/>
<span>
{{
item
.
bankName
}}
{{
item
.
bankNum
}}
</span>
</div>
<div
class=
"step-container"
>
<div
class=
"step-title"
>
注:缴纳完以下费用即可到账
</div>
<van-steps
direction=
"vertical"
:active=
"mainStep"
>
<van-step
v-for=
"(step, index) in steps"
:key=
"index"
>
<template
#default
>
<div
class=
"step-content"
>
<span
class=
"step-text"
>
{{
step
.
text
}}
</span>
<var-button
v-if=
"step.amount && index >= paySteps"
type=
"danger"
@
click=
"handlePay(step)"
>
立即缴纳
</var-button>
<var-button
v-if=
"step.amount && index
<
paySteps
"
type=
"success"
>
已完成缴纳
</var-button>
</div>
</
template
>
</van-step>
</van-steps>
</div>
</van-list>
</div>
<pay-up
ref=
"payUpRef"
/>
<var-button
type=
"primary"
size=
"large"
style=
"margin-top: 20px;"
block
@
click=
"tixian"
>
立即提现
</var-button>
</div>
</template>
<
script
setup
lang=
"ts"
>
import
{
ref
}
from
'
vue
'
<
script
setup
>
import
{
ref
,
onMounted
}
from
'
vue
'
import
request
from
'
@/utils/request
'
const
list
=
ref
([])
const
pageSize
=
ref
(
10
)
const
pageNum
=
ref
(
1
)
const
total
=
ref
(
0
)
const
finished
=
ref
(
false
)
const
loading
=
ref
(
false
)
const
getList
=
async
()
=>
{
try
{
const
data
=
{
withdrawType
:
1
,
beginDate
:
""
}
const
res
=
await
request
.
post
(
`/ops/withdraw/list?pageNum=
${
pageNum
.
value
}
&pageSize=
${
pageSize
.
value
}
`
,
data
)
if
(
res
.
code
===
200
)
{
list
.
value
=
[...
list
.
value
,
...(
res
.
rows
||
[])]
total
.
value
=
res
.
total
||
0
if
(
list
.
value
.
length
>=
total
.
value
)
{
finished
.
value
=
true
}
else
{
pageNum
.
value
++
}
}
else
{
showFailToast
(
res
.
msg
||
'
加载失败
'
)
finished
.
value
=
true
}
}
catch
(
error
)
{
console
.
error
(
'
获取列表失败:
'
,
error
)
showFailToast
(
'
加载失败,请重试
'
)
finished
.
value
=
true
}
finally
{
loading
.
value
=
false
}
import
{
useRouter
}
from
'
vue-router
'
import
payUp
from
'
@/components/payUp.vue
'
const
router
=
useRouter
()
// 银行卡信息
const
bankInfo
=
ref
({})
const
isShow
=
ref
(
false
)
// 主步骤
const
mainStep
=
ref
(
0
)
const
paySteps
=
ref
(
0
)
// 步骤配置
const
stepsBase
=
[
{
text
:
'
请缴纳手续费500元
'
,
amount
:
500
},
{
text
:
'
排队打款中
'
},
{
text
:
'
解除大额收款风控费500元
'
,
amount
:
500
},
{
text
:
'
解除成功
'
},
{
text
:
'
缴纳个人所得税800元
'
,
amount
:
800
},
{
text
:
'
入账中
'
},
{
text
:
'
到账成功
'
}
]
const
steps
=
ref
([])
const
tixian
=
()
=>
{
if
(
!
bankInfo
.
value
.
bankNum
)
{
showToast
(
'
请先绑定银行卡
'
)
return
}
showToast
(
stepsBase
[
paySteps
.
value
].
text
)
}
const
getStatusText
=
(
status
:
string
)
=>
{
switch
(
status
)
{
case
'
0
'
:
case
'
1
'
:
return
'
审核中
'
case
'
2
'
:
return
'
已到账
'
case
'
3
'
:
return
'
已驳回
'
default
:
return
'
未知状态
'
}
const
payUpRef
=
ref
(
null
)
const
addBankCard
=
()
=>
{
router
.
push
(
'
/user/mybankCard
'
)
}
const
getStatusType
=
(
status
:
string
)
=>
{
switch
(
status
)
{
case
'
0
'
:
case
'
1
'
:
return
'
warning
'
case
'
2
'
:
return
'
success
'
case
'
3
'
:
return
'
danger
'
default
:
return
'
default
'
}
}
const
getStepByStatus
=
(
status
:
string
)
=>
{
switch
(
status
)
{
case
'
0
'
:
return
1
case
'
1
'
:
return
2
case
'
2
'
:
return
4
case
'
3
'
:
return
0
default
:
return
0
}
// 处理支付
const
handlePay
=
(
subStep
)
=>
{
payUpRef
.
value
.
open
({
amount
:
subStep
.
amount
,
payTitle
:
subStep
.
text
,
payType
:
1
,
productId
:
123
,
needPassword
:
false
})
}
request
.
get
(
'
/ops/bankcard/list
'
).
then
(
res
=>
{
if
(
res
.
rows
.
length
>
0
)
{
bankInfo
.
value
=
res
.
rows
[
0
]
}
})
const
userInfo
=
ref
({})
userInfo
.
value
=
JSON
.
parse
(
sessionStorage
.
getItem
(
'
userInfo
'
))
mainStep
.
value
=
userInfo
.
value
.
extend4
paySteps
.
value
=
userInfo
.
value
.
extend5
steps
.
value
=
stepsBase
.
filter
((
item
,
index
)
=>
index
<
mainStep
.
value
)
</
script
>
<
style
lang=
"scss"
scoped
>
.myapple-container
{
min-height
:
100vh
;
<
style
scoped
lang=
"scss"
>
.withdraw-page
{
padding
:
20px
10px
;
box-sizing
:
border-box
;
background
:
#f7f8fa
;
}
.content
{
.bank-card
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
16px
;
}
}
.record-card
{
border-radius
:
12px
;
padding
:
16px
;
margin-bottom
:
16px
;
box-shadow
:
0
2px
12px
rgba
(
100
,
101
,
102
,
0
.08
);
background
:
#fff
;
.content-warp
{
height
:
100%
;
overflow-y
:
auto
;
}
.card-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
16px
;
.bank-card
{
margin-bottom
:
10px
;
.amount-info
{
.bankName
{
font-size
:
20px
;
font-weight
:
700
;
color
:
#323233
;
margin-bottom
:
10px
;
}
}
.bank-info
{
display
:
flex
;
flex-direction
:
column
;
}
.label
{
font-size
:
14
px
;
color
:
#666
;
margin-bottom
:
4px
;
}
.bank-name
{
font-size
:
16
px
;
font-weight
:
500
;
color
:
#323233
;
}
.amount
{
font-size
:
24px
;
font-weight
:
bold
;
color
:
#333
;
}
}
.card-number
{
font-size
:
14px
;
color
:
#969799
;
margin-top
:
4px
;
}
.status-tag
{
padding
:
6px
12px
;
}
}
.tip-text
{
color
:
#ff4d4f
;
font-size
:
14px
;
margin-bottom
:
20px
;
padding
:
0
16px
;
}
.progress-section
{
margin
:
20px
0
;
.step-container
{
background
:
#fff
;
border-radius
:
8px
;
padding
:
16px
;
:deep
(
.van-step
)
{
.van-step__title
{
font-size
:
12px
;
}
}
.step-title
{
font-size
:
14px
;
color
:
red
;
}
}
.card-footer
{
.step-content
{
padding
:
8px
0
;
display
:
flex
;
flex-direction
:
column
;
gap
:
8px
;
margin-top
:
16px
;
padding-top
:
16px
;
border-top
:
1px
solid
#f5f5f5
;
justify-content
:
space-between
;
align-items
:
center
;
}
.info-item
{
.step-text
{
font-size
:
14px
;
color
:
#323233
;
}
.sub-steps
{
margin-top
:
12px
;
padding-left
:
16px
;
}
.sub-step
{
display
:
flex
;
align-items
:
center
;
color
:
#666
;
font-size
:
13px
;
margin-bottom
:
12px
;
color
:
#969799
;
}
.van-icon
{
margin-right
:
6px
;
font-size
:
16px
;
}
}
.sub-step.active
{
color
:
#323233
;
}
.sub-step-text
{
flex
:
1
;
font-size
:
14px
;
}
.amount
{
color
:
#ff4d4f
;
margin
:
0
12px
;
font-size
:
14px
;
}
:deep
(
.van-step
)
{
.van-step__circle
{
background-color
:
#1989fa
;
border-color
:
#1989fa
;
}
.van-step__line
{
background-color
:
#1989fa
;
}
}
:deep
(
.van-step
s--horizont
al
)
{
padding
:
0
;
:deep
(
.van-step
--vertic
al
)
{
padding
:
10px
10px
10px
0
;
}
</
style
>
src/views/user/mybankCard.vue
View file @
b4da5cd7
<
script
setup
>
import
request
from
"
@/utils/request
"
;
import
{
isValidBankCard
}
from
'
@/utils/userInfoCheck
'
const
flag
=
ref
(
false
)
const
formData
=
reactive
({
bankName
:
''
,
name
:
''
,
//持卡人
name
:
''
,
//持卡人
bankNum
:
''
,
mrkzt
:
2
,
cardtype
:
1
})
const
popup1
=
ref
(
false
)
const
bankId
=
ref
(
null
)
const
bankList
=
ref
([]);
const
bankInfo
=
ref
(
null
)
function
formatCardNumber
(
cardNumber
)
{
// 检查是否是纯数字
if
(
!
/^
\d
+$/
.
test
(
cardNumber
))
{
return
cardNumber
;
// 如果不是纯数字,直接返回原始卡号
return
cardNumber
;
}
let
formattedNumber
;
const
length
=
cardNumber
.
length
;
if
(
length
<
4
)
{
return
cardNumber
;
// 如果长度小于4,直接返回原始卡号
return
cardNumber
;
}
const
maskedPart
=
"
*
"
.
repeat
(
length
-
4
);
// 生成掩码部分
const
visiblePart
=
cardNumber
.
slice
(
-
4
);
// 获取最后四位
const
maskedPart
=
"
*
"
.
repeat
(
length
-
4
);
const
visiblePart
=
cardNumber
.
slice
(
-
4
);
switch
(
length
)
{
case
16
:
...
...
@@ -36,213 +38,137 @@ function formatCardNumber(cardNumber) {
formattedNumber
=
`
${
maskedPart
.
slice
(
0
,
4
)}
${
maskedPart
.
slice
(
4
,
8
)}
${
maskedPart
.
slice
(
8
,
12
)}
${
maskedPart
.
slice
(
12
,
16
)}
${
visiblePart
}
`
;
break
;
default
:
formattedNumber
=
cardNumber
;
// 如果不是标准长度,显示完整卡号
formattedNumber
=
cardNumber
;
break
;
}
return
formattedNumber
;
}
function
formatCardNumber1
(
cardNumber
)
{
const
formattedNumber
=
cardNumber
.
replace
(
/
(\d{4})(?=\d)
/g
,
"
$1
"
);
// 每四位加一个空格
return
formattedNumber
.
trim
();
// 去掉末尾的空格
const
formattedNumber
=
cardNumber
.
replace
(
/
(\d{4})(?=\d)
/g
,
"
$1
"
);
return
formattedNumber
.
trim
();
}
function
getBackgroundColor
(
bankName
)
{
if
(
bankName
.
includes
(
"
农业
"
))
{
return
"
#009B77
"
;
// 绿色
return
"
#009B77
"
;
}
else
if
(
bankName
.
includes
(
"
工商
"
))
{
return
"
#E03C31
"
;
// 红色
return
"
#E03C31
"
;
}
else
if
(
bankName
.
includes
(
"
建设
"
))
{
return
"
#0072B5
"
;
// 蓝色
return
"
#0072B5
"
;
}
else
if
(
bankName
.
includes
(
"
中国
"
))
{
return
"
#C0C0C0
"
;
// 银色
return
"
#C0C0C0
"
;
}
else
if
(
bankName
.
includes
(
"
交通
"
))
{
return
"
#FF8C00
"
;
// 橙色
return
"
#FF8C00
"
;
}
else
if
(
bankName
.
includes
(
"
招商
"
))
{
return
"
#FF4500
"
;
// 橙红色
}
else
if
(
bankName
.
includes
(
"
浦发
"
))
{
return
"
#4682B4
"
;
// 钢蓝色
}
else
if
(
bankName
.
includes
(
"
中信
"
))
{
return
"
#8A2BE2
"
;
// 蓝紫色
}
else
if
(
bankName
.
includes
(
"
光大
"
))
{
return
"
#FF69B4
"
;
// 粉红色
}
else
if
(
bankName
.
includes
(
"
民生
"
))
{
return
"
#FFD700
"
;
// 金色
}
else
if
(
bankName
.
includes
(
"
兴业
"
))
{
return
"
#6A5ACD
"
;
// 深蓝色
}
else
if
(
bankName
.
includes
(
"
平安
"
))
{
return
"
#FF6347
"
;
// 番茄色
}
else
if
(
bankName
.
includes
(
"
华夏
"
))
{
return
"
#20B2AA
"
;
// 浅海洋蓝
}
else
if
(
bankName
.
includes
(
"
上海
"
))
{
return
"
#FF1493
"
;
// 深粉色
}
else
if
(
bankName
.
includes
(
"
北京
"
))
{
return
"
#8B4513
"
;
// 赭色
}
else
if
(
bankName
.
includes
(
"
南京
"
))
{
return
"
#B22222
"
;
// 火砖色
}
else
if
(
bankName
.
includes
(
"
渤海
"
))
{
return
"
#4682B4
"
;
// 钢蓝色
}
else
if
(
bankName
.
includes
(
"
徽商
"
))
{
return
"
#FF4500
"
;
// 橙红色
}
else
if
(
bankName
.
includes
(
"
江苏
"
))
{
return
"
#2E8B57
"
;
// 海洋绿
}
else
if
(
bankName
.
includes
(
"
深圳发展
"
))
{
return
"
#FF8C00
"
;
// 橙色
}
else
if
(
bankName
.
includes
(
"
中原
"
))
{
return
"
#8B008B
"
;
// 深紫色
}
else
if
(
bankName
.
includes
(
"
南洋商业
"
))
{
return
"
#FFB6C1
"
;
// 浅粉色
}
else
if
(
bankName
.
includes
(
"
东亚
"
))
{
return
"
#7B68EE
"
;
// 橙色
}
else
if
(
bankName
.
includes
(
"
大连
"
))
{
return
"
#ADFF2F
"
;
// 黄绿色
}
else
if
(
bankName
.
includes
(
"
长安
"
))
{
return
"
#FF4500
"
;
// 橙红色
}
else
if
(
bankName
.
includes
(
"
重庆
"
))
{
return
"
#FF6347
"
;
// 番茄色
}
else
if
(
bankName
.
includes
(
"
甘肃
"
))
{
return
"
#FFD700
"
;
// 金色
}
else
if
(
bankName
.
includes
(
"
青岛
"
))
{
return
"
#00BFFF
"
;
// 深天蓝
}
else
if
(
bankName
.
includes
(
"
临商
"
))
{
return
"
#FF69B4
"
;
// 粉红色
}
else
if
(
bankName
.
includes
(
"
西安
"
))
{
return
"
#8A2BE2
"
;
// 蓝紫色
}
else
if
(
bankName
.
includes
(
"
新疆
"
))
{
return
"
#FF8C00
"
;
// 橙色
}
else
if
(
bankName
.
includes
(
"
宁波
"
))
{
return
"
#4682B4
"
;
// 钢蓝色
}
else
if
(
bankName
.
includes
(
"
哈尔滨
"
))
{
return
"
#C71585
"
;
// 中紫色
}
else
if
(
bankName
.
includes
(
"
南方
"
))
{
return
"
#FF4500
"
;
// 橙红色
}
else
if
(
bankName
.
includes
(
"
华融湘江
"
))
{
return
"
#FF6347
"
;
// 番茄色
}
else
if
(
bankName
.
includes
(
"
长城
"
))
{
return
"
#FFD700
"
;
// 金色
}
else
if
(
bankName
.
includes
(
"
盛京
"
))
{
return
"
#00BFFF
"
;
// 深天蓝
}
else
if
(
bankName
.
includes
(
"
吉林
"
))
{
return
"
#FF69B4
"
;
// 粉红色
}
else
if
(
bankName
.
includes
(
"
青海
"
))
{
return
"
#8A2BE2
"
;
// 蓝紫色
}
else
if
(
bankName
.
includes
(
"
陕西
"
))
{
return
"
#FF8C00
"
;
// 橙色
}
else
if
(
bankName
.
includes
(
"
海南
"
))
{
return
"
#4682B4
"
;
// 钢蓝色
}
else
if
(
bankName
.
includes
(
"
云南
"
))
{
return
"
#C71585
"
;
// 中紫色
}
else
if
(
bankName
.
includes
(
"
甘肃
"
))
{
return
"
#FF4500
"
;
// 橙红色
}
else
if
(
bankName
.
includes
(
"
山西
"
))
{
return
"
#FF6347
"
;
// 番茄色
}
else
if
(
bankName
.
includes
(
"
内蒙古
"
))
{
return
"
#FFD700
"
;
// 金色
}
else
if
(
bankName
.
includes
(
"
广西
"
))
{
return
"
#00BFFF
"
;
// 深天蓝
}
else
if
(
bankName
.
includes
(
"
西南
"
))
{
return
"
#FF69B4
"
;
// 粉红色
return
"
#FF4500
"
;
}
else
{
return
"
#
FFFFFF
"
;
// 默认白
色
return
"
#
4682B4
"
;
// 默认蓝
色
}
}
function
getBankList
()
{
request
.
get
(
"
/ops/bankcard/list
"
,
{}).
then
((
res
)
=>
{
if
(
res
.
code
==
200
)
{
if
(
res
.
rows
.
length
)
{
bankList
.
value
=
res
.
rows
?.
map
((
v
)
=>
Object
.
assign
({},
v
,
{
switch
:
false
})
);
// 获取银行卡信息
function
getBankInfo
()
{
request
.
get
(
"
/ops/bankcard/list
"
,
{
params
:{
cardtype
:
1
}}).
then
((
res
)
=>
{
if
(
res
.
code
==
200
&&
res
.
rows
.
length
>
0
)
{
bankInfo
.
value
=
{
...
res
.
rows
[
0
],
switch
:
false
}
bankId
.
value
=
res
.
rows
[
0
].
id
}
});
}
const
editCard
=
(
item
)
=>
{
formData
.
bankName
=
item
.
bankName
formData
.
name
=
item
.
name
formData
.
bankNum
=
item
.
bankNum
formData
.
cardtype
=
item
.
cardtype
popup1
.
value
=
true
// 编辑银行卡
const
editCard
=
()
=>
{
formData
.
bankName
=
bankInfo
.
value
.
bankName
formData
.
name
=
bankInfo
.
value
.
name
formData
.
bankNum
=
bankInfo
.
value
.
bankNum
formData
.
cardtype
=
bankInfo
.
value
.
cardtype
flag
.
value
=
true
bankId
.
value
=
item
.
id
popup1
.
value
=
true
}
const
deleteCard
=
(
item
)
=>
{
showConfirmDialog
({
title
:
'
确认删除该银行卡?
'
,
message
:
`银行卡号
${
item
.
bankNum
}
`
,
}).
then
(()
=>
{
request
({
url
:
"
/business/businessBankCard/delete?id=
"
+
item
.
id
,
method
:
"
delete
"
,
}).
then
((
res
)
=>
{
if
(
res
.
code
==
200
)
{
showSuccessToast
(
'
删除银行卡成功!
'
)
getBankList
();
}
else
{
showFailToast
(
res
.
msg
)
}
})
});
}
function
addCard
()
{
// 提交表单
function
submitForm
()
{
let
reg2
=
isValidBankCard
(
formData
.
bankNum
);
if
(
!
reg2
)
{
showFailToast
(
'
请输入正确的银行卡号
'
)
return
}
formData
.
bankName
=
formData
.
bankName
.
trim
();
request
.
post
(
"
/ops/bankcard/add
"
,
formData
).
then
((
res
)
=>
{
// 根据是否有bankId判断是新增还是编辑
const
url
=
bankId
.
value
?
'
/ops/bankcard/edit
'
:
'
/ops/bankcard/add
'
const
params
=
bankId
.
value
?
{
...
formData
,
bankId
:
bankId
.
value
}
:
formData
request
.
post
(
url
,
params
).
then
((
res
)
=>
{
if
(
res
.
code
==
200
)
{
showSuccessToast
(
'
添加银行卡成功!
'
)
showSuccessToast
(
bankId
.
value
?
'
修改银行卡成功!
'
:
'
添加银行卡成功!
'
)
popup1
.
value
=
false
getBank
List
();
getBank
Info
();
}
else
{
showFailToast
(
res
.
data
.
msg
)
popup1
.
value
=
false
getBankList
();
showFailToast
(
res
.
msg
)
}
});
}
function
openAdd
()
{
// 重置表单
formData
.
bankName
=
''
formData
.
name
=
''
formData
.
bankNum
=
''
formData
.
cardtype
=
1
flag
.
value
=
false
popup1
.
value
=
true
}
getBankList
();
onMounted
(()
=>
{
getBankInfo
()
})
</
script
>
<
template
>
<div
class=
"container"
>
<div
class=
"card-list"
>
<template
v-if=
"bankList.length"
>
<div
v-for=
"bank in bankList"
class=
"card-container"
:class=
"[
getBackgroundColor(bank.bankName) == '#FFFFFF' ? 'blackColor' : '',
]"
:style=
"
{ backgroundColor: getBackgroundColor(bank.bankName) }">
<!-- 已绑定银行卡 -->
<template
v-if=
"bankInfo"
>
<div
class=
"card-container"
:class=
"[
getBackgroundColor(bankInfo.bankName) == '#FFFFFF' ? 'blackColor' : '',
]"
:style=
"
{ backgroundColor: getBackgroundColor(bankInfo.bankName) }">
<div
class=
"bank-name"
>
{{
bank
.
bankName
}}
{{
bank
Info
.
bankName
}}
</div>
<!--
<div
class=
"viewdetail"
@
click=
"editCard(bank)"
>
编辑银行卡
</div>
<div
class=
"viewdetail viewdetail1"
@
click=
"deleteCard(bank)"
>
删除银行卡
</div>
-->
<div
class=
"card-type"
>
可用余额:
{{
}}
元
</div>
<div
class=
"viewdetail"
@
click=
"editCard"
>
编辑
</div>
<div
class=
"card-type"
>
持卡人:
{{
bankInfo
.
name
}}
</div>
<div
class=
"account-number"
>
<span
v-if=
"!bank.switch"
>
{{
formatCardNumber
(
bank
.
bankNum
)
}}
<span
v-if=
"!bank
Info
.switch"
>
{{
formatCardNumber
(
bank
Info
.
bankNum
)
}}
</span>
<span
v-if=
"bank.switch"
>
{{
formatCardNumber1
(
bank
.
bankNum
)
}}
<span
v-if=
"bank
Info
.switch"
>
{{
formatCardNumber1
(
bank
Info
.
bankNum
)
}}
</span>
<var-icon
v-if=
"bank.switch"
class=
"icon"
name=
"view"
color=
"#fff"
:size=
"20"
@
click=
"bank
.switch = !bank
.switch"
/>
<var-icon
v-if=
"!bank.switch"
class=
"icon"
name=
"view-outline"
color=
"#fff"
:size=
"20"
@
click=
"bank
.switch = !bank
.switch"
/>
<var-icon
v-if=
"bank
Info
.switch"
class=
"icon"
name=
"view"
color=
"#fff"
:size=
"20"
@
click=
"bank
Info.switch = !bankInfo
.switch"
/>
<var-icon
v-if=
"!bank
Info
.switch"
class=
"icon"
name=
"view-outline"
color=
"#fff"
:size=
"20"
@
click=
"bank
Info.switch = !bankInfo
.switch"
/>
</div>
</div>
</
template
>
<!-- 未绑定银行卡 -->
<div
v-else
class=
"emptyTips"
>
暂未添加银行卡
</div>
</div>
<var-button
block
type=
"primary"
@
click=
"openAdd"
size=
"large"
>
添加银行卡
</var-button>
<!-- 底部按钮 -->
<var-button
v-if=
"!bankInfo"
block
type=
"primary"
@
click=
"openAdd"
size=
"large"
>
添加银行卡
</var-button>
<!-- 表单弹窗 -->
<var-popup
v-model:show=
"popup1"
position=
"bottom"
>
<div
style=
"padding: 20px;"
>
<div
class=
"warpbox"
>
<div
class=
"title"
style=
"text-align: center;"
>
添加银行卡
</div>
<div
class=
"title"
style=
"text-align: center;"
>
{{ flag ? '修改银行卡' : '添加银行卡' }}
</div>
</div>
<var-form
ref=
"form"
scroll-to-error=
"start"
>
<var-space
direction=
"column"
:size=
"[14, 0]"
>
...
...
@@ -251,7 +177,9 @@ getBankList();
<var-input
placeholder=
"发卡银行:"
:rules=
"v => !!v || '发卡银行不能为空'"
v-model=
"formData.bankName"
/>
</var-space>
</var-form>
<var-button
style=
"margin: 20px 0 40px 0;"
size=
"large"
block
type=
"primary"
@
click=
"addCard"
>
添加银行卡
</var-button>
<var-button
style=
"margin: 20px 0 40px 0;"
size=
"large"
block
type=
"primary"
@
click=
"submitForm"
>
{{ flag ? '确认修改' : '添加银行卡' }}
</var-button>
</div>
</var-popup>
</div>
...
...
@@ -283,15 +211,6 @@ getBankList();
color
:
#fff
;
position
:
relative
;
.defaultcar
{
position
:
absolute
;
right
:
10px
;
top
:
10px
;
border
:
1px
solid
#fff
;
padding
:
2px
10px
;
border-radius
:
5px
;
}
.viewdetail
{
position
:
absolute
;
right
:
10px
;
...
...
@@ -300,13 +219,8 @@ getBankList();
padding
:
2px
10px
;
border-radius
:
5px
;
}
.viewdetail1
{
top
:
60px
;
}
}
.bank-name
{
font-size
:
20px
;
text-align
:
left
;
...
...
@@ -315,8 +229,7 @@ getBankList();
.card-type
{
font-size
:
16px
;
margin
:
5px
0
;
visibility
:
hidden
;
margin
:
10px
0
;
}
.account-number
{
...
...
@@ -332,10 +245,6 @@ getBankList();
.blackColor
{
color
:
#000
;
.defaultcar
{
border
:
1px
solid
#000
;
}
.viewdetail
{
border
:
1px
solid
#000
;
}
...
...
vite.config.ts
View file @
b4da5cd7
...
...
@@ -39,12 +39,12 @@ export default defineConfig({
dts
:
'
src/components.d.ts
'
,
dirs
:
[
'
src/components
'
]
}),
vitePluginBundleObfuscator
({
enable
:
true
,
log
:
true
,
autoExcludeNodeModules
:
true
,
threadPool
:
true
,
})
//
vitePluginBundleObfuscator({
//
enable: true,
//
log: true,
//
autoExcludeNodeModules: true,
//
threadPool: true,
//
})
],
resolve
:
{
alias
:
{
...
...
@@ -77,8 +77,8 @@ export default defineConfig({
port
:
8080
,
proxy
:
{
'
/api
'
:
{
//
target: 'http://27.124.5.14:9023',
target
:
'
http://43.199.109.243:3000/api
'
,
target
:
'
http://27.124.5.14:9023
'
,
//
target: 'http://43.199.109.243:3000/api',
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
api/
,
''
)
}
...
...
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