index.vue 6.3 KB

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