feat(BD可操作的收益): 对接提现接口

This commit is contained in:
hzj 2025-10-30 20:41:06 +08:00
parent 0623bbc316
commit 4ee7b18476
2 changed files with 179 additions and 128 deletions

View File

@ -59,3 +59,50 @@ export const cancelInvite = async (userId) => {
throw error
}
}
// 查询BD成员账单列表
export const getBdMemberBillList = async (type) => {
try {
const response = await get(`/team/bd/member-bill/list?type=${type}`)
return response
} catch (error) {
console.error('Failed to fetch BD member bill list:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}
// 查询BD成员账单明细
export const getBdMemberBillDetailList = async (teamId) => {
try {
const response = await get(`/team/bd/member-bill/detail-list`, { teamId })
return response
} catch (error) {
console.error('Failed to fetch BD member bill detail list:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}
// 查询BD团队月度收入汇总
export const getBdMonthlyIncome = async (bdUserId) => {
try {
const response = await get(`/team/bd/monthly-income`, { bdUserId })
return response
} catch (error) {
console.error('Failed to fetch BD monthly income:', error)
console.error('error:' + error.response.errorMsg)
throw error
}
}
// 提交提现申请
export const withdrawApply = async (data) => {
try {
const response = await post('/team/bd/withdraw/apply', data)
return response
} catch (error) {
console.error('Failed to fetch withdraw apply:', error)
throw error
}
}

View File

@ -29,9 +29,9 @@
"
>
<span v-if="loading" class="loading-text">Loading...</span>
<span v-else style="font-weight: 700; color: #333; font-size: 1.1em">{{
availableIncome
}}</span>
<span v-else style="font-weight: 700; color: #333; font-size: 1.1em"
>${{ availableIncome }}</span
>
</div>
</div>
@ -67,7 +67,75 @@
</button>
</div>
<!-- 转账对象 -->
<!-- Exchange -->
<div v-if="activeAction === 'Exchange'">
<div
style="
background-color: white;
padding: 16px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
"
>
<!-- 兑换金额选择 -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px">
<div
v-for="option in exchangeOptions"
:key="option.id"
@click="selectExchangeOption(option)"
:style="{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
border:
selectedExchangeOption === option.id ? '2px solid #8b5cf6' : '2px solid #e5e7eb',
borderRadius: '12px',
cursor: 'pointer',
transition: 'all 0.2s',
backgroundColor: selectedExchangeOption === option.id ? '#f3f4f6' : 'white',
aspectRatio: '1/1',
}"
>
<img src="../../assets/icon/coin.png" alt="" style="width: 40%" />
<div style="font-weight: 500; color: #373232">
<!-- {{ option.coins }} -->
</div>
<div style="font-weight: 500; color: #131111">${{ option.cash }}</div>
</div>
</div>
</div>
<!-- 兑换按钮 -->
<div style="display: flex; justify-content: center; margin-top: 10px">
<button
style="
width: 70%;
padding: 12px;
background: linear-gradient(135deg, #bb92ff 2.82%, #8b45ff 99.15%);
color: white;
border: none;
border-radius: 32px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
"
@click="handleExchange"
:disabled="!selectedExchangeOption"
:style="{
background: !selectedExchangeOption
? '#ccc'
: 'linear-gradient(135deg, #bb92ff 2.82%, #8b45ff 99.15%)',
opacity: !selectedExchangeOption ? 0.6 : 1,
}"
>
Exchange
</button>
</div>
</div>
<!-- Transfer转账对象 -->
<div v-if="activeAction === 'Transfer'">
<div style="font-weight: 600; margin-bottom: 10px">Transfer to others</div>
<div
@ -178,7 +246,7 @@
</div>
</div>
<!-- 转账部分 -->
<!-- Transfer -->
<div v-if="activeAction === 'Transfer'">
<div
style="
@ -209,7 +277,7 @@
>
<img src="../../assets/icon/coin.png" alt="" style="width: 40%" />
<div style="font-weight: 500; color: #373232">
{{ coin.amount }}
<!-- {{ coin.amount }} -->
</div>
<div style="font-weight: 500; color: #131111">${{ coin.price }}</div>
</div>
@ -245,77 +313,7 @@
</div>
</div>
<!-- Exchange 页面内容 -->
<div v-if="activeAction === 'Exchange'">
<div
style="
background-color: white;
padding: 16px;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
"
>
<!-- 兑换金额选择 -->
<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px">
<div
v-for="option in exchangeOptions"
:key="option.id"
@click="selectExchangeOption(option)"
:style="{
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
alignItems: 'center',
border:
selectedExchangeOption === option.id ? '2px solid #8b5cf6' : '2px solid #e5e7eb',
borderRadius: '12px',
cursor: 'pointer',
transition: 'all 0.2s',
backgroundColor: selectedExchangeOption === option.id ? '#f3f4f6' : 'white',
aspectRatio: '1/1',
}"
>
<img src="../../assets/icon/coin.png" alt="" style="width: 40%" />
<div style="font-weight: 500; color: #373232">
{{ option.coins }}
</div>
<div style="font-weight: 500; color: #131111">
{{ option.cash }}
</div>
</div>
</div>
</div>
<!-- 兑换按钮 -->
<div style="display: flex; justify-content: center; margin-top: 10px">
<button
style="
width: 70%;
padding: 12px;
background: linear-gradient(135deg, #bb92ff 2.82%, #8b45ff 99.15%);
color: white;
border: none;
border-radius: 32px;
font-weight: 600;
cursor: pointer;
transition: all 0.2s;
"
@click="handleExchange"
:disabled="!selectedExchangeOption"
:style="{
background: !selectedExchangeOption
? '#ccc'
: 'linear-gradient(135deg, #bb92ff 2.82%, #8b45ff 99.15%)',
opacity: !selectedExchangeOption ? 0.6 : 1,
}"
>
Exchange
</button>
</div>
</div>
<!-- Cash out 页面内容 -->
<!-- Cash out -->
<div v-if="activeAction === 'Cash out'">
<!-- 提现资料 -->
<!-- 银行帐号信息 -->
@ -464,19 +462,25 @@
import { ref, reactive, onMounted, onUnmounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import MobileHeader from '@/components/MobileHeader.vue'
import { getBankBalance, userBankTransfer } from '@/api/wallet.js'
import {
getBankBalance,
userBankTransfer,
userSalaryCheckExchange,
userBankExchangeGold,
} from '@/api/wallet.js'
import { getSelectedPayee, clearSelectedPayee } from '@/utils/payeeStore.js'
import { showError, showSuccess } from '@/utils/toast.js'
import { setApplyInfo, getApplyInfo } from '@/utils/applyStore.js'
import maskLayer from '@/components/MaskLayer.vue'
import { withdrawApply } from '@/api/bdCenter.js'
import { getUserId } from '@/utils/userStore.js'
const router = useRouter()
const availableIncome = ref('$23456')
const availableIncome = ref('')
const selectedCoin = ref(null)
const selectedExchangeOption = ref(null)
const selectedCashOutOption = ref(null)
const activeAction = ref('Transfer')
const activeAction = ref('Exchange')
const loading = ref(false)
const maskLayerShow = ref(false)
@ -500,12 +504,6 @@ const CashOut = () => {
}
}
//
const Receive = () => {
setApplyInfo()
maskLayerShow.value = false
}
//
const selectedPayee = reactive({
id: null,
@ -530,12 +528,12 @@ const coinOptions = reactive([
//
const exchangeOptions = reactive([
{ id: 1, coins: '10000', cash: '$1' },
{ id: 2, coins: '10000', cash: '$1' },
{ id: 3, coins: '10000', cash: '$1' },
{ id: 4, coins: '10000', cash: '$1' },
{ id: 5, coins: '10000', cash: '$1' },
{ id: 6, coins: '10000', cash: '$1' },
{ id: 1, coins: 10500, cash: 1 },
{ id: 2, coins: 52500, cash: 5 },
{ id: 3, coins: 105000, cash: 10 },
{ id: 4, coins: 525000, cash: 50 },
{ id: 5, coins: 1050000, cash: 100 },
{ id: 6, coins: 2100000, cash: 200 },
])
const bankCardInfo = ref({})
@ -559,14 +557,14 @@ const fetchBankBalance = async () => {
const response = await getBankBalance()
if (response.status && typeof response.body === 'number') {
availableIncome.value = `$${response.body.toFixed(2)}`
availableIncome.value = response.body.toFixed(2) || '0.00'
} else {
availableIncome.value = '$0.00'
availableIncome.value = '-'
}
} catch (error) {
console.error('Failed to fetch bank balance:', error)
availableIncome.value = '$0.00'
showError('Failed to load balance. Please try again.')
availableIncome.value = '-'
showError(error.response.errorMsg)
} finally {
loading.value = false
}
@ -587,7 +585,6 @@ const handleAction = (actionName) => {
//
selectedCoin.value = null
selectedExchangeOption.value = null
selectedCashOutOption.value = null
}
//
@ -621,14 +618,6 @@ const selectExchangeOption = (option) => {
}
}
const selectCashOutOption = (option) => {
if (selectedCashOutOption.value === option.id) {
selectedCashOutOption.value = null
} else {
selectedCashOutOption.value = option.id
}
}
const transfer = async () => {
if (!selectedCoin.value) {
showError('Please select an amount first')
@ -652,25 +641,18 @@ const transfer = async () => {
const response = await userBankTransfer(transferData)
if (response.status) {
showSuccess(`Successfully transferred $${selectedCoinData.price} to ${selectedPayee.name}`)
selectedCoin.value = null
await fetchBankBalance()
} else {
showError(`Failed to transfer $${selectedCoinData.price}`)
}
selectedCoin.value = null
await fetchBankBalance()
} catch (error) {
console.error('Transfer failed:', error)
if (error.errorCode === 5000) {
showError('Insufficient balance')
} else if (error.errorCode === 5010 || error.errorCode === 5009) {
showError('Payment password error')
} else {
showError('Transfer failed, please try again later')
}
showError(error.response.errorMsg)
}
}
const handleExchange = () => {
const handleExchange = async () => {
if (!selectedExchangeOption.value) {
showError('Please select an amount first')
return
@ -679,19 +661,41 @@ const handleExchange = () => {
const selectedOption = exchangeOptions.find(
(option) => option.id === selectedExchangeOption.value
)
showSuccess(`Exchanging ${selectedOption.coins} coins for ${selectedOption.cash}`)
selectedExchangeOption.value = null
try {
//
const response = await userBankExchangeGold({
coinId: selectedOption.id,
amount: selectedOption.cash,
price: selectedOption.cash,
})
if (response.status === true || response.errorCode === 0) {
showSuccess(`Successfully exchanged`)
//
await fetchBankBalance()
}
selectedExchangeOption.value = null
} catch (error) {
console.error('Exchange failed:', error)
showError(error.response.errorMsg)
}
}
const handleCashOut = () => {
if (!selectedCashOutOption.value) {
showError('Please select an amount first')
return
//
const Receive = async () => {
try {
const resApply = await withdrawApply({ ...getApplyInfo(), activityId: getUserId() })
if (resApply.status) {
setApplyInfo()
}
maskLayerShow.value = false
} catch (error) {
maskLayerShow.value = false
showError(error.response.errorMsg)
}
const selectedOption = cashOutOptions.find((option) => option.id === selectedCashOutOption.value)
showSuccess(`Cashing out ${selectedOption.coins} coins for ${selectedOption.cash}`)
selectedCashOutOption.value = null
}
//
@ -706,7 +710,7 @@ onMounted(() => {
onUnmounted(() => {
clearPayee()
setApplyInfo()
// setApplyInfo()
})
</script>