VillageRankList.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. <template>
  2. <Empty v-if="list.length === 0" description="暂无排名数据" />
  3. <FlexRow :gap="20">
  4. <Touchable
  5. v-for="(item) in list"
  6. :key="item.id"
  7. :width="item.rank == 1 ? '40%' : '28.5%'"
  8. position="relative"
  9. justify="space-between"
  10. radius="radius.md"
  11. overflow="hidden"
  12. direction="column"
  13. @click="handleGoDetails(item)"
  14. >
  15. <Image
  16. :src="item.image"
  17. width="100%"
  18. :height="280"
  19. mode="aspectFill"
  20. radius="radius.md"
  21. defaultImage="https://xy.wenlvti.net/app_static/images/village/PlaceholderVillage.jpg"
  22. />
  23. <FlexRow
  24. position="absolute"
  25. :left="0"
  26. :bottom="0"
  27. :right="0"
  28. :padding="10"
  29. center
  30. backgroundColor="rgba(0, 0, 0, 0.5)"
  31. >
  32. <Text :text="item.title" fontConfig="h4" color="white" />
  33. </FlexRow>
  34. <FlexCol
  35. position="absolute"
  36. :left="15"
  37. :top="15"
  38. center
  39. :width="60"
  40. :height="80"
  41. :innerStyle="{
  42. backgroundSize: '100% auto',
  43. backgroundRepeat: 'no-repeat',
  44. backgroundPosition: 'center',
  45. backgroundImage: item.rank == 1 ?
  46. `url('https://xy.wenlvti.net/app_static/images/home/RankBadge1.png')` :
  47. `url('https://xy.wenlvti.net/app_static/images/home/RankBadgeN.png')`,
  48. }"
  49. >
  50. <Text v-if="item.rank > 1" fontConfig="h4" :text="item.rank" color="white" />
  51. </FlexCol>
  52. </Touchable>
  53. </FlexRow>
  54. </template>
  55. <script setup lang="ts">
  56. import LightVillageApi from '@/api/light/LightVillageApi';
  57. import Image from '@/components/basic/Image.vue';
  58. import Text from '@/components/basic/Text.vue';
  59. import Empty from '@/components/feedback/Empty.vue';
  60. import Touchable from '@/components/feedback/Touchable.vue';
  61. import FlexCol from '@/components/layout/FlexCol.vue';
  62. import FlexRow from '@/components/layout/FlexRow.vue';
  63. import { navTo } from '@/components/utils/PageAction';
  64. import { useVillageStore } from '@/store/village';
  65. import { waitTimeOut } from '@imengyu/imengyu-utils';
  66. const props = withDefaults(defineProps<{
  67. list?: {
  68. id: number;
  69. image: string;
  70. title: string;
  71. rank: number;
  72. }[];
  73. jumpToSingle?: boolean;
  74. }>(), {
  75. jumpToSingle: true,
  76. list: () => [
  77. {
  78. id: 1,
  79. image: 'https://mncdn.wenlvti.net/app_static/minnan/images/test/ImageTest1.png',
  80. title: '乡村1',
  81. rank: 1,
  82. },
  83. {
  84. id: 2,
  85. image: 'https://mncdn.wenlvti.net/app_static/minnan/images/test/ImageTest2.png',
  86. title: '乡村2',
  87. rank: 2,
  88. },
  89. {
  90. id: 3,
  91. image: 'https://mncdn.wenlvti.net/app_static/minnan/images/test/ImageTest3.png',
  92. title: '乡村3',
  93. rank: 3,
  94. },
  95. ],
  96. });
  97. const emit = defineEmits([ 'goDetails' ]);
  98. const villageStore = useVillageStore();
  99. async function handleGoDetails(item: { id: number }) {
  100. const details = await LightVillageApi.getVillageDetails(item.id);
  101. if (props.jumpToSingle) {
  102. villageStore.setCurrentVillage(details);
  103. await waitTimeOut(100);
  104. navTo('/pages/home/village/index');
  105. } else {
  106. emit('goDetails', details);
  107. }
  108. }
  109. </script>