Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
杨炀
/
ztx_wx_gzt
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
ef5fda73
authored
2026-04-27 10:06:00 +0800
by
张猛
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
个人会员缴费支付
1 parent
564e3119
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
372 additions
and
371 deletions
personal/goPay_per.vue
personal/goPay_per.vue
View file @
ef5fda7
<
template
>
<view
class=
"container"
>
<view
class=
"content"
>
<view
class=
"card"
>
<view
class=
"yearRow"
>
<view
class=
"label"
>
缴费年限
</view>
<view
class=
"control"
>
<image
class=
"icon"
@
click=
"minusYear"
:src=
"config.baseUrl_api + '/fs/static/dd_02.png'"
mode=
"widthFix"
v-if=
"form.payYear > 1"
></image>
<image
class=
"icon"
:src=
"config.baseUrl_api + '/fs/static/dd_02_g.png'"
mode=
"widthFix"
v-else
></image>
<text
class=
"num"
>
{{
form
.
payYear
}}
年
</text>
<image
class=
"icon"
:src=
"config.baseUrl_api + '/fs/static/btn_03.png'"
mode=
"widthFix"
@
click=
"plusYear"
v-if=
"form.payYear
< 5
"
></image>
<image
class=
"icon"
:src=
"config.baseUrl_api + '/fs/static/btn_03_g.png'"
mode=
"widthFix"
v-else
></image>
</view>
</view>
</view>
<view
class=
"card "
>
<view
class=
"row "
>
<text
class=
"label"
>
费用合计
</text>
<text
class=
"value red"
>
{{
form
.
payYear
*
memberFee
}}
元
</text>
</view>
</view>
<view
class=
"payRow "
>
<radio-group
@
change=
"onPayTypeChange"
>
<label
class=
"radioItem"
>
<radio
value=
"1"
:checked=
"payType === '1'"
class=
"custom-radio"
/>
<view
class=
"payInfo"
>
<image
class=
"icon"
:src=
"config.baseUrl_api + '/fs/static/min.png'"
mode=
"widthFix"
></image>
<text>
民生付
</text>
</view>
</label>
</radio-group>
</view>
<view
class=
"totalRow "
>
<text
class=
"label"
>
支付费用合计
</text>
<text
class=
"value redBig"
>
{{
memberTotalFee
}}
元
</text>
</view>
</view>
<view
class=
"bottomBtn"
>
<button
class=
"payBtn"
@
click=
"handelPay"
:loading=
"isPaying"
>
立即支付 ¥
{{
memberTotalFee
}}
</button>
</view>
</view>
<view
class=
"container"
>
<view
class=
"content"
>
<view
class=
"card"
>
<view
class=
"yearRow"
>
<view
class=
"label"
>
缴费年限
</view>
<view
class=
"control"
>
<image
v-if=
"form.payYear > 1"
:src=
"config.baseUrl_api + '/fs/static/dd_02.png'"
class=
"icon"
mode=
"widthFix"
@
click=
"minusYear"
></image>
<image
v-else
:src=
"config.baseUrl_api + '/fs/static/dd_02_g.png'"
class=
"icon"
mode=
"widthFix"
></image>
<text
class=
"num"
>
{{
form
.
payYear
}}
年
</text>
<image
v-if=
"form.payYear
< 5
"
:src=
"config.baseUrl_api + '/fs/static/btn_03.png'"
class=
"icon"
mode=
"widthFix"
@
click=
"plusYear"
></image>
<image
v-else
:src=
"config.baseUrl_api + '/fs/static/btn_03_g.png'"
class=
"icon"
mode=
"widthFix"
></image>
</view>
</view>
</view>
<view
class=
"card "
>
<view
class=
"row "
>
<text
class=
"label"
>
费用合计
</text>
<text
class=
"value red"
>
{{
form
.
payYear
*
memberFee
}}
元
</text>
</view>
</view>
<view
class=
"payRow "
>
<radio-group
@
change=
"onPayTypeChange"
>
<label
class=
"radioItem"
>
<radio
:checked=
"payType === '1'"
class=
"custom-radio"
value=
"1"
/>
<view
class=
"payInfo"
>
<image
:src=
"config.baseUrl_api + '/fs/static/min.png'"
class=
"icon"
mode=
"widthFix"
></image>
<text>
民生付
</text>
</view>
</label>
</radio-group>
</view>
<view
class=
"totalRow "
>
<text
class=
"label"
>
支付费用合计
</text>
<text
class=
"value redBig"
>
{{
memberTotalFee
}}
元
</text>
</view>
</view>
<view
class=
"bottomBtn"
>
<button
:loading=
"isPaying"
class=
"payBtn"
@
click=
"handelPay"
>
立即支付 ¥
{{
memberTotalFee
}}
</button>
</view>
</view>
</
template
>
<
script
setup
>
import
{
ref
,
computed
,
onMounted
}
from
'vue'
import
{
onLoad
}
from
'@dcloudio/uni-app'
;
import
to
from
'await-to-js'
import
*
as
api
from
'@/common/api.js'
import
{
minShengPay
}
from
'@/common/pay.js'
import
{
ref
,
computed
,
onMounted
}
from
'vue'
import
{
onLoad
}
from
'@dcloudio/uni-app'
;
import
to
from
'await-to-js'
import
*
as
api
from
'@/common/api.js'
import
{
minShengPay
}
from
'@/common/pay.js'
import
config
from
'@/config.js'
const
form
=
ref
({
payYear
:
1
})
// 支付方式
const
payType
=
ref
(
'1'
)
const
isPaying
=
ref
(
false
)
// 费用与优惠
const
memberFee
=
ref
(
0
)
const
memberTotalFee
=
computed
(()
=>
{
return
memberFee
.
value
*
form
.
value
.
payYear
})
onLoad
((
options
)
=>
{
if
(
options
.
baseFormData
)
{
const
data
=
JSON
.
parse
(
decodeURIComponent
(
options
.
baseFormData
))
form
.
value
=
{
...
data
,
payYear
:
1
// 年限默认1
}
}
// 初始化接口
getMyMemberCertUnitFeeApi
()
})
// 减年限
const
minusYear
=
()
=>
{
if
(
form
.
value
.
payYear
>
1
)
{
form
.
value
.
payYear
--
}
}
// 加年限(最大 5 年)
const
plusYear
=
()
=>
{
if
(
form
.
value
.
payYear
<
5
)
{
form
.
value
.
payYear
++
}
}
// 支付方式切换
const
onPayTypeChange
=
(
e
)
=>
{
payType
.
value
=
e
.
detail
.
value
}
const
handelPay
=
async
()
=>
{
if
(
memberTotalFee
.
value
<=
0
)
{
uni
.
showToast
({
title
:
'支付金额异常'
,
icon
:
'none'
})
return
}
// 显示 loading
uni
.
showLoading
({
title
:
'创建订单...'
,
mask
:
true
})
isPaying
.
value
=
true
// 拼接完整参数
const
postData
=
{
...
form
.
value
,
payYear
:
form
.
value
.
payYear
,
payType
:
payType
.
value
,
totalFee
:
memberTotalFee
.
value
}
// 创建订单
const
[
orderErr
,
orderRes
]
=
await
to
(
api
.
insertSinglePay
(
postData
))
uni
.
hideLoading
()
if
(
orderErr
)
{
isPaying
.
value
=
false
// uni.showToast({
// title: '创建订单失败',
// icon: 'none'
// })
return
}
if
(
!
orderRes
.
data
?.
orderId
)
{
isPaying
.
value
=
false
uni
.
showToast
({
title
:
'订单创建异常'
,
icon
:
'none'
})
return
}
// 调起支付
const
[
payErr
]
=
await
to
(
minShengPay
(
orderRes
.
data
.
orderId
,
orderRes
.
data
.
payResult
.
encryptedData
))
isPaying
.
value
=
false
// 支付失败不跳转
if
(
payErr
)
{
return
}
// 支付成功,跳转页面
uni
.
redirectTo
({
url
:
`/personal/sucPay?orderId=
${
orderRes
.
data
.
orderId
}
`
})
}
// 获取会员费
async
function
getMyMemberCertUnitFeeApi
()
{
const
res
=
await
api
.
getZtxFeeConfig
()
memberFee
.
value
=
Number
(
res
.
data
.
personMemberFee
||
1500
)
}
const
form
=
ref
({
payYear
:
1
})
// 支付方式
const
payType
=
ref
(
'1'
)
const
isPaying
=
ref
(
false
)
// 费用与优惠
const
memberFee
=
ref
(
0
)
const
memberTotalFee
=
computed
(()
=>
{
return
memberFee
.
value
*
form
.
value
.
payYear
})
onLoad
((
options
)
=>
{
if
(
options
.
baseFormData
)
{
const
data
=
JSON
.
parse
(
decodeURIComponent
(
options
.
baseFormData
))
form
.
value
=
{
...
data
,
payYear
:
1
// 年限默认1
}
}
// 初始化接口
getMyMemberCertUnitFeeApi
()
})
// 减年限
const
minusYear
=
()
=>
{
if
(
form
.
value
.
payYear
>
1
)
{
form
.
value
.
payYear
--
}
}
// 加年限(最大 5 年)
const
plusYear
=
()
=>
{
if
(
form
.
value
.
payYear
<
5
)
{
form
.
value
.
payYear
++
}
}
// 支付方式切换
const
onPayTypeChange
=
(
e
)
=>
{
payType
.
value
=
e
.
detail
.
value
}
const
handelPay
=
async
()
=>
{
if
(
memberTotalFee
.
value
<=
0
)
{
uni
.
showToast
({
title
:
'支付金额异常'
,
icon
:
'none'
})
return
}
// 显示 loading
uni
.
showLoading
({
title
:
'创建订单...'
,
mask
:
true
})
isPaying
.
value
=
true
form
.
value
.
validityDate
=
undefined
// 拼接完整参数
const
postData
=
{
...
form
.
value
,
payYear
:
form
.
value
.
payYear
,
payType
:
payType
.
value
,
totalFee
:
memberTotalFee
.
value
,
}
// 创建订单
const
[
orderErr
,
orderRes
]
=
await
to
(
api
.
insertSinglePay
(
postData
))
uni
.
hideLoading
()
if
(
orderErr
)
{
isPaying
.
value
=
false
// uni.showToast({
// title: '创建订单失败',
// icon: 'none'
// })
return
}
if
(
!
orderRes
.
data
?.
orderId
)
{
isPaying
.
value
=
false
uni
.
showToast
({
title
:
'订单创建异常'
,
icon
:
'none'
})
return
}
// 调起支付
const
[
payErr
]
=
await
to
(
minShengPay
(
orderRes
.
data
.
orderId
,
orderRes
.
data
.
payResult
.
encryptedData
))
isPaying
.
value
=
false
// 支付失败不跳转
if
(
payErr
)
{
return
}
// 支付成功,跳转页面
uni
.
redirectTo
({
url
:
`/personal/sucPay?orderId=
${
orderRes
.
data
.
orderId
}
`
})
}
// 获取会员费
async
function
getMyMemberCertUnitFeeApi
()
{
const
res
=
await
api
.
getZtxFeeConfig
()
memberFee
.
value
=
Number
(
res
.
data
.
personMemberFee
||
1500
)
}
</
script
>
<
style
scoped
>
.container
{
min-height
:
100vh
;
background-color
:
#f7f7f7
;
}
.content
{
padding
:
20
rpx
20
rpx
120
rpx
;
}
.card
{
background
:
#fff
;
border-radius
:
8
rpx
;
padding
:
25
rpx
20
rpx
;
margin-bottom
:
20
rpx
;
}
.yearRow
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
margin-bottom
:
20
rpx
;
}
.yearRow
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.yearRow
.control
{
display
:
flex
;
align-items
:
center
;
}
.control
image
{
width
:
50
rpx
;
height
:
50
rpx
;
}
.yearRow
.num
{
font-size
:
28
rpx
;
color
:
#333
;
min-width
:
80
rpx
;
text-align
:
center
;
margin
:
0
10
rpx
;
}
.row
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.row
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.row
.value
{
font-size
:
30
rpx
;
color
:
#C4121B
;
font-weight
:
500
;
}
.hintRow
{
display
:
flex
;
align-items
:
flex-start
;
font-size
:
24
rpx
;
line-height
:
1.4
;
}
.hintRow
.hintText
{
color
:
#FF8124
;
flex
:
1
;
margin-top
:
10
rpx
;
}
.deductRow
{
background
:
#fff
;
padding
:
20
rpx
20
rpx
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
10
rpx
;
border-radius
:
8
rpx
;
}
.deductRow
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.deductRow
.value
{
font-size
:
30
rpx
;
color
:
#C4121B
;
}
.payRow
{
background
:
#fff
;
border-radius
:
8
rpx
;
padding
:
20
rpx
20
rpx
;
margin-bottom
:
20
rpx
;
}
.radioItem
{
display
:
flex
;
align-items
:
center
;
}
.payInfo
{
display
:
flex
;
align-items
:
center
;
margin-left
:
15
rpx
;
}
.payInfo
.icon
{
width
:
40
rpx
;
height
:
40
rpx
;
margin-right
:
10
rpx
;
}
.payInfo
text
{
font-size
:
28
rpx
;
color
:
#333
;
}
.totalRow
{
background
:
#fff
;
border-radius
:
8
rpx
;
padding
:
20
rpx
20
rpx
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-top
:
10
rpx
;
}
.totalRow
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.redBig
{
font-size
:
32
rpx
;
color
:
#C4121B
;
font-weight
:
bold
;
}
.bottomBtn
{
position
:
fixed
;
bottom
:
0
;
left
:
0
;
right
:
0
;
padding
:
20
rpx
20
rpx
;
background
:
#fff
;
border-top
:
1
rpx
solid
#eee
;
}
.payBtn
{
width
:
100%
;
height
:
88
rpx
;
line-height
:
88
rpx
;
background-color
:
#C4121B
;
color
:
#fff
;
border-radius
:
8
rpx
;
font-size
:
32
rpx
;
text-align
:
center
;
border
:
none
;
}
.payBtn
[
disabled
]
{
background-color
:
#ccc
;
color
:
#999
;
}
.red
{
color
:
#C4121B
;
}
.icon
{
width
:
30px
;
}
::v-deep
.custom-radio
.wx-radio-input
{
width
:
30
rpx
;
height
:
30
rpx
;
border-radius
:
50%
;
border
:
2
rpx
solid
#ccc
;
}
::v-deep
.custom-radio
.wx-radio-input.wx-radio-input-checked
{
border-color
:
#C4121B
!important
;
background
:
#C4121B
!important
;
}
</
style
>
\ No newline at end of file
.container
{
min-height
:
100vh
;
background-color
:
#f7f7f7
;
}
.content
{
padding
:
20
rpx
20
rpx
120
rpx
;
}
.card
{
background
:
#fff
;
border-radius
:
8
rpx
;
padding
:
25
rpx
20
rpx
;
margin-bottom
:
20
rpx
;
}
.yearRow
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
margin-bottom
:
20
rpx
;
}
.yearRow
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.yearRow
.control
{
display
:
flex
;
align-items
:
center
;
}
.control
image
{
width
:
50
rpx
;
height
:
50
rpx
;
}
.yearRow
.num
{
font-size
:
28
rpx
;
color
:
#333
;
min-width
:
80
rpx
;
text-align
:
center
;
margin
:
0
10
rpx
;
}
.row
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
}
.row
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.row
.value
{
font-size
:
30
rpx
;
color
:
#C4121B
;
font-weight
:
500
;
}
.hintRow
{
display
:
flex
;
align-items
:
flex-start
;
font-size
:
24
rpx
;
line-height
:
1.4
;
}
.hintRow
.hintText
{
color
:
#FF8124
;
flex
:
1
;
margin-top
:
10
rpx
;
}
.deductRow
{
background
:
#fff
;
padding
:
20
rpx
20
rpx
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
10
rpx
;
border-radius
:
8
rpx
;
}
.deductRow
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.deductRow
.value
{
font-size
:
30
rpx
;
color
:
#C4121B
;
}
.payRow
{
background
:
#fff
;
border-radius
:
8
rpx
;
padding
:
20
rpx
20
rpx
;
margin-bottom
:
20
rpx
;
}
.radioItem
{
display
:
flex
;
align-items
:
center
;
}
.payInfo
{
display
:
flex
;
align-items
:
center
;
margin-left
:
15
rpx
;
}
.payInfo
.icon
{
width
:
40
rpx
;
height
:
40
rpx
;
margin-right
:
10
rpx
;
}
.payInfo
text
{
font-size
:
28
rpx
;
color
:
#333
;
}
.totalRow
{
background
:
#fff
;
border-radius
:
8
rpx
;
padding
:
20
rpx
20
rpx
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-top
:
10
rpx
;
}
.totalRow
.label
{
font-size
:
28
rpx
;
color
:
#333
;
}
.redBig
{
font-size
:
32
rpx
;
color
:
#C4121B
;
font-weight
:
bold
;
}
.bottomBtn
{
position
:
fixed
;
bottom
:
0
;
left
:
0
;
right
:
0
;
padding
:
20
rpx
20
rpx
;
background
:
#fff
;
border-top
:
1
rpx
solid
#eee
;
}
.payBtn
{
width
:
100%
;
height
:
88
rpx
;
line-height
:
88
rpx
;
background-color
:
#C4121B
;
color
:
#fff
;
border-radius
:
8
rpx
;
font-size
:
32
rpx
;
text-align
:
center
;
border
:
none
;
}
.payBtn
[
disabled
]
{
background-color
:
#ccc
;
color
:
#999
;
}
.red
{
color
:
#C4121B
;
}
.icon
{
width
:
30px
;
}
::v-deep
.custom-radio
.wx-radio-input
{
width
:
30
rpx
;
height
:
30
rpx
;
border-radius
:
50%
;
border
:
2
rpx
solid
#ccc
;
}
::v-deep
.custom-radio
.wx-radio-input.wx-radio-input-checked
{
border-color
:
#C4121B
!important
;
background
:
#C4121B
!important
;
}
</
style
>
...
...
Write
Preview
Styling with
Markdown
is supported
Attach a file
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 post a comment