快乐的梦鱼 1 天之前
父节点
当前提交
c7e69c3b87

+ 4 - 7
src/api/light/FollowVillageApi.ts

@@ -31,13 +31,10 @@ export class FollowedUserListItem extends DataModel<FollowedUserListItem> {
   gender = 0 as number | null;
   birthday = null as string | null;
   userId = 0 as number | null;
-  followtime = '' as string | null;
-  prevtime = null as Date | null;
-  logintime = null as Date | null;
-  jointime = null as Date | null;
-  prevtimeText = '' as string | null;
-  logintimeText = '' as string | null;
-  jointimeText = '' as string | null;
+  followtime = new Date();
+  prevtime = new Date();
+  logintime = new Date();
+  jointime = new Date();
 }
 
 export class FollowVillageApi extends AppServerRequestModule<DataModel> {

+ 4 - 1
src/components/canvas/MiniRender.ts

@@ -42,7 +42,9 @@ export namespace MiniRender {
     anchorY: number; // 0..1 (relative to height)
   }
 
-  export type RenderObjectEventName = "added" | "removed" | "click" | "touchstart" | "touchmove" | "touchend" | "touchcancel";
+  export type RenderObjectEventName = "added" | "removed" | "click" | 
+    "touchstart" | "touchmove" | "touchend" | "touchcancel" |
+    "animationEnd";
   export type RenderObjectEventHandler = (obj: RenderObject, data?: any) => void;
 
   export class RenderObject implements TransformLike, IRenderable, IUpdatable {
@@ -566,6 +568,7 @@ export namespace MiniRender {
         if (this._frameCursor >= seq.length - 1) {
           this._frameCursor = seq.length - 1;
           this.playing = false;
+          this.emit('animationEnd');
         }
       }
     }

文件差异内容过多而无法显示
+ 54 - 3
src/pages/home/village/components/VillageTree.vue


+ 2 - 0
src/pages/home/village/follow/list.vue

@@ -30,6 +30,7 @@
               <Text :text="item.nickname" fontConfig="contentText" />
             </FlexRow>
             <FlexRow center gap="gap.md">
+              <Text :text="`关注时间:${DateUtils.formatDate(item.followtime, 'YYYY-MM-DD')}`" fontConfig="contentText" />
               <Tag v-if="item.isAdmin" text="管理员" size="small" />
             </FlexRow>
           </BackgroundBox>
@@ -54,6 +55,7 @@ import Touchable from '@/components/feedback/Touchable.vue';
 import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
 import SimplePageListLoader from '@/components/loader/SimplePageListLoader.vue';
 import FollowVillageApi from '@/api/light/FollowVillageApi';
+import { DateUtils } from '@imengyu/imengyu-utils';
 
 const { querys } = useLoadQuerys({
   villageId: 0,

+ 2 - 2
src/pages/home/village/introd/card.vue

@@ -79,7 +79,7 @@
         <FlexRow align="center">
           <FlexCol gap="gap.md"> 
             <Text :text="`${villageInfoLoader.content.value?.levelText || '默认级别'}`" fontConfig="secondText" />  
-            <Text :text="`存储空间内存:${villageInfoLoader.content.value?.sizeText || ''}`" fontConfig="secondText" />
+            <Text :text="`存储空间:${villageInfoLoader.content.value?.sizeText || ''}`" :fontSize="22" fontConfig="secondText" />
           </FlexCol>
         </FlexRow>
         <FlexRow align="center" gap="gap.md">
@@ -402,7 +402,7 @@ const villageInfoLoader = useSimpleDataLoader(async () => {
     title: village?.name || '',
     desc: village?.desc || '',
     address: village?.address,
-    sizeText: `${FormatUtils.formatSize(village?.storageUsed || 0)}已用/${FormatUtils.formatSize(village?.storageLimit || 0)}空间`,
+    sizeText: `${FormatUtils.formatSize(village?.storageUsed || 0)}已用/${FormatUtils.formatSize(village?.storageLimit || 0)}`,
     level: village?.level.toString() || '',
     levelText: village?.levelText || '',
     rankText: village?.rank.toString() || '',

+ 70 - 0
src/pages/home/village/introd/components/PopTextAnim.vue

@@ -0,0 +1,70 @@
+<template>
+  <view
+    v-if="visible"
+    class="pop-text-anim"
+    :class="{ 'pop-text-anim--fading': fading }"
+    @transitionend="handleAnimEnd"
+  >
+    <slot />
+  </view>
+</template>
+
+<script setup lang="ts">
+import { ref, watch, nextTick } from 'vue';
+
+const props = defineProps<{
+  show: boolean;
+}>();
+
+const emit = defineEmits<{
+  (e: 'end'): void;
+}>();
+
+const visible = ref(false);
+const fading = ref(false);
+
+let timer: ReturnType<typeof setTimeout> | null = null;
+
+watch(() => props.show, (val) => {
+  if (val) {
+    visible.value = true;
+    fading.value = false;
+    timer = setTimeout(() => {
+      fading.value = true;
+    }, 1000);
+  } else {
+    cleanup();
+  }
+});
+
+function handleAnimEnd() {
+  cleanup();
+  emit('end');
+}
+
+function cleanup() {
+  visible.value = false;
+  fading.value = false;
+  if (timer) {
+    clearTimeout(timer);
+    timer = null;
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.pop-text-anim {
+  position: absolute;
+  top: -100px;
+  left: 50%;
+  transform: translateX(-50%);
+  opacity: 1;
+  transition: top 0.8s ease-in, opacity 0.8s ease-in;
+  pointer-events: none;
+
+  &--fading {
+    top: 0;
+    opacity: 0;
+  }
+}
+</style>

+ 5 - 1
src/pages/home/village/introd/tree.vue

@@ -31,7 +31,8 @@
           />
         </FlexRow>
         <Height height="space.lg" />
-        <FlexRow center gap="gap.md">
+        <FlexRow position="relative" center gap="gap.md" overflow="visible">
+          <PopTextAnim :show="Boolean(popAnimText)" :text="popAnimText" @end="popAnimText = ''" />
           <Icon icon="https://xy.wenlvti.net/app_static/images/village/IconLight.png" :size="50" />
           <Text :text="`乡源光 ${currentVillage?.lightTotal || 0} ${currentVillage.treeName}`" fontConfig="contentText" fontSize="30rpx" color="#E79412" />
         </FlexRow>
@@ -165,6 +166,7 @@ import TreeApi, { type BlessPackageItem, type GrowthLogFeedItem } from '@/api/li
 import SimplePageContentLoader from '@/components/loader/SimplePageContentLoader.vue';
 import BlessBuyDialog from '../dialogs/BlessBuyDialog.vue';
 import BlessSuccessDialog from '../dialogs/BlessSuccessDialog.vue';
+import PopTextAnim from './components/PopTextAnim.vue';
 
 const GROWTH_FEED_COUNT = 6;
 const DEFAULT_AVATAR = 'https://xy.wenlvti.net/app_static/images/village/PlaceholderVolunteerNew.png';
@@ -285,6 +287,8 @@ async function handleBlessPaySuccessRefresh() {
   activityLoader.reload();
 }
 
+const popAnimText = ref('');
+
 function handleFertilize() {
   handlePickOrWaterOrFertilize('fertilize');
 }