添加打赏支付

This commit is contained in:
kron
2025-09-25 17:07:37 +08:00
parent 91535abfd7
commit f8bc5d094e
3 changed files with 101 additions and 30 deletions

View File

@@ -488,3 +488,13 @@ export const getVIPDescAPI = async () => {
export const getPointBookStatisticsAPI = async () => { export const getPointBookStatisticsAPI = async () => {
return request("GET", `/v2/user/score/sheet/statistics`); return request("GET", `/v2/user/score/sheet/statistics`);
}; };
export const donateAPI = async (amount, name, phone, organizer, advice) => {
return request("POST", `/user/donate`, {
amount,
name,
phone,
organizer,
advice,
});
};

View File

@@ -1,9 +1,16 @@
<script setup> <script setup>
import { ref, reactive } from "vue"; import { ref, reactive, watch } from "vue";
import { donateAPI } from "@/apis";
const props = defineProps({ const props = defineProps({
src: { show: {
type: String, type: Boolean,
default: "", default: false,
},
onClose: {
type: Function,
default: null,
}, },
}); });
const amounts = [5, 20, 50, 80, 100, 200]; const amounts = [5, 20, 50, 80, 100, 200];
@@ -16,9 +23,48 @@ const formData = reactive({
suggestion: "", suggestion: "",
}); });
const onPay = (index) => { const onPay = async (index) => {
selected.value = index; selected.value = index;
const result = await donateAPI(
0.01,
formData.name,
formData.account,
formData.organization,
formData.suggestion
);
const params = result.order.jsApi.params;
if (params) {
wx.requestPayment({
timeStamp: params.timeStamp,
nonceStr: params.nonceStr,
package: params.package,
paySign: params.paySign,
signType: "RSA",
async success(res) {
uni.showToast({
title: "感谢您的支持!",
icon: "none",
});
props.onClose();
},
fail(res) {
console.log("pay error", res);
uni.showToast({
title: "取消支付",
icon: "none",
});
props.onClose();
},
});
}
}; };
watch(
() => props.show,
() => {
selected.value = null;
}
);
</script> </script>
<template> <template>
@@ -105,11 +151,12 @@ const onPay = (index) => {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
margin-top: 20rpx;
} }
.container > view:nth-child(3) > image { .container > view:nth-child(3) > image {
width: 32rpx; width: 32rpx;
height: 32rpx; height: 32rpx;
margin-right: 10rpx; margin: 0 10rpx;
} }
.container > view:nth-child(3) > text { .container > view:nth-child(3) > text {
font-size: 24rpx; font-size: 24rpx;
@@ -139,7 +186,7 @@ const onPay = (index) => {
border: 1rpx solid #fed848; border: 1rpx solid #fed848;
height: 40rpx; height: 40rpx;
line-height: 40rpx; line-height: 40rpx;
padding: 10rpx; padding: 10rpx 20rpx;
font-size: 30rpx; font-size: 30rpx;
margin-right: 10rpx; margin-right: 10rpx;
} }
@@ -149,7 +196,7 @@ const onPay = (index) => {
border: 1rpx solid #fed848; border: 1rpx solid #fed848;
height: 100rpx; height: 100rpx;
line-height: 40rpx; line-height: 40rpx;
padding: 10rpx; padding: 10rpx 20rpx;
font-size: 30rpx; font-size: 30rpx;
margin-right: 10rpx; margin-right: 10rpx;
} }

View File

