1、调整支付
2、调整Websocket监听支付完成
This commit is contained in:
parent
d20202af6d
commit
5f59d3d8d4
@ -101,6 +101,13 @@ export const jzXkFqJfjApi = async (params: any) => {
|
||||
return await post("/mobile/jz/xk/fqjf", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 家长取消选课,不支付
|
||||
*/
|
||||
export const jzXkCancelApi = async (params: any) => {
|
||||
return await post("/mobile/jz/xk/cancel", params);
|
||||
};
|
||||
|
||||
/**
|
||||
* 家长退课
|
||||
*/
|
||||
|
||||
@ -183,6 +183,16 @@
|
||||
"enablePullDownRefresh": false
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/base/course-selection/pay-wait",
|
||||
"style": {
|
||||
"navigationBarTitleText": "",
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarBackgroundColor": "#ffffff",
|
||||
"navigationBarTextStyle": "black",
|
||||
"backgroundColor": "#ffffff"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/base/course-selection/payment-success",
|
||||
"style": {
|
||||
|
||||
42
src/pages/base/course-selection/pay-wait.vue
Normal file
42
src/pages/base/course-selection/pay-wait.vue
Normal file
@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<view class="wh-full">
|
||||
<web-view :src="payUrl"></web-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onLoad } from "@dcloudio/uni-app";
|
||||
import { useWebSocket } from '@/utils/webSocket/webSocket'
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
const { getUser } = useUserStore();
|
||||
|
||||
const payUrl = ref("");
|
||||
const ws = useWebSocket(`/zhxy/webSocket/${getUser.userId}`, (type: string, data: any) => {
|
||||
console.log('收到WebSocket消息:', type, data);
|
||||
if (type === 'pay') {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success',
|
||||
})
|
||||
// 跳转到支付成功页面
|
||||
setTimeout(() => {
|
||||
uni.reLaunch({
|
||||
url: "/pages/base/course-selection/payment-success",
|
||||
});
|
||||
}, 1000)
|
||||
}
|
||||
});
|
||||
onLoad((options: any) => {
|
||||
if (options.payUrl) {
|
||||
payUrl.value = decodeURIComponent(options.payUrl);
|
||||
ws.reconnect();
|
||||
} else {
|
||||
uni.showToast({ title: '缺少支付地址', icon: 'none' })
|
||||
setTimeout(() => {
|
||||
uni.navigateBack()
|
||||
}, 1000)
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@ -19,39 +19,36 @@
|
||||
|
||||
<view class="student-info">
|
||||
<view class="student-avatar">
|
||||
<image
|
||||
src="/static/images/student-avatar.jpg"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<image :src="curXs.xstxUrl || '/static/base/home/11222.png'" class="tx-img"></image>
|
||||
</view>
|
||||
<view class="student-details">
|
||||
<view class="student-name">
|
||||
{{ student.xm }}
|
||||
{{ curXs.xm }}
|
||||
</view>
|
||||
<view class="student-class"
|
||||
>{{ student.njmc }}{{ student.bjmc }}</view
|
||||
>{{ curXs.njmc }}{{ curXs.bjmc }}</view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 课程信息卡片 -->
|
||||
<view class="info-card">
|
||||
<view class="info-card" v-for="(xkqd, index) in xkqdList" :key="index">
|
||||
<view class="card-title">课程信息</view>
|
||||
<view class="divider"></view>
|
||||
|
||||
<view class="course-info">
|
||||
<image
|
||||
class="course-image"
|
||||
:src="imagUrl(course.xkkcImg)"
|
||||
:src="xkqd.lxtp ? imagUrl(xkqd.lxtp) : '/static/base/home/11222.png'"
|
||||
mode="aspectFill"
|
||||
></image>
|
||||
<view class="course-details">
|
||||
<view class="course-name">{{ course.kcmc }}</view>
|
||||
<view class="course-teacher">开课老师:{{ course.jsName }}</view>
|
||||
<view class="course-location">上课地点:{{ course.kcdd }}</view>
|
||||
<view class="course-name">{{ xkqd.kcmc }}</view>
|
||||
<view class="course-teacher">开课老师:{{ xkqd.jsxm }}</view>
|
||||
<view class="course-location">上课地点:{{ xkqd.kcdd }}</view>
|
||||
<view class="course-price"
|
||||
>金额:<text class="price-value">¥{{ course.kcje }}</text></view
|
||||
>金额:<text class="price-value">¥{{ xkqd.kcje }}</text></view
|
||||
>
|
||||
</view>
|
||||
</view>
|
||||
@ -61,7 +58,7 @@
|
||||
<view class="payment-footer">
|
||||
<view class="total-amount">
|
||||
<text>总金额:</text>
|
||||
<text class="amount-value">¥{{ course.kcje }}</text>
|
||||
<text class="amount-value">¥{{ totalJe }}</text>
|
||||
</view>
|
||||
|
||||
<view class="action-buttons">
|
||||
@ -73,25 +70,36 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { xkqddeleteApi } from "@/api/base/server";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { jzXkCancelApi, jzXkFqJfjApi } from "@/api/base/server";
|
||||
import { imagUrl } from "@/utils";
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
const useData = useDataStore();
|
||||
const { getData } = storeToRefs(useData);
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { result } from "lodash";
|
||||
const { getCurXs, getUser } = useUserStore();
|
||||
const { setData, getData } = useDataStore();
|
||||
|
||||
// 学生信息
|
||||
const curXs = computed(() => getCurXs);
|
||||
// 课程信息
|
||||
const xkqdList = computed(() => getData.xkqdList);
|
||||
// 总金额
|
||||
const totalJe = computed(() => {
|
||||
// 循环xkqdList.value 求和
|
||||
if (!xkqdList.value || !xkqdList.value.length) {
|
||||
return 0;
|
||||
}
|
||||
let total = 0;
|
||||
for (let i = 0; i < xkqdList.value.length; i++) {
|
||||
total += xkqdList.value[i].kcje;
|
||||
}
|
||||
return total;
|
||||
});
|
||||
|
||||
// 倒计时
|
||||
// const countdownTime = ref("1分20秒");
|
||||
// let timer: any = null;
|
||||
// let seconds = 1 * 60 + 20; // 1分20秒
|
||||
|
||||
// 学生信息
|
||||
const student = ref(getData.value.studentInfo);
|
||||
|
||||
// 课程信息
|
||||
const course = ref(getData.value.enrolledCourse);
|
||||
console.log(course.value);
|
||||
|
||||
// 开始倒计时
|
||||
// const startCountdown = () => {
|
||||
// timer = setInterval(() => {
|
||||
@ -127,10 +135,10 @@ const cancelRegistration = () => {
|
||||
content: "确定要取消报名吗?",
|
||||
success: async (res) => {
|
||||
if (res.confirm) {
|
||||
await xkqddeleteApi({
|
||||
id: course.value.id,
|
||||
await jzXkCancelApi({
|
||||
xsId: getData.xsId,
|
||||
xkId: getData.xkId
|
||||
});
|
||||
|
||||
uni.showToast({
|
||||
title: "已取消报名",
|
||||
icon: "success",
|
||||
@ -144,10 +152,28 @@ const cancelRegistration = () => {
|
||||
};
|
||||
|
||||
// 立即支付
|
||||
const payNow = () => {
|
||||
uni.showLoading({
|
||||
title: "支付中...",
|
||||
});
|
||||
const payNow = async () => {
|
||||
// const res = await jzXkFqJfjApi({
|
||||
// xsId: getData.xsId,
|
||||
// xkId: getData.xkId,
|
||||
// jffs: "四川农信", // TODO: 目前只支持四川农信
|
||||
// jzId: getUser.jzId,
|
||||
// userId: getUser.userId,
|
||||
// openId: getUser.openId,
|
||||
// });
|
||||
const res = {
|
||||
resultCode: 1,
|
||||
result: "https://pay.weixin.qq.com/wxpay/pay.action?prepay_id=wx20191018103005f5c0c0f5c0c"
|
||||
}
|
||||
if (res.resultCode === 1 && res.result) {
|
||||
uni.redirectTo({
|
||||
url: `/pages/base/course-selection/pay-wait?payUrl=${encodeURIComponent(res.result)}`
|
||||
});
|
||||
}
|
||||
|
||||
// uni.showLoading({
|
||||
// title: "支付中...",
|
||||
// });
|
||||
|
||||
// // 模拟支付过程
|
||||
// setTimeout(() => {
|
||||
|
||||
@ -161,6 +161,7 @@ import dayjs from "dayjs";
|
||||
import { xsKscjApi } from "@/api/base/server";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import { useDataStore } from "@/store/modules/data";
|
||||
import { format } from "path";
|
||||
const { getCurXs } = useUserStore();
|
||||
const { getData } = useDataStore();
|
||||
dayjs.locale("zh-cn");
|
||||
@ -342,7 +343,7 @@ const drawTrendChart = () => {
|
||||
animation: true,
|
||||
background: "#FFFFFF",
|
||||
padding: [15, 15, 0, 15],
|
||||
dataLabel: true,
|
||||
dataLabel: false,
|
||||
dataPointShape: true,
|
||||
enableScroll: false,
|
||||
legend: {
|
||||
@ -358,10 +359,17 @@ const drawTrendChart = () => {
|
||||
dashLength: 2,
|
||||
data: [
|
||||
{
|
||||
min: 80,
|
||||
min: 0,
|
||||
max: 100,
|
||||
},
|
||||
],
|
||||
min: 0, // 纵坐标最小值设为0
|
||||
max: 100, // 纵坐标最大值设为100
|
||||
axisLabel: { // 标签配置
|
||||
show: function(value: any) {
|
||||
return value === 0 || value === 100; // 只显示0和100
|
||||
}
|
||||
},
|
||||
},
|
||||
extra: {
|
||||
line: {
|
||||
@ -497,6 +505,7 @@ onMounted(() => {
|
||||
initKsdj();
|
||||
// 重构显示数据
|
||||
rebuildData();
|
||||
activeTab.value = "trend";
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
|
||||
@ -20,7 +20,7 @@ export const useUserStore = defineStore({
|
||||
// token
|
||||
token: '',
|
||||
//用户注册信息
|
||||
auth: [],
|
||||
auth: []
|
||||
}),
|
||||
getters: {
|
||||
getToken(): string {
|
||||
|
||||
@ -1,85 +1,97 @@
|
||||
import {BASE_WS_URL} from "@/config";
|
||||
import {hideLoading, showLoading} from "@/utils/uniapp";
|
||||
import { BASE_WS_URL } from "@/config";
|
||||
import { hideLoading, showLoading } from "@/utils/uniapp";
|
||||
|
||||
export interface WebSocketReturn {
|
||||
reconnect: () => void,
|
||||
heartbeat: () => void,
|
||||
reconnect: () => void,
|
||||
heartbeat: () => void,
|
||||
closeConnect: () => void
|
||||
}
|
||||
|
||||
let isLoading = false
|
||||
|
||||
function heartbeatState(state: boolean) {
|
||||
if (!state) {
|
||||
if (!isLoading) {
|
||||
showLoading({title: '网络异常,重新连接中'})
|
||||
}
|
||||
isLoading = true
|
||||
}
|
||||
if (state) {
|
||||
hideLoading()
|
||||
isLoading = false
|
||||
if (!state) {
|
||||
if (!isLoading) {
|
||||
showLoading({ title: '网络异常,重新连接中' })
|
||||
}
|
||||
isLoading = true
|
||||
}
|
||||
if (state) {
|
||||
hideLoading()
|
||||
isLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
export let socketSuccess = false
|
||||
|
||||
export function useWebSocket(url: string, callback ?: Function, OBJECT ?: UniNamespace.ConnectSocketOption): WebSocketReturn {
|
||||
let reconnectInterval: NodeJS.Timer | null = null
|
||||
export function useWebSocket(url: string, callback?: Function, OBJECT?: UniNamespace.ConnectSocketOption): WebSocketReturn {
|
||||
let reconnectInterval: NodeJS.Timer | null = null
|
||||
|
||||
function heartbeat() {
|
||||
console.log("启动心跳");
|
||||
if (reconnectInterval) {
|
||||
function heartbeat() {
|
||||
console.log("启动心跳");
|
||||
if (reconnectInterval) {
|
||||
clearInterval(reconnectInterval)
|
||||
}
|
||||
reconnectInterval = setInterval(() => {
|
||||
uni.sendSocketMessage({
|
||||
data: JSON.stringify({
|
||||
action: "heartbeat",
|
||||
message: '心跳'
|
||||
}),
|
||||
success: () => {
|
||||
heartbeatState(true)
|
||||
},
|
||||
fail: (err) => {
|
||||
heartbeatState(false)
|
||||
socketSuccess = false
|
||||
console.log('心跳失败')
|
||||
if (reconnectInterval) {
|
||||
clearInterval(reconnectInterval)
|
||||
}
|
||||
console.log('重新连接')
|
||||
connect()
|
||||
}
|
||||
reconnectInterval = setInterval(() => {
|
||||
uni.sendSocketMessage({
|
||||
data: JSON.stringify({
|
||||
action: "heartbeat",
|
||||
message: '心跳'
|
||||
}),
|
||||
success: () => {
|
||||
heartbeatState(true)
|
||||
},
|
||||
fail: (err) => {
|
||||
heartbeatState(false)
|
||||
socketSuccess = false
|
||||
console.log('心跳失败')
|
||||
if (reconnectInterval) {
|
||||
clearInterval(reconnectInterval)
|
||||
}
|
||||
console.log('重新连接')
|
||||
connect()
|
||||
}
|
||||
})
|
||||
}, 3000)
|
||||
}
|
||||
})
|
||||
}, 5000)
|
||||
}
|
||||
|
||||
//创建一个 WebSocket 连接。
|
||||
function connect() {
|
||||
console.log('连接socket地址', BASE_WS_URL + url)
|
||||
uni.connectSocket({
|
||||
url: BASE_WS_URL + url,
|
||||
...OBJECT,
|
||||
success: () => {
|
||||
socketSuccess = true
|
||||
console.log('socket启动成功')
|
||||
heartbeat()
|
||||
}
|
||||
})
|
||||
}
|
||||
//创建一个 WebSocket 连接。
|
||||
function connect() {
|
||||
console.log('连接socket地址', BASE_WS_URL + url)
|
||||
uni.connectSocket({
|
||||
url: BASE_WS_URL + url,
|
||||
...OBJECT,
|
||||
success: () => {
|
||||
socketSuccess = true
|
||||
console.log('socket启动成功')
|
||||
heartbeat()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
//监听WebSocket接受到服务器的消息事件。
|
||||
uni.onSocketMessage(function (res) {
|
||||
if (callback) {
|
||||
callback('data', res)
|
||||
function closeConnect() {
|
||||
// uni-app 提供的关闭方法(如果支持)
|
||||
if (typeof uni.closeSocket === 'function') {
|
||||
uni.closeSocket({
|
||||
success: () => {
|
||||
console.log('WebSocket 已主动关闭');
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return {reconnect: connect, heartbeat}
|
||||
//监听WebSocket接受到服务器的消息事件。
|
||||
uni.onSocketMessage(function (res) {
|
||||
if (callback) {
|
||||
callback('data', res)
|
||||
}
|
||||
});
|
||||
|
||||
return { reconnect: connect, heartbeat, closeConnect }
|
||||
}
|
||||
|
||||
export function sendSocket(value: string | ArrayBuffer, fail ?: Function) {
|
||||
uni.sendSocketMessage({
|
||||
data: value,
|
||||
})
|
||||
export function sendSocket(value: string | ArrayBuffer, fail?: Function) {
|
||||
uni.sendSocketMessage({
|
||||
data: value,
|
||||
})
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user