Files
uniapp-im-shop/pages/my-index/withdraw.vue
2026-01-06 16:35:57 +08:00

424 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
// 提现页面
import { ref, reactive, computed } from 'vue'
import { navigateTo, navigateBack } from '@/utils/router'
import { onShow } from '@dcloudio/uni-app'
import {
getUserThirdPayList,
getUserBankList,
getUserWithdrawConfig,
getUserIntegral,
addUserWithdraw,
getUserPayPwd
} from '@/api/my-index'
import { useUI } from '@/utils/use-ui'
const { showToast, showDialog } = useUI()
const tixian = ref(null)
const popup = ref(null)
const topData = ref({})
const formData = reactive({
nuber: '',
// 提现方式
paymentAccountId: ''
})
// 选项列表
const withdrawWayList = ref([])
/** 提现数据 */
const withdrawData = reactive({
// 可用积分
availablePoints: 0,
// 最低提现积分
minAmount: 0,
// 手续费类型(1:固定金额2:百分比)
feeType: 0,
// 手续费
feeValue: 0
})
/** 服务费百分比计算,使用计算属性 */
const serviceFee = computed(() => {
const value = (withdrawData.feeValue / 100) * formData.nuber
return Number(value.toFixed(2))
})
/** 获取积分 */
const getIntegral = async () => {
const res = await getUserIntegral()
withdrawData.availablePoints = res.data.availablePoints
}
const getData = async () => {
const res = await getUserWithdrawConfig(topData.value.withdrawalType)
withdrawData.minAmount = res.data.minAmount
withdrawData.feeType = res.data.feeType
withdrawData.feeValue = res.data.feeValue
}
const getList = async () => {
const res = await Promise.all([
getUserThirdPayList(),
getUserBankList()
])
const [thirdPayList, bankList] = res
withdrawWayList.value = [
...thirdPayList.data?.map(v => {
// v.paymentType 1: 微信, 2: 支付宝, 3: 其他
return {
...v,
name: '',
withdrawalType: v.paymentType === 1 ? 2 : 3,
id: v.paymentId
}
}),
...bankList.data?.map(v => {
return {
...v,
name: v.bankName,
withdrawalType: 1,
id: v.cardId
}
})
]
if (withdrawWayList.value.length > 0) {
formData.paymentAccountId = withdrawWayList.value[0].id
topData.value = withdrawWayList.value[0]
getData()
}
}
const onWithdraw = async () => {
if (formData.nuber < withdrawData.minAmount) {
showDialog('提示', '提现积分不能低于最低提现积分', false)
return
}
if (formData.nuber > withdrawData.availablePoints) {
showDialog('提示', '提现积分超过可提积分', false)
return
}
const res = await getUserPayPwd()
if (res?.data) {
tixian.value.open()
} else {
const show = await showDialog('提示', '请先设置支付密码')
if (show) {
navigateTo('/pages/my-index/wallet/edit-password', { type: 0 })
}
}
// await addUserWithdraw(data)
// await showToast(`提现成功`, 'success')
// navigateBack()
}
const submit = async e => {
try {
const data = {
payPassword: e.join(''),
amount: formData.nuber,
withdrawalType: topData.value.withdrawalType,
paymentAccountId: formData.paymentAccountId
}
tixian.value.close()
await addUserWithdraw(data)
await showToast(`提现成功`, 'success')
navigateBack()
} catch (error) {
tixian.value.close()
console.log(error)
}
}
onShow(() => {
getIntegral()
getList()
})
</script>
<template>
<view class="withdraw-box">
<nav-bar isTopBg isPlaceholder title="提现"></nav-bar>
<uu-pwdModal ref="tixian" @success="submit"></uu-pwdModal>
<view class="view-box">
<!-- 选择提现方式 -->
<view class="withdraw-way">
<text>到账方式</text>
<view
v-if="topData?.id"
class="withdraw-way-line"
@click="popup.open('bottom')"
>
<text v-if="[2, 3].includes(topData.withdrawalType)">
{{ topData.withdrawalType === 2 ? '微信' : '支付宝' }}
</text>
<text v-else>{{ topData.name }}</text>
<uni-icons type="right" color="#333333" size="18"></uni-icons>
</view>
<view
v-else
class="withdraw-way-line"
@click="navigateTo('/pages/my-index/wallet/bank-card/index')"
>
<text>去添加</text>
<uni-icons type="right" color="#333333" size="18"></uni-icons>
</view>
</view>
<!-- 提现信息 -->
<view class="withdraw-info">
<text>提现积分</text>
<view class="number-box">
<!-- <text>¥</text> -->
<input
v-model="formData.nuber"
focus
confirm-type="done"
type="digit"
/>
<view
v-if="formData.nuber"
class="right-clos"
@click="formData.nuber = ''"
>
<uni-icons
type="closeempty"
color="#ffffff"
size="12"
></uni-icons>
</view>
<view v-else class="right-box">
<text
class="btn"
@click="
formData.nuber = String(withdrawData.availablePoints)
"
>
全部提现
</text>
<text>可用积分{{ withdrawData.availablePoints }}</text>
</view>
</view>
<view v-if="formData.nuber" class="bottom-info">
<view class="card">
<text>最低提取积分</text>
<text>{{ withdrawData.minAmount }}</text>
</view>
<view class="card">
<text>到账积分</text>
<text>{{ formData.nuber }}</text>
</view>
<view v-if="withdrawData.feeType === 2" class="card">
<text>服务积分</text>
<text>{{ serviceFee }}</text>
</view>
</view>
</view>
</view>
<!-- 底部按钮 -->
<bottom-view>
<cb-button :disabled="!formData.nuber" @click="onWithdraw">
提现
</cb-button>
</bottom-view>
<uni-popup ref="popup" background-color="#f9f9f9">
<view class="popup-top">
<text class="text">选择提现方式</text>
<uni-icons
type="closeempty"
color="#333333"
size="20"
@click="popup.close()"
></uni-icons>
</view>
<view class="list-card">
<view
v-for="(item, index) in withdrawWayList"
:key="index"
class="item"
@click="
() => {
topData = item
formData.paymentAccountId = item.id
popup.close()
getData()
}
"
>
<text v-if="[2, 3].includes(item.withdrawalType)" class="name">
{{ item.withdrawalType === 2 ? '微信' : '支付宝' }}
</text>
<text v-else class="name">{{ item.name }}</text>
<uni-icons
v-if="item.id === formData.paymentAccountId"
type="checkmarkempty"
color="#1b38b9"
size="18"
></uni-icons>
</view>
<view
class="item"
@click="
() => {
popup.close()
navigateTo('/pages/my-index/wallet/bank-card/index')
}
"
>
<text class="name">添加提现方式</text>
<uni-icons type="right" color="#333333" size="18"></uni-icons>
</view>
</view>
</uni-popup>
</view>
</template>
<style lang="scss" scoped>
page {
background: #f9f9f9;
}
.view-box {
padding: 32rpx 26rpx;
}
.withdraw-way {
padding: 32rpx 26rpx;
display: flex;
flex-direction: column;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 28rpx;
color: #333333;
font-style: normal;
text-transform: none;
.withdraw-way-line {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 16rpx;
padding: 32rpx 0;
}
}
.withdraw-info {
background: #ffffff;
padding: 32rpx 26rpx;
border-radius: 16rpx;
margin-top: 16rpx;
display: flex;
flex-direction: column;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 28rpx;
color: #333333;
font-style: normal;
text-transform: none;
.number-box {
margin-top: 32rpx;
display: flex;
align-items: center;
border-bottom: 2rpx solid #f7f7f7;
padding-bottom: 6rpx;
font-size: 38rpx;
font-weight: 600;
input {
width: 100%;
font-size: 68rpx;
margin-left: 10rpx;
}
.right-box {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: flex-end;
justify-content: space-between;
font-weight: 500;
font-size: 22rpx;
color: #9c9c9c;
.btn {
color: #1859e7;
margin-bottom: 16rpx;
}
}
.right-clos {
flex-shrink: 0;
margin-left: 10rpx;
background: #aaaaaa;
width: 34rpx;
height: 34rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 40rpx;
}
}
.bottom-info {
margin-top: 16rpx;
.card + .card {
margin-top: 10rpx;
}
.card {
display: flex;
justify-content: space-between;
text {
color: #888888;
&:last-child {
color: #333333;
}
}
}
}
}
.popup-top {
padding: 32rpx 26rpx;
display: flex;
align-items: center;
justify-content: space-between;
.text {
font-family: PingFang SC, PingFang SC;
font-weight: 600;
font-size: 32rpx;
color: #333333;
font-style: normal;
text-transform: none;
}
}
.list-card {
padding: 32rpx 26rpx;
max-height: 600rpx;
overflow-y: auto;
.item + .item {
margin-top: 14rpx;
}
.item {
background: #ffffff;
padding: 32rpx 26rpx;
border-radius: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
.name {
font-family: PingFang SC, PingFang SC;
font-weight: 600;
font-size: 28rpx;
color: #333333;
font-style: normal;
text-transform: none;
}
}
}
</style>