feat: 前端全量更新 - 含所有本次需求

- 移除秒合约页面及UI
- 合约页Tab改为Position Held/Transaction Record
- 存款/提款/转账页增加BTC/ETH
- 资产页重构(用户信息+盈亏+多语言)
- 注册页改版(匹配新设计稿)
- 日文全面翻译+首页菜单多语言
- 代理专属注册链接支持(?code=)
- 10个locale文件同步更新
This commit is contained in:
li
2026-03-30 20:14:20 +08:00
commit 5f40e4e1b5
605 changed files with 154871 additions and 0 deletions
+488
View File
@@ -0,0 +1,488 @@
<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 style="background-color: rgba(255,255,255,0);"
class="width-100b height-96 radiu-20 padding-w-32 flex align-center justify-between">
<view @click="current=2,voucher_image='',voucher_image_up=''" class="padding-w-18 height-78 radiu-20 text-center line-height-78"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<text :class="current==2?'color-0165EE':''" class="font-28">{{i18n.fastRecord.text9}}</text>
</view>
<view @click="current=1,voucher_image='',voucher_image_up=''" class="padding-w-18 height-78 radiu-20 text-center line-height-78"
:style="'background-color: '+theme.fu_bg+';color: '+theme.text">
<text :class="current==1?'color-0165EE':''" class="font-28">{{i18n.fastRecord.tos2}}</text>
</view>
</view>
<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">Select Coin</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>
<!-- 链类型 -->
<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.text2}}
</view>
<view class="flex align-center flex-wrap">
<view @click="changelian(item,index)" v-for="(item,index) in detail"
: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: 300rpx;">{{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: 2,
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');
}
},
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
this.image = res.data.curr[0].qrcode
this.zhuan_address = res.data.curr[0].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.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>