Files
sociology_app/pages/mine/wallet/recharge/index.vue
2025-06-12 17:09:54 +08:00

1075 lines
28 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 class="container commonPageBox">
<!-- 公共组件-每个页面必须引入 -->
<public-module></public-module>
<z-nav-bar
title="充值"
bgColor="#3AB3AE"
fontColor="#fff"
:homeState="options.source == 'order' ? 1000 : 2000"
:backState="options.source == 'order' ? 2000 : 1000"
></z-nav-bar>
<view>
<view class="cha_jine">
<view class="cj_title PM_font">充值金额</view>
<view class="cj_xiang">
<view
v-for="(item, index) in cjList"
@click="chosPric(item)"
:class="
stepsCj.priceTypeId == item.priceTypeId
? 'Tab_cj cj_price'
: 'cj_price'
"
>
<view class="pr_jg">{{ item.realMoney }}</view>
<view class="pr_yl" :style="item.givejf&&item.givejf>0?' paddingTop: 0':''">{{ item.money }}天医币<text v-if="item.givejf&&item.givejf>0">{{ item.givejf }}积分</text></view>
<view class="pr_lj" v-if="item.description&&item.description!=''">{{item.description}}</view>
</view>
<br clear="both" />
</view>
<view class="limitBlock" v-if="isAndroid">
<text>其他金额</text>
<input type="text" v-model="limitVal" placeholder="请输入充值金额" placeholder-class="limit-placeholder" @input="input()" />
</view>
<view>
<text style="font-size: 24rpx; color: #8e8e8e;">说明 : 天医币属于虚拟产品一经购买概不退还</text>
</view>
<view class="active_block" v-if="isAndroid&&activityContent.remark" v-html="activityContent.remark"></view>
</view>
<view class="cha_fangsh">
<view class="cf_title PM_font">支付方式</view>
<view class="cf_radio">
<u-radio-group v-model="payType">
<view style="width: 100%" v-if="isAndroid">
<view
v-for="(item, index) in paylist"
@click="choseType(item.id)"
:class="payType == item.id ? 'Tab_xf cf_xuanx' : 'cf_xuanx'"
>
<image class="pay_item_img" :src="item.imgUrl" mode="aspectFil">
</image>
{{ item.title }}
<u-radio
:key="index"
activeColor="#3AB3AE"
:name="item.id"
style="float: right; margin-top: 5rpx"
></u-radio>
</view>
</view>
<view style="width: 100%" v-else>
<view
v-for="(item, index) in iosPaylist"
@click="choseType(item.id)"
:class="payType == item.id ? 'Tab_xf cf_xuanx' : 'cf_xuanx'"
>
<image class="pay_item_img" :src="item.imgUrl" mode="aspectFil">
</image>
{{ item.title }}
<u-radio
:key="index"
activeColor="#3AB3AE"
:name="item.id"
style="float: right; margin-top: 5rpx"
></u-radio>
</view>
</view>
</u-radio-group>
</view>
</view>
<view class="agree_wo flexbox" style="float: left; display: flex">
<radio-group class="agree">
<view v-for="(item, index) in argee" :key="index">
<radio
class="agreeRadio"
:value="item.id"
:checked="item.id == radioValue"
color="#3AB3AE"
@click="radioCheck(index)"
></radio>
</view>
</radio-group>
<view
>* 我已阅读并同意<span class="highlight" @click="showXieyi"
>增值服务协议</span
></view
>
</view>
<view class="char_btn">
<view @click="goToPay">立即充值</view>
</view>
</view>
<!-- 充值协议 -->
<u-popup :show="xieyiShow" :round="10" @close="xieyiShow = false">
<view class="tanchu">
<view class="dp_title">{{ xieyi.title }}</view>
<view style="max-height: 1000rpx; overflow-y: scroll">
<view v-html="xieyi.content"></view>
</view>
</view>
</u-popup>
<music-play :playData="playData"></music-play>
</view>
</template>
<script>
import musicPlay from "@/components/music.vue";
import $http from "@/config/requestConfig.js";
import { checkIapOrder } from "@/store/modules/common.js";
// import { // 引入ios支付
// Iap,
// IapTransactionState
// } from "@/utils/iap.js"
import { mapState, mapMutations } from "vuex";
import { setPay, setPayAssign, setWXPay } from "@/config/utils";
// const IAPOrders = [ // 根据这些ids获取到苹果app内商品信息这些ids就是你上面设置的产品id
// 'add69'
// ]
export default {
data() {
return {
playData: {},
options: {},
xieyi: {
title: "",
content: "",
},
chargeOrderSn: "", // 通过query传过来的orderSN二次支付情况
xieyiShow: false,
stepsCj: {},
cjList: [],
argee: [
{
value: false,
id: "1",
},
], // 同意权限
radioValue: "",
orderSn: "", // 订单sn
productid: "",
isAndroid: true, // 是否为安卓环境
payType: null,
paylist: [
{
title: "支付宝",
id: 2,
imgUrl: require("@/static/icon/pay_1.png"),
},
{
title: "微信",
id: 1,
imgUrl: require("@/static/icon/pay_2.png"),
},
],
iosPaylist: [
{
title: "IAP 支付",
id: 3,
imgUrl: require("@/static/icon/pay_2.png"),
},
],
transaction: {
// 成功回调
},
urlList: {
list: "common/bookBuyConfig/getBookBuyConfigList",
},
limitVal: '',
activityContent: {}
};
},
//第一次加载
onLoad(options) {
this.options = options;
if (this.$platform == "ios") {
this.payType = 3;
} else {
this.payType = 1;
}
// 隐藏原生的tabbar
uni.hideTabBar();
this.chargeOrderSn = options.orderSn;
uni.hideTabBar();
this.getDevName();
this.getActivity();
// console.log(e.orderSn,'orderSn')
},
//页面显示
onShow() {
// 隐藏原生的tabbar
// this.iphonepay()
// setTimeout(()=>{
// uni.navigateTo({
// url:'/pages/user/persCount'
// })
// },2000)
},
computed: {
...mapState(["userInfo"]),
},
components: {
musicPlay,
},
//方法
methods: {
...mapMutations(["setUserInfo"]),
// 关闭交易订单
finishTransaction(trans) {
this.iapChannel.finishTransaction(
trans,
(success) => {
console.log("关闭订单成功");
this.setUserInfo({
restoreFlag: false,
});
},
(fail) => {
console.log("关闭订单失败");
},
);
},
async showXieyi() {
// this.$http.get(`sys/agreement/list?key=pay`).then((res) => {
// this.xieyi = res.page.list[0];
// this.xieyiShow = true;
// });
var data = await this.$commonJS.getAgreement(104);
if (data.content) {
data.content = data.content.replace(
/<h5>/g,
'<view style="font-weight: bold;font-size: 32rpx;margin-top: 20rpx;margin-bottom: 20rpx;">',
);
data.content = data.content.replace(/<\/h5>/g, "</view>");
}
this.xieyi = data;
this.xieyiShow = true;
},
radioCheck(index) {
// 勾选用户协议
this.argee.forEach((item) => {
item.isCheck = false;
});
if (this.radioValue == this.argee[index].id) {
this.radioValue = null;
} else {
this.radioValue = this.argee[index].id;
}
// console.log(this.radioValue)
},
getProvider() {
return new Promise((resolve, reject) => {
uni.getProvider({
service: "payment",
success: (res) => {
const iapChannel = res.providers.find((channel) => {
return channel.id === "appleiap";
});
resolve(iapChannel);
// 如果 iapChannel 为 null说明当前包没有包含iap支付模块。注意HBuilder基座不包含 iap 通道
},
});
});
},
requestPayment(orderInfo) {
let that = this;
return new Promise((resolve, reject) => {
uni.requestPayment({
provider: "appleiap",
orderInfo: orderInfo,
success: (res) => {
console.log("uni.requestPayment成功提示", res);
that.iapCheck(res);
resolve(res);
},
fail: (err) => {
console.log("uni.requestPayment失败提示", err);
uni.hideLoading();
// console.log('其他支付错误', err);
that.restoreComplateRequest();
if (err.code == 2) {
uni.showToast({
title: "取消支付,内购订单即将关闭",
icon: "none",
});
} else {
uni.showToast({
title: "支付失败,内购订单即将关闭",
icon: "none",
});
}
reject(err);
},
});
});
},
// 查询未关闭iap订单
async restoreComplateRequest() {
let that = this;
console.log("检测未完成订单");
await this.iapChannel.restoreCompletedTransactions(
{
manualFinishTransaction: true,
},
function (results) {
that.ComplateRequestArr = results;
console.log(
"未完成订单数组共有:=》",
that.ComplateRequestArr.length,
);
if (results && results.length > 0) {
console.log(
"未完成订单数组共有resultsresultsresults=》",
results,
);
results.map((item, index) => {
// "0"为正在支付;"1"为支付成功;"2"为支付失败;"3"为支付已恢复。
// if (item.transactionState == '1') {
// // 已经支付,但是没有走逻辑的内购订单 就发给后台做验证
// that.iapCheck('未完成订单的验证', item, index)
// // that.finishTransaction(item)
// } else if (item.transactionState != '1' || item.transactionState != '0') {
// // 不是正在支付订单,也不是已经支付订单就关闭掉
// // 其他状态的内购订单
console.log(
"未完成订单数组共有resultsresultsresults15=》",
results,
);
that.finishTransaction(item);
// }
});
}
},
);
// }
},
async iphonepay() {
//获取iap通道是判断当前设备是否支持苹果内购支付的必要条件
const that = this;
uni.showLoading({
title: "购买中",
});
this.iapChannel = await this.getProvider();
if (this.iapChannel) {
await this.restoreComplateRequest();
await this.requestOrder();
} else {
uni.hideLoading();
}
},
requestOrder() {
const that = this;
console.log(that.stepsCj.priceTypeId, 88888888);
// ['xxxxx'] 是平台申请拿到的内购商品的id
let IAPOrders = [];
IAPOrders.push("Z" + that.stepsCj.priceTypeId);
console.log(IAPOrders, "IAPOrders");
// 新建订单
// uni.showLoading({
// title: "正在创建订单",
// mask: true,
// });
that.iapChannel.requestProduct(
IAPOrders,
function (event) {
// uni.hideLoading()
console.log(event, "event");
for (var index in event) {
var OrderItem = event[index];
// console.log(OrderItem, 'OrderItem')
console.log(OrderItem.productid, "OrderItem.productid");
that.topay(OrderItem.productid);
}
},
function (erroemsg) {
uni.showToast({
title: "商品获取失败",
icon: "none",
});
},
);
},
async topay(id) {
const that = this;
let orderInfo = {
productid: id,
username: that.orderSn, // 用户标识/订单标识
quantity: 1,
manualFinishTransaction: true, // 3.5.1+ 支持,设置此参数后需要开发者主动关闭订单,参见下面的关闭订单方法 finishTransaction()
};
console.log("支付后的订单信息", orderInfo);
this.transaction = await this.requestPayment(orderInfo);
console.log("支付后的that.transaction", this.transaction);
},
iapCheck(result) {
let that = this;
console.log("进入后台验证");
let data = {
transactionId: result.transactionIdentifier, // 支付交易id
customerOid: that.userInfo.id,
productId: result.payment.productid.slice(1), // 产品id
orderId: result.payment.username, // 系统订单号
receiptData: result.transactionReceipt, // 苹果返回收据
// sandBox: true, //测试数据
// body: that.stepsCj.priceTypeId // 充值类型id
};
console.log("提交给后台的数据", data);
$http
.request({
url: "Ipa/veri",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: {
//默认 无 说明:请求头
"Content-Type": "application/json",
},
})
.then((res) => {
// console.log('res',res);
if (res.code == 0) {
console.log(JSON.stringify(res), "返回信息");
uni.showToast({
title: "充值成功!",
icon: "success",
});
uni.hideLoading();
// console.log("充值订单已处理,请留意账户金额变动....");
// 服务器验证票据有效后在客户端关闭订单 (iapChannel.finishTransaction)
// that.finishTransaction(result);
}
})
.catch((e) => {
uni.hideLoading();
console.log("后台验证失败=>", e);
this.transaction = null;
uni.showModal({
title: "提示",
showCancel: false,
content:
"支付验证失败请稍后重启app如不能解决您的问题可联系官方客服",
success: function (res) {
if (res.confirm) {
console.log("用户点击确定");
}
},
});
});
},
getDevName() {
// 获取使用环境
if (uni.getSystemInfoSync().platform === "android") {
this.isAndroid = true;
// console.log('运行Android上')
} else {
this.isAndroid = false;
// console.log('运行iOS上')
}
this.getData();
},
// 获取充值金额
getData() {
// console.log(this.isAndroid)
if (this.isAndroid) {
this.getAndorList();
} else {
this.getAppleList();
}
},
// 安卓充值列表
getAndorList() {
var data = {
type: "point",
qudao: "Android",
};
$http
.request({
url: this.urlList.list,
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: {
//默认 无 说明请求头1
"Content-Type": "application/json",
},
})
.then((res) => {
console.log("res at line 389:", res);
console.log("res at line 388:", res);
this.cjList = res.bookBuyConfigList;
console.log("this.cjList at line 389:", this.cjList);
this.stepsCj = res.bookBuyConfigList[0];
});
},
// 苹果充值列表
getAppleList() {
var data = {
type: "point",
qudao: "IOS",
};
$http
.request({
url: this.urlList.list,
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: {
//默认 无 说明请求头1
"Content-Type": "application/json",
},
})
.then((res) => {
console.log("res at line 403:", res);
this.cjList = res.bookBuyConfigList;
this.stepsCj = res.bookBuyConfigList[0];
});
},
// 点击充值金额
chosPric(e) {
this.stepsCj = e;
this.limitVal = '';
},
// 选择支付方式1
choseType(e) {
let that = this;
that.payType = e;
},
//获取活动文案
getActivity(){
$http.request({
url: "common/bookBuyConfig/getRechargeActivity",
method: "POST",
data: {},
header: {
"Content-Type": "application/json",
},
})
.then((data) => {
if(data.code==0){
if(data.res&&data.res.length>0){
this.activityContent = data.res[0];
}
}
})
},
//输入金额
input(val){
this.stepsCj = {};
},
// 充值
goToPay() {
this.kaiChar();
},
// 正常充值
kaiChar() {
if (!this.payType) {
uni.showToast({
title: "请勾选支付方式",
icon: "none",
});
return false;
}
if(!this.stepsCj.priceTypeId&&!this.limitVal){
uni.showToast({
title: "请选择充值商品",
icon: "none",
});
return false;
}
const regex = /^[1-9]\d*$/;
//如果输入其他金额
if(this.limitVal){
if(!regex.test(this.limitVal)){
uni.showToast({
title: "充值金额必须为正整数",
icon: "none",
});
return false;
}
//设置充值金额和id
this.stepsCj = {
money: this.limitVal,
priceTypeId: 0
}
}
// 常规充值
if (this.radioValue == "1") {
uni.showLoading({
title: "支付中,请勿离开",
icon: "loading",
});
let that = this;
let data = {
userId: that.userInfo.id, //下单人ID
userPhone: that.userInfo.tel, //收货人手机号
paymentMethod: that.payType, //2支付宝1微信3ios内购
orderMoney: that.stepsCj.money * 1, //订单金额
districtMoney: 0, //优惠金额
realMoney: that.stepsCj.money * 1, //实收金额
orderStatus: 0, //订单状态
orderType: "point", //订单类型
appName: "zmzm",
come: "1",
productId: that.stepsCj.priceTypeId, // 充值的类型id
};
$http
.request({
url: "book/buyOrder/rechargeSave",
method: "POST", // POST、GET、PUT、DELETE具体说明查看官方文档
data,
header: {
//默认 无 说明请求头1
"Content-Type": "application/json",
},
})
.then((res) => {
that.orderSn = res.orderSn;
console.log(res.orderSn, "dingdanhao111111111111");
uni.hideLoading();
if (res.code == 0) {
if (that.payType == 2) {
setPay(
{
typePay: "alipay",
subject: "point",
totalAmount: that.stepsCj.money,
type: that.payType,
relevanceoid: res.orderSn,
body: that.stepsCj.priceTypeId,
},
(res) => {
if (res.success) {
uni.showToast({
title: "支付成功",
});
setTimeout(() => {
uni.navigateTo({
url: "/pages/mine/wallet/index/index?source=recharge",
});
}, 2000);
} else {
uni.showToast({
title: "支付失败",
icon: "none",
image: "../../../../static/icon/ic_close.png",
});
}
},
);
} else if (that.payType == 1) {
// 微信支付
that.orderSn = res.orderSn;
let data1 = {
orderSn: res.orderSn,
buyOrderId: that.stepsCj.priceTypeId,
totalAmount: that.stepsCj.money,
};
console.log(data1, "data1");
// console.log(this.userInfo.channelList,'channelList')
// this.userInfo.channelList.map(item => {
// if(item.id == "wxpay"){
// console.log('支持微信支付')
setWXPay(data1, (res) => {
if (res.success) {
uni.showToast({
title: "支付成功",
});
setTimeout(() => {
uni.navigateTo({
url: "/pages/mine/wallet/index/index?source=recharge",
});
}, 2000);
} else {
console.log(res);
if (res.data.errMsg.indexOf("User canceled") != -1) {
uni.showToast({
title: "用户取消支付",
icon: "none",
image: "../../../../static/icon/ic_close.png",
});
} else {
uni.showToast({
title: "支付失败",
icon: "none",
image: "../../../../static/icon/ic_close.png",
});
}
}
});
// }
// })
} else if (that.payType == 3) {
console.log("苹果支付");
that.iphonepay();
}
}
});
} else {
uni.showToast({
title: "请勾选 已阅读增值服务协议",
icon: "none",
});
return false;
}
},
// 跳转
onPageJump(url) {
uni.navigateTo({
url: url,
});
},
},
};
</script>
<style lang="scss" scoped>
@import "@/style/mixin.scss";
.tanchu {
padding: 40rpx 30rpx 40rpx 30rpx;
position: relative;
.dp_title {
font-size: 32rpx;
margin-bottom: 50rpx;
color: #555;
text-align: center;
font-weight: bold;
}
.dp_add {
position: absolute;
top: 40rpx;
right: 30rpx;
font-size: 22rpx;
background-color: #fd6004;
color: #fff;
border-radius: 10rpx;
padding: 5rpx 10rpx;
.u-icon {
display: inline-block;
margin-right: 5rpx;
}
}
.addressItem {
border: 2px dashed #d9d9d9;
border-radius: 10rpx;
width: 100%;
display: flex;
padding: 20rpx 10rpx;
margin: 25rpx 0 0 0;
align-items: center;
background-color: #fff;
.addrContent {
margin-left: 40rpx;
flex: 1;
.addrContentTop {
display: flex;
align-items: flex-end;
margin: 0 0 15rpx 0;
position: relative;
.userName {
font-size: 35rpx;
font-weight: bold;
margin-right: 30rpx;
}
.userTel {
font-size: 25rpx;
color: #888;
}
.userMoren {
border: 1px solid #fd6004;
color: #fd6004;
padding: 3rpx 10rpx;
font-size: 22rpx;
border-radius: 10rpx;
margin: 0 0 0 20rpx;
}
.chooseCheck {
position: absolute;
top: 3rpx;
right: 6rpx;
}
}
.addrContentBottom {
font-size: 32rpx;
}
}
}
.addressItem.addItem_style {
border-color: #fd6004;
}
.youhuiItem {
border: 1px solid #d9d9d9;
border-radius: 10rpx;
width: 100%;
display: flex;
padding: 20rpx 10rpx;
margin: 25rpx 0 0 0;
align-items: center;
background-color: #fff;
font-size: 30rpx;
}
.youhuiItem > view {
float: left;
}
.youhuiItem.youItem_style {
border-color: #fd6004;
}
}
.agreeRadio {
zoom: 0.8;
}
.cha_jine {
padding: 60rpx 30rpx 40rpx;
// margin: 40rpx 50rpx 0 50rpx;
.cj_title {
font-size: 46rpx;
color: $themeColor;
}
.cj_xiang {
margin-top: 40rpx;
.cj_price {
box-shadow: 0 0 20rpx 0 #0000001a;
float: left;
width: 47%;
margin: 0 5% 30rpx 0;
text-align: center;
padding: 30rpx 0 0;
border-radius: 15rpx;
position: relative;
color: #2d2d2d;
height: 160rpx;
.pr_jg {
font-size: 45rpx;
font-weight: bold;
}
.pr_yl {
padding-top: 10rpx;
font-size: 26rpx;
color: #575555;
text{
width: 100%;
text-align: center;
line-height: 40rpx;
position: absolute;
left: 0;
bottom: 10rpx;
color: red;
display: block;
font-size: 24rpx;
}
}
.pr_lj {
background-image: linear-gradient(180deg, #3ab3ae 0%, #77c9c6 100%);
color: #fff;
position: absolute;
top: -22rpx;
right: -22rpx;
font-size: 24rpx;
line-height: 20px;
padding: 5rpx 10rpx;
border-top-left-radius: 20rpx;
border-bottom-right-radius: 20rpx;
}
}
.cj_price:nth-child(2n) {
margin-right: 0;
}
.Tab_cj {
box-shadow: 0px 0px 5px 0px $themeColor !important;
color: $themeColor;
.pr_yl{
color: $themeColor;
}
}
}
}
.highlight {
color: $themeColor;
}
.cha_fangsh {
padding: 40rpx 30rpx;
.cf_title {
font-size: 46rpx;
color: $themeColor;
}
.cf_radio {
margin-top: 20rpx;
.cf_xuanx {
font-size: 32rpx;
padding: 20rpx 0;
margin-bottom: 20rpx;
border-bottom: 1px solid #ededed;
image {
width: 40rpx;
height: 40rpx;
display: inline-block;
margin-right: 20rpx;
vertical-align: bottom;
}
}
.Tab_xf {
// background-color: #fdf1e9cc;
}
}
}
.agree_wo {
color: #aaa;
font-size: 25rpx;
margin-top: 30rpx;
padding: 30rpx;
// margin: 40rpx 50rpx 0 50rpx;
padding-bottom: 180rpx;
}
.char_btn {
width: 100%;
background: #fff;
padding: 20rpx 0;
position: fixed;
right: 0;
bottom: 0;
view {
background: $themeBgColor;
color: #fff;
width: 90%;
margin: 0 auto;
text-align: center;
font-size: 30rpx;
padding: 20rpx 0;
border-radius: 50rpx;
}
}
.pay_item_img {
width: 50rpx;
height: 50rpx;
float: left;
margin-right: 20rpx;
}
.agree {
width: auto !important;
}
.commonPageBox {
background-color: #fff !important;
}
.limitBlock{
display: flex;
align-items: center;
margin-bottom: 10rpx;
text{
font-size: 28rpx;
}
input{
display: inline-block;
margin-left: 20rpx;
width: 300rpx;
height: 70rpx;
border: 1rpx solid #ededed;
border-radius: 10rpx;
line-height: 40rpx;
padding: 20rpx;
font-size: 28rpx;
color: #666;
}
}
.limit-placeholder{
font-size: 25rpx;
color: #8b8c90 !important;
}
.active_block{
width: 100%;
background-color: rgba(58, 179, 174, 0.2);
border-radius: 10rpx;
padding: 10rpx 20rpx;
font-size: 28rpx;
line-height: 42rpx;
margin-top: 15rpx;
color: #333;
}
/deep/.active_block span{
color: red;
font-size: 32rpx;
font-weight: bold;
padding: 0 5rpx;
}
/deep/.active_block span:first-child{
padding: 0 5rpx 0 0;
}
/deep/.active_block p{
padding-top: 10rpx;
color: #666;
font-size: 24rpx;
line-height: 34rpx;
}
/deep/.active_block p span{
padding: 0 5rpx !important;
}
</style>