| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308 |
- <template>
- <FlexCol :gap="20" :padding="30" :innerStyle="{
- marginTop: '-130px',
- backgroundImage: 'url(https://xy.wenlvti.net/app_static/images/home/BannerHome.png)',
- backgroundSize: '100% auto',
- backgroundRepeat: 'no-repeat',
- backgroundPosition: 'top center',
- backgroundColor: themeContext.resolveThemeColor('background.primary'),
- }">
- <FlexCol position="absolute" :left="0" :top="0">
- <StatusBarSpace />
- <Button
- @click="showCityPopup = true"
- icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png"
- :text="currentCity"
- type="custom"
- color="transparent"
- />
- </FlexCol>
- <Height height="200px" />
- <FlexCol :gap="20" align="center">
- <SearchBar v-model="searchKeywords" placeholder="搜索" :innerStyle="{
- backgroundColor: 'white',
- borderRadius: '20rpx',
- borderWidth: '1px',
- borderStyle: 'solid',
- borderColor: themeContext.resolveThemeColor('primary'),
- width: '650rpx',
- }" />
- <Image
- src="https://xy.wenlvti.net/app_static/images/home/BannerIndex.png"
- width="700rpx"
- height="200px"
- mode="aspectFill"
- :innerStyle="{
- borderRadius: '20rpx',
- clipPath: 'ellipse(100% 90% at 50% 0%)'
- }"
- />
- </FlexCol>
- <LightMap
- small
- :city="currentCity"
- :lonlat="currentLocation.currentLonlat.value"
- @getCurrentLonlat="currentLocation.getCurrentExactLocation"
- @selectVillage="goDetails"
- @regionChanged="currentRegion=$event"
- >
- <NoticeBar
- v-if="currentNoticeContent"
- :content="currentNoticeContent"
- :innerStyle="{
- position: 'absolute',
- top: '20rpx',
- left: '20rpx',
- right: '20rpx',
- zIndex: 100,
- borderRadius: '30rpx',
- }"
- :textStyle="{
- fontSize: '26rpx',
- }"
- icon="https://xy.wenlvti.net/app_static/images/home/IconLightActive.png"
- :iconProps="{
- size: 34,
- }"
- textColor="#C9211F"
- backgroundColor="#D9492E10"
- />
- </LightMap>
- <FlexRow justify="space-between" :padding="[10, 16]" gap="gap.md">
- <Button
- icon="https://xy.wenlvti.net/app_static/images/home/IconSwitch.png"
- radius="radius.lg"
- :padding="[10, 30]"
- @click="showCityPopup = true"
- >
- 切换城市
- </Button>
- <Button
- icon="https://xy.wenlvti.net/app_static/images/home/IconFollow.png"
- radius="radius.lg" :padding="[10, 30]"
- @click="showMyFollowPopup = true"
- >
- 我的关注
- </Button>
- <Button
- icon="https://xy.wenlvti.net/app_static/images/home/IconLight.png"
- radius="radius.lg" :padding="[10, 30]"
- @click="navTo('/pages/home/light/submit-map', { city: currentCity })"
- >
- 点亮村社
- </Button>
- </FlexRow>
- <HomeTitle title="乡村排名" showMore @moreClicked="navTo('/pages/home/village/rank/village', {
- regionId: currentRegion ?? undefined,
- })" />
- <VillageRankList :list="villageRankListLoader.content.value ?? []" :jumpToSingle="false" @goDetails="goDetails" />
- <HomeTitle title="志愿者排名" showMore :lightCount="3" @moreClicked="navTo('/pages/home/village/rank/volunteer', {
- regionId: currentRegion ?? undefined,
- })" />
- <VillageUserRankList :list="villageUserRankListLoader.content.value ?? []" />
- <HomeTitle title="精选记忆" showMore />
- <MasonryGrid>
- <MasonryGridItem
- v-for="(item, i) in recommendLoader.list.value"
- :key="i"
- :width="340"
- >
- <IndexCommonImageItem
- :image="item.image"
- :title="item.title"
- :desc="item.desc"
- :userName="item.userName"
- :likes="item.likes"
- :isLike="item.isLike"
- @click="goMessageDetails(item)"
- />
- </MasonryGridItem>
- </MasonryGrid>
- <Loadmore status="nomore" />
- <Height :height="150" />
- <Popup
- v-model:show="showCityPopup"
- closeable
- position="top"
- size="80vh"
- >
- <CitySelect @selectCity="handleSelectCity" />
- </Popup>
- <Popup
- v-model:show="showMyFollowPopup"
- closeable
- position="bottom"
- round
- size="80vh"
- >
- <VillageMyFollow @goDetails="goDetails" />
- </Popup>
- </FlexCol>
- </template>
- <script setup lang="ts">
- import { onMounted, ref, watch } from 'vue';
- import { useTheme } from '@/components/theme/ThemeDefine';
- import { useSimpleDataLoader } from '@/components/composeabe/loader/SimpleDataLoader';
- import { useStorageVar } from '@/components/composeabe/StorageVar';
- import { useVillageStore } from '@/store/village';
- import { useGetCurrentLocation } from './composeabe/GetCurrentLocation';
- import { useSimplePageListLoader } from '@/components/composeabe/loader/SimplePageListLoader';
- import { ArrayUtils, waitTimeOut } from '@imengyu/imengyu-utils';
- import { toast } from '@/components/utils/DialogAction';
- import { navTo } from '@/components/utils/PageAction';
- import Image from '@/components/basic/Image.vue';
- import Loadmore from '@/components/display/loading/Loadmore.vue';
- import FlexCol from '@/components/layout/FlexCol.vue';
- import FlexRow from '@/components/layout/FlexRow.vue';
- import Height from '@/components/layout/space/Height.vue';
- import SearchBar from '@/components/form/SearchBar.vue';
- import Button from '@/components/basic/Button.vue';
- import HomeTitle from '@/common/components/parts/HomeTitle.vue';
- import VillageRankList from './components/VillageRankList.vue';
- import VillageUserRankList from './components/VillageUserRankList.vue';
- import MasonryGrid from '@/components/layout/masonry/MasonryGrid.vue';
- import MasonryGridItem from '@/components/layout/masonry/MasonryGridItem.vue';
- import IndexCommonImageItem from '@/common/components/parts/IndexCommonImageItem.vue';
- import Popup from '@/components/dialog/Popup.vue';
- import CitySelect from './components/CitySelect.vue';
- import VillageMyFollow from './components/VillageMyFollow.vue';
- import MapApi from '@/api/map/MapApi';
- import LightMap from './components/LightMap.vue';
- import NoticeBar from '@/components/display/NoticeBar.vue';
- import StatusBarSpace from '@/components/layout/space/StatusBarSpace.vue';
- import FollowVillageApi from '@/api/light/FollowVillageApi';
- import LightVillageApi, { VillageListItem } from '@/api/light/LightVillageApi';
- import type { CityItem } from '@/api/map/MapApi';
- const emit = defineEmits(['goVillage']);
- const villageStore = useVillageStore();
- const themeContext = useTheme();
- const searchKeywords = ref('');
- const showCityPopup = ref(false);
- const showMyFollowPopup = ref(false);
- const currentRegion = ref<number | null>(null);
- const { value: currentCity } = useStorageVar('currentCityName', '');
- const currentLocation = useGetCurrentLocation({
- onCityChanged: (city) => {
- currentCity.value = city;
- },
- });
- const currentNoticeContent = ref('目前厦门市已被点亮一个社区,刚刚小亮贡献了10个光源,让湖里区点亮了一个社区');
- const villageRankListLoader = useSimpleDataLoader(async () => {
- const res = await LightVillageApi.getVillageRankList({ region_id: currentRegion.value ?? undefined, num: 3 });
- return res.map((item, i) => ({
- image: item.image ?? '',
- title: item.name,
- rank: i + 1,
- id: item.id,
- }));
- });
- const villageUserRankListLoader = useSimpleDataLoader(async () => {
- const res = (await LightVillageApi.getVolunteerRankList({ region_id: currentRegion.value ?? undefined, num: 3 }))
- .map((item, i) => ({
- id: item.id,
- image: item.image ?? '',
- title: item.name,
- rank: i + 1,
- score: item.points,
- }));
- if (res.length >= 3) {
- //移动第一名到中间
- const first = res[0];
- ArrayUtils.removeAt(res, 0);
- ArrayUtils.insert(res, 1, first);
- }
- return res
- });
- const recommendLoader = useSimplePageListLoader(20, async (page, pageSize, params) => {
- const res = await LightVillageApi.getMessages(page, pageSize, params?.keywords ?? '');
- return {
- list: res.data.map((item) => ({
- image: item.image ?? '',
- title: item.title,
- desc: item.content ?? '',
- userName: item.nick_name ?? '',
- likes: item.like_count,
- isLike: false,
- })),
- total: res.total,
- };
- }, true);
- watch(currentRegion, async (newVal) => {
- await villageRankListLoader.reload();
- await villageUserRankListLoader.reload();
- });
- async function goDetails(item: VillageListItem) {
- showMyFollowPopup.value = false;
- const details = await LightVillageApi.getVillageDetails(item.id);
- villageStore.setCurrentVillage(details);
- await waitTimeOut(100);
- emit('goVillage')
- }
- function goMessageDetails(item: any) {
- uni.openOfficialAccountArticle({
- url: item.jump_url,
- fail: (err) => {
- console.error(err);
- },
- })
- }
- async function handleChangedCity(city: string) {
- currentCity.value = city;
- try {
- const res = (await MapApi.simpleGetRegion(city)).requireData();
- currentLocation.currentLonlat.value = {
- longitude: Number(res.center.split(',')[0]),
- latitude: Number(res.center.split(',')[1]),
- };
- console.log('currentLocation.currentLonlat.value', currentLocation.currentLonlat.value);
- } catch (error) {
- console.error(error);
- return;
- }
- }
- function handleSelectCity(city: CityItem) {
- currentCity.value = city.name;
- showCityPopup.value = false;
- handleChangedCity(city.name);
- }
- onMounted(async () => {
- try {
- if (currentCity.value) {
- await currentLocation.setCurrentLocationWithCity(currentCity.value);
- } else {
- await currentLocation.getCurrentFuzzyLocation();
- }
- } catch (error) {
- console.error(error);
- toast('获取当前位置失败,现在显示的是');
- }
- const res = await FollowVillageApi.getFollowVillageList({ page: 1, pageSize: 200 });
- villageStore.setMyFollowVillages(res.list);
- if (res.list.length > 0) {
- const currentVillage = villageStore.loadCurrentVillage();
- if (currentVillage) {
- villageStore.setCurrentVillage(res.list.find(p => p.id === currentVillage) as VillageListItem);
- } else {
- villageStore.setCurrentVillage(res.list[0]);
- }
- }
- });
- </script>
|