feat: PC端对接越南AlinPay支付(充值+提现)

- recharge2.vue: area_id==3显示AlinPay充值表单,最低1,000,000 VND
- withdrawal.vue: 越南银行列表+银行卡提现,最低1,000,000 VND验证
- store/index.js: userInfo增加area_id字段
- login.vue: 三种登录流程均保存area_id
- config.json: isRecharge改为true

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:
li
2026-03-22 12:55:55 +08:00
co-authored by Claude Happy
parent bc6561acf9
commit 1fe554f907
5 changed files with 173 additions and 40 deletions
+87 -4
View File
@@ -1,9 +1,20 @@
<template>
<div class="recharge2" >
<div class="btn off-btn" @click="offPop"></div>
<div class="btn pay2-btn" @click="isShowPop('recharge')">{{Language.recharge_offline2}} </div>
<div class="btn pay2-btn" v-if="userInfo.area_id != 3" @click="isShowPop('recharge')">{{Language.recharge_offline2}} </div>
<div class="title">{{Language.recharge_online2}}</div>
<iframe class="page" :src="webconfig.PayUrl+'?uid='+userInfo.uid+'&api_token='+userInfo.api_token"></iframe>
<!-- 越南 AlinPay 在线充值 -->
<div class="view" v-if="userInfo.area_id == 3">
<div class="alin-form">
<div class="alin-item">
<label>{{Language.withdraw_page_withdrawal_amount || '充值金额'}}</label>
<input class="input" type="number" v-model="alinAmount" placeholder="Tối thiểu 1,000,000">
</div>
<button class="btn alin-submit" @click="submitAlin">{{Language.withdraw_page_confirm || '确认充值'}}</button>
</div>
</div>
<!-- 其他渠道 iframe -->
<iframe v-else class="page" :src="webconfig.PayUrl+'?uid='+userInfo.uid+'&api_token='+userInfo.api_token"></iframe>
</div>
</template>
@@ -14,6 +25,8 @@ import { mapState } from 'vuex'
export default {
data() {
return {
alinAmount: '',
ApiUrl: JSON.parse(localStorage.getItem('ApiUrl'))
}
},
@@ -27,13 +40,45 @@ export default {
isShowPop(type){
this.$store.dispatch('updatemainPop',{type:type,ishow:true});
},
submitAlin(){
if(!this.alinAmount || this.alinAmount <= 0){
this.$message({type:'warning', message:'Vui lòng nhập số tiền!'});
return;
}
if(this.alinAmount < 1000000){
this.$message({type:'warning', message:'Số tiền tối thiểu là 1,000,000'});
return;
}
var encryptstring = encrypt(JSON.stringify({
user_id: this.userInfo.uid,
price: this.alinAmount,
client: 1,
username: this.userInfo.nickname,
api_token: this.userInfo.api_token,
})).toString();
this.$axios.post(this.ApiUrl+'/alin_online_order', {encryptData:encryptstring}).then(
response=>{
if(response.data.Success==1){
const data = JSON.parse(decrypt(response.data.Data));
if(data.status == 1 && data.url){
window.open(data.url, '_blank');
} else {
this.$message({type:'error', message: data.message || '充值失败'});
}
} else {
this.$message({type:'error', message: response.data.Msg || '充值失败'});
}
}).catch(error=>{
console.log(error);
this.$message({type:'error', message:'充值请求失败'});
});
},
},
computed: {
...mapState(['userInfo','webconfig','Language'])
},
watch:{
},
}
</script>
@@ -77,6 +122,44 @@ export default {
width:100%;
height: 250px;
}
.recharge2 .alin-form{
padding: 30px 40px;
}
.recharge2 .alin-item{
margin-bottom: 15px;
}
.recharge2 .alin-item label{
color: #ccc;
font-size: 14px;
display: block;
margin-bottom: 8px;
}
.recharge2 .alin-item .input{
width: 100%;
height: 35px;
background: rgba(0,0,0,0.5);
border: 1px solid #907545;
border-radius: 5px;
color: #e5b932;
padding: 0 10px;
font-size: 14px;
box-sizing: border-box;
}
.recharge2 .alin-submit{
width: 100%;
height: 40px;
background: linear-gradient(to right, #e5b932, #c5971e);
border: none;
border-radius: 5px;
color: #161107;
font-size: 16px;
font-weight: bold;
cursor: pointer;
margin-top: 10px;
}
.recharge2 .alin-submit:hover{
opacity: 0.9;
}
.recharge2 .page{
border: none;
width:100%;
+61 -14
View File
@@ -35,14 +35,14 @@
<label>{{Language.withdraw_page_bank_name}}</label>
<el-select class="input-box" v-model="recharge_bank" :placeholder="Language.withdraw_page_select_bank">
<el-option
v-for="item in bankData"
v-for="item in (userInfo.area_id == 3 ? vnBankData : bankData)"
:key="item.value"
:label="item.text"
:value="item.text">
</el-option>
</el-select>
</div>
<div class="item">
<div class="item" v-if="userInfo.area_id != 3">
<label>{{Language.withdraw_page_subsidiary}}</label>
<input class="input" type="text" :placeholder="Language.withdraw_page_input" v-model="recharge_bank_branch">
</div>
@@ -77,7 +77,7 @@
<div class="li">
<div class="item">
<label>{{Language.withdraw_page_withdrawal_amount}}</label>
<input class="input" type="text" v-model="recharge_money" :placeholder="Language.withdraw_page_input" >
<input class="input" type="text" v-model="recharge_money" :placeholder="userInfo.area_id == 3 ? 'Tối thiểu 1,000,000 VND' : Language.withdraw_page_input" >
</div>
</div>
@@ -99,6 +99,7 @@ export default {
return {
isClickadd:false,
bankData:bankData,
vnBankData:[],
recharge_name:'',//收款人名
recharge_bank:'',//银行
recharge_bank_branch:'',//支行
@@ -120,11 +121,11 @@ export default {
var encryptstring= encrypt(JSON.stringify({
user_id:userInfo.uid,
api_token:userInfo.api_token,
})).toString();
})).toString();
this.$axios.post(this.ApiUrl+'/show_withdrawal',{encryptData:encryptstring}).then(
response=>{
if(response.data.Success==1){
const data=JSON.parse(decrypt(response.data.Data));
const data=JSON.parse(decrypt(response.data.Data));
this.ongoing_money=data.ongoing_money;
this.finish_money=data.finish_money;
this.collectBank=data.user_bank;
@@ -138,6 +139,22 @@ export default {
error=>{
console.log(error)
})
// 越南用户加载银行列表
if(userInfo.area_id == 3){
var encryptBankReq = encrypt(JSON.stringify({
user_id:userInfo.uid,
api_token:userInfo.api_token,
})).toString();
this.$axios.post(this.ApiUrl+'/get_bank_list_vn',{encryptData:encryptBankReq}).then(
response=>{
if(response.data.Success==1){
const data=JSON.parse(decrypt(response.data.Data));
if(data.status == 1 && data.data){
this.vnBankData = data.data.map(function(item){ return {value:item.code, text:item.name}; });
}
}
}).catch(error=>{ console.log(error); })
}
},
methods:{
payType(index){
@@ -151,9 +168,39 @@ export default {
},
Submission(){
var userInfo=this.userInfo;
if(this.collectBank==''){
var isVN = userInfo.area_id == 3;
// 越南用户走 apply_withdraw_bank,字段不同
if(isVN){
if(this.recharge_name==''){
this.$message({type: 'warning',message: '请填写持卡人名称!'});
}else if(this.recharge_bank==''){
this.$message({type: 'warning',message: '请选择银行!'});
}else if(this.recharge_cardnumber==''){
this.$message({type: 'warning',message: '请填写银行卡号!'});
}else if(this.recharge_money==''){
this.$message({type: 'warning',message: '请填写提现金额!'});
}else if(Number(this.recharge_money) < 1000000){
this.$message({type: 'warning',message: 'Số tiền rút tối thiểu là 1,000,000 VND'});
}else if(this.recharge_money>this.userInfo.money){
this.$message({type: 'warning',message: '您的余额没有那么多钱!'});
}else{
var encryptstring= encrypt(JSON.stringify({
user_id:userInfo.uid,
account_name:this.recharge_name,
account_number:this.recharge_cardnumber,
bank_code:this.recharge_bank,
bank_name:this.recharge_bank,
amount:this.recharge_money,
api_token:userInfo.api_token,
})).toString();
this.postData(encryptstring);
}
return;
}
if(this.collectBank==''){
//填写提交
// console.log('填写提交1')
if(this.recharge_name==''){
this.$message({type: 'warning',message: '请填写持卡人名称!'});
}else if(this.recharge_bank==''){
@@ -175,11 +222,10 @@ export default {
recharge_cardnumber:this.recharge_cardnumber,
recharge_money:this.recharge_money,
api_token:userInfo.api_token,
})).toString();
})).toString();
this.postData(encryptstring);
}
}else if(this.collectBank!=''&&this.isClickadd==false){ //选择银行卡提交
// console.log('选择银行卡提交')
if(this.recharge_money==''){
this.$message({type: 'warning',message: '请填写提现金额!'});
}else if(this.recharge_money>this.userInfo.money){
@@ -193,11 +239,10 @@ export default {
recharge_cardnumber:this.collectVal.receivables_bank_number,
recharge_money:this.recharge_money,
api_token:userInfo.api_token,
})).toString();
})).toString();
this.postData(encryptstring);
}
}else if(this.collectBank!=''&&this.isClickadd==true){ //填写提交
// console.log('填写提交')
if(this.recharge_name==''){
this.$message({type: 'warning',message: '请填写持卡人名称!'});
}else if(this.recharge_bank==''){
@@ -219,16 +264,18 @@ export default {
recharge_cardnumber:this.recharge_cardnumber,
recharge_money:this.recharge_money,
api_token:userInfo.api_token,
})).toString();
})).toString();
this.postData(encryptstring);
}
}
},
postData(encryptstring){
this.$axios.post(this.ApiUrl+'/withdrawal',{encryptData:encryptstring}).then(
// 越南用户走 apply_withdraw_bank 接口
var url = this.userInfo.area_id == 3 ? '/apply_withdraw_bank' : '/withdrawal';
this.$axios.post(this.ApiUrl+url,{encryptData:encryptstring}).then(
response=>{
if(response.data.Success==1){
const data=JSON.parse(decrypt(response.data.Data));
const data=JSON.parse(decrypt(response.data.Data));
this.ongoing_money=data.ongoing_money;
this.finish_money=data.finish_money;
this.$store.commit('updateMoney',data.newMoney)
+7 -4
View File
@@ -173,6 +173,7 @@ export default {
memo:data.memo,
is_sw:data.is_sw,
bet_type:data.bet_type,
area_id:data.area_id||0,
user_limit:{
limit_high: data.limit_high||0,
limit_high_pair: data.limit_high_pair||0,
@@ -184,8 +185,8 @@ export default {
}
// console.log(data)
this.$cookies.set("userInfo",userInfo);
this.InitializationData();
this.$router.push({ path:'/main'});
this.InitializationData();
this.$router.push({ path:'/main'});
}
})
.catch(error=>{
@@ -286,6 +287,7 @@ export default {
memo:data.memo,
is_sw:data.is_sw,
bet_type:data.bet_type,
area_id:data.area_id||0,
user_limit:{
limit_high: data.limit_high||0,
limit_high_pair: data.limit_high_pair||0,
@@ -296,7 +298,7 @@ export default {
}
}
this.$cookies.set("userInfo",userInfo);
this.InitializationData();
this.InitializationData();
this.$router.push({ path:'/main'})
}
})
@@ -327,6 +329,7 @@ export default {
memo:data.memo,
is_sw:data.is_sw,
bet_type:data.bet_type,
area_id:data.area_id||0,
user_limit:{
limit_high: data.limit_high||0,
limit_high_pair: data.limit_high_pair||0,
@@ -337,7 +340,7 @@ export default {
}
}
this.$cookies.set("userInfo",userInfo);
this.InitializationData();
this.InitializationData();
this.$router.push({ path:'/main'})
}
})
+2
View File
@@ -28,6 +28,7 @@ const state = {
memo: "",
is_sw: 0,
bet_type: "",
area_id: 0,
},
tabData: [],
asktype: { type: null, isclick: true },
@@ -114,6 +115,7 @@ const mutations = {
state.userInfo.api_token = value.api_token;
state.userInfo.memo = value.memo;
state.userInfo.is_sw = value.is_sw;
state.userInfo.area_id = value.area_id || 0;
(state.userInfo.bet_type = value.bet_type),
(state.userInfo.user_limit = value.user_limit || {
limit_high: 0,
+16 -18
View File
@@ -1,36 +1,34 @@
{
"ApiUrl":"http://192.168.88.251:85/pcapi",
"SockUrl":"192.168.88.251:6080",
"ServerPort":"6080",
"HallUrl": "https://v.yourvideo.com/yg/hall.flv",
"LoginLogo": "http://192.168.88.251:85/static/logo/wb_logo.png",
"LogoPng": "http://192.168.88.251:85/static/logo/wb_logo.png",
"TitlePng": "http://192.168.88.251:85/static/logo/wb_200_60.png",
"ApiUrl":"https://api.g7g7.top/pcapi",
"SockUrl":"wss://api.g7g7.top",
"ServerPort":"443",
"HallUrl": "https://v1.yourvideo.com/kr/pRzcSz.flv",
"LoginLogo": "https://api.g7g7.top/static/logo/og_logo_180_180.png",
"LogoPng": "https://api.g7g7.top/static/logo/og_logo_160_143.png",
"TitlePng": "https://api.g7g7.top/static/logo/og_logo_title_200_60.png",
"entranceQrcode":"http://192.168.88.251:85/static/logo/normal_entranceQrcode.png?v=10",
"agentUrl":"http://192.168.88.249",
"entranceQrcode":"https://api.g7g7.top/static/logo/og_qrcode.jpg",
"agentUrl":"https://agt.g7g7.top",
"BgMusic": "static/sound/bg.mp3",
"IframeUrl": "https://p.abc.com/video.html",
"IframeUrl": "https://p.g7g7.top/video.html",
"PayUrl": "",
"AppUrl": "https://www.abc.com/",
"AppQrcode": "http://192.168.88.251:85/static/logo/app_qrcode.png?v=10",
"ServerQrcode": "http://192.168.88.251:85/static/logo/cus.jpeg",
"customerLink": "https://kf.tvbn018.vip/index/index/home?visiter_id=&visiter_name=&avatar=&groupid=0&business_id=2",
"AppUrl": "https://og-w.g7g7.top/",
"AppQrcode": "https://api.g7g7.top/static/logo/og_qrcode.png",
"ServerQrcode": "https://api.g7g7.top/static/logo/og_service.png",
"isCancelBet": "1",
"isChipSet": "1",
"Title": "WINBEST",
"Title": "OG ONLINE CASINO",
"baccarat": true,
"dt": true,
"flopTime": 1000,
"videoZoom": false,
"nn": false,
"nn": true,
"multiple": true,
"onlyTel": false,
"sanka": false,
"isUpdateOnline":true,
"isRegister":false,
"isRecharge":false,
"isRecharge":true,
"isServerCode":true,
"isSetExpired":true,
"sound":2,