Onlife/pages/myProxy/myProxy.vue
2025-04-19 15:38:48 +08:00

925 lines
23 KiB
Vue
Raw Permalink 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="container">
<web-view :webview-styles="webviewStyles" style="visibility: hidden; height: 1px; width: 100%;" src="/static/web3/transfer-web.html" @message="handleWebViewMessage"
:fullscreen="false" :update-title="false"></web-view>
<swiper class="swiper" @change="onSwiperChange" :current="currentIndex" :previous-margin="'50rpx'"
:next-margin="'50rpx'" :circular="false">
<swiper-item v-for="(item, index) in vipLists" :key="item.id">
<view class="swiper-item" :class="{ 'active': index === currentIndex }">
<view :style="{background:'url('+ base_Url + item.img +') no-repeat',backgroundSize:'100% 100%'}"
class="card main-card">
<view class="card-title">用戶等級</view>
<view class="card-content">{{ item.title }}</view>
<view class="card-subtitle">預計收益 {{ item.salesTarget }} USDT</view>
</view>
</view>
</swiper-item>
</swiper>
<view class="card" v-if="currentUserData.coin && currentUserData.coin > 0">
<view class="card-label">升級費用:</view>
<view class="card-value">{{ currentUserData.coin || 0 }} USDT</view>
</view>
<view class="card"
v-if="currentUserData.cond_user_cnt && currentUserData.cond_user_cnt > 0 && currentIndex > 0">
<view class="card-label">直推{{vipLists[currentIndex - 1].title}}人數滿{{currentUserData.cond_user_cnt}}個自動升級
</view>
</view>
<view class="card" v-if="currentUserData.cond_ord_fee && currentUserData.cond_ord_fee > 0" style="
display: flex;
align-items: center;
justify-content: space-between;
">
<view class="card-label" v-if="currentUserData.lv < 2">單次購買算力滿{{currentUserData.cond_ord_fee}}U自動升級</view>
<view class="card-label" v-if="currentUserData.lv > 2">單次購買算力滿{{currentUserData.cond_ord_fee}}U升級</view>
</view>
<view class="card">
<view class="card-label">直推收益比例:</view>
<view class="card-value">{{ currentUserData.parent_rate * 100 }}%</view>
</view>
<view v-if="currentUserData.area_rate && currentUserData.area_rate > 0" class="card">
<view class="card-label">區域收益: {{ currentUserData.area_rate * 100 }}%</view>
</view>
<view v-if="currentUserData.children_rate > 0" class="card">
<view class="card-label">下級收益: {{ currentUserData.children_rate * 100 }}%</view>
</view>
<view v-if="item" v-for="(item,index) in currentUserData.context" :key="index" class="card">
<view class="card-label">{{item}}</view>
</view>
<view class="card" v-if="currentUserData.lv == 3">
<view class="card-label">區域:</view>
<view class="card-value" @tap="chooseCity">{{region.label}}</view>
</view>
<view class="card" v-if="currentUserData.lv == 4">
<view class="card-label">區域:</view>
<view class="card-value" @tap="chooseCity1">{{region1.label}}</view>
</view>
<view @click="payXieyiClick" style="display: flex;align-items: center;">
<checkbox-group @change="payXieyiChange" v-model="xieChecked" v-if="currentUserData.agreement"
style="margin-bottom: 40rpx;">
<checkbox :disabled="isDisable" style="font-size: 25rpx;color: #fff;" value="1">
我已閱讀並同意
<text @tap.stop="showModalXieyi = true">代理商協議書</text>
</checkbox>
</checkbox-group>
</view>
<button v-if="!currentUserData.waitautouplv" class="confirm-button"
@click="showUpgradeModal(currentUserData)">立即升級</button>
<button v-if="currentUserData.waitautouplv && currentUserData.lv > 2 && currentUserData.vfs == 0"
class="confirm-button" @click="autoOrShenhe(currentUserData)">消費達標(待升級)</button>
<button v-if="currentUserData.vfs == 1 && currentUserData.lv == currentUserData.cache_level"
class="confirm-button" style="background-color: #777a9e;">審核中...</button>
<!-- 協議書 -->
<view v-if="showModalXieyi" class="modal_xieyi">
<view class="xieyi_main">
<view class="xieyi_header">
<text @tap="showModalXieyi = false">×</text>
</view>
<scroll-view @scroll="checkScroll" scroll-y="true" class="xieyi_footer">
<view v-html="currentUserData.agreement"></view>
</scroll-view>
</view>
</view>
<!-- 升級彈窗 -->
<view v-if="showModal" class="modal" @click.self="cancelUpgrade">
<view class="modal-content">
<view class="modal-header">
<text class="modal-title">升級確認</text>
<text class="modal-close" @click="cancelUpgrade">×</text>
</view>
<view class="modal-body">
<view v-for="(item,idex) in vipTipsMoney" :key="item.id">
<view class="modal-item">
<text class="modal-label">收款地址:</text>
<text class="modal-value">{{adressOptions(item.to_addr) }}</text>
</view>
<view class="modal-item">
<text class="modal-label">轉賬地址:</text>
<text class="modal-value">{{adressOptions(item.from_addr) }}</text>
</view>
<view class="modal-item">
<text class="modal-label">金額(USDT):</text>
<text class="modal-value">{{ item.coin }}</text>
</view>
</view>
<view class="modal-item">
<text class="modal-label">訂單號:</text>
<text class="modal-value">{{ orderId }}</text>
</view>
<view class="modal-item">
<text class="modal-label">升級名稱:</text>
<text class="modal-value">{{ vipTips.title }}</text>
</view>
</view>
<view class="modal-footer">
<button class="modal-button cancel" @click="cancelUpgrade">取消</button>
<button class="modal-button confirm" @click="confirmUpgrade">確認</button>
</view>
</view>
</view>
<!-- 密碼彈框 -->
<view class="modal" v-if="modalName">
<view class="modal-content">
<view class="modal-header">
<view class="content">請輸入驗證信息</view>
</view>
<view class="modal-body">
<view class="modal-item">
<text class="modal-label">邮箱:</text>
<view class="">{{userInfos.email}}</view>
</view>
<view class="modal-item">
<text class="modal-label">支付密碼:</text>
<u--input color="#fff" style="width: 70%;" :value="zhifuMima" :password="showPassword1"
border="none" @input="handleInput"></u--input>
<img :src="!showPassword1 ? showpwdImg : hidepwdImg" @tap="changePassword()"
style="width: 50rpx;height: 50rpx;"></img>
</view>
<view class="modal-item zf_mod_item">
<text class="modal-label">郵箱驗證碼:</text>
<u--input color="#fff" style="width: 70%;" v-model="emailCode" border="none"></u--input>
<view class="sendcode" @click="tosendemail">{{emaiTip}}</view>
</view>
<view class="modal-item zf_mod_item">
<text class="modal-label">谷歌驗證碼:</text>
<u--input color="#fff" style="width: 70%;" v-model="googleCode" border="none"></u--input>
<view class="sendcode" @click="googleemail">{{googleTip}}</view>
</view>
</view>
<view class="modal-footer">
<button class="modal-button cancel" @tap="hideModal">取消</button>
<button class="modal-button confirm" @tap="modalBtn">確定</button>
</view>
</view>
</view>
<!-- 選擇區 -->
<mpvueCityPicker v-if="currentUserData.lv == 3" ref="mpvueCityPicker" :selectedArea="userAreaQ"
:pickerValueDefault="cityPickerValue" @onCancel="onCancel" @onConfirm="onConfirm"></mpvueCityPicker>
<!-- 選擇省 -->
<provincePickerVue v-if="currentUserData.lv == 4" ref="mpvueCityPicker1" :pickerValueDefault="cityPickerValue1"
@onCancel1="onCancel1" :selectedArea="userAreaS" @onConfirm1="onConfirm1"></provincePickerVue>
</view>
</template>
<script>
import {
BASE_URL
} from '@/request/config.js'
import {
_viplist,
_walletinfo,
_levelupinfo,
_sendcoin,
_userInfos,
_chksubdata,
_chkarea,
_getareas,
_emailSend
} from "@/request/api.js"
import publicFn from '@/common/publicFunction.js'
import mpvueCityPicker from '@/components/mpvue-citypicker/mpvueCityPicker.vue'
import provincePickerVue from '@/components/mpvue-citypicker/provincePicker.vue'
import {
publicjiemi
} from "@/common/jiemi.js"
import MD5 from "blueimp-md5";
export default {
components: {
mpvueCityPicker,
provincePickerVue
},
data() {
return {
emailCode:"",
googleCode:"",
emaiTip:"發送",
googleTip:"發送",
shengjiId: "",
webviewStyles: {
progress: false,
width: "0px",
height: "0px"
},
webviewInstance: null,
showpwdImg: "static/icon/eye_on.png",
hidepwdImg: "static/icon/eye_off.png",
showPassword1: true,
oneSee: false,
xieChecked: [],
isDisable: true,
userAreaQ: [],
userAreaS: [],
isUplodes: false,
showModalXieyi: false,
isCheckXieyi: false,
base_Url: "",
zhifuMima: "", //支付密碼
modalName: false,
pgsVal: 5,
areaVip: "",
currentIndex: 0,
weiwancheng: [],
vipLists: [],
showModal: false,
vipTips: {}, //等級升級信息
vipTipsMoney: [], //付款信息
orderId: "",
BNBlist: [],
yue: 0,
bnbJine: 0,
BNBjine: 0,
zhifujine: 0,
cityPickerValue: [0, 0, 1],
cityPickerValue1: [0, 0, 0],
region: {
label: "請點擊選擇區域",
value: [],
cityCode: ""
},
region1: {
label: "請點擊選擇省份",
value: [],
code: ""
},
userInfos: {},
currentUserData: {},
userPrivateKey: "",
oblalCityCode: "",
}
},
onReady() {
// 获取当前页面
const currentWebview = this.$scope.$getAppWebview();
// 获取web-view组件对象
this.webviewInstance = currentWebview.children()[0];
},
onShow() {
this.getUserInfos();
this.getareasList();
this.base_Url = BASE_URL;
},
methods: {
async tosendemail(){
if (this.emaiTip == "發送") {
let num = 60;
let emaiTimer = setInterval(() => {
this.emaiTip = num + 's';
num--;
if (num < 0) {
this.emaiTip = "發送";
clearInterval(emaiTimer)
}
}, 1000)
let res = await _emailSend({
email: this.userInfos.email,
event: "check"
});
if (res.code === 1) {
uni.showToast({
title: '發送成功',
icon: 'none'
});
}else{
uni.showToast({
title: res.msg,
icon: 'none'
});
}
} else {
return
}
},
googleemail() {
let num = 60;
let googleTimer = setInterval(() => {
this.googleTip = num + 's';
num--;
if (num < 0) {
this.googleTip = "發送";
clearInterval(googleTimer)
}
}, 1000)
},
handleWebViewMessage(event) {
let _that = this;
let obj = event.detail.data;
console.log('收到WebView消息:', obj);
if (obj.length > 0) {
uni.hideLoading()
if (obj[0].status == 'success') {
uni.showToast({
title: "打款成功",
icon: "success",
duration: 1000
})
_that.modalName = false;
let sjObj = {};
_that.vipTipsMoney.map(item => {
if (item.id == _that.shengjiId) {
sjObj = item;
}
})
_that.tijiaoCoinlog(sjObj.id, sjObj.from_addr, sjObj.to_addr, sjObj.coin, sjObj.type, obj[0].hash);
_that.emailCode = "";
_that.googleCode = "";
_that.emaiTip = "發送";
_that.googleTip = "發送";
} else {
uni.showToast({
title: '打款失敗',
icon: "none",
duration: 1000
})
}
}
},
handleInput(event) {
this.zhifuMima = event;
},
changePassword() {
this.showPassword1 = !this.showPassword1;
},
payXieyiClick() {
if (this.oneSee) {
this.isDisable = false;
} else {
uni.showToast({
title: "請先宣讀協議書",
icon: "none",
duration: 1000
})
}
},
checkScroll(event) {
const windowHeight = uni.getSystemInfoSync().windowHeight;
const element = event.target;
if (element.scrollHeight - element.scrollTop - windowHeight < 10) {
uni.showToast({
title: "代理商協議書閱讀完成",
icon: "none",
duration: 1000
})
this.oneSee = true;
}
},
async getareasList() {
let res = await _getareas();
if (res.code === 1) {
this.userAreaQ = res.data.q;
this.userAreaS = res.data.s;
}
},
adressOptions(data) {
let start = data.substring(0, 24);
let end = data.substring(data.length - 4);
let middle = "…";
let finalString = start + middle + end;
return finalString
},
payXieyiChange(e) {
if (e.target.value.length > 0) {
this.isCheckXieyi = true;
} else {
this.isCheckXieyi = false;
}
},
async getUserInfos() {
let res = await _userInfos();
if (res.code === 1) {
this.userInfos = res.data.userinfo;
this.userArea = this.userInfos.area;
this.userPrivateKey = uni.getStorageSync(`user_privateKey_${this.userInfos.id}`)
this.getViplist();
this.getIsUploade();
}
},
async getIsUploade() {
let res = await _chksubdata();
if (res.code === 1) {
this.isUplodes = res.data.submit;
}
},
onConfirm(e) {
this.region = e;
this.cityPickerValue = e.value;
},
onCancel() {},
onConfirm1(e) {
this.region1 = e;
this.cityPickerValue1 = e.value;
},
onCancel1() {},
chooseCity() {
this.$refs.mpvueCityPicker.show()
},
chooseCity1() {
this.$refs.mpvueCityPicker1.show()
},
async modalBtn() {
let _that = this;
if (!_that.zhifuMima || !_that.emailCode || !_that.googleCode) return uni.showToast({
title: '請填寫正確資訊',
icon: 'none'
})
const params = {
code: _that.emailCode,
googlecode: _that.googleCode,
paykey: MD5(_that.zhifuMima + (Math.floor(Date.now() / 1000))),
timestamp: Math.floor(Date.now() / 1000),
}
let res = await _walletinfo(params);
if (res.code === 1) {
_that.vipTipsMoney.map(item => {
_that.qukuailian(item.from_addr, item.to_addr, item.coin, item.id, item.type)
})
}else{
uni.showToast({
title: res.msg,
icon: 'none'
})
}
},
async qukuailian(from_addr, to_addr, coin, id, type) {
var _that = this;
_that.shengjiId = id;
uni.showLoading({
title: "打款中..."
})
let userSiyao = await publicjiemi(2, _that.zhifuMima, from_addr);
const params = {
type: 'shengji',
fromAdress: from_addr,
toAdress: to_addr,
coin: 0.0001,
privateKey: userSiyao
};
if (_that.webviewInstance) {
_that.webviewInstance.evalJS(`
usdtTransfer(${JSON.stringify(params)});
`);
}
},
hideModal() {
this.modalName = false;
this.emailCode = "";
this.googleCode = "";
this.emaiTip = "發送";
this.googleTip = "發送";
},
// 提交打款記錄
async tijiaoCoinlog(oid, from_addr, to_addr, coin, type, hash) {
var that = this;
let data = {
oid: oid,
from_addr: from_addr,
to_addr: to_addr,
coin: coin,
tx: hash
}
let res = await _sendcoin(data);
if (res.code === 1) {
if (!that.isUplodes) {
uni.navigateTo({
url: "/pages/myProxy/uplode?area=" + that.oblalCityCode
})
return
}
}
},
async getViplist() {
let _that = this;
let res = await _viplist();
if (res.code === 1) {
let obj = res.data;
obj.forEach(item => {
if (item.area_rate) {
item.area_rate = Number(item.area_rate);
}
if (item.children_rate) {
item.children_rate = Number(item.children_rate);
}
})
let newArray = [];
obj.map((item, index) => {
if (item.lv >= _that.userInfos.level) {
newArray.push(item)
}
})
this.vipLists = newArray;
this.currentUserData = this.vipLists[this.currentIndex]
}
},
onSwiperChange(e) {
this.currentIndex = e.detail.current;
this.currentUserData = {
...this.vipLists[this.currentIndex]
}
this.oblalCityCode = "";
},
async autoOrShenhe(vipinfo) {
let cityCode = "";
if (vipinfo.lv == 3 && this.region.cityCode == "") {
uni.showToast({
title: "該選擇區域",
icon: "none"
})
return
}
if (vipinfo.lv == 4 && this.region1.code == "") {
uni.showToast({
title: "該選擇省份",
icon: "none"
})
return
}
if (!this.isCheckXieyi) {
uni.showToast({
title: "請勾選協議書",
icon: "none"
})
return
}
if (vipinfo.lv == 3) {
cityCode = this.region.cityCode;
}
if (vipinfo.lv == 4) {
cityCode = this.region1.code + "0000";
}
let res = await _chkarea({
area: cityCode
});
if (res.data.area_cnt == 1) {
uni.showToast({
title: "該區域已被代理",
icon: "none"
})
return
}
uni.navigateTo({
url: `/pages/myProxy/uplode?area=${cityCode}`
})
},
async showUpgradeModal(data) {
let that = this;
if (data.lv < 2) {
uni.switchTab({
url: "/pages/index/index"
})
return
}
if (!this.isCheckXieyi && data.lv > 2) {
uni.showToast({
title: "請勾選協議書",
icon: "none"
})
return
}
let cityCode = "";
if (data.lv == 3) {
cityCode = this.region.cityCode;
}
if (data.lv == 4 && this.region1.code != "") {
cityCode = this.region1.code + "0000";
}
this.oblalCityCode = cityCode;
let ress = await _chkarea({
area: cityCode
});
if (ress.data.area_cnt == 1) {
uni.showToast({
title: "該區域已被代理",
icon: "none"
})
return
}
let res = await _levelupinfo({
lv: data.lv,
area: cityCode
});
if (res.code === 1) {
this.orderId = 'ORD-' + Math.random().toString(36).substr(2, 9);
this.showModal = true;
this.vipTips = res.data.lvinfo;
this.vipTipsMoney = res.data.sendinfo;
this.getYue()
} else {
uni.showToast({
title: res.msg,
icon: 'none',
})
if (res.msg == "請先綁定上級關係") {
setTimeout(() => {
uni.navigateTo({
url: "/pages/myuser/myuser"
})
}, 500)
}
}
},
cancelUpgrade() {
this.showModal = false;
},
// 獲取錢包餘額
getYue() {
var that = this;
this.yue = 0
this.qianbaojine = 0
this.bnbJine = 0
uni.request({
url: "https://nfta.ikiry.com/balances?address=" + this.vipTipsMoney[0].from_addr,
success(res) {
that.yue = res.data.usdtBalance / 1000000000000000000;
that.BNBjine = Number(res.data.bnbBalance)
}
})
},
confirmUpgrade() {
if (this.BNBjine == 0) return uni.showToast({
title: 'GAS 費不足',
icon: 'none',
})
else if (this.yue < this.zongjine) return uni.showToast({
title: '餘額不足不能支付。。。',
icon: 'none',
})
else {
this.modalName = true;
this.showModal = false;
}
}
}
}
</script>
<style lang="scss">
::v-deep .uni-checkbox-input {
width: 12px;
height: 12px;
}
.confirm-button {
width: 80%;
height: 50px;
border-radius: 25px;
background-color: #4CAF50;
color: white;
font-size: 18px;
display: flex;
justify-content: center;
align-items: center;
margin-bottom: 20px;
}
.container {
width: 100vw;
min-height: 100vh;
padding: 20px;
box-sizing: border-box;
background: linear-gradient(to bottom, #000033, #51599b);
}
.title {
font-size: 24px;
color: #ffffff;
text-align: center;
margin-bottom: 20px;
}
.swiper {
height: 350px;
margin-bottom: 15px;
}
.card {
background-color: rgba(255, 255, 255, 0.1);
border-radius: 10px;
padding: 15px 10px;
margin-bottom: 15px;
}
.main-card {
padding: 20px;
height: 100%;
}
.card-title {
font-size: 18px;
color: #ffffff;
margin-bottom: 10px;
}
.card-content {
font-size: 24px;
color: #ffffff;
font-weight: bold;
margin-bottom: 5px;
}
.card-subtitle {
font-size: 14px;
color: #e0e0e0;
}
.card-label {
font-size: 16px;
color: #e0e0e0;
margin-bottom: 5px;
}
.card-value {
font-size: 20px;
color: #ffffff;
font-weight: bold;
}
.swiper {
height: 180px;
margin-bottom: 15px;
}
.swiper-item {
display: flex;
justify-content: center;
align-items: center;
transition: all 0.3s ease;
transform: scale(0.9);
}
.swiper-item.active {
transform: scale(1);
}
.main-card {
width: 90%;
height: 90%;
background-color: rgba(255, 255, 255, 0.2);
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: all 0.3s ease;
}
.active .main-card {
background-color: rgba(255, 255, 255, 0.3);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.2);
}
/* 原有的樣式保持不變 */
.modal_xieyi {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 999;
.xieyi_main {
width: 100%;
height: 100%;
background-color: #fff;
padding: 20px;
box-sizing: border-box;
.xieyi_header {
height: 30px;
line-height: 30px;
text-align: right;
}
.xieyi_footer {
height: calc(100% - 30px);
text-indent: 2rem;
overflow: auto;
}
}
}
.modal {
position: fixed;
left: 0;
right: 0;
bottom: 0;
top: 0;
background-color: rgba(0, 0, 0, 0.6);
display: flex;
align-items: flex-end;
z-index: 999;
}
.modal-content {
background-color: #b6b5c8;
border-radius: 20px 20px 0 0;
padding: 20px;
box-sizing: border-box;
width: 100%;
animation: slideUp 0.3s ease-out;
box-shadow: 0 -4px 10px rgba(0, 0, 0, 0.1);
}
@keyframes slideUp {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
}
.modal-title {
font-size: 20px;
font-weight: bold;
color: #333;
}
.modal-close {
font-size: 24px;
color: #999;
cursor: pointer;
}
.modal-body {
margin-bottom: 20px;
}
.modal-item {
display: flex;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #f0f0f0;
}
.modal-label {
color: #666;
font-size: 14px;
margin-right: 20rpx;
}
.modal-value {
flex: 1;
font-weight: bold;
color: #333;
font-size: 14px;
word-break: break-all;
text-align: right;
overflow: hidden;
/* 超出部分隱藏 */
text-overflow: ellipsis;
/* 超出部分顯示省略號 */
white-space: nowrap;
/* 不換行 */
}
.modal-footer {
display: flex;
justify-content: space-between;
}
.modal-button {
width: 48%;
height: 44px;
border-radius: 22px;
font-size: 16px;
font-weight: bold;
border: none;
cursor: pointer;
transition: all 0.3s ease;
}
.modal-button.cancel {
background-color: #f0f0f0;
color: #333;
}
.modal-button.cancel:hover {
background-color: #e0e0e0;
}
.modal-button.confirm {
background-color: #4CAF50;
color: white;
}
.modal-button.confirm:hover {
background-color: #45a049;
}
</style>
<style lang="scss">
.container {
::v-deep .uni-checkbox-input {
width: 12px;
height: 12px;
}
}
</style>