Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
zyjj2025
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
zyjj2025
Commits
125778df
Commit
125778df
authored
Jan 27, 2025
by
qd01
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
代码更新 缴费
parent
025fa3cb
Changes
8
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
517 additions
and
269 deletions
+517
-269
app.vue
app/app.vue
+1
-4
PayUp.vue
app/components/PayUp.vue
+253
-190
index.vue
app/pages/index/index.vue
+14
-5
index.vue
app/pages/my/index.vue
+12
-1
[id].vue
app/pages/product/company/[id].vue
+47
-28
product.vue
app/pages/user/product.vue
+112
-1
zjmx.vue
app/pages/user/zjmx.vue
+50
-40
payment.d.ts
app/types/payment.d.ts
+28
-0
No files found.
app/app.vue
View file @
125778df
...
...
@@ -21,10 +21,7 @@ const keepAliveRouteNames = computed(() => {
</
template
>
<
style
>
@font-face
{
font-family
:
pingfang
;
src
:
url('./static/PingFangSC-Regular.otf')
;
}
.fade-enter-active
,
.fade-leave-active
{
...
...
app/components/PayUp.vue
View file @
125778df
<
template
>
<div
class=
"container"
>
<!--
<var-popup
:show=
"props.show"
position=
"bottom"
close-on-click-overlay
@
update:show=
"(val) => emit('update:show', val)"
@
closed=
"handleClose"
>
<var-popup
v-model:show=
"showPopup"
position=
"bottom"
@
closed=
"handleClose"
>
<div
class=
"pop"
>
<!-- 付款金额 -->
<div
class=
"top"
>
<span
class=
"title"
>
付款金额
</span>
<span
class=
"money"
>
{{
props
.
mony
}}{{
props
.
dw
}}
</span>
<span
class=
"money"
>
{{
paymentConfig
.
mony
}}{{
paymentConfig
.
dw
}}
</span>
</div>
<!-- 支付方式 -->
<div
class=
"pays"
>
<var-radio-group
:model-value=
"selectedPayment"
@
update:model-value=
"handlePaymentChange
"
>
<van-radio-group
v-model=
"selectedPayment
"
>
<var-card
class=
"payment-methods"
>
<var-cell
v-for=
"method in visiblePaymentMethods"
:key=
"method.name"
:class=
"['payment-item',
{ active: selectedPayment === method.name }]">
<template
#left
>
<div
class=
"payment-left"
>
<img
:src=
"method.icon"
:alt=
"method.label"
class=
"payment-icon"
>
<span
class=
"payment-label"
>
{{
method
.
label
}}
</span>
<van-cell
clickable
@
click=
"selectedPayment = method.name"
v-for=
"method in visiblePaymentMethods"
:key=
"method.name"
:class=
"['payment-item',
{ active: selectedPayment === method.name }]">
<template
#title
>
<div
class=
"item1"
>
<img
:src=
"method.icon"
mode=
""
class=
"payment-icon"
>
<div
class=
"paywarp"
>
<div
class=
"title"
>
{{
method
.
label
}}
</div>
<div
class=
"sub"
>
银行单笔限额200000.00元
</div>
</div>
</div>
</
template
>
<
template
#right
>
<var
-radio
:name=
"method.name"
/>
<
template
#right-icon
>
<van
-radio
:name=
"method.name"
/>
</
template
>
</var
-cell>
</van
-cell>
</var-card>
</var
-radio-group>
</van
-radio-group>
</div>
<var-notice-bar
v-if=
"props.isBindc"
:content=
"text1"
/>
<var-notice-bar
v-if=
"props.isBindpay"
:content=
"text2"
/>
<div
v-if=
"props.zfsm"
class=
"note-text"
>
注:{{ props.zfsm }}
</div>
<!-- 提示信息 -->
<div
v-if=
"paymentConfig.zfsm"
class=
"note-text"
>
注:{{ paymentConfig.zfsm }}
</div>
<!-- 提交按钮 -->
<var-button
block
type=
"primary"
class=
"submit-btn"
:loading=
"isSubmitting"
:disabled=
"isSubmitting"
@
click=
"handleSubmit"
>
{{ isSubmitting ? `提交确认,请勿退出${countdown}` : props
.btn }}
{{ isSubmitting ? `提交确认,请勿退出${countdown}` : paymentConfig
.btn }}
</var-button>
</div>
</var-popup>
--
>
1111
</var-popup
>
<!-- 密码输入弹窗 -->
<!-- <var-popup :show="showPasswordInput" @update:show="(val) => showPasswordInput = val
" position="center">
<var-popup
v-model:show=
"showPasswordInput
"
position=
"center"
>
<div
class=
"password-popup"
>
<span
class=
"password-title"
>
请输入支付密码
</span>
<var-input
v-model=
"password"
type=
"password"
maxlength=
"6"
:focused=
"showPasswordInput"
@change="handlePasswordChange"
@keyup.enter="handlePasswordFinish" />
@
keyup.enter=
"handlePasswordFinish"
/>
<span
class=
"password-hint"
>
默认支付密码:123456
</span>
</div>
</var-popup> -->
</div>
</var-popup>
</template>
<
script
setup
lang=
"ts"
>
import
{
ref
,
computed
}
from
'
vue
'
import
{
Snackbar
}
from
'
@varlet/ui
'
import
{
post
}
from
'
@/utils/request
'
import
type
{
PaymentProps
,
PaymentMethod
}
from
'
@/types/payment
'
import
{
useDebounceFn
}
from
'
@vueuse/core
'
import
{
ref
,
computed
,
watch
}
from
'
vue
'
;
import
{
post
}
from
'
@/utils/request
'
;
import
type
{
PaymentProps
,
PaymentMethod
}
from
'
@/types/payment
'
;
import
{
useDebounceFn
}
from
'
@vueuse/core
'
;
// 支付方式图标
import
wxIcon
from
'
@/static/payup/wx.svg
'
import
zfbIcon
from
'
@/static/payup/zfb.svg
'
import
ylIcon
from
'
@/static/payup/yinlian.svg
'
import
jljIcon
from
'
@/static/payup/jlj.svg
'
import
fhIcon
from
'
@/static/payup/fh.svg
'
import
yjIcon
from
'
@/static/payup/yj.svg
'
const
props
=
withDefaults
(
defineProps
<
PaymentProps
>
(),
{
show
:
false
,
mony
:
0
,
import
wxIcon
from
'
@/static/payup/wx.svg
'
;
import
zfbIcon
from
'
@/static/payup/zfb.svg
'
;
import
ylIcon
from
'
@/static/payup/yinlian.svg
'
;
import
jljIcon
from
'
@/static/payup/jlj.svg
'
;
import
fhIcon
from
'
@/static/payup/fh.svg
'
;
import
yjIcon
from
'
@/static/payup/yj.svg
'
;
// 定义默认值
const
defaultConfig
=
{
dw
:
'
元
'
,
btn
:
'
确认支付
'
})
btn
:
'
确认支付
'
,
url
:
'
/ops/daybook
'
,
password
:
false
,
needCheck
:
false
,
payway
:
0
,
wechat
:
1
,
zfb
:
1
,
ysf
:
1
,
tzj
:
0
,
jtqb
:
0
,
dtqb
:
0
,
zfsm
:
''
,
isBindc
:
true
,
isBindpay
:
false
};
// props 只接收必要的属性,移除 show
const
props
=
defineProps
<
{
paymentInfo
:
{
mony
:
number
productId
:
string
type
:
number
}
}
>
();
// 内部状态,包含 show
const
paymentConfig
=
ref
({
show
:
false
,
// show 移到内部维护
...
defaultConfig
,
...
props
.
paymentInfo
});
// 监听 props 变化
watch
(()
=>
props
.
paymentInfo
,
(
newVal
)
=>
{
paymentConfig
.
value
=
{
...
paymentConfig
.
value
,
// 保持当前的 show 状态
...
defaultConfig
,
...
newVal
};
},
{
deep
:
true
});
// 定义事件,移除 update:show
const
emit
=
defineEmits
<
{
(
e
:
'
update:show
'
,
value
:
boolean
):
void
(
e
:
'
close
'
):
void
(
e
:
'
beforeClick
'
,
key
:
string
):
void
}
>
()
(
e
:
'
close
'
):
void
;
(
e
:
'
beforeClick
'
,
key
:
string
):
void
;
}
>
();
// 修改 showPopup 计算属性
const
showPopup
=
computed
({
get
:
()
=>
paymentConfig
.
value
.
show
,
set
:
(
val
)
=>
{
paymentConfig
.
value
.
show
=
val
;
if
(
!
val
)
emit
(
'
close
'
);
},
});
// 提供打开方法给父组件
const
open
=
()
=>
{
paymentConfig
.
value
.
show
=
true
;
};
// 暴露方法给父组件
defineExpose
({
open
});
// 状态管理
const
selectedPayment
=
ref
(
'
ali
'
)
const
isSubmitting
=
ref
(
false
)
const
countdown
=
ref
(
6
)
const
showPasswordInput
=
ref
(
false
)
const
password
=
ref
(
''
)
// 提示文本
const
text1
=
'
该笔费用为开通国际银行卡跨国转账至中国境内银行卡手续费,该费用由中国银保监会收取
'
const
text2
=
'
该笔款项是一带一路银行卡绑定第三方支付手续费,费用由第三方收取
'
const
selectedPayment
=
ref
(
'
ali
'
);
const
isSubmitting
=
ref
(
false
);
const
countdown
=
ref
(
6
);
const
showPasswordInput
=
ref
(
false
);
const
password
=
ref
(
''
);
// 支付方式列表
const
paymentMethods
=
computed
<
PaymentMethod
[]
>
(()
=>
[
{
name
:
'
wechat
'
,
label
:
'
微信支付
'
,
icon
:
wxIcon
,
visible
:
p
rops
.
wechat
===
1
},
{
name
:
'
ali
'
,
label
:
'
支付宝支付
'
,
icon
:
zfbIcon
,
visible
:
p
rops
.
zfb
===
1
},
{
name
:
'
yl
'
,
label
:
'
云闪付
'
,
icon
:
ylIcon
,
visible
:
p
rops
.
ysf
===
1
},
{
name
:
'
tzj
'
,
label
:
'
保额
'
,
icon
:
jljIcon
,
visible
:
p
rops
.
tzj
===
1
},
{
name
:
'
jtqb
'
,
label
:
'
体验金
'
,
icon
:
fhIcon
,
visible
:
p
rops
.
jtqb
===
1
},
{
name
:
'
dtqb
'
,
label
:
'
动态钱包
'
,
icon
:
yjIcon
,
visible
:
p
rops
.
dtqb
===
1
}
])
{
name
:
'
wechat
'
,
label
:
'
微信支付
'
,
icon
:
wxIcon
,
visible
:
p
aymentConfig
.
value
.
wechat
===
1
},
{
name
:
'
ali
'
,
label
:
'
支付宝支付
'
,
icon
:
zfbIcon
,
visible
:
p
aymentConfig
.
value
.
zfb
===
1
},
{
name
:
'
yl
'
,
label
:
'
云闪付
'
,
icon
:
ylIcon
,
visible
:
p
aymentConfig
.
value
.
ysf
===
1
},
{
name
:
'
tzj
'
,
label
:
'
保额
'
,
icon
:
jljIcon
,
visible
:
p
aymentConfig
.
value
.
tzj
===
1
},
{
name
:
'
jtqb
'
,
label
:
'
体验金
'
,
icon
:
fhIcon
,
visible
:
p
aymentConfig
.
value
.
jtqb
===
1
},
{
name
:
'
dtqb
'
,
label
:
'
动态钱包
'
,
icon
:
yjIcon
,
visible
:
p
aymentConfig
.
value
.
dtqb
===
1
},
])
;
const
visiblePaymentMethods
=
computed
(()
=>
paymentMethods
.
value
.
filter
(
method
=>
method
.
visible
)
)
paymentMethods
.
value
.
filter
(
(
method
)
=>
method
.
visible
)
)
;
// 处理支付方式变更
const
handlePaymentChange
=
(
value
:
string
)
=>
{
selectedPayment
.
value
=
value
}
// 提交处理(带防抖)
const
handleSubmit
=
useDebounceFn
(
async
()
=>
{
if
(
paymentConfig
.
value
.
password
)
{
showPasswordInput
.
value
=
true
;
return
;
}
const
uniqueKey
=
paymentConfig
.
value
.
needCheck
?
generateUniqueKey
()
:
undefined
;
if
(
paymentConfig
.
value
.
needCheck
&&
uniqueKey
)
{
emit
(
'
beforeClick
'
,
uniqueKey
);
}
startCountdown
();
await
handlePayment
(
uniqueKey
);
},
1000
);
// 关闭弹窗
const
handleClose
=
()
=>
{
paymentConfig
.
value
.
show
=
false
;
};
// 密码处理
const
handlePasswordFinish
=
()
=>
{
if
(
password
.
value
===
'
123456
'
)
{
showPasswordInput
.
value
=
false
;
handlePayment
();
}
else
{
showFailToast
(
'
密码错误
'
);
}
password
.
value
=
''
;
};
// 生成唯一标识
const
generateUniqueKey
=
()
=>
{
const
chars
=
'
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
'
return
Array
.
from
({
length
:
99
},
()
=>
chars
[
Math
.
floor
(
Math
.
random
()
*
chars
.
length
)]
).
join
(
''
)
}
const
chars
=
'
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
'
;
return
Array
.
from
({
length
:
99
},
()
=>
chars
[
Math
.
floor
(
Math
.
random
()
*
chars
.
length
)]).
join
(
''
);
};
// 倒计时处理
const
startCountdown
=
()
=>
{
isSubmitting
.
value
=
true
isSubmitting
.
value
=
true
;
const
timer
=
setInterval
(()
=>
{
countdown
.
value
--
countdown
.
value
--
;
if
(
countdown
.
value
<=
0
)
{
clearInterval
(
timer
)
isSubmitting
.
value
=
false
countdown
.
value
=
6
clearInterval
(
timer
)
;
isSubmitting
.
value
=
false
;
countdown
.
value
=
6
;
}
},
1000
)
}
},
1000
)
;
}
;
// 支付处理
const
handlePayment
=
async
(
uniqueKey
?:
string
)
=>
{
if
(
!
selectedPayment
.
value
)
{
Snackbar
.
error
(
'
请选择支付方式
'
)
return
showFailToast
(
'
请选择支付方式
'
);
return
;
}
const
paymentData
=
{
productId
:
p
rops
.
productId
,
productId
:
p
aymentConfig
.
value
.
productId
,
remark
:
selectedPayment
.
value
,
balance
:
p
rops
.
mony
,
type
:
p
rops
.
type
,
...(
uniqueKey
&&
{
bakCol3
:
uniqueKey
})
}
balance
:
p
aymentConfig
.
value
.
mony
,
type
:
p
aymentConfig
.
value
.
type
,
...(
uniqueKey
&&
{
bakCol3
:
uniqueKey
})
,
}
;
try
{
const
res
=
await
post
(
p
rops
.
url
||
''
,
paymentData
)
const
res
=
await
post
(
p
aymentConfig
.
value
.
url
||
''
,
paymentData
);
if
(
res
.
code
===
200
)
{
if
(
props
.
payway
===
0
)
{
window
.
location
.
href
=
res
.
msg
let
script
=
res
.
msg
location
.
href
=
script
handleClose
();
}
else
{
Snackbar
.
success
(
res
.
msg
)
setTimeout
(()
=>
{
window
.
location
.
href
=
'
/pages/product/product
'
},
1000
)
}
handleClose
()
}
else
{
Snackbar
.
error
(
res
.
msg
)
showFailToast
(
res
.
msg
);
}
}
catch
(
error
)
{
console
.
error
(
'
Payment error:
'
,
error
)
Snackbar
.
error
(
'
支付失败,请稍后重试
'
)
console
.
error
(
'
Payment error:
'
,
error
)
;
showFailToast
(
'
支付失败,请稍后重试
'
);
}
}
// 提交处理(带防抖)
const
handleSubmit
=
useDebounceFn
(
async
()
=>
{
if
(
props
.
password
)
{
showPasswordInput
.
value
=
true
return
}
const
uniqueKey
=
props
.
needCheck
?
generateUniqueKey
()
:
undefined
if
(
props
.
needCheck
)
{
emit
(
'
beforeClick
'
,
uniqueKey
)
}
startCountdown
()
await
handlePayment
(
uniqueKey
)
},
1000
)
// 密码处理
const
handlePasswordFinish
=
(
value
:
string
)
=>
{
if
(
value
===
'
123456
'
)
{
showPasswordInput
.
value
=
false
handlePayment
()
}
else
{
Snackbar
.
error
(
'
密码错误
'
)
}
password
.
value
=
''
}
const
handleClose
=
()
=>
{
emit
(
'
update:show
'
,
false
)
emit
(
'
close
'
)
}
};
</
script
>
<
style
lang=
"scss"
scoped
>
.container
{
font-family
:
pingfang
;
}
.pop
{
background
:
#f5f6f7
;
border-radius
:
12px
12px
0
0
;
padding
:
20px
;
background
:
#ffffff
;
border-radius
:
16px
16px
0
0
;
padding
:
12px
;
box-shadow
:
0
-4px
12px
rgba
(
0
,
0
,
0
,
0
.1
);
}
.top
{
.top
{
text-align
:
center
;
margin-bottom
:
20px
;
display
:
flex
;
flex-direction
:
column
;
.title
{
font-size
:
22
px
;
display
:
block
;
margin-bottom
:
10px
;
font-size
:
18
px
;
color
:
#333
;
font-weight
:
500
;
}
.money
{
font-size
:
28px
;
color
:
#fa7307
;
}
font-weight
:
bold
;
}
}
.payment-methods
{
margin
:
20px
0
;
}
.payment-item
{
padding
:
12px
;
margin
:
16px
0
;
border-radius
:
12px
;
overflow
:
hidden
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0
.1
);
.
payment-left
{
.
item1
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
img
{
width
:
30px
;
height
:
30px
;
margin-right
:
8px
;
}
.payment-icon
{
width
:
20px
;
height
:
20px
;
.title
{
font-weight
:
500
;
font-size
:
14px
;
color
:
#0E0E0E
;
}
.sub
{
font-weight
:
400
;
font-size
:
12px
;
color
:
#999999
;
}
}
}
.payment-item
{
transition
:
background-color
0
.2s
;
&
.active
{
background-color
:
#f5f6f7
;
}
}
.note-text
{
color
:
red
;
padding
:
10px
0
;
color
:
#ff4d4f
;
font-size
:
14px
;
margin-top
:
16px
;
text-align
:
center
;
}
.submit-btn
{
margin-top
:
20px
;
margin-top
:
24px
;
border-radius
:
8px
;
font-size
:
16px
;
font-weight
:
500
;
}
.password-popup
{
padding
:
20px
;
padding
:
24px
;
background
:
#ffffff
;
border-radius
:
12px
;
text-align
:
center
;
.password-title
{
font-size
:
18px
;
margin-bottom
:
20px
;
display
:
block
;
color
:
#333
;
margin-bottom
:
16px
;
}
.password-hint
{
color
:
#999
;
font-size
:
14px
;
margin-top
:
10px
;
display
:
block
;
color
:
#999
;
margin-top
:
12px
;
}
}
</
style
>
\ No newline at end of file
app/pages/index/index.vue
View file @
125778df
...
...
@@ -25,6 +25,14 @@ const handleClick = (item) => {
navigateTo
(
"
/user/singIn
"
);
}
}
const
show
=
ref
(
false
)
const
getuserinfo
=
async
()
=>
{
const
res
=
await
get
(
'
/system/user/
'
,
{})
if
(
res
.
dld
==
2
){
show
.
value
=
true
}
}
getuserinfo
()
const
showGuide
=
ref
(
false
)
const
content
=
ref
([])
const
content3
=
ref
([])
...
...
@@ -42,6 +50,9 @@ const getNotices = async () => {
console
.
error
(
'
Failed to fetch notices:
'
,
error
)
}
}
const
handleConfirm
=
()
=>
{
navigateTo
(
'
/product
'
)
}
getNotices
()
const
handleNewsItemClick
=
(
item
)
=>
{
navigateTo
(
`/newsDetail/
${
item
.
noticeId
}
`
)
...
...
@@ -50,6 +61,8 @@ const handleNewsItemClick = (item) => {
<
template
>
<div
class=
"container"
>
<van-dialog
v-model:show=
"show"
@
confirm=
"handleConfirm"
confirmButtonColor=
"red"
confirmButtonText=
"前往会场认购"
cancelButtonText=
"先不前往认购"
title=
"恭喜您获得债券认购资格,您的购买意向申请已经通过,现在可以认购债权了,您要前往认购吗?"
show-cancel-button
>
</van-dialog>
<GuideModal
v-model=
"showGuide"
:guide-list=
"content"
/>
<div
class=
"imgwarp"
>
<img
src=
"/static/pages/home/14.png"
>
...
...
@@ -79,11 +92,7 @@ const handleNewsItemClick = (item) => {
</div>
<NewsCard
:content3=
"content3"
@
itemClick=
"handleNewsItemClick"
/>
</div>
<!-- 恭喜您获得债券认购资格,您的购买意向申请已经通过,现在可以认购债权了,您要前往认购吗
两个按钮
(前往会场认购)
(先不前往认购) -->
</div>
</
template
>
...
...
app/pages/my/index.vue
View file @
125778df
...
...
@@ -187,6 +187,17 @@ fetchData()
<
/div
>
<
/div
>
<
/div
>
<
var
-
divider
/>
<
div
class
=
"
assets-grid
"
>
<
div
class
=
"
asset-item
"
v
-
ripple
>
<
div
class
=
"
amount
"
>
{{
userData
.
q6
||
0
}}
<
/div
>
<
div
class
=
"
label
"
>
分销奖励
<
/div
>
<
div
class
=
"
actions
"
>
<
button
class
=
"
action-btn primary
"
@
click
=
"
gotx(userData.q6 || 0, 6, '分销奖励')
"
>
提现
<
/button
>
<
button
class
=
"
action-btn secondary
"
@
click
=
"
gomx(6)
"
>
明细
<
/button
>
<
/div
>
<
/div>
<
/div
>
<
/div
>
<!--
广告横幅
-->
...
...
@@ -350,7 +361,7 @@ fetchData()
.
asset
-
item
{
text
-
align
:
center
;
flex
:
1
;
width
:
25
%
;
.
amount
{
font
-
size
:
18
px
;
...
...
app/pages/product/company/[id].vue
View file @
125778df
...
...
@@ -2,7 +2,7 @@
import
{
ref
,
onMounted
}
from
'
vue
'
import
{
get
}
from
'
@/utils/request
'
import
ExpandableText
from
'
@/components/ExpandableText.vue
'
import
PayUp
from
'
~/components/PayUp.vue
'
definePageMeta
({
layout
:
'
default
'
,
title
:
'
产品详情
'
,
...
...
@@ -63,33 +63,48 @@ const fetchData = async () => {
loading
.
value
=
false
}
}
const
showBuy
=
ref
(
false
)
const
handleBuy
=
()
=>
{
showBuy
.
value
=
true
const
paymentInfo
=
ref
({
mony
:
200
,
productId
:
''
,
type
:
0
});
const
payupRef
=
ref
();
const
handleBuy
=
(
item
)
=>
{
paymentInfo
.
value
.
productId
=
item
.
productId
paymentInfo
.
value
.
mony
=
item
.
price
payupRef
.
value
?.
open
();
}
const
handleBuy1
=
()
=>
{
if
(
!
subForm
.
value
.
a7
||
!
subForm
.
value
.
a8
){
showFailToast
(
'
请填写完整信息
'
)
return
false
}
subForm
.
value
.
a3
=
productArr
.
value
.
productName
subForm
.
value
.
a4
=
productArr
.
value
.
productId
subForm
.
value
.
a5
=
1
post
(
`/yw3/add`
,
subForm
.
value
).
then
(
res
=>
{
if
(
res
?.
code
==
200
)
{
subForm
.
value
=
{}
showSuccessToast
(
'
提交成功
'
)
}
else
{
showBuy
.
value
=
false
showFailToast
(
res
.
msg
)
}
})
const
handleClose
=
()
=>
{
paymentInfo
.
value
.
show
=
false
;
}
const
others
=
ref
(
false
)
// const handleBuy1 = () => {
// if (!subForm.value.a7 || !subForm.value.a8) {
// showFailToast('请填写完整信息')
// return false
// }
// subForm.value.a3 = productArr.value.productName
// subForm.value.a4 = productArr.value.productId
// subForm.value.a5 = 1
// post(`/yw3/add`, subForm.value).then(res => {
// if (res?.code == 200) {
// subForm.value = {}
// showSuccessToast('提交成功')
// } else {
// showBuy.value = false
// showFailToast(res.msg)
// }
// })
// }
fetchData
()
</
script
>
<
template
>
<div
class=
"container"
>
<PayUp
ref=
"payupRef"
:payment-info=
"paymentInfo"
@
close=
"handleClose"
/>
<var-loading
description=
"加载中..."
:loading=
"loading"
>
<div
style=
"margin-bottom: 50px"
>
<div
class=
"company-title"
>
{{
companyInfo
.
a1
}}
</div>
...
...
@@ -127,7 +142,7 @@ fetchData()
</var-card>
</div>
<van-submit-bar
:price=
"productArr.price * 100"
@
click=
"handleBuy"
label=
"总价"
button-text=
"立即购买"
<van-submit-bar
:price=
"productArr.price * 100"
@
click=
"handleBuy
(productArr)
"
label=
"总价"
button-text=
"立即购买"
safe-area-inset-bottom
>
<
template
#default
>
<div>
...
...
@@ -138,18 +153,20 @@ fetchData()
</
template
>
</van-submit-bar>
</var-loading>
<var-popup
position=
"bottom"
v-model:show=
"
showBuy
"
>
<var-popup
position=
"bottom"
v-model:show=
"
others
"
>
<div
class=
"popup-example-block"
>
<div
class=
"title"
>
您暂时没有购买资格
</div>
<div
class=
"title"
>
如您有意向购买 请登记您的信息
</div>
<var-form
ref=
"form"
scroll-to-error=
"start"
>
<var-space
direction=
"column"
:size=
"[14, 0]"
>
<var-input
placeholder=
"姓名"
:rules=
"v => !!v || '姓名不能为空'"
v-model=
"subForm.a7"
/>
<var-input
placeholder=
"电话"
type=
"number"
maxlength=
"11"
:rules=
"v => !!v || '电话不能为空'"
v-model=
"subForm.a8"
/>
<var-input
placeholder=
"电话"
type=
"number"
maxlength=
"11"
:rules=
"v => !!v || '电话不能为空'"
v-model=
"subForm.a8"
/>
</var-space>
</var-form>
<var-button
size=
"large"
style=
"margin-top: 16px;"
block
type=
"danger"
@
click=
"handleBuy1"
>
确认提交信息
</var-button>
<var-button
size=
"large"
style=
"margin-top: 16px;"
block
type=
"info"
@
click=
"showBuy = false"
>
我没有购买意向,误点
</var-button>
<var-button
size=
"large"
style=
"margin-top: 16px;"
block
type=
"info"
@
click=
"others = false"
>
我没有购买意向,误点
</var-button>
</div>
</var-popup>
</div>
...
...
@@ -225,10 +242,12 @@ fetchData()
}
}
}
.popup-example-block
{
.popup-example-block
{
height
:
400px
;
padding
:
16px
;
.title
{
.title
{
font-size
:
16px
;
font-weight
:
600
;
color
:
red
;
...
...
app/pages/user/product.vue
View file @
125778df
<
template
>
<div
class=
"container"
>
<div
class=
"empty-tips"
>
暂未购买过产品
</div>
<div
class=
"empty-tips"
v-if=
"productList.length === 0"
>
暂未购买过产品
</div>
<template
v-else
>
<div
class=
"card"
v-for=
"item in productList"
:key=
"item?.productData?.productId"
@
click=
"navigateTo('/product/company/' + item?.productData?.productId)"
>
<div
class=
"leftbox"
>
<div
class=
"title"
>
{{
item
.
productData
.
productName
}}
</div>
<div>
购买时间:
{{
item
.
createTime
}}
</div>
<div>
订单号:
{{
item
.
orderId
}}
</div>
<div
style=
"margin: 6px;"
>
<span
style=
"font-size: 12px;color: red;border: 1px solid red;border-radius: 5px;padding: 5px;"
>
央企送拍
</span>
<span
style=
"font-size: 12px;margin: 0 10px;color: red;border: 1px solid red;border-radius: 5px;padding: 5px;"
>
国有资产
</span>
<span
style=
"font-size: 12px;color: red;border: 1px solid red;border-radius: 5px;padding: 5px;"
>
放心付
</span>
</div>
<div
class=
"content"
>
<div
v-for=
"(info, index) in [
{ title: '售价', value: item.productData.price + '元' },
{ title: '每日收益', value: item.productData.productType + '元' },
{ title: '收益周期', value: item.productData.buttonStyle }
]" :key="index" class="item">
<div
class=
"item-title"
>
{{
info
.
title
}}
</div>
<div
class=
"item-value"
>
{{
info
.
value
}}
</div>
</div>
</div>
<div>
赠送公司分红
<span
style=
"color: red;"
>
{{
item
.
productData
.
productTitle
}}
</span>
元
</div>
</div>
</div>
</
template
>
</div>
</template>
<
script
setup
>
...
...
@@ -11,6 +42,12 @@ definePageMeta({
keepalive
:
true
})
const
productList
=
ref
([])
const
getProductList
=
async
()
=>
{
const
res
=
await
get
(
'
/api/api/transfer/listUser?orderType=0
'
)
productList
.
value
=
res
.
data
}
getProductList
()
</
script
>
<
style
lang=
"scss"
scoped
>
.container
{
...
...
@@ -25,5 +62,79 @@ definePageMeta({
color
:
#999
;
font-size
:
14px
;
}
.card
{
margin
:
16px
6px
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
stretch
;
background-color
:
#fff
;
border-radius
:
12px
;
box-shadow
:
0
2px
12px
rgba
(
0
,
0
,
0
,
0
.1
);
overflow
:
hidden
;
transition
:
all
0
.3s
ease
;
&
:hover
{
transform
:
translateY
(
-2px
);
box-shadow
:
0
4px
20px
rgba
(
0
,
0
,
0
,
0
.15
);
}
&
-active
{
transform
:
scale
(
0
.98
);
opacity
:
0
.8
;
}
}
.leftbox
{
padding
:
16px
;
flex
:
1
;
.title
{
font-size
:
16px
;
font-weight
:
bold
;
color
:
#333
;
margin-bottom
:
12px
;
}
.content
{
display
:
grid
;
grid-template-columns
:
repeat
(
3
,
1fr
);
gap
:
2px
;
.item
{
text-align
:
center
;
.item-title
{
font-size
:
14px
;
color
:
#666
;
margin-bottom
:
4px
;
}
.item-value
{
font-size
:
14px
;
color
:
#e62129
;
font-weight
:
500
;
}
}
}
}
.rightbox
{
width
:
60px
;
background-color
:
#e62129
;
color
:
#fff
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
cursor
:
pointer
;
transition
:
all
0
.3s
ease
;
.title
{
writing-mode
:
vertical-lr
;
text-orientation
:
upright
;
font-weight
:
500
;
}
}
}
</
style
>
\ No newline at end of file
app/pages/user/zjmx.vue
View file @
125778df
<
script
setup
>
import
{
ref
,
watch
,
onMounted
}
from
'
vue
'
import
{
get
,
post
}
from
'
~/utils/request
'
import
{
ref
,
watch
}
from
'
vue
'
import
{
post
}
from
'
~/utils/request
'
const
route
=
useRoute
()
...
...
@@ -26,6 +26,7 @@ const range = ref([
{
text
:
"
生活补贴
"
,
value
:
1
},
{
text
:
"
产品收益
"
,
value
:
2
},
{
text
:
"
公司分红
"
,
value
:
5
},
{
text
:
"
分销奖励
"
,
value
:
6
},
])
// 获取路由参数中的tab
...
...
@@ -36,16 +37,21 @@ const resetList = () => {
list
.
value
=
[]
pageNum
.
value
=
1
finished
.
value
=
false
loading
.
value
=
false
loading
.
value
=
true
// 改为 true,避免 van-list 立即触发 load
total
.
value
=
0
emptyTipsShow
.
value
=
false
getList
()
}
watch
(
active
,
()
=>
{
// Tab 点击处理
const
handleClick
=
(
item
)
=>
{
if
(
active
.
value
===
item
.
value
)
return
active
.
value
=
item
.
value
resetList
()
}
)
}
const
getList
=
async
()
=>
{
if
(
loading
.
value
)
{
// 添加loading检查,避免重复请求
try
{
const
data
=
{
balanceType
:
active
.
value
,
...
...
@@ -62,9 +68,6 @@ const getList = async () => {
}
else
{
pageNum
.
value
++
}
if
(
list
.
value
.
length
>=
total
.
value
)
{
finished
.
value
=
true
}
}
else
{
showFailToast
(
res
.
msg
||
'
加载失败
'
)
finished
.
value
=
true
...
...
@@ -75,15 +78,13 @@ const getList = async () => {
}
finally
{
loading
.
value
=
false
}
}
}
// Tab 点击处理
const
handleClick
=
(
item
)
=>
{
if
(
active
.
value
===
item
.
value
)
return
active
.
value
=
item
.
value
// 初始加载
onMounted
(()
=>
{
resetList
()
}
})
</
script
>
<
template
>
...
...
@@ -94,9 +95,15 @@ const handleClick = (item) => {
{{
item
.
text
}}
</var-tab>
</var-tabs>
<!-- List -->
<van-list
class=
"list-container"
v-model:loading=
"loading"
:finished=
"finished"
finished-text=
"没有更多了"
@
load=
"getList"
>
<van-list
class=
"list-container"
v-model:loading=
"loading"
:finished=
"finished"
finished-text=
"没有更多了"
@
load=
"getList"
>
<div
v-for=
"(item, index) in list"
:key=
"index"
class=
"detail-item"
>
<!-- 头部信息 -->
<div
class=
"item-header"
>
...
...
@@ -106,7 +113,8 @@ const handleClick = (item) => {
item
.
balanceType
==
0
?
'
信用分
'
:
item
.
balanceType
==
1
?
'
生活补贴
'
:
item
.
balanceType
==
2
?
'
产品收益
'
:
item
.
balanceType
==
5
?
'
公司分红
'
:
''
item
.
balanceType
==
5
?
'
公司分红
'
:
item
.
balanceType
==
6
?
'
分销奖励
'
:
''
}}
</span>
</div>
...
...
@@ -140,6 +148,7 @@ const handleClick = (item) => {
剩余:{{ item.amount }}{{ item.balanceType === 2 || item.balanceType === 1 ? '元' : '' }}
</div>
</div>
<div
class=
"item-footer"
>
<time>
{{ item.time }}
</time>
</div>
...
...
@@ -153,6 +162,7 @@ const handleClick = (item) => {
min-height
:
calc
(
100vh
-
54px
);
background
:
#fff
;
font-family
:
pingfang
;
.fixed-tabs
{
position
:
fixed
;
top
:
52px
;
...
...
app/types/payment.d.ts
0 → 100644
View file @
125778df
export
interface
PaymentProps
{
show
:
boolean
;
// 是否显示弹窗
mony
:
number
;
// 金额
dw
:
string
;
// 单位
btn
:
string
;
// 按钮文字
productId
:
string
;
// 产品 ID
type
:
number
;
// 支付类型
url
:
string
;
// 支付接口地址
password
:
boolean
;
// 是否需要密码
needCheck
:
boolean
;
// 是否需要校验
payway
:
number
;
// 支付方式
wechat
:
number
;
// 是否显示微信支付
zfb
:
number
;
// 是否显示支付宝支付
ysf
:
number
;
// 是否显示云闪付
tzj
:
number
;
// 是否显示保额
jtqb
:
number
;
// 是否显示体验金
dtqb
:
number
;
// 是否显示动态钱包
zfsm
?:
string
;
// 支付说明
isBindc
?:
boolean
;
// 是否绑定银行卡
isBindpay
?:
boolean
;
// 是否绑定支付
}
export
interface
PaymentMethod
{
name
:
string
;
// 支付方式名称
label
:
string
;
// 显示名称
icon
:
string
;
// 图标路径
visible
:
boolean
;
// 是否显示
}
\ No newline at end of file
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