index.vue 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. <template>
  2. <view class="d-flex flex-col bg-base">
  3. <u-tabs
  4. :list="tabs"
  5. :current="tabCurrentIndex"
  6. lineWidth="30"
  7. lineColor="#d9492e"
  8. :activeStyle="{
  9. color: '#000',
  10. fontWeight: 'bold',
  11. transform: 'scale(1.05)'
  12. }"
  13. :inactiveStyle="{
  14. color: '#606266',
  15. transform: 'scale(1)'
  16. }"
  17. :scrollable="true"
  18. class="top-tab"
  19. @click="onTabClick"
  20. />
  21. <view class="d-flex flex-col p-2">
  22. <uni-search-bar
  23. v-model="searchValue"
  24. radius="100"
  25. bgColor="#fff"
  26. placeholder="搜索地图数据库"
  27. clearButton="auto"
  28. cancelButton="none"
  29. @confirm="doSearch"
  30. />
  31. </view>
  32. <view class="d-flex flex-row justify-around p-2 pt-0">
  33. <SimpleDropDownPicker v-if="tabCurrentIndex == 2" v-model="selectedTag" :columns="categoryData.content.value" />
  34. <SimpleDropDownPicker v-if="tabCurrentIndex <= 2" v-model="selectedLevel" :columns="levelData.content.value" />
  35. <SimpleDropDownPicker v-if="tabCurrentIndex <= 2" v-model="selectedRegion" :columns="regionData.content.value" />
  36. </view>
  37. <view class="d-flex flex-row flex-wrap justify-between">
  38. <map
  39. id="map"
  40. class="w-100"
  41. style="height:80vh"
  42. :makers="[]"
  43. :scale="13"
  44. @markertap="onMarkerTap"
  45. />
  46. </view>
  47. </view>
  48. </template>
  49. <script setup lang="ts">
  50. import { ref, watch } from 'vue';
  51. import { useSimplePageListLoader } from '@/common/composeabe/SimplePageListLoader';
  52. import { navTo } from '@/common/utils/PageAction';
  53. import { useSimpleDataLoader } from '@/common/composeabe/SimpleDataLoader';
  54. import SimpleDropDownPicker from '@/common/components/SimpleDropDownPicker.vue';
  55. import SeminarContent from '@/api/inheritor/SeminarContent';
  56. import CommonContent, { GetContentListParams } from '@/api/CommonContent';
  57. import UnmoveableContent from '@/api/inheritor/UnmoveableContent';
  58. import ProjectsContent from '@/api/inheritor/ProjectsContent';
  59. import { onLoad } from '@dcloudio/uni-app';
  60. import AppCofig from '@/common/config/AppCofig';
  61. import VillageApi from '@/api/inhert/VillageApi';
  62. import ScenicSpotContent from '@/api/fusion/ScenicSpotContent';
  63. import { useTabControl } from '@/common/composeabe/TabControl';
  64. const {
  65. tabCurrentIndex ,
  66. tabs,
  67. onTabClick
  68. } = useTabControl({
  69. tabs: [
  70. {
  71. name: '非遗项目'
  72. },
  73. {
  74. name: '非遗传习所'
  75. },
  76. {
  77. name: '文物古迹'
  78. },
  79. {
  80. name: '传统村落'
  81. },
  82. {
  83. name: '闽南文化景区'
  84. },
  85. ],
  86. onTabChange() {
  87. listLoader.loadData(undefined, true);
  88. },
  89. })
  90. const mapCtx = uni.createMapContext('map');
  91. const categoryData = useSimpleDataLoader(async () =>
  92. [{
  93. id: 0,
  94. name: '全部分类'
  95. }].concat((await CommonContent.getCategoryList(3)).map((item) => ({
  96. id: item.id,
  97. name: item.title,
  98. })))
  99. , true);
  100. const levelData = useSimpleDataLoader(async () =>
  101. [{
  102. id: 0,
  103. name: '全部级别'
  104. }].concat((await CommonContent.getCategoryList(2)).map((item) => ({
  105. id: item.id,
  106. name: item.title,
  107. })))
  108. , true);
  109. const regionData = useSimpleDataLoader(async () =>
  110. [{
  111. id: 0,
  112. name: '全部区域'
  113. }].concat((await CommonContent.getCategoryList(1)).map((item) => ({
  114. id: item.id,
  115. name: item.title,
  116. })))
  117. , true);
  118. const selectedTag = ref(0);
  119. const selectedLevel = ref(0);
  120. const selectedRegion = ref(0);
  121. const searchValue = ref('');
  122. const listLoader = useSimplePageListLoader(50, async (page, pageSize) => {
  123. let res;
  124. switch (tabCurrentIndex.value) {
  125. default:
  126. case 0:
  127. res = (await ProjectsContent.getContentList(new GetContentListParams().setSelfValues({
  128. level: selectedLevel.value == 0 ? undefined: selectedLevel.value,
  129. region: selectedRegion.value == 0 ? undefined: selectedRegion.value,
  130. keywords: searchValue.value,
  131. }), page, pageSize));
  132. break;
  133. case 1:
  134. res = (await SeminarContent.getContentList(new GetContentListParams().setSelfValues({
  135. level: selectedLevel.value == 0 ? undefined: selectedLevel.value,
  136. region: selectedRegion.value == 0 ? undefined: selectedRegion.value,
  137. keywords: searchValue.value,
  138. }), page, pageSize));
  139. break;
  140. case 2:
  141. res = (await UnmoveableContent.getContentList(new GetContentListParams().setSelfValues({
  142. crType: selectedTag.value == 0 ? undefined: selectedTag.value,
  143. level: selectedLevel.value == 0 ? undefined: selectedLevel.value,
  144. region: selectedRegion.value == 0 ? undefined: selectedRegion.value,
  145. keywords: searchValue.value,
  146. }), page, pageSize));
  147. break;
  148. case 3: {
  149. const list = (await VillageApi.getVallageList()).filter(p =>
  150. (!searchValue.value || p.villageName.indexOf(searchValue.value) > -1)
  151. )
  152. res = { list, total: list.length };
  153. break;
  154. }
  155. case 4:
  156. res = (await ScenicSpotContent.getContentList(new GetContentListParams().setSelfValues({
  157. keywords: searchValue.value,
  158. }), page, pageSize))
  159. break;
  160. }
  161. const makers = res.list.map((p) => {
  162. if (!p.longitude || !p.latitude) {
  163. p.longitude = AppCofig.defaultLonLat[0] + Math.random() * 0.1 - 0.05;
  164. p.latitude = AppCofig.defaultLonLat[1] + Math.random() * 0.1 - 0.05;
  165. }
  166. return {
  167. //...p,
  168. id: p.id,
  169. longitude: Number(p.longitude),
  170. latitude: Number(p.latitude),
  171. iconPath: p.thumbnail || p.image || AppCofig.defaultImage,
  172. width: 40,
  173. height: 40,
  174. joinCluster: true,
  175. callout: {
  176. content: p.title,
  177. color: "#ffffff",
  178. fontSize: 15,
  179. borderRadius: 15,
  180. padding: "10",
  181. bgColor: "#d9492e",
  182. display: "ALWAYS",
  183. },
  184. }
  185. })
  186. mapCtx.includePoints({
  187. points: makers.map(p => ({
  188. latitude: p.latitude,
  189. longitude: p.longitude,
  190. })),
  191. padding: [20, 20, 20, 20],
  192. });
  193. mapCtx.addMarkers({
  194. clear: true,
  195. markers: makers,
  196. })
  197. return { list: makers, total: res.total };
  198. }, true);
  199. watch(selectedLevel, () => {
  200. listLoader.loadData(undefined, true);
  201. });
  202. watch(selectedRegion, () => {
  203. listLoader.loadData(undefined, true);
  204. });
  205. watch(selectedTag, () => {
  206. listLoader.loadData(undefined, true);
  207. });
  208. function doSearch() {
  209. listLoader.loadData(undefined, true);
  210. }
  211. function onMarkerTap(e: { markerId: number }) {
  212. goDetails(e.markerId);
  213. }
  214. function goDetails(id: number) {
  215. switch (tabCurrentIndex.value) {
  216. case 0:
  217. case 1: navTo('/pages/inhert/intangible/details', { id }); break;
  218. case 2: navTo('/pages/inhert/artifact/details', { id }); break;
  219. case 3: navTo('/pages/inhert/village/details', { id }); break;
  220. default:
  221. case 4: navTo('/pages/article/details', { id }); break;
  222. }
  223. }
  224. onLoad((query) => {
  225. mapCtx.initMarkerCluster({
  226. enableDefaultStyle: false,
  227. zoomOnClick: true,
  228. gridSize: 60,
  229. });
  230. mapCtx.on('markerClusterCreate', (e: { clusters: any[] }) => {
  231. const customClusters = e.clusters.map((cluster) => {
  232. const { center, clusterId, markerIds } = cluster;
  233. return {
  234. ...center,
  235. width: 0,
  236. height: 0,
  237. clusterId,
  238. label: {
  239. content: markerIds.length.toString(), // 聚合点的数量
  240. fontSize: 16,
  241. color: '#fff',
  242. width: 50,
  243. height: 50,
  244. bgColor: '#419afcD9', // 背景颜色
  245. borderRadius: 25,
  246. textAlign: 'center',
  247. anchorX: -10,
  248. anchorY: -35,
  249. },
  250. };
  251. });
  252. mapCtx.addMarkers({
  253. markers: customClusters,
  254. clear: false,
  255. });
  256. })
  257. tabCurrentIndex.value = Number(query?.tab || 0) - 1;
  258. listLoader.loadData(undefined, true);
  259. })
  260. </script>