1、调整支付

2、调整Websocket监听支付完成
This commit is contained in:
ywyonui 2025-07-01 16:17:13 +08:00
parent d20202af6d
commit 5f59d3d8d4
7 changed files with 204 additions and 98 deletions

View File

@ -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);
};
/**
* 退
*/

View File

@ -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": {

View 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>

View File

@ -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("120");
// let timer: any = null;
// let seconds = 1 * 60 + 20; // 120
//
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(() => {

View File

@ -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; // 0100
}
},
},
extra: {
line: {
@ -497,6 +505,7 @@ onMounted(() => {
initKsdj();
//
rebuildData();
activeTab.value = "trend";
}
})
.catch((error) => {

View File

@ -20,7 +20,7 @@ export const useUserStore = defineStore({
// token
token: '',
//用户注册信息
auth: [],
auth: []
}),
getters: {
getToken(): string {

View File

@ -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接受到服务器的消息事件。
uni.onSocketMessage(function (res) {
if (callback) {
callback('data', res)
}
});
return {reconnect: connect, heartbeat}
}
export function sendSocket(value: string | ArrayBuffer, fail ?: Function) {
uni.sendSocketMessage({
data: value,
//创建一个 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()
}
})
}
function closeConnect() {
// uni-app 提供的关闭方法(如果支持)
if (typeof uni.closeSocket === 'function') {
uni.closeSocket({
success: () => {
console.log('WebSocket 已主动关闭');
}
});
}
}
//监听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,
})
}