Преглед на файлове

📦 对接赐福购买接口

快乐的梦鱼 преди 1 месец
родител
ревизия
7c9ae38a5b

+ 4 - 1
src/api/light/LightVillageApi.ts

@@ -179,7 +179,10 @@ export class LightVillageApi extends AppServerRequestModule<DataModel> {
       page: page,
       pageSize: pageSize,
     });
-    return transformArrayDataModel<VillageListItem>(VillageListItem, transformSomeToArray(res.requireData().data), `村落`, true);
+    return {
+      total: res.requireData().total,
+      list: transformArrayDataModel<VillageListItem>(VillageListItem, transformSomeToArray(res.requireData().data), `村落`, true)
+    }
   }
   
   async getVillageDetails(id: number) {

+ 41 - 1
src/api/light/TreeApi.ts

@@ -157,6 +157,45 @@ export class BlessOrderItem extends DataModel<BlessOrderItem> {
   statusText = '';
   payTimeText = '';
 }
+export class BlessOrderConfirm extends DataModel<BlessOrderConfirm> {
+  constructor() {
+    super(BlessOrderConfirm, '赐福订单确认');
+    this.setNameMapperCase('Camel', 'Snake');
+    this._convertTable = {
+      order: { 
+        clientSide: 'object', 
+        clientSideChildDataModel: BlessOrderItem, 
+        serverSide: 'undefined', 
+        clientSideRequired: true 
+      },
+      pay: { 
+        clientSide: 'object',
+        clientSideChildDataModel: {
+          convertTable: {
+            appId: { clientSide: 'string', clientSideRequired: true },
+            timeStamp: { clientSide: 'string', clientSideRequired: true },
+            nonceStr: { clientSide: 'string', clientSideRequired: true },
+            package: { clientSide: 'string', clientSideRequired: true },
+            signType: { clientSide: 'string', clientSideRequired: true },
+            paySign: { clientSide: 'string', clientSideRequired: true },
+          }
+        },
+        serverSide: 'undefined',
+        clientSideRequired: true,
+      },
+    };
+  }
+
+  order !: BlessOrderItem;
+  pay !: {
+    appId: string;
+    timeStamp: string;
+    nonceStr: string;
+    package: string;
+    signType: string;
+    paySign: string;
+  };
+}
 
 export class UpgradePackageItem extends DataModel<UpgradePackageItem> {
   constructor() {
@@ -571,7 +610,8 @@ export class TreeApi extends AppServerRequestModule<DataModel> {
       village_id: villageId,
       bless_id: blessId,
     });
-    return transformDataModel<BlessOrderItem>(BlessOrderItem, res.requireData());
+    const data = res.requireData();
+    return transformDataModel<BlessOrderConfirm>(BlessOrderConfirm, data);
   }
 
   /**

+ 25 - 11
src/pages/home/village/bless/my-orders.vue

@@ -1,7 +1,7 @@
 <template>
   <CommonTopBanner title="我的赐福订单">
     <SimplePageListLoader :loader="listLoader" :emptyView="{ text: '冷冷清清,等你来添光加彩' }">
-      <FlexCol gap="gap.md">
+      <FlexCol gap="gap.md" padding="padding.md">
         <BackgroundBox
           v-for="item in listLoader.list.value"
           :key="item.id" 
@@ -21,15 +21,17 @@
             align="center"
           >
             <FlexCol>
-              <Text fontConfig="lightImportantTitle">{{ item.blessName }}</Text>
-              <Text :size="23" :text="`${item.villageName} ${item.addLight}乡源光/${item.addFruit}乡源果`" />
+              <Text fontConfig="lightImportantTitle" fontFamily="SongtiSCBlack">{{ item.blessName }}</Text>
+              <Text :fontSize="23" :text="`${item.villageName} ${item.addLight}乡源光/${item.addFruit}乡源果`" />
             </FlexCol>
-            <FlexCol>
+            <FlexCol align="flex-end">
               <FlexRow align="center" gap="gap.sm">
-                <Text :size="23" fontFamily="SongtiSCBlack">¥</Text>
-                <Text :size="40" fontFamily="SongtiSCBlack">{{ item.amount }}</Text>
+                <Text :fontSize="23" fontConfig="lightGoldTitle">¥</Text>
+                <Text fontConfig="lightGoldTitle">{{ item.amount }}</Text>
+                <Width :width="10" />
+                <Tag size="small" :text="item.statusText" :type="getStatusTypeByStatusText(item.statusText)" />
               </FlexRow>
-              <Text :size="23">{{ item.createtime }}</Text>
+              <Text fontConfig="secondText">{{ item.createtime }}</Text>
             </FlexCol>
           </Touchable>
         </BackgroundBox>
@@ -39,17 +41,19 @@
 </template>
 
 <script setup lang="ts">
+import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
+import { useAuthStore } from '@/store/auth';
+import { useSimplePageListLoader } from '@/components/composeabe/loader/SimplePageListLoader';
 import FlexCol from '@/components/layout/FlexCol.vue';
 import TreeApi from '@/api/light/TreeApi';
 import SimplePageListLoader from '@/components/loader/SimplePageListLoader.vue';
-import { useSimplePageListLoader } from '@/components/composeabe/loader/SimplePageListLoader';
 import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
 import Touchable from '@/components/feedback/Touchable.vue';
 import Text from '@/components/basic/Text.vue';
-import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
-import { useAuthStore } from '@/store/auth';
 import FlexRow from '@/components/layout/FlexRow.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
+import Tag from '@/components/display/Tag.vue';
+import Width from '@/components/layout/space/Width.vue';
 
 const { querys } = useLoadQuerys({
   villageId: 0,
@@ -58,7 +62,7 @@ const { querys } = useLoadQuerys({
 });
 const authStore = useAuthStore();
 
-const listLoader = useSimplePageListLoader(10, async (page, pageSize) => {
+const listLoader = useSimplePageListLoader(20, async (page, pageSize) => {
   if (!querys.value.villageId || !authStore.userId) {
     return {
       list: [],
@@ -77,4 +81,14 @@ const listLoader = useSimplePageListLoader(10, async (page, pageSize) => {
   };
 });
 
+function getStatusTypeByStatusText(statusText: string): 'warning' | 'success' | 'default' {
+  switch (statusText) {
+    case '待支付':
+      return 'warning';
+    case '已支付':
+      return 'success';
+    default:
+      return 'default';
+  }
+}
 </script>

+ 63 - 0
src/pages/home/village/dialogs/BlessSuccessDialog.vue

@@ -0,0 +1,63 @@
+<template>
+  <CommonDialog v-model:show="show">
+    <FlexCol gap="gap.lg" width="600rpx" align="center" :padding="35">
+      <Image
+        src="https://xy.wenlvti.net/app_static/images/home/bless/IconHeader.png"
+        :width="300" 
+        :height="100" 
+      />
+      <Height :height="20" />
+      <Text 
+        textAlign="center" 
+        text="感谢您为村社带来的祝福!"
+        fontConfig="lightGoldTitle"
+      />
+    </FlexCol>
+  </CommonDialog>
+</template>
+
+<script setup lang="ts">
+import type { BlessPackageItem } from '@/api/light/TreeApi';
+import CommonDialog from '@/common/components/CommonDialog.vue';
+import FrameButton from '@/common/components/FrameButton.vue';
+import PrimaryButton from '@/common/components/PrimaryButton.vue';
+import Image from '@/components/basic/Image.vue';
+import Text from '@/components/basic/Text.vue';
+import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
+import FlexCol from '@/components/layout/FlexCol.vue';
+import FlexRow from '@/components/layout/FlexRow.vue';
+import Height from '@/components/layout/space/Height.vue';
+import { DateUtils } from '@imengyu/imengyu-utils';
+import { computed, ref } from 'vue';
+
+const show = ref(false);
+
+const props = defineProps<{
+  currentBless?: BlessPackageItem;
+}>();
+const emit = defineEmits(['buyBless']);
+
+const infoGrids = computed(() => [
+  {
+    label: '村社加乡源光',
+    image: 'https://xy.wenlvti.net/app_static/images/home/bless/IconLight.png',
+    value: props.currentBless?.addLight || 0,
+    unit: '光',
+  },
+  {
+    label: '用户得乡源果',
+    image: 'https://xy.wenlvti.net/app_static/images/home/bless/IconFruit.png',
+    value: props.currentBless?.addFruit || 0,
+    unit: '个',
+  },
+]);
+const effectiveDate = computed(() => {
+  return DateUtils.formatDate(DateUtils.dateAddDays(new Date(), props.currentBless?.days || 0), 'YYYY-MM-DD');
+});
+
+defineExpose({
+  show: () => {
+    show.value = true;
+  },
+});
+</script>

+ 25 - 3
src/pages/home/village/introd/tree.vue

@@ -132,6 +132,9 @@
     :currentBless="currentBless" 
     @buyBless="handleBuyBlessConfirm"
   />
+  <BlessSuccessDialog 
+    ref="blessSuccessDialogRef" 
+  />
 </template>
 
 <script setup lang="ts">
@@ -157,6 +160,7 @@ import Progress from '@/components/display/Progress.vue';
 import TreeApi, { type BlessPackageItem, type GrowthLogFeedItem } from '@/api/light/TreeApi';
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 import BlessBuyDialog from '../dialogs/BlessBuyDialog.vue';
+import BlessSuccessDialog from '../dialogs/BlessSuccessDialog.vue';
 
 const GROWTH_FEED_COUNT = 6;
 const DEFAULT_AVATAR = 'https://xy.wenlvti.net/app_static/images/village/PlaceholderVolunteer.png';
@@ -165,6 +169,7 @@ const villageStore = useVillageStore();
 const { requireLoginAsync } = useRequireLogin();
 
 const blessBuyDialogRef = ref<InstanceType<typeof BlessBuyDialog>>();
+const blessSuccessDialogRef = ref<InstanceType<typeof BlessSuccessDialog>>();
 const villageTreeRef = ref<InstanceType<typeof VillageTree>>();
 const currentBless = ref<BlessPackageItem>();
 
@@ -248,9 +253,26 @@ async function handleBuyBlessConfirm() {
     uni.showLoading({
       title: '请稍后...',
     });
-    const order = await TreeApi.createBlessOrder(villageStore.currentVillage?.id, currentBless.value.id);
-    if (order) {
-      console.log(order);
+    const payInfo = await TreeApi.createBlessOrder(villageStore.currentVillage?.id, currentBless.value.id);
+    if (payInfo) {  
+      uni.requestPayment({
+        provider: 'wxpay',
+        appId: payInfo.pay.appId,
+        timeStamp: payInfo.pay.timeStamp,
+        nonceStr: payInfo.pay.nonceStr,
+        package: payInfo.pay.package,
+        signType: payInfo.pay.signType,
+        paySign: payInfo.pay.paySign,
+        success: () => {
+          blessSuccessDialogRef.value?.show();
+          setTimeout(() => {
+            activityLoader.reload();
+          }, 2000);
+        },
+        fail: (err) => {
+          showError(err);
+        },
+      });
     }
   } catch (error) {
     showError(error);