@@ -1,5 +1,5 @@
<script setup> <script setup>
import { ref, computed, onMounted, onBeforeUnmount } from "vue"; import { ref, computed, onMounted, onBeforeUnmount, watch } from "vue";
import { onShow, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app"; import { onShow, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
import Container from "@/components/Container.vue"; import Container from "@/components/Container.vue";
import PointRecord from "@/components/PointRecord.vue"; import PointRecord from "@/components/PointRecord.vue";
@@ -32,7 +32,6 @@ const isIOS = computed(() => {
const showModal = ref(false); const showModal = ref(false);
const showTip = ref(false); const showTip = ref(false);
const data = ref({ const data = ref({
yellowRate: 0,
weeksCheckIn: [], weeksCheckIn: [],
}); });
@@ -45,7 +44,21 @@ const toListPage = () => {
}); });
}; };
onShow(async () => { const onSignin = () => {
showModal.value = true;
};
const startScoring = () => {
if (user.value.id) {
uni.navigateTo({
url: "/pages/point-book-create",
});
} else {
showModal.value = true;
}
};
const loadData = async () => {
const result = await getPointBookListAPI(1); const result = await getPointBookListAPI(1);
list.value = result.slice(0, 3); list.value = result.slice(0, 3);
const result2 = await getPointBookStatisticsAPI(); const result2 = await getPointBookStatisticsAPI();
@@ -61,21 +74,18 @@ onShow(async () => {
setTimeout(() => { setTimeout(() => {
drawHeatMap(rect.width, rect.height, result2.weekArrows); drawHeatMap(rect.width, rect.height, result2.weekArrows);
}, 500); }, 500);
});
const onSignin = () => {
showModal.value = true;
}; };
const startScoring = () => { watch(
if (user.value.id) { () => user.value.id,
uni.navigateTo({ (id) => {
url: "/pages/point-book-create", if (id) loadData();
});
} else {
showModal.value = true;
} }
}; );
onShow(async () => {
if (user.value.id) loadData();
});
onMounted(async () => { onMounted(async () => {
uni.$on("point-book-signin", onSignin); uni.$on("point-book-signin", onSignin);
@@ -188,23 +198,27 @@ onShareTimeline(() => {
</view> </view>
<view class="statistics"> <view class="statistics">
<view> <view>
<text>{{ data.todayTotalArrow }}</text> <text>{{ data.todayTotalArrow || "-" }}</text>
<text>今日射箭</text> <text>今日射箭</text>
</view> </view>
<view> <view>
<text>{{ data.totalArrow }}</text> <text>{{ data.totalArrow || "-" }}</text>
<text>累计射箭</text> <text>累计射箭</text>
</view> </view>
<view> <view>
<text>{{ data.totalDay }}</text> <text>{{ data.totalDay || "-" }}</text>
<text>已训练天数</text> <text>已训练天数</text>
</view> </view>
<view> <view>
<text>{{ data.averageRing }}</text> <text>{{ data.averageRing || "-" }}</text>
<text>平均环数</text> <text>平均环数</text>
</view> </view>
<view> <view>
<text>{{ Number(data.yellowRate * 100).toFixed(2) }}</text> <text>{{
data.yellowRate !== undefined
? Number(data.yellowRate * 100).toFixed(2)
: "-"
}}</text>
<text>黄心率%</text> <text>黄心率%</text>
</view> </view>
<view> <view>
@@ -229,7 +243,7 @@ onShareTimeline(() => {
</button> </button>
</view> </view>
<RingBarChart :data="data.ringRate" /> <RingBarChart :data="data.ringRate" />
<view class="title"> <view class="title" v-if="user.id">
<image src="../static/point-book-title2.png" mode="widthFix" /> <image src="../static/point-book-title2.png" mode="widthFix" />
</view> </view>
<block v-for="(item, index) in list" :key="index"> <block v-for="(item, index) in list" :key="index">
@@ -249,7 +263,7 @@ onShareTimeline(() => {
<Signin :onClose="() => (showModal = false)" :noBg="true" /> <Signin :onClose="() => (showModal = false)" :noBg="true" />
</SModal> </SModal>
<ScreenHint2 :show="showTip" :onClose="() => (showTip = false)"> <ScreenHint2 :show="showTip" :onClose="() => (showTip = false)">
<RewardUs /> <RewardUs :show="showTip" :onClose="() => (showTip = false)" />
</ScreenHint2> </ScreenHint2>
</Container> </Container>
</template> </template>