feat(recharge): add recharge package selection flow

- add new getRechargeOptions API endpoint in AigcApi
- replace CustomAmountCard with RechargePackageList component
- implement fetching and selection logic for recharge packages
- update UI to use correct recharge data fields
- add validation for selected recharge option
This commit is contained in:
duanshuwen
2026-07-13 10:27:03 +08:00
parent cadddb5c3f
commit 29bf6afe55
3 changed files with 58 additions and 15 deletions

View File

@@ -5,16 +5,16 @@
<view class="package-list"> <view class="package-list">
<view <view
v-for="item in packages" v-for="item in packages"
:key="item.id" :key="getPackageKey(item)"
:class="['package-card', { 'is-selected': item.id === selectedId }]" :class="['package-card', { 'is-selected': getPackageKey(item) === selectedKey }]"
@tap="emit('select', item)" @tap="emit('select', item)"
> >
<view class="package-copy"> <view class="package-copy">
<text class="package-points">{{ item.points }}积分</text> <text class="package-points">{{ item.rechargePoints }}积分</text>
<text class="package-origin">原价 ¥{{ item.originalPrice }} · {{ item.discount }}</text> <text class="package-origin">充值金额</text>
</view> </view>
<text class="package-price">¥{{ formatPrice(item.price) }}</text> <text class="package-price">¥{{ formatPrice(item.rechargeAmount) }}</text>
</view> </view>
</view> </view>
</view> </view>
@@ -26,7 +26,7 @@ defineProps({
type: Array, type: Array,
default: () => [], default: () => [],
}, },
selectedId: { selectedKey: {
type: String, type: String,
default: "", default: "",
}, },
@@ -35,6 +35,8 @@ defineProps({
const emit = defineEmits(["select"]); const emit = defineEmits(["select"]);
const formatPrice = (price) => Number(price).toLocaleString("zh-CN"); const formatPrice = (price) => Number(price).toLocaleString("zh-CN");
const getPackageKey = (item) => `${item?.rechargeAmount ?? ""}-${item?.rechargePoints ?? ""}`;
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@@ -17,8 +17,10 @@
@ledger="handleOpenLedger" @ledger="handleOpenLedger"
/> />
<CustomAmountCard <RechargePackageList
v-model="customAmount" :packages="rechargeOptions"
:selected-key="selectedRechargeKey"
@select="handleSelectRechargeOption"
/> />
<RechargeFooter <RechargeFooter
@@ -32,21 +34,30 @@
<script setup> <script setup>
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import { onShow } from "@dcloudio/uni-app"; import { onLoad, onShow } from "@dcloudio/uni-app";
import TopNavBar from "@/components/TopNavBar/index.vue"; import TopNavBar from "@/components/TopNavBar/index.vue";
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js"; import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
import { rechargeCredit } from "@/request/api/AigcApi.js"; import { getRechargeOptions, rechargeCredit } from "@/request/api/AigcApi.js";
import BalanceCard from "./components/BalanceCard/index.vue"; import BalanceCard from "./components/BalanceCard/index.vue";
import CustomAmountCard from "./components/CustomAmountCard/index.vue";
import RechargeFooter from "./components/RechargeFooter/index.vue"; import RechargeFooter from "./components/RechargeFooter/index.vue";
import RechargePackageList from "./components/RechargePackageList/index.vue";
const { pointBalance: balancePoints, fetchCurrentCredit } = useCurrentCredit(); const { pointBalance: balancePoints, fetchCurrentCredit } = useCurrentCredit();
const customAmount = ref("1"); const rechargeOptions = ref([]);
const selectedRechargeOption = ref(null);
const paying = ref(false); const paying = ref(false);
const getRechargeOptionKey = (option) => {
if (!option) return "";
return `${option.rechargeAmount ?? ""}-${option.rechargePoints ?? ""}`;
};
const selectedRechargeKey = computed(() => getRechargeOptionKey(selectedRechargeOption.value));
const payPrice = computed(() => { const payPrice = computed(() => {
const amount = Number.parseInt(customAmount.value || "0", 10); const amount = Number(selectedRechargeOption.value?.rechargeAmount);
return Number.isNaN(amount) ? 0 : amount; return Number.isFinite(amount) ? amount : 0;
}); });
const showToast = (title) => { const showToast = (title) => {
@@ -56,6 +67,22 @@ const showToast = (title) => {
}); });
}; };
const fetchRechargeOptions = async () => {
try {
const res = await getRechargeOptions();
if (res?.code === 0 && Array.isArray(res.data)) {
rechargeOptions.value = res.data;
selectedRechargeOption.value = res.data[0] || null;
}
} catch (error) {
console.error("获取积分充值档位失败", error);
}
};
onLoad(() => {
fetchRechargeOptions();
});
onShow(() => { onShow(() => {
fetchCurrentCredit(); fetchCurrentCredit();
}); });
@@ -74,6 +101,10 @@ const handleOpenLedger = () => {
}); });
}; };
const handleSelectRechargeOption = (option) => {
selectedRechargeOption.value = option;
};
const requestWechatPay = (payData) => { const requestWechatPay = (payData) => {
const { nonceStr, packageVal, paySign, signType, timeStamp } = payData || {}; const { nonceStr, packageVal, paySign, signType, timeStamp } = payData || {};
@@ -107,9 +138,14 @@ const requestWechatPay = (payData) => {
const handlePay = async () => { const handlePay = async () => {
if (paying.value) return; if (paying.value) return;
if (!selectedRechargeOption.value) {
showToast("请选择充值档位");
return;
}
const rechargeAmount = payPrice.value; const rechargeAmount = payPrice.value;
if (!Number.isInteger(rechargeAmount) || rechargeAmount <= 0) { if (!Number.isInteger(rechargeAmount) || rechargeAmount <= 0) {
showToast("请输入正确的充值金额"); showToast("充值档位金额错误,请重试");
return; return;
} }

View File

@@ -20,6 +20,10 @@ function getCurrentCredit() {
return request.get("/hotelBiz/credit/current", {}); return request.get("/hotelBiz/credit/current", {});
} }
function getRechargeOptions() {
return request.get("/hotelBiz/credit/recharge/options", {});
}
function rechargeCredit(args) { function rechargeCredit(args) {
return request.post("/hotelBiz/credit/recharge", args); return request.post("/hotelBiz/credit/recharge", args);
} }
@@ -30,5 +34,6 @@ export {
getAigcGeneratorTaskList, getAigcGeneratorTaskList,
createAigcGeneratorTask, createAigcGeneratorTask,
getCurrentCredit, getCurrentCredit,
getRechargeOptions,
rechargeCredit, rechargeCredit,
}; };