PixelAI-mobile/pages/mobile_web/recharge/detail.vue

632 lines
17 KiB
Vue
Raw Permalink Normal View History

2025-01-22 20:25:38 +08:00
<template>
<!-- #ifdef APP -->
<view class="recharge-detail" :style="{ paddingTop: CustomBar+'rpx' }">
<view class="app-top" :style="{ height: CustomBar+'rpx',
background: topLevel===0? '#ffffff00' : `rgba(255, 255, 255,${topLevel})` }"></view>
<!-- #endif -->
<!-- #ifndef APP -->
<view class="recharge-detail">
<!-- #endif -->
<view class="rd-top">
<!-- #ifdef MP -->
<view :style="{height: `${StatusBar}px`}"></view>
<view class="app-top" :style="{height: `${StatusBar}px`,background: topLevel===0? '#ffffff00' : `rgba(255, 255, 255,${topLevel})`}"></view>
<view class="mobile-logo" :style="{height: `${CustomBarHeight}px`,backgroundColor: `rgba(255, 255, 255,${topLevel})`}">
<!-- #endif -->
<!-- #ifndef MP -->
<view class="mobile-logo" :style="{backgroundColor: `rgba(255, 255, 255,${topLevel})`}">
<!-- #endif -->
<u-icon name="arrow-left" size="40" class="back" @click="back"
:color="topLevel===0? '#f9f9f9' : `rgba(194, 234, 4,${topLevel})`"></u-icon>
<image :src="fileUrl+logo"></image>
<view style="width: 75rpx;"></view>
</view>
<view class="recharge-top" :style="{background:item.background}">
<view class="recharge-header" :style="{background:item.detailBackground}">
<view class="header-top">
<image :src="myFileUrl+item.icon"></image>
<view class="recharge-introduce">
<view class="introduce-title">[充值] PIXEL.AI虚拟货币充值</view>
<view class="introduce-price">单价<text> {{ item.price }} /</text></view>
<view class="introduce-name">类型<text>{{ item.name }}</text></view>
<view class="introduce-time">有效性<text>{{ item.time }}</text></view>
</view>
</view>
<view class="header-bottom">
<text>· {{ item.description }}</text>
<!-- <u-icon name="arrow-right" size="24" /> -->
</view>
</view>
<view class="recharge-body">
<view class="recharge-bt">
充值额度
</view>
<view class="recharge-tags">
<u-tag v-for="(item,index) in options" :key="index" :index="index"
:text="item+'颗'" @click="selectElement" :class="selectElementIndex===index?'u-tag-select':''"></u-tag>
<!-- <u-tag :index="-1" :class="selectElementIndex===-1?'u-tag-select':''"
:text="otherNum?(otherNum+'颗'):'其它数量'" @click="selectOtherElement"></u-tag> -->
</view>
</view>
</view>
</view>
<view class="recharge-pay">
<view class="recharge-pl">
<view class="recharge-plt">
总计<text>{{ form.price?((form.price*form.num).toFixed(2)):0 }}</text>
</view>
<view class="recharge-plb">
<u-checkbox size="30" @change="isAgree = !isAgree" :activeColor="item.payFontColor" v-model="isAgree" />
我已阅读并同意<text @click="toAgree">PIXEL.AI支付协议</text>
</view>
</view>
<view class="recharge-pr">
<button :loading="payLoading" :style="{background:item.payFontColor,boxShadow:item.payBoxShadow}"
type="button" @click="payClick">立即支付</button>
</view>
</view>
<u-keyboard ref="uKeyboard" mode="number" v-model="showKeyboard" :cancelBtn="false"
:dotEnabled="false" :confirmBtn="false" @change="valChange" @backspace="backspace"></u-keyboard>
<u-toast ref="uToast"></u-toast>
<u-popup class="pay-popup" v-model="showPayResult" mode="bottom" border-radius="30">
<view class="popup-view">
<view class="popup-title">{{ payResult.result || '支付失败' }} {{ payResult.amount }}</view>
<view class="popup-payfont">微信支付</view>
<view class="popup-content">
<view class="content-result" v-if="payResult.result">
钻石余额{{ (personCount-options[payResult.buyType-1]) || 0 }}
<text :style="{ backgroundImage: item.payFontColor }">+ {{ options[payResult.buyType-1] }}</text>
</view>
<view class="content-result" v-else>
钻石余额{{ personCount || 0 }}
</view>
<view class="content-time">{{ dateFormat(payResult.createTime) }}</view>
</view>
<view class="popup-btn" @click="showPayResult = false" v-if="payResult.result"
:style="{ background: item.payFontColor, boxShadow: item.payBoxShadow }">
</view>
<view class="popup-btn" @click="showPayResult = false" v-else
:style="{ background: payErrorColor, boxShadow: payBoxShadow }">
</view>
</view>
</u-popup>
</view>
</template>
<script>
import configService from '@/common/config.service.js';
export default {
// #ifdef MP
options: {
styleIsolation: 'shared'
},
// #endif
2025-01-22 20:25:38 +08:00
data(){
return{
// #ifdef MP
// 微信小程序自定义导航栏参数
StatusBar: this.StatusBar || 0,
CustomBarHeight: this.Custom.height+(this.Custom.top-this.StatusBar)*2 || 0,
// #endif
// 基础地址
fileUrl: configService.fileUrl + 'pixel/home/',
myFileUrl: configService.fileUrl + 'pixel/my/',
// logo图标
logo: 'logo-new.png',
topLevel: 0,// 页面是否滚动到顶
//支付详情
item:{
icon: 'diamond.png',
price: 0.1,
name: '钻石-diamond',
description: '通用制图货币,助力高端操作~',
time: '无限制',
background:'linear-gradient( 190deg, #4BACFF 0%, rgba(255,255,255,0.77) 100%)',// 详情总体背景
detailBackground:'linear-gradient( 80deg, rgba(255,255,255,0.77) 0%, #4BACFF 100%)',// 详情内部单元背景
payFontColor:'linear-gradient( 90deg, rgba(54,141,255,0.99) 0%, #72A0FF 100%)',// 支付按钮颜色及复选框颜色
payBoxShadow:'0px 2px 10px 1px rgba(54,141,255,0.19)',// 支付按钮阴影
},
// 支付失败按钮颜色
payErrorColor: 'linear-gradient( 90deg, rgba(255, 81, 51, 1.0) 0%, #ff8b74 100%)',
// 支付失败按钮阴影
payBoxShadow:'0px 2px 10px 1px rgba(255, 122, 56, 0.2)',
// 支付订单
form:{
price: 0.1,// 单价
num: 0,// 数量
},
// 元素选择下标
selectElementIndex: '',
// 额度选项
options: [50,100,200,300,500,1000],
// 其它数量
otherNum: '',
isAgree:false, //是否同意协议
// 打开键盘
showKeyboard: false,
// 支付按钮加载效果
payLoading: false,
// 订单表单
orderForm: {
amount: '',// 金额
buyType: '',// 1-5, 2-10, 3-20, 4-30, 5-50, 6-100——这里换序号1、2、3...
// memberAccount: '',// 支付人账号
memberId: '',// 用户id
orderType: '个人账户钻石充值',// 支付用途
},
// 显示支付结果
showPayResult: false,
// 剩余钻石余额
personCount: 0,
// 支付结果
payResult: {}
}
},
onPageScroll(e) {
// #ifndef H5
const level = e.scrollTop/60;
if(level<=1) this.topLevel = level;
else this.topLevel = 1;
// #endif
},
onShow(){
let orderId = uni.getStorageSync('payVisabled');
if(orderId){
this.showPayResult = true;
this.getPayResult(orderId);
this.myCurrency();
uni.setStorageSync('payVisabled','');
}
// #ifndef H5
},
// #endif
// #ifdef H5
let that = this;
window.onscroll = function () {
//为了保证兼容性,这里取三个值,哪个有值取哪一个
//scrollTop就是触发滚轮事件时滚轮的高度
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
const level = scrollTop/60;
if(level<=1) that.topLevel = level;
else that.topLevel = 1;
}
},
onHide() {
window.onscroll = null;
},
// #endif
onLoad(){
const { username, id } = JSON.parse(this.$store.state.user_message);
// this.orderForm.memberAccount = username;
this.orderForm.memberId = id;
},
methods:{
// 获取支付结果
async getPayResult(id){
let res = await this.$api.singleOrder(id);
if(res.success){
this.payResult = res.data;
}else{
this.$refs.uToast.show({type:'error',title: "支付结果获取失败!"});
}
},
// 获取我的余额
async myCurrency(){
let res = await this.$api.getCurrency();
if(res?.success){
this.personCount = res.data.numerical;
} else {
this.$refs.uToast.show({type:'error',title: "余额数据拉取失败!"});
}
},
// 时间格式化
dateFormat(time){
let date = time ? new Date(time) : new Date();
let month = date.getMonth()+1,
day = date.getDate(),
hour = date.getHours(),
minute = date.getMinutes(),
second = date.getSeconds();
return `${date.getFullYear()}${month<10?'0':''}${month}${day<10?'0':''}${day} ${hour<10?'0':''}${hour}:${minute<10?'0':''}${minute}`;
},
// 返回
back(){
2025-02-18 11:53:32 +08:00
// #ifdef MP || APP
2025-02-08 13:39:32 +08:00
uni.navigateBack();
// #endif
2025-02-18 11:53:32 +08:00
// #ifndef MP || APP
2025-01-22 20:25:38 +08:00
uni.redirectTo({
url: '/pages/mobile_web/recharge/recharge'
})
2025-02-08 13:39:32 +08:00
// #endif
2025-01-22 20:25:38 +08:00
},
// 支付协议
toAgree() {
// 跳转富文本
},
// 元素选择
selectElement(index){
const selected = this.selectElementIndex === index;
this.form.num = selected ? 0 : this.options[index];
this.selectElementIndex = selected ? '' : index;
this.orderForm.buyType = selected ? '' : index + 1;
},
// 更多数量
selectOtherElement(index){
const selected = this.selectElementIndex === index;
// this.form.num = selected ? 0 : this.options[index];
if(selected){
this.form.num = 0;
this.selectElementIndex = '';
} else {
this.showKeyboard = true;
}
},
// 按键被点击(点击退格键不会触发此事件)
valChange(val) {
// 将每次按键的值拼接到value变量中注意+=写法
this.otherNum += val;
this.form.num = this.otherNum;
this.selectElementIndex = -1;
},
// 退格键被点击
backspace() {
// 删除value的最后一个字符
if(this.otherNum.length){
this.otherNum = this.otherNum.substr(0, this.otherNum.length - 1);
this.form.num = this.otherNum?this.otherNum:0;
this.selectElementIndex = this.otherNum?-1:'';
}
},
// 支付
async payClick() {
2025-02-07 21:28:40 +08:00
// #ifdef APP || MP
this.$refs.uToast.show({type:'warning',title: "暂未开通小程序和APP端的支付方式请使用外部浏览器进行充值"});
return;
// #endif
// #ifndef APP || MP
2025-01-22 20:25:38 +08:00
if(this.isMpWeb()) return;
// #endif
if(!this.isAgree){
this.$refs.uToast.show({type:'warning',title: "请阅读并勾选同意《PIXEL.AI支付协议》"});
return;
}
const { num, price } = this.form;
if(!num||num<50){
this.$refs.uToast.show({type:'warning',title: "购买数量至少50颗"});
return;
}
try{
this.payLoading = true;
this.orderForm.amount = (price*num).toFixed(2);
// this.orderForm.amount = 0.01;// 测试换成0.01
let res = await this.$api.h5Pay(this.orderForm);
if(res.success){
let url = res.data.h5Url;
uni.setStorageSync('payVisabled',res.data.id);
if(this.UniPlatform === 'web'){
location.href = url + '&redirect_url=' + encodeURIComponent(window.location.href);
}else{
uni.navigateTo({
url: `/pages/index/webview?title=微信支付&src=${encodeURI(url)}`
})
}
}else{
this.$refs.uToast.show({type:'error',title: "订单创建失败!"});
}
}catch(e){
}finally{
this.payLoading = false;
}
},
2025-02-07 21:28:40 +08:00
// #ifndef APP || MP
2025-01-22 20:25:38 +08:00
// 判断是否在微信内置浏览器打开
isMpWeb(){
if(navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){
this.$refs.uToast.show({type:'warning',title: "请在手机浏览器打开,进行支付操作!"});
return true;
}else{
return false;
}
},
// #endif
}
}
</script>
<style scoped lang="scss">
.recharge-detail{
display: flex;
flex-direction: column;
min-height: 100vh;
background: linear-gradient(to bottom, #53a8ed 0%, #f9f9f9 30%, #f9f9f9 100%);
2025-01-22 20:25:38 +08:00
// #ifdef APP || MP
.app-top{
width: 100%;
position: fixed;
z-index: 81;
}
// #endif
.rd-top{
// #ifdef APP
.app-top{
width: 100%;
position: fixed;
z-index: 81;
top: 0;
}
// #endif
.mobile-logo{
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
.back{
margin-left: 35rpx;
margin-top: 5rpx
}
position: fixed;
z-index: 81;
padding: 15rpx 0;
image{
width: 200rpx;
height: 45rpx;
}
// .u-icon{
// }
}
.recharge-top{
height: 710rpx;
display: flex;
align-items: center;
flex-direction: column;
padding: 0 32rpx;
.recharge-header{
margin-top: 120rpx;
display: flex;
height: 350rpx;
width: 100%;
border-radius: 16rpx;
flex-direction: column;
justify-content: space-between;
padding: 64rpx 30rpx 36rpx;
.header-top{
display: flex;
image{
width: 160rpx;
height: 160rpx;
margin-right: 40rpx;
}
.recharge-introduce{
display: flex;
flex-direction: column;
font-size: 26rpx;
.introduce-title{
font-weight: bold;
font-size: 34rpx;
margin-bottom: 10rpx;
}
.introduce-price{
text{
font-weight: bold;
}
margin-bottom: 10rpx;
}
.introduce-name{
text{
color:#005fd2;
}
margin-bottom: 10rpx;
}
.introduce-time{
}
}
}
.header-bottom{
margin-left: 10rpx;
font-family: PingFang SC, PingFang SC;
font-weight: 500;
font-size: 24rpx;
color: #5e5e5e;
overflow: hidden;
text-overflow: ellipsis;
display: flex;
align-items: center;
text{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: 20rpx;
}
}
}
.recharge-body{
margin-top: 24rpx;
display: flex;
// height: 400rpx;
width: 100%;
border-radius: 16rpx;
flex-direction: column;
justify-content: space-between;
padding: 32rpx 0;
background-color: #FFFFFF;
margin-bottom: -80%;
.recharge-bt{
font-size: 32rpx;
color: #000000;
margin: 0 42rpx;
}
.recharge-tags{
margin: 32rpx 42rpx 0;
display: grid;
grid-gap: 26rpx;
grid-template-columns: repeat(3,1fr);
/deep/.u-tag{
2025-01-22 20:25:38 +08:00
// width: 200rpx;
height: 74rpx;
font-size: 28rpx;
display: flex;
color: rgba(41,121,255,0.6);
background-color: #fff;
align-items: center;
justify-content: center;
&:active{
opacity: 0.8;
}
}
.u-tag-select{
// #ifndef MP
2025-01-22 20:25:38 +08:00
box-shadow: 0 0 15rpx #eee;
color: #2979ff;
background-color: rgba(236,245,255,0.8);
// #endif
// #ifdef MP
/deep/.u-tag{
box-shadow: 0 0 15rpx #eee;
color: #2979ff;
background-color: rgba(236,245,255,0.8);
}
// #endif
2025-01-22 20:25:38 +08:00
}
}
}
}
}
.recharge-pay {
display: flex;
justify-content: space-around;
position: fixed;
padding: 26rpx 30rpx;
width: 100%;
bottom: 0;
left: 0;
height: 150rpx;
background-color: #FFFFFF;
.recharge-pl{
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-around;
width: calc(100% - 228rpx);
.recharge-plt{
font-weight: 500;
font-size: 30rpx;
color: #000000;
line-height: 48rpx;
display: flex;
align-items: center;
text{
font-size: 36rpx;
color: #FF3640;
}
}
.recharge-plb{
font-weight: 500;
font-size: 24rpx;
color: #AFAFAF;
display: flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text{
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #368DFF;
}
.u-checkbox{
display: inline;
margin-right: 10rpx;
min-width: 30rpx;
}
}
}
.recharge-pr{
min-width: 228rpx;
display: flex;
align-items: center;
button{
width: 100%;
height: 88rpx;
border-radius: 44rpx;
font-weight: 500;
font-size: 28rpx;
color: #FFFFFF;
line-height: 120rpx;
display: flex;
justify-content: center;
align-items: center;
&:active{
opacity: 0.8;
}
}
}
}
.pay-popup{
.popup-view{
background-color: #f5f5f5;
padding: 60rpx 25rpx 20rpx;
display: flex;
flex-direction: column;
align-items: center;
.popup-title{
color: #212121;
font-size: 46rpx;
font-weight: bold;
}
.popup-payfont{
margin: 20rpx 0 36rpx;
color: #373737;
font-size: 28rpx;
}
.popup-content{
width: 100%;
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx 40rpx;
font-size: 30rpx;
.content-result{
font-size: 34rpx;
margin-bottom: 40rpx;
text{
margin-left: 10rpx;
font-weight: bold;
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.content-time{
color: #AFAFAF;
text-align: end;
}
}
.popup-btn{
border-radius: 56rpx;
width: 100%;
height: 100rpx;
font-size: 34rpx;
margin: 50rpx 0 40rpx;
font-weight: bold;
display: flex;
align-items: center;
justify-content: center;
color: #eee;
&:active{
opacity: 0.8;
}
}
}
}
}
</style>