Ver código fonte

feat/offline-activity(cycling-rankings): 优化骑行排行榜页面

- 添加筛选功能,可按活动筛选排行榜
- 增加用户自身排名和累计里程显示
- 优化排行榜前三名展示效果
- 调整页面布局和样式
EvilDragon 2 meses atrás
pai
commit
e1fc595f13

+ 2 - 1
packages/app/src/components/bottom-app-bar.vue

@@ -7,6 +7,7 @@ const props = defineProps<{
   placeholder?: boolean
   border?: boolean
   transparent?: boolean
+  customClass?: string
 }>()
 
 const { proxy } = getCurrentInstance() as any
@@ -45,7 +46,7 @@ onMounted(async () => {
         border ? 'border-t border-t-solid border-[#ececec]' : '',
       ]"
     >
-      <div class="px-3.5 py-2.5" :class="[transparent ? '' : 'bg-white']">
+      <div class="px-3.5 py-2.5" :class="[transparent ? '' : 'bg-white', customClass]">
         <div class=""><slot></slot></div>
       </div>
       <div

+ 3 - 2
packages/app/src/components/page-helper-evo.vue

@@ -8,8 +8,9 @@ const props = withDefaults(
     request: (query: any) => Promise<IResData<R>>
     query?: Partial<Q> & { [key: symbol]: any }
     automatic?: boolean
+    isLoadMore?: boolean
   }>(),
-  { automatic: true, query: () => ({}) },
+  { automatic: true, isLoadMore: true, query: () => ({}) },
 )
 const slot = defineSlots<{
   default(props: { data?: R['list']; items?: T[]; source?: R }): any
@@ -56,7 +57,7 @@ watch(
 )
 onReachBottom(async () => {
   console.log('Page Helper Reach Bottom')
-
+  if (!props.isLoadMore) return
   if (data.value?.list?.length < pageSize.value) {
     return (nomore.value = true)
   }

+ 3 - 0
packages/app/src/core/libs/net-images.ts

@@ -15,4 +15,7 @@ export enum NetImages {
   HonorsLogo = 'https://image.zhuchaohui.com/zhucaohui/109805f7e6a8866e6484eea793de572e97cde85c5d65a2f514cf66aacc41609d.svg',
   WechatChannelsGuide = 'https://image.zhuchaohui.com/zhucaohui/4127d21eb75ab479b89f566f0d9479664d595091098acedf0ec29d696a60d034.png',
   VideoTutorial = '',
+  RankingOne = 'https://image.zhuchaohui.com/zhucaohui/5743d060b96571f4540adf66b1f40ed8f0c313d721ce0932d06227b4e31e6a48.svg',
+  RankingTwo = 'https://image.zhuchaohui.com/zhucaohui/2709798b4445b57e349b8e244825885983bf634e2b7f3706f181912753e2d567.svg',
+  RankingThree = 'https://image.zhuchaohui.com/zhucaohui/d70fae2ba6688e0e82bfc1025f2005432de2dc1a1353eddb0da061245b37d970.svg',
 }

+ 129 - 14
packages/app/src/pages/home/offline-activity/cycling-rankings/index.vue

@@ -4,10 +4,24 @@
 <script setup lang="ts">
 import NavbarEvo from '@/components/navbar-evo.vue'
 import { NetImages } from '../../../../core/libs/net-images'
-import { getRidings } from '../../../../core/libs/requests'
+import { getRidingOptions, getRidings } from '../../../../core/libs/requests'
 import PageHelperEvo from '@/components/page-helper-evo.vue'
+import dayjs from 'dayjs'
+import BottomAppBar from '@/components/bottom-app-bar.vue'
+import { useUserStore } from '@/store'
+import { storeToRefs } from 'pinia'
 
+const userStore = useUserStore()
+const { userInfo } = storeToRefs(userStore)
+const current = ref('')
 // const { data, run } = useRequest(() => ({}), { initialData: [] })
+const { data: ridingOptions, run: setRidingOptions } = useRequest(() => getRidingOptions(), {
+  initialData: [],
+})
+const query = computed(() => (current.value ? { activityId: current.value } : {}))
+onLoad(async () => {
+  await setRidingOptions()
+})
 onShareAppMessage(() => ({
   title: '骑行排行榜',
 }))
@@ -18,20 +32,53 @@ onShareTimeline(() => ({
 <template>
   <div class="flex-grow flex flex-col bg-[length:100%]">
     <NavbarEvo transparent dark title="骑行榜"></NavbarEvo>
-    <div class="aspect-[1.19/1]">
+    <div class="aspect-[1.19/1] relative">
       <wd-img
         width="100%"
         custom-class="vertical-bottom"
         mode="widthFix"
         :src="NetImages.CyclingRankingsHeaderBg"
       ></wd-img>
+      <div class="absolute bottom-60 left-7.25">
+        <wd-picker
+          v-model="current"
+          :columns="[
+            { label: '全部', value: '' },
+            ...ridingOptions.map((it) => ({ label: it.name, value: it.id })),
+          ]"
+          use-default-slot
+        >
+          <div class="text-[white] text-sm font-normal font-['PingFang_SC'] leading-relaxed">
+            <!--          {{ dayjs(year).format('YYYY') }}-->
+            {{ ridingOptions.find((it) => it.id === current)?.name ?? '全部' }}
+            <wd-icon name="arrow-down" size="12" class="text-[#ffffff]"></wd-icon>
+          </div>
+        </wd-picker>
+      </div>
     </div>
-    <PageHelperEvo class="flex-grow flex flex-col" :request="getRidings" :query="{}">
+    <PageHelperEvo
+      class="flex-grow flex flex-col"
+      :request="getRidings"
+      :is-load-more="false"
+      :query="query"
+    >
       <template #default="{ source }">
         <div class="flex-grow relative bg-[linear-gradient(180deg,#EFEFEF_0.4%,#FFF_21.41%)]">
           <div class="absolute h-4 top--4 left-0 right-0 bg-[#EFEFEF] rounded-t-2xl"></div>
           <div class="flex justify-between">
-            <template v-for="(it, i) in source.list.slice(0, 3)" :key="i">
+            <template
+              v-for="(it, i) in [
+                ...source.list.slice(0, 3),
+                ...Array.from({
+                  length: source?.list?.length < 3 ? 3 - source?.list?.length : 0,
+                }).map(() => ({
+                  radeKmTotal: '0',
+                  avatar: '',
+                  memberStylistName: '暂无',
+                })),
+              ]"
+              :key="i"
+            >
               <div
                 class="flex-1 py-2 relative"
                 :class="`${i === 0 ? 'w-[143px] h-[141px] bg-white rounded-xl relative bottom-8 pt-4 order-1 ' : ''}`"
@@ -49,14 +96,32 @@ onShareTimeline(() => ({
                 >
                   骑行里程km
                 </div>
-                <div class="absolute top--30 left-0 right-0 flex flex-col items-center gap-2">
-                  <wd-img
-                    class="rounded-full border-2 border-solid border-[#c5cdd4] overflow-hidden"
-                    width="71"
-                    height="71"
-                    round
-                    :src="it.avatar"
-                  ></wd-img>
+                <div class="absolute top--34 left-0 right-0 flex flex-col items-center gap-2">
+                  <div class="relative">
+                    <wd-img
+                      class="rounded-full border-2 border-solid border-[#c5cdd4] overflow-hidden"
+                      width="71"
+                      height="71"
+                      round
+                      :src="it.avatar || NetImages.DefaultAvatar"
+                    ></wd-img>
+                    <div
+                      class="absolute left-0"
+                      :class="{ 0: 'top--5', 1: 'top--0', 2: 'top--0' }[i]"
+                    >
+                      <wd-img
+                        width="76"
+                        mode="widthFix"
+                        :src="
+                          {
+                            0: NetImages.RankingOne,
+                            1: NetImages.RankingTwo,
+                            2: NetImages.RankingThree,
+                          }[i]
+                        "
+                      ></wd-img>
+                    </div>
+                  </div>
                   <div
                     class="text-center text-white text-base font-normal font-['PingFang_SC'] leading-relaxed"
                   >
@@ -67,7 +132,7 @@ onShareTimeline(() => ({
               </div>
             </template>
           </div>
-          <div class="flex flex-col gap-8 mt--10">
+          <div class="flex flex-col gap-8 mt--14">
             <template v-for="(it, i) in source.list" :key="i">
               <div v-if="i > 2" class="flex items-center gap-2 px-7">
                 <div
@@ -75,7 +140,11 @@ onShareTimeline(() => ({
                 >
                   {{ i < 9 ? '0' + (i + 1) : i + 1 }}
                 </div>
-                <wd-img class="w-8 h-8 rounded-full" round :src="it.avatar" />
+                <wd-img
+                  class="w-8 h-8 rounded-full"
+                  round
+                  :src="it.avatar || NetImages.DefaultAvatar"
+                />
                 <div
                   class="text-center text-black/80 text-sm font-normal font-['PingFang_SC'] leading-relaxed"
                 >
@@ -98,6 +167,52 @@ onShareTimeline(() => ({
             </template>
           </div>
         </div>
+        <BottomAppBar fixed placeholder custom-class="p-0!">
+          <div class="bg-gradient-to-b from-neutral-100 to-white shadow-inner">
+            <div class="py-3 flex items-center gap-2 px-7">
+              <div
+                class="text-center w-8 text-black/40 text-base font-bold font-['DIN'] leading-relaxed"
+              >
+                <!--            {{ i < 9 ? '0' + (i + 1) : i + 1 }}-->
+                {{
+                  source.list.findIndex((it) => it.memberStylistName === userInfo.nickname) === -1
+                    ? '-'
+                    : source.list.findIndex((it) => it.memberStylistName === userInfo.nickname) +
+                          1 <
+                        9
+                      ? '0' +
+                        (source.list.findIndex((it) => it.memberStylistName === userInfo.nickname) +
+                          1)
+                      : source.list.findIndex((it) => it.memberStylistName === userInfo.nickname) +
+                        1
+                }}
+              </div>
+              <wd-img class="w-12 h-12 rounded-full" round :src="userInfo.avatar" />
+              <div
+                class="text-center text-black/80 text-sm font-normal font-['PingFang_SC'] leading-relaxed"
+              >
+                {{ userInfo.nickname ?? NetImages.DefaultAvatar }}
+              </div>
+              <div class="flex-1"></div>
+              <div>
+                <div
+                  class="text-center text-black/80 text-xl font-bold font-['D-DIN'] leading-relaxed"
+                >
+                  <!--              {{ it.radeKmTotal }}-->
+                  {{
+                    source.list.find((it) => it.memberStylistName === userInfo.nickname)
+                      ?.radeKmTotal ?? 0
+                  }}
+                </div>
+                <div
+                  class="text-center text-black/40 text-[10px] font-normal font-['PingFang_SC'] leading-relaxed"
+                >
+                  累计里程km
+                </div>
+              </div>
+            </div>
+          </div>
+        </BottomAppBar>
       </template>
     </PageHelperEvo>
   </div>