index.vue 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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 list;
  124. switch (tabCurrentIndex.value) {
  125. default:
  126. case 0:
  127. list = (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)).list;
  132. break;
  133. case 1:
  134. list = (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)).list;
  139. break;
  140. case 2:
  141. list = (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)).list;
  147. break;
  148. case 3:
  149. list = (await VillageApi.getVallageList()).filter(p =>
  150. (!searchValue.value || p.villageName.indexOf(searchValue.value) > -1)
  151. );
  152. break;
  153. case 4:
  154. list = (await ScenicSpotContent.getContentList(new GetContentListParams().setSelfValues({
  155. keywords: searchValue.value,
  156. }), page, pageSize)).list
  157. break;
  158. }
  159. const res = list.map((p) => {
  160. if (!p.longitude || !p.latitude) {
  161. p.longitude = AppCofig.defaultLonLat[0] + Math.random() * 0.1 - 0.05;
  162. p.latitude = AppCofig.defaultLonLat[1] + Math.random() * 0.1 - 0.05;
  163. }
  164. return {
  165. //...p,
  166. id: p.id,
  167. longitude: Number(p.longitude),
  168. latitude: Number(p.latitude),
  169. iconPath: p.thumbnail || p.image || AppCofig.defaultImage,
  170. width: 40,
  171. height: 40,
  172. joinCluster: true,
  173. callout: {
  174. content: p.title,
  175. color: "#ffffff",
  176. fontSize: 15,
  177. borderRadius: 15,
  178. padding: "10",
  179. bgColor: "#d9492e",
  180. display: "ALWAYS",
  181. },
  182. }
  183. })
  184. mapCtx.includePoints({
  185. points: res.map(p => ({
  186. latitude: p.latitude,
  187. longitude: p.longitude,
  188. })),
  189. padding: [20, 20, 20, 20],
  190. });
  191. mapCtx.addMarkers({
  192. clear: true,
  193. markers: res,
  194. })
  195. return res;
  196. }, true);
  197. watch(selectedLevel, () => {
  198. listLoader.loadData(undefined, true);
  199. });
  200. watch(selectedRegion, () => {
  201. listLoader.loadData(undefined, true);
  202. });
  203. watch(selectedTag, () => {
  204. listLoader.loadData(undefined, true);
  205. });
  206. function doSearch() {
  207. listLoader.loadData(undefined, true);
  208. }
  209. function onMarkerTap(e: { markerId: number }) {
  210. goDetails(e.markerId);
  211. }
  212. function goDetails(id: number) {
  213. switch (tabCurrentIndex.value) {
  214. default:
  215. case 0: navTo('/pages/article/details', { id }); break;
  216. case 1: navTo('/pages/inhert/intangible/details', { id }); break;
  217. case 2: navTo('/pages/inhert/artifact/details', { id }); break;
  218. case 3: navTo('/pages/inhert/village/details', { id }); break;
  219. }
  220. }
  221. onLoad((query) => {
  222. mapCtx.initMarkerCluster({
  223. enableDefaultStyle: false,
  224. zoomOnClick: true,
  225. gridSize: 60,
  226. });
  227. mapCtx.on('markerClusterCreate', (e: { clusters: any[] }) => {
  228. const customClusters = e.clusters.map((cluster) => {
  229. const { center, clusterId, markerIds } = cluster;
  230. return {
  231. ...center,
  232. width: 0,
  233. height: 0,
  234. clusterId,
  235. label: {
  236. content: markerIds.length.toString(), // 聚合点的数量
  237. fontSize: 16,
  238. color: '#fff',
  239. width: 50,
  240. height: 50,
  241. bgColor: '#419afcD9', // 背景颜色
  242. borderRadius: 25,
  243. textAlign: 'center',
  244. anchorX: -10,
  245. anchorY: -35,
  246. },
  247. };
  248. });
  249. mapCtx.addMarkers({
  250. markers: customClusters,
  251. clear: false,
  252. });
  253. })
  254. tabCurrentIndex.value = Number(query?.tab || 0) - 1;
  255. listLoader.loadData(undefined, true);
  256. })
  257. </script>