Lufaneng 11 months ago
parent 0abb3ae117
commit c452b83a66

@ -50,7 +50,7 @@
<view class="form" v-else> <view class="form" v-else>
<uv-form labelAlign="left" labelWidth="auto" labelPosition="left" :model="formField" :rules="rules" <uv-form labelAlign="left" labelWidth="auto" labelPosition="left" :model="formField" :rules="rules"
ref="form"> ref="form">
<uv-form-item :prop="item.key" :label="item.name + ''" v-for="item in currentTemplate.params"> <uv-form-item :prop="item.key" :label="item.name + ''" v-for="item in (currentTemplate.params?.filter(item => item.enabled) || [])">
<uv-input :type="item.type === 'number' ? 'digit' : 'text'" v-model="item.value" color="#000" <uv-input :type="item.type === 'number' ? 'digit' : 'text'" v-model="item.value" color="#000"
border="bottom" :placeholderStyle="{ color: '#666778' }" placeholder="请输入"></uv-input> border="bottom" :placeholderStyle="{ color: '#666778' }" placeholder="请输入"></uv-input>
</uv-form-item> </uv-form-item>
@ -152,7 +152,7 @@
const modalRef = ref(null) const modalRef = ref(null)
const confirmGenerate = () => { const confirmGenerate = () => {
const params = {} const params = {}
currentTemplate.value.params.forEach(item => { currentTemplate.value.params?.filter(item => item.enabled).forEach(item => {
params[item.name] = item.value params[item.name] = item.value
}) })
RPC.post('/template_create_task', {template_id:currentTemplate.value.id,template_data:params}).then(() => { RPC.post('/template_create_task', {template_id:currentTemplate.value.id,template_data:params}).then(() => {
@ -177,8 +177,8 @@
page: 1, page: 1,
limit: -1 limit: -1
}).then(res => { }).then(res => {
templateList.value = res.rows || [] templateList.value = (res.rows || []).filter(item => item.enabled)
currentTemplate.value = res.rows[0] ? JSON.parse(JSON.stringify(res.rows[0])) : {} currentTemplate.value = templateList.value[0] ? JSON.parse(JSON.stringify(templateList.value[0])) : {}
}).finally(() => { }).finally(() => {
loading.value = false loading.value = false
}) })

@ -17,11 +17,7 @@
<view class="user-details"> <view class="user-details">
<view class="username"> <view class="username">
{{userStore.userInfo.username}} {{userStore.userInfo.username}}
<u-icon <u-icon name="checkmark-circle-fill" color="#ffa500" size="16"></u-icon>
name="checkmark-circle-fill"
color="#ffa500"
size="16"
></u-icon>
</view> </view>
<view class="user-id">用户ID: {{userStore.userInfo.id}}</view> <view class="user-id">用户ID: {{userStore.userInfo.id}}</view>
<view class="membership"> <view class="membership">
@ -42,13 +38,7 @@
</view> </view>
<view class="balance-amount">¥50.00</view> <view class="balance-amount">¥50.00</view>
</div> </div>
<uv-button <uv-button type="primary" color="#fff" customStyle="color:#000;width:90px" shape="circle" @click="recharge">
type="primary"
color="#fff"
customStyle="color:#000;width:90px"
shape="circle"
@click="recharge"
>
充值 充值
</uv-button> </uv-button>
</view> </view>
@ -56,16 +46,13 @@
<!-- 会员套餐 --> <!-- 会员套餐 -->
<view class="membership-section"> <view class="membership-section">
<view class="membership-grid"> <view class="membership-grid">
<view <view class="membership-item" :class="{ active: selectedPlan === item.id }" v-for="item in planList"
class="membership-item" :key="item.id" @click="selectPlan(item)">
:class="{ active: selectedPlan === 'monthly' }" <view class="tag" v-if="item.tags">{{item.tags}}</view>
@click="selectPlan('monthly')" <view class="plan-name">{{item.name}}</view>
> <view class="plan-price">¥{{item.price_cents}}</view>
<view class="tag">新人特惠</view>
<view class="plan-name">包月会员</view>
<view class="plan-price">¥120</view>
</view> </view>
<view <!-- <view
class="membership-item" class="membership-item"
:class="{ active: selectedPlan === 'season' }" :class="{ active: selectedPlan === 'season' }"
@click="selectPlan('season')" @click="selectPlan('season')"
@ -84,60 +71,46 @@
<view class="plan-name">包年会员</view> <view class="plan-name">包年会员</view>
<view class="plan-price">¥1000</view> <view class="plan-price">¥1000</view>
<view class="plan-discount">立减¥440</view> <view class="plan-discount">立减¥440</view>
</view> </view> -->
</view> </view>
</view> </view>
<!-- 支付方式 --> <!-- 支付方式 -->
<view class="payment-section"> <view class="payment-section">
<!-- 微信支付 --> <!-- 微信支付 -->
<view <view class="payment-item" :class="{ active: selectedPayment === 'wallet' }"
class="payment-item" @click="selectPayment('wallet')">
:class="{ active: selectedPayment === 'wechat' }" <view class="payment-info">
@click="selectPayment('wechat')" <uv-icon name="empty-coupon" color="#07c160" size="24"></uv-icon>
> <text class="payment-name">钱包支付</text>
</view>
<uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'wallet' ? '#ff3333' : '#ccc'"
size="20"></uv-icon>
</view>
<view class="payment-item" :class="{ active: selectedPayment === 'wxpay' }" @click="selectPayment('wxpay')">
<view class="payment-info"> <view class="payment-info">
<uv-icon name="weixin-fill" color="#07c160" size="24"></uv-icon> <uv-icon name="weixin-fill" color="#07c160" size="24"></uv-icon>
<text class="payment-name">微信支付</text> <text class="payment-name">微信支付</text>
</view> </view>
<uv-icon <uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'wxpay' ? '#ff3333' : '#ccc'"
name="checkmark-circle-fill" size="20"></uv-icon>
:color="selectedPayment === 'wechat' ? '#ff3333' : '#ccc'"
size="20"
></uv-icon>
</view> </view>
<!-- 支付宝支付 - 仅在H5环境显示 --> <!-- 支付宝支付 - 仅在H5环境显示 -->
<view <view v-if="showAlipay" class="payment-item" :class="{ active: selectedPayment === 'alipay' }"
v-if="showAlipay" @click="selectPayment('alipay')">
class="payment-item"
:class="{ active: selectedPayment === 'alipay' }"
@click="selectPayment('alipay')"
>
<view class="payment-info"> <view class="payment-info">
<uv-icon <uv-icon name="/static/imgs/alipay.png" color="#1677ff" size="24"></uv-icon>
name="/static/imgs/alipay.png"
color="#1677ff"
size="24"
></uv-icon>
<text class="payment-name">支付宝</text> <text class="payment-name">支付宝</text>
</view> </view>
<uv-icon <uv-icon name="checkmark-circle-fill" :color="selectedPayment === 'alipay' ? '#ff3333' : '#ccc'"
name="checkmark-circle-fill" size="20"></uv-icon>
:color="selectedPayment === 'alipay' ? '#ff3333' : '#ccc'"
size="20"
></uv-icon>
</view> </view>
</view> </view>
<!-- 底部按钮 --> <!-- 底部按钮 -->
<view class="bottom-section"> <view class="bottom-section">
<uv-button <uv-button type="primary" size="large" @click="confirmPayment" :loading="paying">
type="primary"
size="large"
@click="confirmPayment"
:loading="paying"
>
确认支付 确认支付
</uv-button> </uv-button>
<view class="agreement"> <view class="agreement">
@ -149,10 +122,18 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import {
import { onShow } from "@dcloudio/uni-app"; ref,
onMounted
} from "vue";
import {
onShow
} from "@dcloudio/uni-app";
import HeaderCustom from "/components/HeaderCustom/HeaderCustom.vue"; import HeaderCustom from "/components/HeaderCustom/HeaderCustom.vue";
import { useAuthStore, useUserStore } from "@/store"; import {
useAuthStore,
useUserStore
} from "@/store";
import RPC from "@/utils/request"; import RPC from "@/utils/request";
const modal = ref(null); const modal = ref(null);
@ -160,14 +141,27 @@ const authStore = useAuthStore();
const userStore = useUserStore(); const userStore = useUserStore();
// //
const selectedPlan = ref("season"); // const selectedPlan = ref("");
const selectedPayment = ref("wechat"); // const selectedPayment = ref("wxpay"); //
const paying = ref(false); const paying = ref(false);
const showAlipay = ref(true); // const showAlipay = ref(true); //
const planList = ref([])
const getPlanList = () => {
RPC.post('/membership_plan/list', {
page: 1,
limit: -1,
orderby: [{
sort: 'asc'
}]
}).then(res => {
planList.value = (res.rows || []).filter(item => item.enabled)
selectedPlan.value = planList.value[0] ? planList.value[0].id : ''
})
}
getPlanList()
// //
const selectPlan = (plan) => { const selectPlan = (plan) => {
selectedPlan.value = plan; selectedPlan.value = plan.id;
}; };
// //
@ -189,37 +183,6 @@ const recharge = () => {
}); });
}; };
//
const getPlanPrice = (plan) => {
const prices = {
monthly: 120,
season: 300,
yearly: 1000,
};
return prices[plan] || 0;
};
//
const getPlanName = (plan) => {
const names = {
monthly: "包月会员",
season: "包季会员",
yearly: "包年会员",
};
return names[plan] || "";
};
//
const createOrder = async (params) => {
try {
// API
const result = await RPC.post("/api/order/create", params);
return result.data;
} catch (error) {
console.error("创建订单失败:", error);
throw error;
}
};
// //
const wechatPay = async (orderInfo) => { const wechatPay = async (orderInfo) => {
@ -236,7 +199,10 @@ const wechatPay = async (orderInfo) => {
}); });
console.log("微信支付成功:", paymentResult); console.log("微信支付成功:", paymentResult);
return { success: true, data: paymentResult }; return {
success: true,
data: paymentResult
};
} catch (error) { } catch (error) {
console.error("微信支付失败:", error); console.error("微信支付失败:", error);
if (error.errMsg === "requestPayment:fail cancel") { if (error.errMsg === "requestPayment:fail cancel") {
@ -251,8 +217,7 @@ const wechatPay = async (orderInfo) => {
if (typeof WeixinJSBridge !== "undefined") { if (typeof WeixinJSBridge !== "undefined") {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
WeixinJSBridge.invoke( WeixinJSBridge.invoke(
"getBrandWCPayRequest", "getBrandWCPayRequest", {
{
appId: orderInfo.appId, appId: orderInfo.appId,
timeStamp: orderInfo.timeStamp, timeStamp: orderInfo.timeStamp,
nonceStr: orderInfo.nonceStr, nonceStr: orderInfo.nonceStr,
@ -262,7 +227,10 @@ const wechatPay = async (orderInfo) => {
}, },
(res) => { (res) => {
if (res.err_msg === "get_brand_wcpay_request:ok") { if (res.err_msg === "get_brand_wcpay_request:ok") {
resolve({ success: true, data: res }); resolve({
success: true,
data: res
});
} else if (res.err_msg === "get_brand_wcpay_request:cancel") { } else if (res.err_msg === "get_brand_wcpay_request:cancel") {
reject(new Error("用户取消支付")); reject(new Error("用户取消支付"));
} else { } else {
@ -275,7 +243,10 @@ const wechatPay = async (orderInfo) => {
// //
const payUrl = orderInfo.mwebUrl; // H5 const payUrl = orderInfo.mwebUrl; // H5
window.location.href = payUrl; window.location.href = payUrl;
return { success: true, redirect: true }; return {
success: true,
redirect: true
};
} }
// #endif // #endif
}; };
@ -286,7 +257,10 @@ const alipayPay = async (orderInfo) => {
// H5 // H5
const payUrl = orderInfo.payUrl; // H5 const payUrl = orderInfo.payUrl; // H5
window.location.href = payUrl; window.location.href = payUrl;
return { success: true, redirect: true }; return {
success: true,
redirect: true
};
// #endif // #endif
}; };
@ -309,21 +283,12 @@ const confirmPayment = async () => {
} }
paying.value = true; paying.value = true;
try { try {
// 1. // 1.
const orderParams = { const orderParams = {
plan: selectedPlan.value, user_id: userStore.userInfo?.id,
planName: getPlanName(selectedPlan.value), plan_id: selectedPlan.value,
amount: getPlanPrice(selectedPlan.value), pay_channel: selectedPayment.value
paymentMethod: selectedPayment.value,
userId: userStore.userInfo?.id || "mock_user_id",
// #ifdef MP-WEIXIN
platform: "mp-weixin",
// #endif
// #ifdef H5
platform: "h5",
// #endif
}; };
uni.showLoading({ uni.showLoading({
@ -331,40 +296,45 @@ const confirmPayment = async () => {
}); });
// 2. // 2.
// const orderResult = await createOrder(orderParams); const orderNum = await RPC.post('/membership/order/create', orderParams);
// //
const orderResult = { // const orderResult = {
orderId: "ORDER_" + Date.now(), // orderId: "ORDER_" + Date.now(),
amount: orderParams.amount, // amount: orderParams.amount,
// // //
wechatPayInfo: { // wechatPayInfo: {
appId: "wx1234567890", // appId: "wx1234567890",
timeStamp: String(Date.now()), // timeStamp: String(Date.now()),
nonceStr: "random_string_" + Date.now(), // nonceStr: "random_string_" + Date.now(),
package: "prepay_id=wx_prepay_id_123456", // package: "prepay_id=wx_prepay_id_123456",
signType: "RSA", // signType: "RSA",
paySign: "mock_pay_sign_123456", // paySign: "mock_pay_sign_123456",
// H5 // // H5
mwebUrl: // mwebUrl: "https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx_prepay_id_123456",
"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx_prepay_id_123456", // },
}, // //
// // alipayInfo: {
alipayInfo: { // orderString: "mock_alipay_order_string_123456",
orderString: "mock_alipay_order_string_123456", // payUrl: "https://openapi.alipay.com/gateway.do?mock_pay_url",
payUrl: "https://openapi.alipay.com/gateway.do?mock_pay_url", // },
}, // };
};
uni.hideLoading(); uni.hideLoading();
// 3. // 3.
let paymentResult; let paymentResult;
if (selectedPayment.value === "wxpay") {
if (selectedPayment.value === "wechat") { const orderResult = await RPC.post('/membership/order/pay_by_wechat',{
"order_no": orderNum.order_no
})
uni.showLoading({ uni.showLoading({
title: "正在跳转微信支付...", title: "正在跳转微信支付...",
}); });
if(1==1) {
console.log('orderResult',orderResult)
return
}
paymentResult = await wechatPay(orderResult.wechatPayInfo); paymentResult = await wechatPay(orderResult.wechatPayInfo);
} else if (selectedPayment.value === "alipay") { } else if (selectedPayment.value === "alipay") {
uni.showLoading({ uni.showLoading({
@ -406,12 +376,15 @@ const confirmPayment = async () => {
} catch (error) { } catch (error) {
uni.hideLoading(); uni.hideLoading();
console.error("支付失败:", error); console.error("支付失败:", error);
console.log('error', error)
let errorMessage = "支付失败,请重试"; let errorMessage = "支付失败,请重试";
if (error.message === "用户取消支付") { if (error.message === "用户取消支付") {
errorMessage = "支付已取消"; errorMessage = "支付已取消";
} else if (error.message) { } else if (error.message) {
errorMessage = error.message; errorMessage = error.message;
} else if (error) {
errorMessage = error
} }
uni.showToast({ uni.showToast({
@ -502,7 +475,6 @@ const checkEnvironment = () => {
// #ifdef MP-WEIXIN // #ifdef MP-WEIXIN
// //
showAlipay.value = false; showAlipay.value = false;
selectedPayment.value = "wechat";
// #endif // #endif
// #ifdef H5 // #ifdef H5
@ -511,7 +483,6 @@ const checkEnvironment = () => {
// //
const ua = navigator.userAgent.toLowerCase(); const ua = navigator.userAgent.toLowerCase();
const isWechat = ua.indexOf("micromessenger") !== -1; const isWechat = ua.indexOf("micromessenger") !== -1;
selectedPayment.value = isWechat ? "wechat" : "alipay";
// #endif // #endif
}; };
@ -534,7 +505,8 @@ onShow(() => {
padding-bottom: 120px; padding-bottom: 120px;
/* #ifdef H5 */ /* #ifdef H5 */
padding-bottom: 170px; /* H5环境下需要更多空间 (底部按钮高度 + tabBar高度 + 间距) */ padding-bottom: 170px;
/* H5环境下需要更多空间 (底部按钮高度 + tabBar高度 + 间距) */
/* #endif */ /* #endif */
} }
@ -643,10 +615,13 @@ onShow(() => {
.membership-grid { .membership-grid {
display: flex; display: flex;
justify-content: space-between;
gap: 8px; gap: 8px;
overflow-x: auto;
.membership-item { .membership-item {
flex: 1; width: 24%;
flex-shrink: 0;
background: white; background: white;
border-radius: 12px; border-radius: 12px;
padding: 16px 12px; padding: 16px 12px;
@ -739,7 +714,8 @@ onShow(() => {
border-top: 1px solid #e5e5e5; border-top: 1px solid #e5e5e5;
/* #ifdef H5 */ /* #ifdef H5 */
bottom: 50px; /* H5环境下给tabBar留出空间 */ bottom: 50px;
/* H5环境下给tabBar留出空间 */
/* #endif */ /* #endif */
.agreement { .agreement {

@ -83,7 +83,9 @@
}); });
uni.downloadFile({ uni.downloadFile({
url: record.result_url, url: record.result_url,
// url:'https://ksdt-1255846884.cos.ap-shanghai.myqcloud.com/lift-result/2025/09/24/d6180add4cd94875a1854a4febce8966.pdf',
success: (res) => { success: (res) => {
console.log(res)
if (res.statusCode === 200) { if (res.statusCode === 200) {
uni.saveFile({ uni.saveFile({
tempFilePath: res.tempFilePath, tempFilePath: res.tempFilePath,

@ -262,9 +262,13 @@ $uv.http.interceptors.response.use(
console.log(response) console.log(response)
/* 对响应错误做点什么 */ /* 对响应错误做点什么 */
const codeMsg = { const codeMsg = {
401:"登录过期",
404: "您所请求的资源无法找到", 404: "您所请求的资源无法找到",
500: "服务器内部错误,无法完成请求", 500: "服务器内部错误,无法完成请求",
}; };
if(response.statusCode == '401') {
redirectToLoginPage()
}
const errMsg = codeMsg[response.statusCode] ?? "异常错误"; const errMsg = codeMsg[response.statusCode] ?? "异常错误";
$uv.toast(errMsg); $uv.toast(errMsg);
return Promise.reject(new Error(errMsg)); return Promise.reject(new Error(errMsg));

Loading…
Cancel
Save