Files
h5-uniapp/pages/index/recharge.vue
T
li 6b02df55ab feat: contract account tab, full i18n, male avatar, PC home stretch
- Asset page: add Contract account row + tab, show num_lh balance
- Total Assets = Spot + Contract + Fiat
- All Chinese text eliminated (z-paging, loadmore, colorui, pages)
- Password/payword pages use image captcha instead of OTP
- Home page PC: full-width stretch layout
- Register captcha input type fix, invite code lock
2026-04-05 13:05:27 +08:00

522 lines
17 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 :style="'background-color: '+theme.bg+';color: '+theme.text">
<!-- 头部 -->
<view class="width-750 relative flex align-center justify-center"
:style="{height: `calc(${statusBar}px + 110rpx)`}">
<view class="width-750 fixed1 bgimg1"
:style="{paddingTop: statusBar + 'px', height: `calc(${statusBar}px + 110rpx)`}">
<view class="width-750 height-110 padding-w-30 flex align-center justify-center">
<view @click="_goback" class="cuIcon-back font-40 color-white"
style="position: absolute;left: 30rpx;"></view>
<text class="font-36 color-white weight-bold">{{i18n.recharge.title1}}</text>
<image @click="router.push('/pages/index/rechargeRecord')" class="width-36 height-36"
src="/static/imgs/index/jilu.png" style="position: absolute;right: 30rpx;"></image>
</view>
</view>
</view>
<!-- 身体 -->
<view class="width-750">
<view class="height-305 bgimg2 padding-t-10 padding-w-30">
<view class="">
<view v-if="current==2" :style="'background-color: '+theme.fu_bg+';color: '+theme.text"
class="width-100b radiu-20 padding-w-32 margin-t-20">
<view @click="bankshow=true" class="height-80 flex align-center justify-between">
<text class="font-28 weight-bold">{{bank.bank_name}} ({{bank.bank_user}})</text>
<i class="cuIcon-right font-28"></i>
</view>
<view class="height-70 flex align-center justify-between">
<text class="font-28 weight-bold">{{bank.card_num}}</text>
<i @click="copy(bank.card_num)" class='cuIcon-copy font-30 color-0165EE'></i>
</view>
<view v-if="current==2" class="height-58 line-height-58">
<text class="font-24">{{i18n.recharge.huilv}} {{bank.exchange}} USDT</text>
</view>
</view>
<!-- 币种选择 -->
<view v-if="current==1" class="width-100b radiu-20 padding-w-32 padding-b-20 margin-t-20"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="height-90 padding-t-27 font-28 weight-bold">{{i18n.recharge.text1}}</view>
<view class="flex align-center flex-wrap">
<view @click="changeCoinType(item)" v-for="(item,index) in coinTypes" :key="item.id"
:class="currid==item.id?'onbox':'offbox'" class="numbold-font margin-r-14">{{item.name}}
</view>
</view>
</view>
<!-- 链类型BTC 时不显示链选择器其他币种显示过滤后的链列表 -->
<view v-if="current==1 && filteredDetail.length > 1" class="width-100b radiu-20 padding-w-32 padding-b-20 margin-t-20"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="height-90 padding-t-27 font-28 weight-bold">{{i18n.recharge.text2}}
</view>
<view class="flex align-center flex-wrap">
<view @click="changelian(item,index)" v-for="(item,index) in filteredDetail"
:class="index==lian?'onbox':'offbox'" class="numbold-font margin-r-14">{{item.lian}}
</view>
</view>
</view>
<!-- 二维码 -->
<view v-if="current==1" class="codebox" :style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="flex align-center justify-center">
<text class="font-28 weight-bold">{{i18n.recharge.text3}}</text>
</view>
<view class="margin-t-30 flex align-center justify-center">
<view class="width-260 height-260 radiu-10 flex align-center justify-center"
style="border: 4rpx solid #52F3C9;">
<image class="width-242 height-242" :src="image?image:'/static/APEClogo@2x.png'"
mode=""></image>
</view>
</view>
<!-- <view @click="saveImage()"
class="width-240 height-66 radiu-33 flex align-center justify-center margin-0-auto margin-t-38"
style="border: 1px solid #0165EE;">
<text class="font-28 color-0165EE weight-bold">{{i18n.recharge.text4}}</text>
</view> -->
<view class="font-26 nummedium-font margin-20-auto text-center">{{zhuan_address}}</view>
<view @click="copy(zhuan_address)"
class="width-240 height-66 radiu-33 flex align-center justify-center margin-0-auto"
style="border: 1px solid #52F3C9;">
<text class="font-28 color-0165EE weight-bold">{{i18n.recharge.text6}}</text>
</view>
</view>
<view class="radiu-20 margin-t-10" :style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="width-100b height-160 padding-w-32 padding-c-27 flex direction-column justify-between">
<view class="flex align-center justify-between">
<text v-if="current==1" class="font-28 weight-bold">{{i18n.recharge.title4}}</text>
<text v-if="current==2" class="font-28 weight-bold">{{i18n.recharge.new1}}</text>
<text v-if="current==2" class="font-26">{{i18n.recharge.text9}}{{Number(num*bank.exchange).toFixed(4)}}</text>
</view>
<input class="font-28" :placeholder="current==1?i18n.recharge.title8:i18n.recharge.new2" type="number" v-model="num" />
</view>
<view v-if="current==1" class="width-100b height-160 padding-w-32 padding-c-27 flex direction-column justify-between">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.recharge.title5}}</text>
</view>
<input class="font-28" :placeholder="i18n.recharge.title9" type="text" v-model="address" />
</view>
<!-- <view v-if="current==2" class="width-100b height-160 padding-w-32 padding-c-27 flex direction-column justify-between">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.recharge.title15}}</text>
</view>
<input class="font-28" :placeholder="i18n.recharge.title18" type="text" v-model="bank_name" />
</view> -->
<!-- <view v-if="current==2" class="width-100b height-160 padding-w-32 padding-c-27 flex direction-column justify-between">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.recharge.title16}}</text>
</view>
<input class="font-28" :placeholder="i18n.recharge.title19" type="number" v-model="card_num" />
</view> -->
<view class="width-100b height-160 padding-w-32 padding-c-27 flex direction-column justify-between">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.recharge.title7}}</text>
</view>
<input class="font-28" password :placeholder="i18n.recharge.title11" type="text"
v-model="pay_pwd" />
</view>
<view class="width-100b padding-w-32 padding-c-27 flex direction-column justify-between">
<view class="font-28 weight-bold flex align-center justify-between">
<text>{{i18n.recharge.title17}}</text>
</view>
<view class="height-200 flex align-center justify-center">
<view @click="chooseImage()"
class="width-200 height-200 flex align-center justify-center radiu-20"
:style="'background-color: '+theme.bg">
<image v-if="voucher_image" class="width-200 height-200" :src="voucher_image" mode=""></image>
<i v-else class='cuIcon-add font-50 weight-bold'></i>
</view>
</view>
</view>
</view>
<view class="width-600 margin-0-auto margin-t-30">
<u-button v-if="current==1" @click="chongzhi" class="custom-style" type="primary" style="background-color: #3ECEB2;">{{i18n.appeal.text1}}
</u-button>
<u-button v-if="current==2" @click="yinhangka()" class="custom-style" type="primary" style="background-color: #3ECEB2; margin-top: 30rpx;">{{i18n.appeal.text1}}
</u-button>
</view>
</view>
<!-- 空盒子 -->
<view class="height-40"></view>
</view>
</view>
<!-- 币种弹窗 -->
<u-popup v-model="show" mode="bottom" border-radius="20">
<view class="height-437 padding-w-30 padding-b-36"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="flex align-center justify-between padding-c-32">
<text class="font-28">{{i18n.recharge.text7}}</text>
<text @click.stop="show=false" class="font-26 color-C3C3C3">{{i18n.recharge.text8}}</text>
</view>
<view class="height-278">
<scroll-view scroll-y="true" class="height-220">
<view @click.stop="changecurr(item)" v-for="(item,index) in list"
class="height-72 padding-w-30 flex align-center margin-b-17 font-28">
{{item.name}}
</view>
</scroll-view>
</view>
</view>
</u-popup>
<!-- 银行弹窗 -->
<u-popup v-model="bankshow" mode="bottom" border-radius="20">
<view class="height-517 padding-w-30 padding-b-36"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<view class="flex align-center justify-between padding-c-32">
<text class="font-28">{{i18n.fastRecord.text9}}</text>
<text @click.stop="bankshow=false" class="font-26 color-C3C3C3">{{i18n.recharge.text8}}</text>
</view>
<view class="height-358">
<scroll-view scroll-y="true" class="height-300">
<view @click.stop="changebank(item)" v-for="(item,index) in bankList"
class="height-72 flex align-center margin-b-17">
<image class="width-38 height-38 radiu-50b margin-r-18" :src="item.logo_image" mode=""></image>
<text class="font-28">{{item.curr_name}} {{item.name}} ({{item.bank_user}})</text>
</view>
</scroll-view>
</view>
</view>
</u-popup>
</view>
</template>
<script>
import clipboard from "@/components/clipboard.js"
export default {
data() {
return {
statusBar: uni.getSystemInfoSync().statusBarHeight,
current: 1,
show: false,
bankshow:false,
list: [],
lian: 0,
curr: '',
currid: '',
detail: [],
zhuan_address: '',
image: '',
xieyi: '',
theme: '',
num: '',
address: '',
hash: '',
pay_pwd: '',
flag: true,
coinTypes: [],
bankList:[],
bank: {},
voucher_image: '',
voucher_image_up: '',
// card_num: '',
// bank_name: '',
}
},
computed: {
i18n() {
return this.$t('message');
},
// 根据当前选中币种过滤链列表
// BTC: 只保留名称含 "BTC" 的链(或空)
// ETH: 过滤掉 TRC-20,只保留 ERC-20
// USDT: 保留全部
filteredDetail() {
if (!this.detail || this.detail.length === 0) return []
const name = (this.curr || '').toUpperCase()
if (name === 'BTC') {
// BTC 不需要链选择,只取第一条直接显示地址
return this.detail.slice(0, 1)
}
if (name === 'ETH') {
// ETH 只保留 ERC-20,过滤掉 TRC-20
const erc = this.detail.filter(item => {
const lian = (item.lian || '').toUpperCase()
return !lian.includes('TRC')
})
return erc.length > 0 ? erc : this.detail.slice(0, 1)
}
// USDT 及其他:保留全部
return this.detail
}
},
onLoad(e) {
if(e.current==2){
this.current = e.current
}
},
onShow() {
if (uni.getStorageSync("theme") == "dark") {
this.theme = this.$store.state.darkTheme
} else {
this.theme = this.$store.state.lightTheme
}
this.getcurrlist()
},
methods: {
chongzhi() {
if (!this.flag) return
if (this.num == '') return this.tos(this.i18n.recharge.title8)
if (this.address == '') return this.tos(this.i18n.recharge.title9)
if (this.paypwd == '') return this.tos(this.i18n.recharge.title11)
this.post('/wallet/recharge_sub', {
type:1,
num: this.num,
address: this.address,
hash: this.hash,
pay_pwd: this.pay_pwd,
voucher_image: this.voucher_image_up
}).then(res => {
console.log(res)
if (res.code == 1) {
this.tos(res.msg)
this.paypwd = ''
setTimeout(() => {
uni.navigateTo({
url: '/pages/index/rechargeRecord'
})
}, 500)
}
})
},
copy(data) {
// #ifndef H5
clipboard.setText(data);
// #endif
// #ifdef H5
let result
let textarea = document.createElement("textarea")
textarea.value = data
textarea.readOnly = "readOnly"
document.body.appendChild(textarea)
textarea.select() // 选中文本内容
textarea.setSelectionRange(0, data.length)
result = document.execCommand("copy")
textarea.remove()
// #endif
this.tos(this.i18n.mine.share.copySuceed)
},
saveImage(image) {
var that = this;
uni.saveImageToPhotosAlbum({
filePath: that.image,
success(res) {
that.tos(that.i18n.mine.share.codeSuceed)
}
})
},
// 获取充值内容
getdetails(id) {
this.post('/wallet/get_wallet_address', {
id: id
},true).then(res => {
console.log(res)
if (res.code == 1) {
this.bank = res.data.bank[0]
this.bankList = res.data.bank
this.detail = res.data.curr
this.lian = 0
// 根据当前币种过滤后取第一条链的地址显示
const name = (this.curr || '').toUpperCase()
let firstChain = res.data.curr[0]
if (name === 'ETH' && res.data.curr.length > 0) {
const erc = res.data.curr.filter(item => {
return !(item.lian || '').toUpperCase().includes('TRC')
})
if (erc.length > 0) firstChain = erc[0]
}
this.image = firstChain ? firstChain.qrcode : ''
this.zhuan_address = firstChain ? firstChain.address : ''
}
})
},
// 获取币种
getcurrlist() {
this.post('/wallet/reg_curr').then(res => {
console.log(res)
if (res.code == 1) {
this.list = res.data
// 构建币种选择列表,确保包含 BTC 和 ETH
let types = [...res.data]
let names = types.map(t => t.name.toUpperCase())
if (!names.includes('BTC')) {
types.push({ id: 'btc_static', name: 'BTC' })
}
if (!names.includes('ETH')) {
types.push({ id: 'eth_static', name: 'ETH' })
}
this.coinTypes = types
this.curr = res.data[0].name
this.currid = res.data[0].id
this.getdetails(this.currid)
}
})
},
changeCoinType(item) {
if (this.currid == item.id) return
this.curr = item.name
this.currid = item.id
this.voucher_image = ''
this.voucher_image_up = ''
this.lian = 0
// 静态条目(btc_static / eth_static)没有真实 API id
// 不调用 getdetails,改为构造占位链数据
if (item.id === 'btc_static') {
this.detail = [{ lian: 'BTC', qrcode: '', address: '' }]
this.image = ''
this.zhuan_address = ''
return
}
if (item.id === 'eth_static') {
this.detail = [{ lian: 'ERC-20', qrcode: '', address: '' }]
this.image = ''
this.zhuan_address = ''
return
}
this.getdetails(this.currid)
},
changecurr(item) {
this.curr = item.name
this.currid = item.id
this.getdetails(this.currid)
this.show = false
},
changebank(item){
this.bank = item
this.bankshow = false
},
changelian(item, index) {
if (this.lian != index) {
this.lian = index
this.image = item.qrcode
this.zhuan_address = item.address
}
},
yinhangka() {
if (!this.flag) return
if (this.num == '') return this.tos(this.i18n.recharge.title8)
// if (this.bank_name == '') return this.tos(this.i18n.recharge.title18)
// if (this.card_num == '') return this.tos(this.i18n.recharge.title19)
if (this.paypwd == '') return this.tos(this.i18n.recharge.title11)
this.post('/wallet/recharge_sub', {
type:2,
num: this.num,
bank_id: this.bank.id,
pay_pwd: this.pay_pwd,
// bank_name: this.bank_name,
// card_num: this.card_num,
voucher_image: this.voucher_image_up
}).then(res => {
console.log(res)
if (res.code == 1) {
this.tos(res.msg)
this.paypwd = ''
setTimeout(() => {
uni.navigateTo({
url: '/pages/index/rechargeRecord'
})
}, 500)
}
})
},
chooseImage() {
let self = this
uni.chooseImage({
count: 1,
success: (chooseImageRes) => {
const tempFilePaths = chooseImageRes.tempFilePaths;
self.voucher_image = tempFilePaths[0]
uni.showLoading({
mask:true
})
uni.uploadFile({
url: this.upload + '/publics/image_upload',
filePath: tempFilePaths[0],
name: 'file',
success: (res) => {
let data = JSON.parse(res.data)
if (data.code == 1) {
self.voucher_image_up = data.data.url
}
},
complete:() =>{
uni.hideLoading()
}
})
}
})
},
}
}
</script>
<style lang="scss">
.fixed1 {
position: fixed;
top: 0;
z-index: 1000;
// background-color: #FFFFFF;
}
.bgimg1 {
// background-image: url(../../static/imgs/index/bgimg1.png);
// background-repeat: repeat;
// background-size: 100% 100%;
background: linear-gradient(180deg, #52F3C9 0%, #3ECEB2 100%);
}
.bgimg2 {
// background-image: url(../../static/imgs/index/bgimg2.png);
// background-repeat: repeat;
// background-size: 100% 100%;
background: linear-gradient(180deg, #3ECEB2 0%, #52F3C9 100%);
}
.onbox {
height: 56rpx;
padding: 0 24rpx;
background: linear-gradient(180deg, #52F3C9 0%, #3ECEB2 100%);
border-radius: 28rpx;
text-align: center;
line-height: 56rpx;
font-size: 28rpx;
color: #FFFFFF;
}
.offbox {
height: 56rpx;
padding: 0 24rpx;
background: rgba(139, 153, 162, 0.2);
border-radius: 28rpx;
text-align: center;
line-height: 56rpx;
font-size: 28rpx;
color: #8B99A2;
}
.codebox {
width: 690rpx;
height: 500rpx;
// background: #FFFFFF;
box-shadow: 0rpx 0rpx 0rpx #EBF0F6;
opacity: 1;
border-radius: 20rpx;
margin-top: 20rpx;
padding: 27rpx 32rpx 39rpx;
}
</style>