Files
Portal/pages/withdraw.vue
T
18a4d03c3a feat: 对接越南AlinPay支付(充值+提现)
- recharge.vue: 新增ALIN_VN充值模板,最低1,000,000 VND
- withdraw.vue: 新增银行卡提现模板,银行列表API加载,最低1,000,000 VND
- api.js: 新增alinDeposit/applyWithdrawBank/getBankListVn接口

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-03-22 12:55:52 +08:00

457 lines
12 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.
<template>
<view class="withdraw">
<u-navbar
title=""
bgColor="#000"
:placeholder="true"
:fixed="true"
leftIcon=""
height="60"
>
<view slot="left">
<text class="navbar-lab">{{ $lang.withdraw }}</text>
</view>
</u-navbar>
<view class="content">
<view class="list">
<view class="lable money"
>{{ $lang.balance }}{{ userInfo.money }}</view
>
</view>
<!-- USDT 提现 -->
<template v-if="userInfo.pay_channel != 'ALIN_VN'">
<view class="picker-view" @click="show = true">
<u-input
readonly
:placeholder="$lang.pleaseChoose"
color="#93979b"
v-model="type"
border="none"
>
<u--text
:text="$lang.chooseWithdraw"
slot="prefix"
margin="0 3px 0 0"
type="tips"
></u--text>
<u-icon
slot="suffix"
name="arrow-down-fill"
color="#757272"
size="16"
></u-icon>
</u-input>
</view>
<u-picker
:title="$lang.pleaseChooseWithdraw"
closeOnClickOverlay
:show="show"
:columns="columns"
:cancelText="$lang.cancel"
:confirmText="$lang.confirm"
@cancel="close"
@close="close"
@confirm="confirm"
></u-picker>
<view class="list">
<view class="lable">{{ $lang.walletAddress }}</view>
<u-input
class="input"
color="#947b2b"
clearable
:placeholder="$lang.enterWithdrawalAddress"
border="surround"
v-model="address"
></u-input>
</view>
<view class="list">
<view class="lable">{{ $lang.amount }}</view>
<u-input
class="input"
color="#947b2b"
clearable
:placeholder="$lang.enterWithdrawalamount"
border="surround"
v-model="money"
></u-input>
</view>
<view class="list">
<view class="lab">{{ $lang.rechargeWithdrawNetwork }}</view>
<view class="type">TRC20</view>
</view>
<view class="list">
<u-button
@tap="applyWithdraw"
class="button"
color="#e5b932"
:text="$lang.submit"
></u-button>
</view>
<view class="list">
<view class="tip">{{ $lang.withdrawTip }}</view>
<view class="tip">{{ $lang.commission }}:1 USDT</view>
</view>
</template>
<!-- 越南银行卡提现 -->
<template v-if="userInfo.pay_channel == 'ALIN_VN'">
<view class="picker-view" @click="showBankPicker = true">
<u-input
readonly
:placeholder="$lang.pleaseChoose || '请选择'"
color="#93979b"
v-model="bankName"
border="none"
>
<u--text
:text="$lang.bankName || '银行名称'"
slot="prefix"
margin="0 3px 0 0"
type="tips"
></u--text>
<u-icon
slot="suffix"
name="arrow-down-fill"
color="#757272"
size="16"
></u-icon>
</u-input>
</view>
<u-picker
:title="$lang.bankName || '选择银行'"
closeOnClickOverlay
:show="showBankPicker"
:columns="bankColumns"
:cancelText="$lang.cancel"
:confirmText="$lang.confirm"
@cancel="showBankPicker = false"
@close="showBankPicker = false"
@confirm="confirmBank"
></u-picker>
<view class="list">
<view class="lable">{{ $lang.accountName || '账户姓名' }}</view>
<u-input
class="input"
color="#947b2b"
clearable
:placeholder="$lang.enterAccountName || '请输入账户姓名'"
border="surround"
v-model="accountName"
></u-input>
</view>
<view class="list">
<view class="lable">{{ $lang.accountNumber || '银行卡号' }}</view>
<u-input
class="input"
color="#947b2b"
clearable
:placeholder="$lang.enterAccountNumber || '请输入银行卡号'"
border="surround"
v-model="accountNumber"
></u-input>
</view>
<view class="list">
<view class="lable">{{ $lang.amount }}</view>
<u-input
class="input"
color="#947b2b"
clearable
type="number"
:placeholder="'Tối thiểu 1,000,000 VND'"
border="surround"
v-model="money"
></u-input>
</view>
<view class="list">
<u-button
@tap="applyWithdrawBank"
class="button"
color="#e5b932"
:text="$lang.submit"
></u-button>
</view>
<view class="list">
<view class="tip">{{ $lang.withdrawTip }}</view>
</view>
</template>
</view>
<view class="mb60"></view>
</view>
</template>
<script>
import { mapState } from "vuex";
export default {
data() {
return {
address: "",
money: "",
type: "USDT",
show: false,
columns: [["USDT"]],
// 越南银行卡提现
bankName: "",
bankCode: "",
accountName: "",
accountNumber: "",
showBankPicker: false,
bankColumns: [[]],
bankList: [],
};
},
computed: {
...mapState({
userInfo: (state) => state.app.userInfo,
$lang: (state) => state.app.lang[state.app.language],
}),
},
onLoad() {
// 越南渠道加载银行列表
if (this.userInfo && this.userInfo.pay_channel === 'ALIN_VN') {
this.loadBankList();
}
},
methods: {
confirm(chose) {
this.type = chose.value[0];
this.close();
},
close() {
this.show = false;
},
applyWithdraw() {
const params = {
user_id: this.userInfo.id,
to_addr: this.address,
amount: this.money,
};
if (!params.to_addr) {
this.$toast({
message: this.$lang.enterWithdrawalAddress,
duration: 2000,
});
} else if (!params.amount) {
this.$toast({
message: this.$lang.amountCannotBe0,
duration: 2000,
});
} else {
this.$toast({
type: "loading",
message: this.$lang.submittingApplication,
duration: 200000,
});
this.$api
.applyWithdraw(params)
.then((res) => {
if (res.Success) {
this.$toast({
type: "success",
message: res.Msg,
duration: 2000,
});
this.address = "";
this.money = "";
} else {
this.$toast({
message: res.Msg,
duration: 2000,
});
}
})
.catch((err) => {
console.log(err);
})
.finally(() => {
this.$toastHide();
});
}
},
// 加载越南银行列表
loadBankList() {
this.$api
.getBankListVn({ user_id: this.userInfo.id })
.then((res) => {
if (res.Data && res.Data.data) {
this.bankList = res.Data.data;
this.bankColumns = [res.Data.data.map((item) => item.name)];
}
})
.catch((err) => {
console.log(err);
});
},
// 选择银行
confirmBank(chose) {
this.bankName = chose.value[0];
this.bankCode = chose.value[0];
this.showBankPicker = false;
},
// 越南银行卡提现
applyWithdrawBank() {
if (!this.bankName) {
this.$toast({
message: this.$lang.bankName || '请选择银行',
duration: 2000,
});
return;
}
if (!this.accountName) {
this.$toast({
message: this.$lang.enterAccountName || '请输入账户姓名',
duration: 2000,
});
return;
}
if (!this.accountNumber) {
this.$toast({
message: this.$lang.enterAccountNumber || '请输入银行卡号',
duration: 2000,
});
return;
}
if (!this.money || this.money <= 0) {
this.$toast({
message: this.$lang.amountCannotBe0,
duration: 2000,
});
return;
}
if (Number(this.money) < 1000000) {
this.$toast({
message: 'Số tiền rút tối thiểu là 1,000,000 VND',
duration: 2000,
});
return;
}
if (Number(this.money) > Number(this.userInfo.money)) {
this.$toast({
message: this.$lang.insufficientBalance || 'Số dư không đủ',
duration: 2000,
});
return;
}
const params = {
user_id: this.userInfo.id,
account_name: this.accountName,
account_number: this.accountNumber,
bank_code: this.bankCode,
bank_name: this.bankName,
amount: this.money,
};
this.$toast({
type: "loading",
message: this.$lang.submittingApplication || '提交中...',
duration: 200000,
});
this.$api
.applyWithdrawBank(params)
.then((res) => {
if (res.Success) {
this.$toast({
type: "success",
message: res.Msg,
duration: 2000,
});
this.bankName = "";
this.bankCode = "";
this.accountName = "";
this.accountNumber = "";
this.money = "";
} else {
this.$toast({
message: res.Msg,
duration: 2000,
});
}
})
.catch((err) => {
console.log(err);
})
.finally(() => {
this.$toastHide();
});
},
},
};
</script>
<style lang="scss" scoped>
.withdraw {
background: #0b1520;
width: 100%;
min-height: 100vh;
.navbar-lab {
color: #fff;
font-weight: 500;
font-size: 18px;
}
.content {
margin: 5px 5px;
border: 2px solid #947b2b;
background: #222222;
box-sizing: border-box;
padding: 15px;
min-height: 400px;
.picker-view {
border: 2px solid #947b2b;
padding: 8px;
border-radius: 5px;
}
.list {
font-size: 14px;
text-align: center;
.lab {
color: #757272;
margin: 10px 0;
}
.lable {
text-align: left;
color: #ddd;
margin-top: 20px;
font-size: 16px;
margin-bottom: 10px;
}
.money {
font-size: 16px;
margin-top: 0;
padding: 15px 0;
color: #e5b932;
}
.btn {
height: 30px;
font-weight: 600;
color: #0b1520 !important;
}
.type {
width: 70px;
height: 35px;
background: #e5b932;
border-radius: 40px;
text-align: center;
line-height: 35px;
font-weight: 600;
margin: 10px auto;
}
.input {
line-height: 30px;
height: 30px;
}
.button {
line-height: 45px;
height: 45px;
color: #0b1520 !important;
font-weight: bold;
margin-top: 30px;
margin-bottom: 10px;
}
.tip {
color: #cc4c0e;
font-size: 13px;
text-align: justify;
}
}
}
}
</style>