|
@@ -28,9 +28,7 @@
|
|
|
/>
|
|
/>
|
|
|
</FlexCol>
|
|
</FlexCol>
|
|
|
|
|
|
|
|
- <VillageMiniMap
|
|
|
|
|
- @getedCurrentLonlat="getedCurrentLonlat"
|
|
|
|
|
- />
|
|
|
|
|
|
|
+ <VillageMiniMap />
|
|
|
<FlexRow justify="space-between" :padding="[10, 16]">
|
|
<FlexRow justify="space-between" :padding="[10, 16]">
|
|
|
<Button icon="/static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">切换城市</Button>
|
|
<Button icon="/static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">切换城市</Button>
|
|
|
<Button icon="/static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">我的关注</Button>
|
|
<Button icon="/static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">我的关注</Button>
|
|
@@ -41,12 +39,35 @@
|
|
|
<VillageRankList />
|
|
<VillageRankList />
|
|
|
|
|
|
|
|
<HomeTitle title="志愿者排名" showMore :lightCount="3" />
|
|
<HomeTitle title="志愿者排名" showMore :lightCount="3" />
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ <VillageUserRankList />
|
|
|
|
|
|
|
|
<HomeTitle title="精选记忆" showMore />
|
|
<HomeTitle title="精选记忆" showMore />
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
|
|
+ <MasonryGrid>
|
|
|
|
|
+ <ImageBlock2
|
|
|
|
|
+ v-for="(item, i) in recommendLoader.content.value"
|
|
|
|
|
+ :key="i"
|
|
|
|
|
+ :src="item.image"
|
|
|
|
|
+ :title="item.title"
|
|
|
|
|
+ :desc="item.desc"
|
|
|
|
|
+ :width="340"
|
|
|
|
|
+ :imageWidth="340"
|
|
|
|
|
+ :imageRadius="15"
|
|
|
|
|
+ backgroundColor="transparent"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #footer>
|
|
|
|
|
+ <FlexRow justify="space-between" align="center" :padding="[10,0]" :margin="[10,0,0,0]">
|
|
|
|
|
+ <FlexRow align="center" :gap="10">
|
|
|
|
|
+ <Avatar :url="item.image" :size="40" />
|
|
|
|
|
+ <Text :text="item.userName" :fontSize="24" color="gray" />
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+ <FlexRow align="center" :gap="10">
|
|
|
|
|
+ <Icon icon="favorite" :color="item.isLike ? 'primary' : 'gray'" :size="30" />
|
|
|
|
|
+ <Text :text="item.likes" :fontSize="30" :color="item.isLike ? 'primary' : 'gray'" />
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+ </FlexRow>
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </ImageBlock2>
|
|
|
|
|
+ </MasonryGrid>
|
|
|
|
|
|
|
|
<Loadmore status="nomore" />
|
|
<Loadmore status="nomore" />
|
|
|
<Height :height="150" />
|
|
<Height :height="150" />
|
|
@@ -54,131 +75,42 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { navTo } from '@/components/utils/PageAction';
|
|
|
|
|
-import { goCommonContentDetail, goCommonContentList } from '../article/common/CommonContent';
|
|
|
|
|
|
|
+import { ref } from 'vue';
|
|
|
import { useTheme } from '@/components/theme/ThemeDefine';
|
|
import { useTheme } from '@/components/theme/ThemeDefine';
|
|
|
import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
|
|
import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
|
|
|
-import { ref } from 'vue';
|
|
|
|
|
-import VillageApi from '@/api/inhert/VillageApi';
|
|
|
|
|
-import VillageInfoApi from '@/api/inhert/VillageInfoApi';
|
|
|
|
|
-import Box from '@/common/components/parts/Box.vue';
|
|
|
|
|
-import SimplePageContentLoader from '@/common/components/SimplePageContentLoader.vue';
|
|
|
|
|
-import AppCofig from '@/common/config/AppCofig';
|
|
|
|
|
import Image from '@/components/basic/Image.vue';
|
|
import Image from '@/components/basic/Image.vue';
|
|
|
-import Text from '@/components/basic/Text.vue';
|
|
|
|
|
import Loadmore from '@/components/display/loading/Loadmore.vue';
|
|
import Loadmore from '@/components/display/loading/Loadmore.vue';
|
|
|
-import Touchable from '@/components/feedback/Touchable.vue';
|
|
|
|
|
import FlexCol from '@/components/layout/FlexCol.vue';
|
|
import FlexCol from '@/components/layout/FlexCol.vue';
|
|
|
import FlexRow from '@/components/layout/FlexRow.vue';
|
|
import FlexRow from '@/components/layout/FlexRow.vue';
|
|
|
import Height from '@/components/layout/space/Height.vue';
|
|
import Height from '@/components/layout/space/Height.vue';
|
|
|
-import Width from '@/components/layout/space/Width.vue';
|
|
|
|
|
-import CommonContent, { GetContentListParams } from '@/api/CommonContent';
|
|
|
|
|
-import UnmoveableContent from '@/api/inheritor/UnmoveableContent';
|
|
|
|
|
import SearchBar from '@/components/form/SearchBar.vue';
|
|
import SearchBar from '@/components/form/SearchBar.vue';
|
|
|
import VillageMiniMap from './components/VillageMiniMap.vue';
|
|
import VillageMiniMap from './components/VillageMiniMap.vue';
|
|
|
import Button from '@/components/basic/Button.vue';
|
|
import Button from '@/components/basic/Button.vue';
|
|
|
import HomeTitle from '@/common/components/parts/HomeTitle.vue';
|
|
import HomeTitle from '@/common/components/parts/HomeTitle.vue';
|
|
|
import VillageRankList from './components/VillageRankList.vue';
|
|
import VillageRankList from './components/VillageRankList.vue';
|
|
|
|
|
+import VillageUserRankList from './components/VillageUserRankList.vue';
|
|
|
|
|
+import MasonryGrid from '@/components/layout/masonry/MasonryGrid.vue';
|
|
|
|
|
+import ImageBlock2 from '@/components/display/block/ImageBlock2.vue';
|
|
|
|
|
+import VillageInfoApi from '@/api/inhert/VillageInfoApi';
|
|
|
|
|
+import Avatar from '@/components/display/Avatar.vue';
|
|
|
|
|
+import Icon from '@/components/basic/Icon.vue';
|
|
|
|
|
+import Text from '@/components/basic/Text.vue';
|
|
|
|
|
|
|
|
const themeContext = useTheme();
|
|
const themeContext = useTheme();
|
|
|
-
|
|
|
|
|
-const currentLonlat = ref<{ longitude: number, latitude: number }>({ longitude: 0, latitude: 0 });
|
|
|
|
|
const searchKeywords = ref('');
|
|
const searchKeywords = ref('');
|
|
|
|
|
|
|
|
-function getedCurrentLonlat(lonlat: { longitude: number, latitude: number }) {
|
|
|
|
|
- currentLonlat.value = lonlat;
|
|
|
|
|
- recommendedNearbySitesLoader.loadData();
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function goVillageDetails(e: any) {
|
|
|
|
|
- const id = typeof e.markerId == 'number' ? e.markerId : e.id;
|
|
|
|
|
- uni.setStorageSync('VillageTemp', JSON.stringify(villageLoader.content.value?.find(p => p.id == id)));
|
|
|
|
|
- setTimeout(() => {
|
|
|
|
|
- navTo('/pages/home/village/details', { id: id });
|
|
|
|
|
- }, 200);
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-/** 根据两点经纬度计算直线距离(米),Haversine 公式 */
|
|
|
|
|
-function getDistanceMeters(
|
|
|
|
|
- lon1: number, lat1: number,
|
|
|
|
|
- lon2: number, lat2: number
|
|
|
|
|
-): number {
|
|
|
|
|
- const R = 6371000; // 地球半径 米
|
|
|
|
|
- const dLat = (lat2 - lat1) * Math.PI / 180;
|
|
|
|
|
- const dLon = (lon2 - lon1) * Math.PI / 180;
|
|
|
|
|
- const a =
|
|
|
|
|
- Math.sin(dLat / 2) * Math.sin(dLat / 2) +
|
|
|
|
|
- Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
|
|
|
|
|
- Math.sin(dLon / 2) * Math.sin(dLon / 2);
|
|
|
|
|
- const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
|
|
|
|
|
- return R * c;
|
|
|
|
|
-}
|
|
|
|
|
-function getDistance(longitude: number, latitude: number): string {
|
|
|
|
|
- const meters = getDistanceMeters(longitude, latitude, currentLonlat.value.longitude, currentLonlat.value.latitude);
|
|
|
|
|
- if (meters < 100) return '一百米内';
|
|
|
|
|
- if (meters < 1000) return `${Math.round(meters / 100) * 100}米`;
|
|
|
|
|
- return `${Math.round(meters / 1000)}km`;
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-const recommendedNearbySitesLoader = useSimpleDataLoader(async () => {
|
|
|
|
|
- const res = (await CommonContent.getContentList(new GetContentListParams()
|
|
|
|
|
- .setModelId(UnmoveableContent.modelId)
|
|
|
|
|
- .setSelfValues({
|
|
|
|
|
- longitude: currentLonlat.value.longitude,
|
|
|
|
|
- latitude: currentLonlat.value.latitude,
|
|
|
|
|
- }), 1, 8, undefined, true)).list;
|
|
|
|
|
-
|
|
|
|
|
- for (const item of res)
|
|
|
|
|
- item.distance = getDistance(item.longitude, item.latitude);
|
|
|
|
|
- return res;
|
|
|
|
|
-});
|
|
|
|
|
-
|
|
|
|
|
-const villageLoader = useSimpleDataLoader(async () => {
|
|
|
|
|
- const res = (await VillageApi.getVallageList(undefined, 1)).map((p, i) => ({
|
|
|
|
|
- ...p,
|
|
|
|
|
- id: p.id ?? i,
|
|
|
|
|
- title: p.villageName,
|
|
|
|
|
- longitude: Number(p.longitude),
|
|
|
|
|
- latitude: Number(p.latitude),
|
|
|
|
|
- width: 30,
|
|
|
|
|
- height: 30,
|
|
|
|
|
- iconPath: p.thumbnail || p.image,
|
|
|
|
|
- }));
|
|
|
|
|
- return res;
|
|
|
|
|
-});
|
|
|
|
|
-
|
|
|
|
|
const recommendLoader = useSimpleDataLoader(async () => {
|
|
const recommendLoader = useSimpleDataLoader(async () => {
|
|
|
- //const category = (await CommonContent.getCategoryList(151)).find(p => p.title == '省级');
|
|
|
|
|
- return (await VillageApi.getVallageList(undefined, 1));
|
|
|
|
|
|
|
+ const res = (await VillageInfoApi.getListForDiscover(
|
|
|
|
|
+ 1, 20,
|
|
|
|
|
+ '',
|
|
|
|
|
+ ));
|
|
|
|
|
+ return res.list.concat(res.list).map((item) => ({
|
|
|
|
|
+ ...item,
|
|
|
|
|
+ isLike: Math.random() > 0.5,
|
|
|
|
|
+ likes: Math.floor(Math.random() * 1000),
|
|
|
|
|
+ userName: '用户' + Math.floor(Math.random() * 1000000),
|
|
|
|
|
+ badge: item.villageName || '',
|
|
|
|
|
+ }))
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
-const discoverLoader = useSimpleDataLoader(async () => {
|
|
|
|
|
- return (await VillageInfoApi.getListForDiscover(1, 10)).list.map((item) => {
|
|
|
|
|
- return {
|
|
|
|
|
- ...item,
|
|
|
|
|
- image: (item.thumbnail || item.image) as string,
|
|
|
|
|
- desc: item.desc || '',
|
|
|
|
|
- title: item.title,
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
-});
|
|
|
|
|
-
|
|
|
|
|
-const newsLoader = useSimpleDataLoader(async () => {
|
|
|
|
|
- return (await CommonContent.getContentList(new GetContentListParams()
|
|
|
|
|
- .setModelId(18)
|
|
|
|
|
- .setMainBodyColumnId(363)
|
|
|
|
|
- , 1, 8)).list;
|
|
|
|
|
-});
|
|
|
|
|
-
|
|
|
|
|
-function goDiscoverDetails(item: any) {
|
|
|
|
|
- navTo('/pages/home/discover/details', {
|
|
|
|
|
- id: item.id,
|
|
|
|
|
- collectModelId: item.collectModuleId,
|
|
|
|
|
- collectModelInternalName: item.collectModuleInternalName,
|
|
|
|
|
- });
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
-function goList(keywords: string) {
|
|
|
|
|
-}
|
|
|
|
|
-
|
|
|
|
|
</script>
|
|
</script>
|