|
@@ -10,11 +10,12 @@
|
|
|
}">
|
|
}">
|
|
|
<FlexCol position="absolute" :left="30" :top="0" :right="30">
|
|
<FlexCol position="absolute" :left="30" :top="0" :right="30">
|
|
|
<StatusBarSpace />
|
|
<StatusBarSpace />
|
|
|
- <FlexRow justify="space-between" align="center">
|
|
|
|
|
|
|
+ <FlexRow justify="space-between" align="flex-start">
|
|
|
<Button
|
|
<Button
|
|
|
@click="showCityPopup = true"
|
|
@click="showCityPopup = true"
|
|
|
icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png"
|
|
icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png"
|
|
|
size="medium"
|
|
size="medium"
|
|
|
|
|
+ :radius="40"
|
|
|
:text="currentCity"
|
|
:text="currentCity"
|
|
|
/>
|
|
/>
|
|
|
<Image
|
|
<Image
|
|
@@ -38,24 +39,8 @@
|
|
|
</template>
|
|
</template>
|
|
|
</SimpleTransition>
|
|
</SimpleTransition>
|
|
|
|
|
|
|
|
- <Height height="150px" />
|
|
|
|
|
|
|
+ <Height height="80px" />
|
|
|
<FlexCol :gap="20" align="center">
|
|
<FlexCol :gap="20" align="center">
|
|
|
- <FlexRow justify="space-between" align="center" width="100%">
|
|
|
|
|
- <SearchBar
|
|
|
|
|
- v-model="searchKeywords"
|
|
|
|
|
- placeholder="搜索"
|
|
|
|
|
- :innerStyle="{
|
|
|
|
|
- backgroundColor: 'white',
|
|
|
|
|
- borderRadius: '20rpx',
|
|
|
|
|
- borderWidth: '1px',
|
|
|
|
|
- borderStyle: 'solid',
|
|
|
|
|
- borderColor: themeContext.resolveThemeColor('primary'),
|
|
|
|
|
- width: '630rpx',//490rpx
|
|
|
|
|
- }"
|
|
|
|
|
- @search="handleSearch"
|
|
|
|
|
- />
|
|
|
|
|
- <!-- <Button icon="ai-thinking" @click="handleGoAI" text="问AI" /> -->
|
|
|
|
|
- </FlexRow>
|
|
|
|
|
<ImageSwiper
|
|
<ImageSwiper
|
|
|
:images="bannerLoader.content.value || []"
|
|
:images="bannerLoader.content.value || []"
|
|
|
:height="appConfiguration?.banners.home.height"
|
|
:height="appConfiguration?.banners.home.height"
|
|
@@ -69,6 +54,50 @@
|
|
|
/>
|
|
/>
|
|
|
</FlexCol>
|
|
</FlexCol>
|
|
|
|
|
|
|
|
|
|
+ <FlexRow justify="space-between" align="center" width="100%">
|
|
|
|
|
+ <SearchBar
|
|
|
|
|
+ v-model="searchKeywords"
|
|
|
|
|
+ placeholder="搜索村社"
|
|
|
|
|
+ :innerStyle="{
|
|
|
|
|
+ backgroundColor: 'white',
|
|
|
|
|
+ borderRadius: '20rpx',
|
|
|
|
|
+ borderWidth: '1px',
|
|
|
|
|
+ borderStyle: 'solid',
|
|
|
|
|
+ borderColor: themeContext.resolveThemeColor('primary'),
|
|
|
|
|
+ width: '630rpx',//490rpx
|
|
|
|
|
+ }"
|
|
|
|
|
+ @search="handleSearch"
|
|
|
|
|
+ />
|
|
|
|
|
+ <!-- <Button icon="ai-thinking" @click="handleGoAI" text="问AI" /> -->
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+
|
|
|
|
|
+ <HomeTitle title="今日推荐" showMore @moreClicked="emit('goDiscover')" />
|
|
|
|
|
+ <FlexRow gap="gap.lg" align="stretch" justify="space-between">
|
|
|
|
|
+ <Touchable
|
|
|
|
|
+ v-for="item in recommendLoader.content.value"
|
|
|
|
|
+ :key="item.id"
|
|
|
|
|
+ position="relative"
|
|
|
|
|
+ radius="radius.md"
|
|
|
|
|
+ shadow="default"
|
|
|
|
|
+ gap="gap.lg"
|
|
|
|
|
+ direction="row"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ overflow="hidden"
|
|
|
|
|
+ border="1px solid #fff"
|
|
|
|
|
+ :flexShrink="0"
|
|
|
|
|
+ width="48%"
|
|
|
|
|
+ @click="handleGoRecommendDetails(item)"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Image :src="item.image" :width="400" :height="270" />
|
|
|
|
|
+ <FlexCol position="absolute" :inset="{ b: -1, l: -1, r: -1 }" backgroundColor="background.primary" padding="padding.md" gap="gap.md">
|
|
|
|
|
+ <Text fontConfig="contentSpeicalText" fontFamily="SongtiSCBlack" :lines="1" :wrap="false">{{ item.title }}</Text>
|
|
|
|
|
+ <Text fontSize="fontSize.sm" :text="item.desc" :lines="1" :maxWidth="200" />
|
|
|
|
|
+ </FlexCol>
|
|
|
|
|
+ </Touchable>
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+
|
|
|
|
|
+ <Height :height="10" />
|
|
|
|
|
+
|
|
|
<LightMap
|
|
<LightMap
|
|
|
small
|
|
small
|
|
|
:city="currentCity"
|
|
:city="currentCity"
|
|
@@ -107,7 +136,7 @@
|
|
|
radius="radius.lg"
|
|
radius="radius.lg"
|
|
|
:padding="[10, 30]"
|
|
:padding="[10, 30]"
|
|
|
text="切换城市"
|
|
text="切换城市"
|
|
|
- :textProps="{ fontSize: 'fontSize.sm' }"
|
|
|
|
|
|
|
+ :textProps="{ wrap: false }"
|
|
|
@click="showCityPopup = true"
|
|
@click="showCityPopup = true"
|
|
|
/>
|
|
/>
|
|
|
<Button
|
|
<Button
|
|
@@ -115,7 +144,7 @@
|
|
|
radius="radius.lg" :padding="[10, 30]"
|
|
radius="radius.lg" :padding="[10, 30]"
|
|
|
@click="showMyFollowPopup = true"
|
|
@click="showMyFollowPopup = true"
|
|
|
text="我的关注"
|
|
text="我的关注"
|
|
|
- :textProps="{ fontSize: 'fontSize.sm' }"
|
|
|
|
|
|
|
+ :textProps="{ wrap: false }"
|
|
|
/>
|
|
/>
|
|
|
<BubbleTip
|
|
<BubbleTip
|
|
|
v-model:show="showLightTip"
|
|
v-model:show="showLightTip"
|
|
@@ -129,13 +158,72 @@
|
|
|
<Button
|
|
<Button
|
|
|
icon="https://xy.wenlvti.net/app_static/images/home/IconLight.png"
|
|
icon="https://xy.wenlvti.net/app_static/images/home/IconLight.png"
|
|
|
radius="radius.lg" :padding="[10, 30]"
|
|
radius="radius.lg" :padding="[10, 30]"
|
|
|
- :textProps="{ fontSize: 'fontSize.sm' }"
|
|
|
|
|
|
|
+ :textProps="{ wrap: false }"
|
|
|
text="点亮村社"
|
|
text="点亮村社"
|
|
|
@click="handleLightVillage"
|
|
@click="handleLightVillage"
|
|
|
/>
|
|
/>
|
|
|
</BubbleTip>
|
|
</BubbleTip>
|
|
|
</FlexRow>
|
|
</FlexRow>
|
|
|
|
|
|
|
|
|
|
+ <HomeTitle title="今日共建任务" showMore @moreClicked="navTo('/pages/home/village/task/index')" />
|
|
|
|
|
+ <scroll-view scroll-x>
|
|
|
|
|
+ <FlexRow gap="gap.lg" align="stretch">
|
|
|
|
|
+ <Touchable
|
|
|
|
|
+ v-for="item in taskListLoader.content.value"
|
|
|
|
|
+ :key="item.id"
|
|
|
|
|
+ backgroundColor="white"
|
|
|
|
|
+ radius="radius.md"
|
|
|
|
|
+ padding="padding.md"
|
|
|
|
|
+ shadow="default"
|
|
|
|
|
+ gap="gap.lg"
|
|
|
|
|
+ direction="row"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ :flexShrink="0"
|
|
|
|
|
+ :innerStyle="{ minWidth: '400rpx' }"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Icon :icon="item.image || 'space'" :size="100" />
|
|
|
|
|
+ <FlexCol gap="gap.md">
|
|
|
|
|
+ <Text fontConfig="contentSpeicalText" fontFamily="SongtiSCBlack">{{ item.name }}</Text>
|
|
|
|
|
+ <Text fontSize="fontSize.sm" :text="item.desc" :lines="1" :maxWidth="400" />
|
|
|
|
|
+ <Text v-if="item.points > 0" fontConfig="secondText">+{{ item.points }}文化积分</Text>
|
|
|
|
|
+ <FlexRow>
|
|
|
|
|
+ <Button v-if="item.rewardFruit > 0" icon="https://xy.wenlvti.net/app_static/images/village/IconFruit.png" size="mini" :text="`+${item.rewardFruit}乡源果`" />
|
|
|
|
|
+ <Button v-if="item.rewardLight > 0" icon="https://xy.wenlvti.net/app_static/images/village/IconLight.png" size="mini" :text="`+${item.rewardLight}乡源光`" />
|
|
|
|
|
+ <Button v-if="item.rewardWater > 0" icon="https://xy.wenlvti.net/app_static/images/village/IconWatering.png" size="mini" :text="`+${item.rewardWater}浇水次数`" />
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+ </FlexCol>
|
|
|
|
|
+ </Touchable>
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+ </scroll-view>
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+ <HomeTitle title="最新动态" />
|
|
|
|
|
+ <FlexCol gap="gap.lg">
|
|
|
|
|
+ <FlexRow
|
|
|
|
|
+ v-for="item in noticeListLoader.content.value?.slice(0, 3) || [] "
|
|
|
|
|
+ :key="item.item.id"
|
|
|
|
|
+ backgroundColor="background.tertiary"
|
|
|
|
|
+ radius="radius.md"
|
|
|
|
|
+ :padding="[20, 30]"
|
|
|
|
|
+ gap="gap.lg"
|
|
|
|
|
+ align="center"
|
|
|
|
|
+ >
|
|
|
|
|
+ <Avatar
|
|
|
|
|
+ :src="(item.item.avatar as string)"
|
|
|
|
|
+ :size="80"
|
|
|
|
|
+ :round="false"
|
|
|
|
|
+ :radius="10"
|
|
|
|
|
+ />
|
|
|
|
|
+ <FlexCol>
|
|
|
|
|
+ <Text :text="item.item.title" fontConfig="contentText" />
|
|
|
|
|
+ <Text
|
|
|
|
|
+ :text="`来自${item.item.villageName}`"
|
|
|
|
|
+ fontConfig="secondText"
|
|
|
|
|
+ />
|
|
|
|
|
+ </FlexCol>
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+ </FlexCol>
|
|
|
|
|
+
|
|
|
<HomeTitle title="乡村排名" showMore @moreClicked="navTo('/pages/home/village/rank/village', {})" />
|
|
<HomeTitle title="乡村排名" showMore @moreClicked="navTo('/pages/home/village/rank/village', {})" />
|
|
|
<VillageRankList :list="villageRankListLoader.content.value ?? []" :jumpToSingle="false" @goDetails="handleGoVillageDetails" />
|
|
<VillageRankList :list="villageRankListLoader.content.value ?? []" :jumpToSingle="false" @goDetails="handleGoVillageDetails" />
|
|
|
|
|
|
|
@@ -213,7 +301,7 @@ import { useAuthStore } from '@/store/auth';
|
|
|
import { useRequireLogin } from '@/common/composeabe/RequireLogin';
|
|
import { useRequireLogin } from '@/common/composeabe/RequireLogin';
|
|
|
import { useUserTools } from '@/common/composeabe/UserTools';
|
|
import { useUserTools } from '@/common/composeabe/UserTools';
|
|
|
import { useGetNotice } from './village/composeabe/GetNotice';
|
|
import { useGetNotice } from './village/composeabe/GetNotice';
|
|
|
-import { waitTimeOut } from '@imengyu/imengyu-utils';
|
|
|
|
|
|
|
+import { DateUtils, waitTimeOut } from '@imengyu/imengyu-utils';
|
|
|
import { toast, loading, hideLoading, confirm } from '@/components/utils/DialogAction';
|
|
import { toast, loading, hideLoading, confirm } from '@/components/utils/DialogAction';
|
|
|
import { navTo } from '@/components/utils/PageAction';
|
|
import { navTo } from '@/components/utils/PageAction';
|
|
|
import { injectAppConfiguration } from '@/api/system/useAppConfiguration';
|
|
import { injectAppConfiguration } from '@/api/system/useAppConfiguration';
|
|
@@ -237,7 +325,7 @@ import Width from '@/components/layout/space/Width.vue';
|
|
|
import IntroClamTip from './village/dialogs/IntroClamTip.vue';
|
|
import IntroClamTip from './village/dialogs/IntroClamTip.vue';
|
|
|
import MemoryTimeOut from '@/components/composeabe/MemoryTimeOut';
|
|
import MemoryTimeOut from '@/components/composeabe/MemoryTimeOut';
|
|
|
import ImageSwiper from '@/common/components/parts/ImageSwiper.vue';
|
|
import ImageSwiper from '@/common/components/parts/ImageSwiper.vue';
|
|
|
-import { type CommonInfoModel } from '@/api/inhert/VillageInfoApi';
|
|
|
|
|
|
|
+import VillageInfoApi, { type CommonInfoModel } from '@/api/inhert/VillageInfoApi';
|
|
|
import PostIndex from './village/dialogs/PostIndex.vue';
|
|
import PostIndex from './village/dialogs/PostIndex.vue';
|
|
|
import FrameButton from '@/common/components/FrameButton.vue';
|
|
import FrameButton from '@/common/components/FrameButton.vue';
|
|
|
import type { RegionItem } from '@/api/map/RegionApi';
|
|
import type { RegionItem } from '@/api/map/RegionApi';
|
|
@@ -250,6 +338,11 @@ import RecommendTab from './recommend/RecommendTab.vue';
|
|
|
import GoodsTab from './recommend/GoodsTab.vue';
|
|
import GoodsTab from './recommend/GoodsTab.vue';
|
|
|
import TravelTab from './recommend/TravelTab.vue';
|
|
import TravelTab from './recommend/TravelTab.vue';
|
|
|
import CulturalTab from './recommend/CulturalTab.vue';
|
|
import CulturalTab from './recommend/CulturalTab.vue';
|
|
|
|
|
+import Avatar from '@/components/display/Avatar.vue';
|
|
|
|
|
+import Text from '@/components/basic/Text.vue';
|
|
|
|
|
+import TreeApi from '@/api/light/TreeApi';
|
|
|
|
|
+import Touchable from '@/components/feedback/Touchable.vue';
|
|
|
|
|
+import Icon from '@/components/basic/Icon.vue';
|
|
|
|
|
|
|
|
const props = defineProps({
|
|
const props = defineProps({
|
|
|
currentScrollTop: {
|
|
currentScrollTop: {
|
|
@@ -257,7 +350,7 @@ const props = defineProps({
|
|
|
default: 0,
|
|
default: 0,
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
|
-const emit = defineEmits(['goVillage','goDig']);
|
|
|
|
|
|
|
+const emit = defineEmits(['goVillage','goDig','goDiscover']);
|
|
|
const authStore = useAuthStore();
|
|
const authStore = useAuthStore();
|
|
|
const villageStore = useVillageStore();
|
|
const villageStore = useVillageStore();
|
|
|
const themeContext = useTheme();
|
|
const themeContext = useTheme();
|
|
@@ -282,7 +375,7 @@ const currentLocation = useGetCurrentLocation({
|
|
|
},
|
|
},
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const { currentNoticeContent } = useGetNotice();
|
|
|
|
|
|
|
+const { currentNoticeContent, noticeListLoader } = useGetNotice();
|
|
|
|
|
|
|
|
const bannerLoader = useSimpleDataLoader(async () => {
|
|
const bannerLoader = useSimpleDataLoader(async () => {
|
|
|
return (await BannerApi.getBannerList({
|
|
return (await BannerApi.getBannerList({
|
|
@@ -313,7 +406,15 @@ const villageUserRankListLoader = useSimpleDataLoader(async () => {
|
|
|
}));
|
|
}));
|
|
|
return res
|
|
return res
|
|
|
});
|
|
});
|
|
|
-
|
|
|
|
|
|
|
+const taskListLoader = useSimpleDataLoader(async () => {
|
|
|
|
|
+ return (await TreeApi.getTaskList({
|
|
|
|
|
+ page: 1,
|
|
|
|
|
+ pageSize: 5,
|
|
|
|
|
+ })).list;
|
|
|
|
|
+});
|
|
|
|
|
+const recommendLoader = useSimpleDataLoader(async () => {
|
|
|
|
|
+ return (await VillageInfoApi.getListForDiscover({ page: 1, pageSize: 2 })).list;
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
const showLightTipTimeout = new MemoryTimeOut('LightTip', 1000 * 3600 * 2);//2h
|
|
const showLightTipTimeout = new MemoryTimeOut('LightTip', 1000 * 3600 * 2);//2h
|
|
|
const showLightTip = ref(false);
|
|
const showLightTip = ref(false);
|