|
|
@@ -0,0 +1,163 @@
|
|
|
+
|
|
|
+
|
|
|
+<template>
|
|
|
+ <CommonTopBanner
|
|
|
+ title="购买AI对话次数"
|
|
|
+ showNav
|
|
|
+ :customBack="true"
|
|
|
+ @backPressed="handleBack"
|
|
|
+ >
|
|
|
+ <FlexCol gap="gap.lg" padding="padding.md">
|
|
|
+
|
|
|
+ <template v-if="step === 'choose'">
|
|
|
+ <FlexCol padding="padding.md" center>
|
|
|
+ <Text
|
|
|
+ text="欢迎购买AI对话次数,购买后立即生效,请选择购买套餐"
|
|
|
+ fontConfig="contentText" :fontSize="30" textAlign="center"
|
|
|
+ />
|
|
|
+ </FlexCol>
|
|
|
+
|
|
|
+ <BoxMid
|
|
|
+ v-for="item in loader.content.value" :key="item.id"
|
|
|
+ direction="row" justify="space-between" align="center" gap="gap.md"
|
|
|
+ >
|
|
|
+ <FlexCol width="74%" gap="gap.md">
|
|
|
+ <FlexCol gap="gap.md">
|
|
|
+ <Text :text="item.name" fontConfig="lightImportantTitle" :fontSize="42" />
|
|
|
+ <Text :text="`${item.timeTypeText === '限时' ? `临时 ${item.days} 天管理员` : '永久'}`" :fontSize="32" :color="item.timeTypeText === '永久' ? 'warning' : 'success'" />
|
|
|
+ </FlexCol>
|
|
|
+ </FlexCol>
|
|
|
+ <FlexRow align="center" gap="gap.lg">
|
|
|
+ <Icon icon="https://xy.wenlvti.net/app_static/images/village/IconFruit.png" :size="40" />
|
|
|
+ <Text :text="moneyToFruit(item.price)" fontConfig="lightGoldTitle" :fontSize="40" />
|
|
|
+ <FrameButton primary text="选择" @click="handleChoose(item)" />
|
|
|
+ </FlexRow>
|
|
|
+ </BoxMid>
|
|
|
+
|
|
|
+ </template>
|
|
|
+ <template v-else-if="step === 'pay'">
|
|
|
+
|
|
|
+ <FlexCol padding="padding.md" center>
|
|
|
+ <Text
|
|
|
+ text="请选择您要付款方式"
|
|
|
+ fontConfig="contentText" :fontSize="30" textAlign="center"
|
|
|
+ />
|
|
|
+ </FlexCol>
|
|
|
+
|
|
|
+ <BuyFruitInfo :price="choosedLevel?.price || 0" @pay="handleDirectPay(3)">
|
|
|
+ <template #prepend>
|
|
|
+ <BoxMid direction="row" justify="space-between" align="center" gap="gap.md">
|
|
|
+ <FlexCol width="74%">
|
|
|
+ <Text text="在线支付" fontConfig="lightImportantTitle" :fontSize="42" />
|
|
|
+ <Text text="若乡源果不足,还支持微信线支付方式,立即生效" fontConfig="lightGoldTitle" :fontSize="30" />
|
|
|
+ </FlexCol>
|
|
|
+ <FrameButton primary text="选择" @click="handleDirectPay(1)" />
|
|
|
+ </BoxMid>
|
|
|
+ </template>
|
|
|
+ </BuyFruitInfo>
|
|
|
+ </template>
|
|
|
+ </FlexCol>
|
|
|
+ </CommonTopBanner>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
|
|
|
+import { useRequireLogin } from '@/common/composeabe/RequireLogin';
|
|
|
+import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
|
|
|
+import { ref } from 'vue';
|
|
|
+import { back, backAndCallOnPageBack } from '@/components/utils/PageAction';
|
|
|
+import { showError } from '@/common/composeabe/ErrorDisplay';
|
|
|
+import BoxMid from '@/common/components/box/BoxMid.vue';
|
|
|
+import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
|
|
|
+import FrameButton from '@/common/components/FrameButton.vue';
|
|
|
+import Text from '@/components/basic/Text.vue';
|
|
|
+import FlexCol from '@/components/layout/FlexCol.vue';
|
|
|
+import OfficialApi, { type AiPackageItem } from '@/api/light/OfficialApi';
|
|
|
+import BuyFruitInfo from './components/BuyFruitInfo.vue';
|
|
|
+import FlexRow from '@/components/layout/FlexRow.vue';
|
|
|
+import Icon from '@/components/basic/Icon.vue';
|
|
|
+import { useFruitConversion } from '../../composeabe/FruitConverit';
|
|
|
+import { waitTimeOut } from '@imengyu/imengyu-utils';
|
|
|
+
|
|
|
+const { requireLoginAsync } = useRequireLogin();
|
|
|
+const { moneyToFruit } = useFruitConversion();
|
|
|
+
|
|
|
+function handlePaySuccess() {
|
|
|
+ setTimeout(() => {
|
|
|
+ backAndCallOnPageBack('paySuccessAndRefresh', {});
|
|
|
+ }, 100);
|
|
|
+}
|
|
|
+
|
|
|
+const { querys } = useLoadQuerys({
|
|
|
+ villageId: 0,
|
|
|
+}, () => {
|
|
|
+
|
|
|
+});
|
|
|
+
|
|
|
+const step = ref<'choose' | 'pay'>('choose');
|
|
|
+const choosedLevel = ref<AiPackageItem|null>(null);
|
|
|
+const loader = useSimpleDataLoader(async () => {
|
|
|
+ return (await OfficialApi.getAiPackageList(1, 10)).list;
|
|
|
+})
|
|
|
+
|
|
|
+function handleBack() {
|
|
|
+ if (step.value === 'pay')
|
|
|
+ step.value = 'choose';
|
|
|
+ else
|
|
|
+ back();
|
|
|
+}
|
|
|
+async function handleChoose(level: AiPackageItem) {
|
|
|
+ uni.showLoading({ title: '请稍后...' });
|
|
|
+ step.value = 'pay';
|
|
|
+ choosedLevel.value = level;
|
|
|
+ await waitTimeOut(1000);
|
|
|
+ uni.hideLoading();
|
|
|
+}
|
|
|
+async function handleDirectPay(payType: 1 | 3) {
|
|
|
+ if (!requireLoginAsync('登录后为村社升级,做出你的贡献哦'))
|
|
|
+ return;
|
|
|
+ if (!choosedLevel.value)
|
|
|
+ throw new Error('请选择购买套餐');
|
|
|
+ try {
|
|
|
+ uni.showLoading({ title: '创建订单中...' });
|
|
|
+ const { order: orderInfo, pay: payInfo } = await OfficialApi.payAiPackage(
|
|
|
+ querys.value.villageId,
|
|
|
+ choosedLevel.value.id,
|
|
|
+ payType,
|
|
|
+ );
|
|
|
+ if (payType === 1) {
|
|
|
+ if (!payInfo)
|
|
|
+ throw new Error('支付信息不存在');
|
|
|
+ uni.requestPayment({
|
|
|
+ provider: 'wxpay',
|
|
|
+ appId: payInfo.appId,
|
|
|
+ timeStamp: payInfo.timeStamp,
|
|
|
+ nonceStr: payInfo.nonceStr,
|
|
|
+ package: payInfo.package,
|
|
|
+ signType: payInfo.signType,
|
|
|
+ paySign: payInfo.paySign,
|
|
|
+ success: () => {
|
|
|
+ handlePaySuccess();
|
|
|
+ },
|
|
|
+ fail: (err) => {
|
|
|
+ showError(`支付失败: ${err.errMsg}`);
|
|
|
+ },
|
|
|
+ });
|
|
|
+ } else if (payType === 3) {
|
|
|
+ handlePaySuccess();
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ showError(e);
|
|
|
+ } finally {
|
|
|
+ uni.hideLoading();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+defineExpose({
|
|
|
+ onPageBack(name: string, data: any) {
|
|
|
+ if (name === 'handlePaySuccess') {
|
|
|
+ handlePaySuccess();
|
|
|
+ }
|
|
|
+ },
|
|
|
+});
|
|
|
+</script>
|