feat(recharge): add points recharge agreement flow
- add new API request for fetching points top up agreement content - update recharge footer with agreement checkbox and protocol link - add agreement popup modal to display full agreement text - add payment pre-validation to enforce agreement acceptance before payment - handle loading and error states for agreement retrieval - adjust recharge footer layout to accommodate new UI elements
This commit is contained in:
@@ -32,9 +32,20 @@
|
||||
<RechargeFooter
|
||||
:price="payPrice"
|
||||
:loading="paying"
|
||||
:agreed="agreementAccepted"
|
||||
:agreement-ready="agreementReady"
|
||||
@update:agreed="agreementAccepted = $event"
|
||||
@view-agreement="handleViewAgreement"
|
||||
@pay="handlePay"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<AgreePopup
|
||||
:visible="agreementVisible"
|
||||
title="积分充值协议"
|
||||
:agreement="agreementContent"
|
||||
@close="agreementVisible = false"
|
||||
/>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -43,7 +54,12 @@ import { computed, ref } from "vue";
|
||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||
import TopNavBar from "@/components/TopNavBar/index.vue";
|
||||
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
||||
import { getRechargeOptions, rechargeCredit } from "@/request/api/AigcApi.js";
|
||||
import {
|
||||
getPointsTopUpAgreement,
|
||||
getRechargeOptions,
|
||||
rechargeCredit,
|
||||
} from "@/request/api/AigcApi.js";
|
||||
import AgreePopup from "@/pages/login/components/AgreePopup/index.vue";
|
||||
import BalanceCard from "./components/BalanceCard/index.vue";
|
||||
import CustomAmountCard from "./components/CustomAmountCard/index.vue";
|
||||
import RechargeFooter from "./components/RechargeFooter/index.vue";
|
||||
@@ -55,6 +71,12 @@ const selectedRechargeOption = ref(null);
|
||||
const customAmount = ref("");
|
||||
const rechargeMode = ref("package");
|
||||
const paying = ref(false);
|
||||
const agreementAccepted = ref(false);
|
||||
const agreementContent = ref("");
|
||||
const agreementLoading = ref(false);
|
||||
const agreementVisible = ref(false);
|
||||
|
||||
const agreementReady = computed(() => Boolean(agreementContent.value.trim()));
|
||||
|
||||
const getRechargeOptionKey = (option) => {
|
||||
if (!option) return "";
|
||||
@@ -97,8 +119,41 @@ const fetchRechargeOptions = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
const fetchPointsTopUpAgreement = async (showError = false) => {
|
||||
if (agreementLoading.value) return false;
|
||||
|
||||
agreementLoading.value = true;
|
||||
try {
|
||||
const res = await getPointsTopUpAgreement();
|
||||
const content = typeof res?.data === "string" ? res.data.trim() : "";
|
||||
if (res?.code === 0 && content) {
|
||||
agreementContent.value = content;
|
||||
return true;
|
||||
}
|
||||
|
||||
agreementContent.value = "";
|
||||
agreementAccepted.value = false;
|
||||
if (showError) {
|
||||
showToast(res?.msg || "协议加载失败,请重试");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("获取积分充值协议失败", error);
|
||||
agreementContent.value = "";
|
||||
agreementAccepted.value = false;
|
||||
if (showError) {
|
||||
showToast("协议加载失败,请重试");
|
||||
}
|
||||
} finally {
|
||||
agreementLoading.value = false;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
onLoad(() => {
|
||||
agreementAccepted.value = false;
|
||||
fetchRechargeOptions();
|
||||
fetchPointsTopUpAgreement();
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
@@ -129,6 +184,23 @@ const handleSelectCustomAmount = () => {
|
||||
selectedRechargeOption.value = null;
|
||||
};
|
||||
|
||||
const handleViewAgreement = async () => {
|
||||
if (agreementReady.value) {
|
||||
agreementVisible.value = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (agreementLoading.value) {
|
||||
showToast("协议加载中,请稍候");
|
||||
return;
|
||||
}
|
||||
|
||||
const loaded = await fetchPointsTopUpAgreement(true);
|
||||
if (loaded) {
|
||||
agreementVisible.value = true;
|
||||
}
|
||||
};
|
||||
|
||||
const requestWechatPay = (payData) => {
|
||||
const { nonceStr, packageVal, paySign, signType, timeStamp } = payData || {};
|
||||
|
||||
@@ -174,6 +246,21 @@ const handlePay = async () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (agreementLoading.value) {
|
||||
showToast("协议加载中,请稍候");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!agreementReady.value) {
|
||||
showToast("协议加载失败,请重试");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!agreementAccepted.value) {
|
||||
showToast("请先阅读并同意积分充值协议");
|
||||
return;
|
||||
}
|
||||
|
||||
paying.value = true;
|
||||
uni.showLoading({ title: "正在发起支付..." });
|
||||
|
||||
|
||||
Reference in New Issue
Block a user