|
|
@@ -26,6 +26,18 @@
|
|
|
<Width :width="150" />
|
|
|
</FlexRow>
|
|
|
</FlexCol>
|
|
|
+ <SimpleTransition name="fade" :show="currentScrollTop > 1000" :duration="300">
|
|
|
+ <template #show="{ classNames }">
|
|
|
+ <view
|
|
|
+ :class="['top-nav-fade ',...classNames]"
|
|
|
+ :style="{ backgroundColor: themeContext.resolveThemeColor('background.primary') }"
|
|
|
+ :left="0" :top="0" :right="0" :zIndex="200"
|
|
|
+ >
|
|
|
+ <StatusBarSpace />
|
|
|
+ </view>
|
|
|
+ </template>
|
|
|
+ </SimpleTransition>
|
|
|
+
|
|
|
<Height height="150px" />
|
|
|
<FlexCol :gap="20" align="center">
|
|
|
<FlexRow justify="space-between" align="center" width="100%">
|
|
|
@@ -130,24 +142,98 @@
|
|
|
scoreSuffix="积分"
|
|
|
@goDetails="navTo('/pages/home/village/volunteer/detail', { id: $event.id })"
|
|
|
/>
|
|
|
+ </FlexCol>
|
|
|
|
|
|
- <HomeTitle title="精选记忆">
|
|
|
- <template #right>
|
|
|
- <FrameButton
|
|
|
- size="small"
|
|
|
- icon="https://xy.wenlvti.net/app_static/images/village/IconLargeHistory.png"
|
|
|
- text="我也来写"
|
|
|
- @click="handleGoPublish()"
|
|
|
- />
|
|
|
- </template>
|
|
|
- </HomeTitle>
|
|
|
+ <view class="recommmend-header" :style="stickyStyle">
|
|
|
+ <FlexCol :padding="[0,30]">
|
|
|
+ <HomeTitle title="精选记忆">
|
|
|
+ <template #right>
|
|
|
+ <FrameButton
|
|
|
+ size="small"
|
|
|
+ icon="https://xy.wenlvti.net/app_static/images/village/IconLargeHistory.png"
|
|
|
+ text="我也来写"
|
|
|
+ @click="handleGoPublish()"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </HomeTitle>
|
|
|
+ </FlexCol>
|
|
|
+ <Tabs
|
|
|
+ v-model:currentIndex="recommendTabCurrent"
|
|
|
+ :tabs="recommendTabs"
|
|
|
+ />
|
|
|
+ </view>
|
|
|
|
|
|
- <SimplePageListLoader :loader="recommendLoader">
|
|
|
- <FlexRow justify="space-between" wrap gap="gap.md">
|
|
|
+ <FlexCol padding="padding.md">
|
|
|
+ <SimplePageListLoader v-if="recommendTabCurrent === 0" :loader="recommendLoader">
|
|
|
+ <MasonryGrid :items="recommendLoader.list.value" itemKey="id">
|
|
|
+ <template #default="{ item }">
|
|
|
+ <IndexCommonImageItem
|
|
|
+ :width="354"
|
|
|
+ :image="item.image"
|
|
|
+ :title="item.title"
|
|
|
+ :desc="item.content ?? ''"
|
|
|
+ :userName="item.villageVolunteerName ?? ''"
|
|
|
+ :userAvatar="item.villageVolunteerAvatar"
|
|
|
+ :likes="item.likeNum"
|
|
|
+ :isLike="item.likeType === 1"
|
|
|
+ @click="handleGoRecommendDetails(item)"
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </MasonryGrid>
|
|
|
+ </SimplePageListLoader>
|
|
|
+ <SimplePageListLoader v-else-if="recommendTabCurrent === 1" :loader="goodsLoader">
|
|
|
+ <FlexRow wrap justify="space-around" gap="gap.sm">
|
|
|
+ <BoxMid
|
|
|
+ v-for="good in goodsLoader.list.value" :key="good.id"
|
|
|
+ :innerStyle="{
|
|
|
+ width: 'calc(50% - 70rpx)',
|
|
|
+ }"
|
|
|
+ >
|
|
|
+ <Touchable direction="column" gap="gap.lg" @click="handleGoRecommendDetails(good)">
|
|
|
+ <Image
|
|
|
+ :src="good.image"
|
|
|
+ :radius="20"
|
|
|
+ width="100%"
|
|
|
+ height="300rpx"
|
|
|
+ mode="aspectFill"
|
|
|
+ />
|
|
|
+ <Text :text="good.title" fontConfig="titleText" />
|
|
|
+ <FlexRow align="center" gap="gap.md">
|
|
|
+ <Avatar
|
|
|
+ :src="good.villageVolunteerAvatar"
|
|
|
+ :size="40"
|
|
|
+ defaultAvatar="https://xy.wenlvti.net/app_static/images/mine/DefaultAvatar.png"
|
|
|
+ />
|
|
|
+ <Text :text="`发布人: ${good.villageVolunteerName}`" fontConfig="contentText" />
|
|
|
+ </FlexRow>
|
|
|
+ </Touchable>
|
|
|
+ </BoxMid>
|
|
|
+ <FlexCol v-if="goodsLoader.list.value && goodsLoader.list.value.length % 2 !== 0" width="calc(50%)" />
|
|
|
+ </FlexRow>
|
|
|
+ </SimplePageListLoader>
|
|
|
+ <SimplePageListLoader v-else-if="recommendTabCurrent === 2" :loader="travelLoader">
|
|
|
+ <FlexRow wrap justify="space-between" gap="gap.sm">
|
|
|
<IndexCommonImageItem
|
|
|
- v-for="(item, i) in recommendLoader.list.value"
|
|
|
- :key="i"
|
|
|
- :width="340"
|
|
|
+ v-for="item in travelLoader.list.value" :key="item.id"
|
|
|
+ :width="354"
|
|
|
+ fixHeight
|
|
|
+ :image="item.image"
|
|
|
+ :title="item.title"
|
|
|
+ :desc="item.content ?? ''"
|
|
|
+ :userName="item.villageVolunteerName ?? ''"
|
|
|
+ :userAvatar="item.villageVolunteerAvatar"
|
|
|
+ :likes="item.likeNum"
|
|
|
+ :isLike="item.likeType === 1"
|
|
|
+ @click="handleGoRecommendDetails(item)"
|
|
|
+ />
|
|
|
+ </FlexRow>
|
|
|
+ </SimplePageListLoader>
|
|
|
+ <SimplePageListLoader v-else-if="recommendTabCurrent === 3" :loader="culturalLoader">
|
|
|
+ <FlexRow wrap justify="space-between" gap="gap.sm">
|
|
|
+ <IndexCommonImageItem
|
|
|
+ v-for="item in culturalLoader.list.value" :key="item.id"
|
|
|
+ :width="354"
|
|
|
+ fixHeight
|
|
|
:image="item.image"
|
|
|
:title="item.title"
|
|
|
:desc="item.content ?? ''"
|
|
|
@@ -207,6 +293,7 @@ import { waitTimeOut } from '@imengyu/imengyu-utils';
|
|
|
import { toast, loading, hideLoading, confirm } from '@/components/utils/DialogAction';
|
|
|
import { navTo } from '@/components/utils/PageAction';
|
|
|
import { injectAppConfiguration } from '@/api/system/useAppConfiguration';
|
|
|
+import { CollectableModulesIdMap } from '@/common/data/CollectableModulesIdMap';
|
|
|
import Image from '@/components/basic/Image.vue';
|
|
|
import FlexCol from '@/components/layout/FlexCol.vue';
|
|
|
import FlexRow from '@/components/layout/FlexRow.vue';
|
|
|
@@ -235,7 +322,21 @@ import FrameButton from '@/common/components/FrameButton.vue';
|
|
|
import type { RegionItem } from '@/api/map/RegionApi';
|
|
|
import BubbleTip from '@/components/feedback/BubbleTip.vue';
|
|
|
import BannerApi from '@/api/system/Banner';
|
|
|
+import Tabs from '@/components/nav/Tabs.vue';
|
|
|
+import BoxMid from '@/common/components/box/BoxMid.vue';
|
|
|
+import Touchable from '@/components/feedback/Touchable.vue';
|
|
|
+import Text from '@/components/basic/Text.vue';
|
|
|
+import Avatar from '@/components/display/Avatar.vue';
|
|
|
+import MasonryGrid from '@/components/layout/masonry/MasonryGrid.vue';
|
|
|
+import { DynamicColor, statusBarHeight } from '@/components/theme/ThemeTools';
|
|
|
+import SimpleTransition from '@/components/anim/SimpleTransition.vue';
|
|
|
|
|
|
+const props = defineProps({
|
|
|
+ currentScrollTop: {
|
|
|
+ type: Number,
|
|
|
+ default: 0,
|
|
|
+ },
|
|
|
+});
|
|
|
const emit = defineEmits(['goVillage','goDig']);
|
|
|
const authStore = useAuthStore();
|
|
|
const villageStore = useVillageStore();
|
|
|
@@ -293,10 +394,6 @@ const villageUserRankListLoader = useSimpleDataLoader(async () => {
|
|
|
return res
|
|
|
});
|
|
|
|
|
|
-const recommendLoader = useSimplePageListLoader(20, async (page, pageSize) => {
|
|
|
- return await VillageInfoApi.getListForDiscover(page, pageSize);
|
|
|
-}, true);
|
|
|
-
|
|
|
|
|
|
const showLightTipTimeout = new MemoryTimeOut('LightTip', 1000 * 3600 * 2);//2h
|
|
|
const showLightTip = ref(false);
|
|
|
@@ -309,6 +406,70 @@ function handleCloseLightTip() {
|
|
|
showLightTipTimeout.recordTime();
|
|
|
}
|
|
|
|
|
|
+const recommendTabCurrent = ref(0);
|
|
|
+const recommendTabs = ref([
|
|
|
+ {
|
|
|
+ text: '推荐',
|
|
|
+ value: 0,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '好物',
|
|
|
+ value: 1,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '乡游',
|
|
|
+ value: 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ text: '文化',
|
|
|
+ value: 3,
|
|
|
+ },
|
|
|
+]);
|
|
|
+const recommendLoader = useSimplePageListLoader(20, async (page, pageSize) => {
|
|
|
+ return await VillageInfoApi.getListForDiscover({ page, pageSize });
|
|
|
+}, true);
|
|
|
+const goodsLoader = useSimplePageListLoader(20, async (page, pageSize) => {
|
|
|
+ return await VillageInfoApi.getListForDiscover({
|
|
|
+ page,
|
|
|
+ pageSize,
|
|
|
+ collectModuleId: CollectableModulesIdMap['goods'],
|
|
|
+ });
|
|
|
+}, false);
|
|
|
+const travelLoader = useSimplePageListLoader(20, async (page, pageSize) => {
|
|
|
+ return await VillageInfoApi.getMiltListForDiscover({
|
|
|
+ page,
|
|
|
+ pageSize,
|
|
|
+ collectModuleIds: [
|
|
|
+ CollectableModulesIdMap['travel_guide'],
|
|
|
+ CollectableModulesIdMap['route'],
|
|
|
+ CollectableModulesIdMap['environment'],
|
|
|
+ CollectableModulesIdMap['relic'],
|
|
|
+ CollectableModulesIdMap['spots'],
|
|
|
+
|
|
|
+ ],
|
|
|
+ });
|
|
|
+}, true);
|
|
|
+const culturalLoader = useSimplePageListLoader(20, async (page, pageSize) => {
|
|
|
+ return await VillageInfoApi.getMiltListForDiscover({
|
|
|
+ page,
|
|
|
+ pageSize,
|
|
|
+ collectModuleIds: [
|
|
|
+ CollectableModulesIdMap['cultural'],
|
|
|
+ CollectableModulesIdMap['folk_culture'],
|
|
|
+ CollectableModulesIdMap['story'],
|
|
|
+ ],
|
|
|
+ });
|
|
|
+}, true);
|
|
|
+
|
|
|
+const stickyStyle = themeContext.useThemeStyle({
|
|
|
+ position: 'sticky',
|
|
|
+ top: (statusBarHeight - 10) + 'px',
|
|
|
+ left: 0,
|
|
|
+ right: 0,
|
|
|
+ zIndex: '100',
|
|
|
+ backgroundColor: DynamicColor('background.primary'),
|
|
|
+});
|
|
|
+
|
|
|
function handleGoRecommendDetails(item: CommonInfoModel) {
|
|
|
navTo(`/pages/home/discover/details`, { id: item.id });
|
|
|
}
|
|
|
@@ -431,4 +592,25 @@ defineExpose({
|
|
|
}
|
|
|
}
|
|
|
})
|
|
|
-</script>
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss">
|
|
|
+.top-nav-fade {
|
|
|
+ position: fixed;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ right: 0;
|
|
|
+ z-index: 200;
|
|
|
+ transition: opacity 0.3s ease-in-out;
|
|
|
+
|
|
|
+ &.fade-enter-active,
|
|
|
+ &.fade-leave-active {
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.fade-enter-from,
|
|
|
+ &.fade-leave-to {
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|