index.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. <template>
  2. <FlexCol :gap="20" :padding="30" :innerStyle="{
  3. marginTop: '-130px',
  4. backgroundImage: 'url(/static/images/home/BannerHome.png)',
  5. backgroundSize: '100% auto',
  6. backgroundRepeat: 'no-repeat',
  7. backgroundPosition: 'top center',
  8. backgroundColor: themeContext.resolveThemeColor('background.primary'),
  9. }">
  10. <Height height="200px" />
  11. <FlexCol :gap="20" align="center">
  12. <SearchBar v-model="searchKeywords" placeholder="搜索" :innerStyle="{
  13. backgroundColor: 'white',
  14. borderRadius: '20rpx',
  15. borderWidth: '1px',
  16. borderStyle: 'solid',
  17. borderColor: themeContext.resolveThemeColor('primary'),
  18. width: '650rpx',
  19. }" />
  20. <Image
  21. src="/static/images/home/BannerIndex.png"
  22. width="700rpx"
  23. mode="widthFix"
  24. :innerStyle="{
  25. borderRadius: '20rpx',
  26. clipPath: 'ellipse(100% 90% at 50% 0%)'
  27. }"
  28. />
  29. </FlexCol>
  30. <VillageMiniMap />
  31. <FlexRow justify="space-between" :padding="[10, 16]">
  32. <Button icon="/static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">切换城市</Button>
  33. <Button icon="/static/images/home/IconSwitch.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">我的关注</Button>
  34. <Button icon="/static/images/home/IconLight.png" :radius="40" :padding="[10, 30]" :iconProps="{ innerStyle: { marginRight: '10rpx' }}">点亮村社</Button>
  35. </FlexRow>
  36. <HomeTitle title="乡村排名" showMore />
  37. <VillageRankList />
  38. <HomeTitle title="志愿者排名" showMore :lightCount="3" />
  39. <VillageUserRankList />
  40. <HomeTitle title="精选记忆" showMore />
  41. <MasonryGrid>
  42. <MasonryGridItem
  43. v-for="(item, i) in recommendLoader.content.value"
  44. :key="i"
  45. :width="340"
  46. >
  47. <ImageBlock2
  48. :src="item.image"
  49. :title="item.title"
  50. :desc="item.desc"
  51. :width="340"
  52. :imageWidth="340"
  53. :imageRadius="15"
  54. backgroundColor="transparent"
  55. >
  56. <template #footer>
  57. <FlexRow justify="space-between" align="center" :padding="[10,0]" :margin="[10,0,0,0]">
  58. <FlexRow align="center" :gap="10">
  59. <Avatar :url="item.image" :size="40" />
  60. <Text :text="item.userName" :fontSize="24" color="gray" />
  61. </FlexRow>
  62. <FlexRow align="center" :gap="10">
  63. <Icon icon="favorite" :color="item.isLike ? 'primary' : 'gray'" :size="30" />
  64. <Text :text="item.likes" :fontSize="30" :color="item.isLike ? 'primary' : 'gray'" />
  65. </FlexRow>
  66. </FlexRow>
  67. </template>
  68. </ImageBlock2>
  69. </MasonryGridItem>
  70. </MasonryGrid>
  71. <Loadmore status="nomore" />
  72. <Height :height="150" />
  73. </FlexCol>
  74. </template>
  75. <script setup lang="ts">
  76. import { ref } from 'vue';
  77. import { useTheme } from '@/components/theme/ThemeDefine';
  78. import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
  79. import Image from '@/components/basic/Image.vue';
  80. import Loadmore from '@/components/display/loading/Loadmore.vue';
  81. import FlexCol from '@/components/layout/FlexCol.vue';
  82. import FlexRow from '@/components/layout/FlexRow.vue';
  83. import Height from '@/components/layout/space/Height.vue';
  84. import SearchBar from '@/components/form/SearchBar.vue';
  85. import VillageMiniMap from './components/VillageMiniMap.vue';
  86. import Button from '@/components/basic/Button.vue';
  87. import HomeTitle from '@/common/components/parts/HomeTitle.vue';
  88. import VillageRankList from './components/VillageRankList.vue';
  89. import VillageUserRankList from './components/VillageUserRankList.vue';
  90. import ImageBlock2 from '@/components/display/block/ImageBlock2.vue';
  91. import VillageInfoApi from '@/api/inhert/VillageInfoApi';
  92. import Avatar from '@/components/display/Avatar.vue';
  93. import Icon from '@/components/basic/Icon.vue';
  94. import Text from '@/components/basic/Text.vue';
  95. import MasonryGrid from '@/components/layout/masonry/MasonryGrid.vue';
  96. import MasonryGridItem from '@/components/layout/masonry/MasonryGridItem.vue';
  97. const themeContext = useTheme();
  98. const searchKeywords = ref('');
  99. const recommendLoader = useSimpleDataLoader(async () => {
  100. const res = (await VillageInfoApi.getListForDiscover(
  101. 1, 20,
  102. '',
  103. ));
  104. return res.list.concat(res.list,res.list, res.list, res.list).sort(() => Math.random() - 0.5).map((item) => ({
  105. ...item,
  106. isLike: Math.random() > 0.5,
  107. likes: Math.floor(Math.random() * 1000),
  108. userName: '用户' + Math.floor(Math.random() * 1000000),
  109. badge: item.villageName || '',
  110. }))
  111. });
  112. </script>