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>
This commit is contained in:
@@ -184,6 +184,38 @@
|
|||||||
@confirm="confirmPicker"
|
@confirm="confirmPicker"
|
||||||
></u-picker>
|
></u-picker>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- 越南 AlinPay 在线充值 -->
|
||||||
|
<template v-if="userInfo.pay_channel == 'ALIN_VN'">
|
||||||
|
<view class="picker-view">
|
||||||
|
<u-input
|
||||||
|
placeholder="Tối thiểu 1,000,000"
|
||||||
|
color="#93979b"
|
||||||
|
v-model="amount"
|
||||||
|
type="number"
|
||||||
|
border="none"
|
||||||
|
>
|
||||||
|
<u--text
|
||||||
|
:text="$lang.rechargeAmount || '充值金额'"
|
||||||
|
slot="prefix"
|
||||||
|
margin="0 3px 0 0"
|
||||||
|
type="tips"
|
||||||
|
></u--text>
|
||||||
|
</u-input>
|
||||||
|
</view>
|
||||||
|
<view class="list mb60">
|
||||||
|
<u-button
|
||||||
|
class="button"
|
||||||
|
color="#e5b932"
|
||||||
|
:text="$lang.submit"
|
||||||
|
@click="submitAlin"
|
||||||
|
></u-button>
|
||||||
|
</view>
|
||||||
|
<view class="list">
|
||||||
|
<view class="tip">
|
||||||
|
{{ $lang.rechargeTip }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
<view class="mb60"></view>
|
<view class="mb60"></view>
|
||||||
</view>
|
</view>
|
||||||
@@ -324,6 +356,59 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 越南 AlinPay 充值
|
||||||
|
submitAlin() {
|
||||||
|
if (!this.amount || this.amount <= 0) {
|
||||||
|
this.$toast({
|
||||||
|
message: 'Vui lòng nhập số tiền',
|
||||||
|
duration: 2000,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.amount < 1000000) {
|
||||||
|
this.$toast({
|
||||||
|
message: 'Số tiền tối thiểu là 1,000,000',
|
||||||
|
duration: 2000,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const params = {
|
||||||
|
user_id: this.userInfo.id,
|
||||||
|
price: this.amount,
|
||||||
|
client: 3,
|
||||||
|
username: this.userInfo.username,
|
||||||
|
};
|
||||||
|
this.$toast({
|
||||||
|
type: "loading",
|
||||||
|
message: `${this.$lang.submit}...`,
|
||||||
|
duration: 200000,
|
||||||
|
});
|
||||||
|
this.$api
|
||||||
|
.alinDeposit(params)
|
||||||
|
.then((res) => {
|
||||||
|
const d = res.Data || {};
|
||||||
|
if (d.status == 1 && d.url) {
|
||||||
|
const o = navigator.userAgent;
|
||||||
|
const isiOS = !!o.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);
|
||||||
|
if (isiOS) {
|
||||||
|
window.location.href = d.url;
|
||||||
|
} else {
|
||||||
|
window.open(d.url, "_blank");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.$toast({
|
||||||
|
message: d.message || '充值失败',
|
||||||
|
duration: 2000,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.$toastHide();
|
||||||
|
});
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
+274
-72
@@ -18,77 +18,161 @@
|
|||||||
>{{ $lang.balance }}:{{ userInfo.money }}</view
|
>{{ $lang.balance }}:{{ userInfo.money }}</view
|
||||||
>
|
>
|
||||||
</view>
|
</view>
|
||||||
<view class="picker-view" @click="show = true">
|
<!-- USDT 提现 -->
|
||||||
<u-input
|
<template v-if="userInfo.pay_channel != 'ALIN_VN'">
|
||||||
readonly
|
<view class="picker-view" @click="show = true">
|
||||||
:placeholder="$lang.pleaseChoose"
|
<u-input
|
||||||
color="#93979b"
|
readonly
|
||||||
v-model="type"
|
:placeholder="$lang.pleaseChoose"
|
||||||
border="none"
|
color="#93979b"
|
||||||
>
|
v-model="type"
|
||||||
<u--text
|
border="none"
|
||||||
:text="$lang.chooseWithdraw"
|
>
|
||||||
slot="prefix"
|
<u--text
|
||||||
margin="0 3px 0 0"
|
:text="$lang.chooseWithdraw"
|
||||||
type="tips"
|
slot="prefix"
|
||||||
></u--text>
|
margin="0 3px 0 0"
|
||||||
<u-icon
|
type="tips"
|
||||||
slot="suffix"
|
></u--text>
|
||||||
name="arrow-down-fill"
|
<u-icon
|
||||||
color="#757272"
|
slot="suffix"
|
||||||
size="16"
|
name="arrow-down-fill"
|
||||||
></u-icon>
|
color="#757272"
|
||||||
</u-input>
|
size="16"
|
||||||
</view>
|
></u-icon>
|
||||||
<u-picker
|
</u-input>
|
||||||
:title="$lang.pleaseChooseWithdraw"
|
</view>
|
||||||
closeOnClickOverlay
|
<u-picker
|
||||||
:show="show"
|
:title="$lang.pleaseChooseWithdraw"
|
||||||
:columns="columns"
|
closeOnClickOverlay
|
||||||
:cancelText="$lang.cancel"
|
:show="show"
|
||||||
:confirmText="$lang.confirm"
|
:columns="columns"
|
||||||
@cancel="close"
|
:cancelText="$lang.cancel"
|
||||||
@close="close"
|
:confirmText="$lang.confirm"
|
||||||
@confirm="confirm"
|
@cancel="close"
|
||||||
></u-picker>
|
@close="close"
|
||||||
<view class="list">
|
@confirm="confirm"
|
||||||
<view class="lable">{{ $lang.walletAddress }}</view>
|
></u-picker>
|
||||||
<u-input
|
<view class="list">
|
||||||
class="input"
|
<view class="lable">{{ $lang.walletAddress }}</view>
|
||||||
color="#947b2b"
|
<u-input
|
||||||
clearable
|
class="input"
|
||||||
:placeholder="$lang.enterWithdrawalAddress"
|
color="#947b2b"
|
||||||
border="surround"
|
clearable
|
||||||
v-model="address"
|
:placeholder="$lang.enterWithdrawalAddress"
|
||||||
></u-input>
|
border="surround"
|
||||||
</view>
|
v-model="address"
|
||||||
<view class="list">
|
></u-input>
|
||||||
<view class="lable">{{ $lang.amount }}</view>
|
</view>
|
||||||
<u-input
|
<view class="list">
|
||||||
class="input"
|
<view class="lable">{{ $lang.amount }}</view>
|
||||||
color="#947b2b"
|
<u-input
|
||||||
clearable
|
class="input"
|
||||||
:placeholder="$lang.enterWithdrawalamount"
|
color="#947b2b"
|
||||||
border="surround"
|
clearable
|
||||||
v-model="money"
|
:placeholder="$lang.enterWithdrawalamount"
|
||||||
></u-input>
|
border="surround"
|
||||||
</view>
|
v-model="money"
|
||||||
<view class="list">
|
></u-input>
|
||||||
<view class="lab">{{ $lang.rechargeWithdrawNetwork }}</view>
|
</view>
|
||||||
<view class="type">TRC20</view>
|
<view class="list">
|
||||||
</view>
|
<view class="lab">{{ $lang.rechargeWithdrawNetwork }}</view>
|
||||||
<view class="list">
|
<view class="type">TRC20</view>
|
||||||
<u-button
|
</view>
|
||||||
@tap="applyWithdraw"
|
<view class="list">
|
||||||
class="button"
|
<u-button
|
||||||
color="#e5b932"
|
@tap="applyWithdraw"
|
||||||
:text="$lang.submit"
|
class="button"
|
||||||
></u-button>
|
color="#e5b932"
|
||||||
</view>
|
:text="$lang.submit"
|
||||||
<view class="list">
|
></u-button>
|
||||||
<view class="tip">{{ $lang.withdrawTip }}</view>
|
</view>
|
||||||
<view class="tip">{{ $lang.commission }}:1 USDT</view>
|
<view class="list">
|
||||||
</view>
|
<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>
|
||||||
<view class="mb60"></view>
|
<view class="mb60"></view>
|
||||||
</view>
|
</view>
|
||||||
@@ -104,6 +188,14 @@ export default {
|
|||||||
type: "USDT",
|
type: "USDT",
|
||||||
show: false,
|
show: false,
|
||||||
columns: [["USDT"]],
|
columns: [["USDT"]],
|
||||||
|
// 越南银行卡提现
|
||||||
|
bankName: "",
|
||||||
|
bankCode: "",
|
||||||
|
accountName: "",
|
||||||
|
accountNumber: "",
|
||||||
|
showBankPicker: false,
|
||||||
|
bankColumns: [[]],
|
||||||
|
bankList: [],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -112,7 +204,12 @@ export default {
|
|||||||
$lang: (state) => state.app.lang[state.app.language],
|
$lang: (state) => state.app.lang[state.app.language],
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
onLoad() {},
|
onLoad() {
|
||||||
|
// 越南渠道加载银行列表
|
||||||
|
if (this.userInfo && this.userInfo.pay_channel === 'ALIN_VN') {
|
||||||
|
this.loadBankList();
|
||||||
|
}
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
confirm(chose) {
|
confirm(chose) {
|
||||||
this.type = chose.value[0];
|
this.type = chose.value[0];
|
||||||
@@ -169,6 +266,111 @@ export default {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
// 加载越南银行列表
|
||||||
|
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>
|
</script>
|
||||||
|
|||||||
@@ -53,6 +53,18 @@ let api = {
|
|||||||
ybfDeposit: async (params) => {
|
ybfDeposit: async (params) => {
|
||||||
return await ajax.post("/deposit", params);
|
return await ajax.post("/deposit", params);
|
||||||
},
|
},
|
||||||
|
// 越南AlinPay充值
|
||||||
|
alinDeposit: async (params) => {
|
||||||
|
return await ajax.post("/alin_online_order", params);
|
||||||
|
},
|
||||||
|
// 越南银行卡提现
|
||||||
|
applyWithdrawBank: async (params) => {
|
||||||
|
return await ajax.post("/apply_withdraw_bank", params);
|
||||||
|
},
|
||||||
|
// 获取越南银行列表
|
||||||
|
getBankListVn: async (params) => {
|
||||||
|
return await ajax.post("/get_bank_list_vn", params);
|
||||||
|
},
|
||||||
// 获取用户信息
|
// 获取用户信息
|
||||||
getUserInfo: async (params) => {
|
getUserInfo: async (params) => {
|
||||||
return await ajax.post("/get_user_info", params);
|
return await ajax.post("/get_user_info", params);
|
||||||
|
|||||||
Reference in New Issue
Block a user