1
0

App.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. <template>
  2. <!-- <div>地图页面</div> -->
  3. <div class="tabbar">
  4. <div class="nav">
  5. <el-button-group class="ml-4">
  6. <el-button
  7. :type="currentType(0) ? 'primary' : 'default'"
  8. @click="handleSelect(0)"
  9. >地图</el-button
  10. >
  11. <el-button
  12. :type="currentType(1) ? 'primary' : 'default'"
  13. @click="handleSelect(1)"
  14. >卡片</el-button
  15. >
  16. </el-button-group>
  17. </div>
  18. <el-form-item label="所属架构:" class="filter">
  19. <com-company v-model="state.deptId" :id="state.caseId" />
  20. </el-form-item>
  21. </div>
  22. <div ref="mapEl" class="map-container" v-show="currentType(0)"></div>
  23. <div class="card-container" v-show="currentType(1)">
  24. <div class="card-list">
  25. <template v-for="item of list" v-if="list.length > 0">
  26. <el-card
  27. style="width: 480px"
  28. shadow="hover"
  29. @click="handCardClick(item.caseId)"
  30. >
  31. <img
  32. class="cover"
  33. :src="
  34. item.cover
  35. ? item.cover
  36. : 'https://test-mix3d.4dkankan.com/code/assets/pic.d5781b0c.jpg'
  37. "
  38. style="width: 100%"
  39. />
  40. <div class="card">
  41. <span> 项目: {{ item.projectName }}</span>
  42. <span> 地址: {{ item.projectAddress }}</span>
  43. <span> 类别: {{ item.projectSite }}</span>
  44. </div>
  45. </el-card>
  46. </template>
  47. <template v-else>
  48. <div class="no-data">
  49. <img :src="emptyBG" />
  50. <span>暂无数据</span>
  51. </div>
  52. </template>
  53. </div>
  54. </div>
  55. </template>
  56. <script setup lang="ts">
  57. import { onMounted, ref, computed, onBeforeMount } from "vue";
  58. // import { useRouteQuery } from "@vueuse/router";
  59. import AMapLoader from "@amap/amap-jsapi-loader";
  60. import axios from "axios";
  61. import { getFuseCodeLink } from "../../view/case/help";
  62. import comCompany from "./company-select/index.vue";
  63. import { reactive } from "vue";
  64. import { watch } from "vue";
  65. import { ElLoading } from "element-plus";
  66. import linkIco from "@/assets/image/fire.ico";
  67. import { useUrlSearchParams } from "@vueuse/core";
  68. import emptyBG from "@/assets/image/empty__empty.png";
  69. const params = useUrlSearchParams("history");
  70. console.log("params", params.deptId);
  71. const current = ref(0);
  72. const list = ref<any>([]);
  73. const state = reactive({
  74. deptId: params.deptId || "",
  75. // caseId: params.caseId || "",
  76. });
  77. const link = document.querySelector<HTMLLinkElement>("#app-icon")!;
  78. link.setAttribute("href", linkIco);
  79. document.title = "案件显示";
  80. const currentType = computed(() => (type: number) => current.value === type);
  81. const handleSelect = (type: number) => {
  82. current.value = type;
  83. };
  84. const getQuery = (
  85. caseId: number,
  86. share: boolean = false,
  87. single: boolean = false
  88. ) =>
  89. `${getFuseCodeLink(caseId, true)}${share ? "&share=1" : ""}${
  90. single ? "&single=1" : ""
  91. }#show/summary`;
  92. const request = axios.create({
  93. baseURL: "",
  94. timeout: 1000,
  95. headers: {
  96. share: 1,
  97. "Content-Type": "application/json",
  98. },
  99. });
  100. const mapEl = ref<HTMLDivElement>();
  101. const getDataQuest = () => {
  102. return new Promise(async (reslove, reject) => {
  103. const res = await request.post(
  104. "https://xj-mix3d.4dkankan.com/fusion-xj/web/fireProject/queryProject",
  105. {
  106. pageNum: 1,
  107. pageSize: 10000,
  108. deptId: state.deptId,
  109. }
  110. );
  111. console.log("res.data", res);
  112. if (res.status === 200 && res.data.code === 0) {
  113. reslove(res.data.data.list);
  114. } else {
  115. reslove([]);
  116. }
  117. });
  118. };
  119. const refresh = async () => {
  120. const loading = ElLoading.service({
  121. lock: true,
  122. text: "Loading",
  123. background: "rgba(0, 0, 0, 0.7)",
  124. });
  125. const data = (await getDataQuest()) as any as any[];
  126. console.log("data", data);
  127. list.value = data as any[];
  128. loading.close();
  129. };
  130. watch(
  131. () => state.deptId,
  132. () => {
  133. refresh();
  134. },
  135. {
  136. immediate: true,
  137. deep: true,
  138. }
  139. );
  140. const loadMap = async () => {
  141. const AMap = await AMapLoader.load({
  142. plugins: ["AMap.PlaceSearch"],
  143. key: "e661b00bdf2c44cccf71ef6070ef41b8",
  144. version: "2.0",
  145. });
  146. const map = new AMap.Map(mapEl.value, {
  147. WebGLParams: {
  148. preserveDrawingBuffer: true,
  149. },
  150. resizeEnable: true,
  151. });
  152. //添加插件
  153. AMap.plugin(
  154. ["AMap.ToolBar", "AMap.Scale", "AMap.HawkEye", "AMap.MapType"],
  155. function () {
  156. //异步同时加载多个插件
  157. // map.addControl(new AMap.HawkEye()); //显示缩略图
  158. map.addControl(new AMap.Scale()); //显示当前地图中心的比例尺
  159. map.addControl(new AMap.MapType()); //显示当前地图中心的比例尺
  160. }
  161. );
  162. console.log("map", map);
  163. const initMakers = async () => {
  164. const data = (await getDataQuest()) as any as any[];
  165. console.log("data", data);
  166. const positions: any[] = [];
  167. list.value = data as any[];
  168. Array.from(data).forEach((item: any) => {
  169. // console.log(item)
  170. const latlng = item.latlng;
  171. const coord = latlng.split(",");
  172. console.log("coord", coord, item.caseId);
  173. const url = getQuery(item.caseId, true);
  174. console.log("url", url);
  175. const icon = new AMap.Icon({
  176. image:
  177. "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
  178. size: new AMap.Size(22, 28), //图标所处区域大小
  179. imageSize: new AMap.Size(22, 28), //图标大小
  180. });
  181. const pos = coord.reverse();
  182. positions.push(pos);
  183. const marker = new AMap.Marker({
  184. icon: icon,
  185. position: pos,
  186. title: item.title,
  187. label: item.title,
  188. extData: { url: url, id: item.caseId },
  189. // offset: new AMap.Pixel(-26, -54),
  190. });
  191. marker.setMap(map);
  192. marker.on("click", () => {
  193. const data = marker.getExtData();
  194. window.open(data.url);
  195. console.log("click", data);
  196. });
  197. });
  198. var polygon = new AMap.Polygon({
  199. path: positions,
  200. map: map,
  201. strokeOpacity: 0, //透明
  202. fillOpacity: 0, //透明
  203. bubble: true, //事件穿透到地图
  204. });
  205. var overlaysList = map.getAllOverlays("polygon"); //获取多边形图层
  206. map.setFitView(); //自适应显示
  207. };
  208. initMakers();
  209. };
  210. onMounted(() => {
  211. // console.log("caseId", caseId);
  212. loadMap();
  213. });
  214. const handCardClick = (id: number) => {
  215. const url = getQuery(id, true);
  216. console.log("url", url);
  217. window.open(url);
  218. };
  219. </script>
  220. <style>
  221. body {
  222. padding: 0;
  223. margin: 0;
  224. }
  225. .map-container {
  226. width: 100%;
  227. height: 100vh;
  228. }
  229. .tabbar {
  230. display: flex;
  231. width: 100%;
  232. position: fixed;
  233. top: 30px;
  234. z-index: 10000;
  235. justify-items: center;
  236. justify-content: center;
  237. }
  238. .tabbar .nav {
  239. display: flex;
  240. /* background: white; */
  241. justify-content: center;
  242. align-items: center;
  243. }
  244. .el-form-item {
  245. margin-bottom: 0px !important;
  246. }
  247. .tabbar .nav .nav_item {
  248. padding: 10px;
  249. cursor: pointer;
  250. }
  251. .card-container {
  252. width: 100%;
  253. padding-top: 100px;
  254. }
  255. .card-list {
  256. margin: 0 auto;
  257. display: flex;
  258. gap: 50px 25px;
  259. width: 90%;
  260. flex-direction: row;
  261. flex-wrap: wrap;
  262. }
  263. .cover {
  264. cursor: pointer;
  265. max-height: 220px;
  266. object-fit: cover;
  267. }
  268. .card {
  269. display: flex;
  270. flex-direction: column;
  271. cursor: pointer;
  272. gap: 10px;
  273. }
  274. .filter {
  275. margin: 0;
  276. margin-left: 20px;
  277. }
  278. .amap-ctrl-list-layer {
  279. z-index: 100000;
  280. }
  281. .no-data {
  282. width: 100%;
  283. height: 100%;
  284. /* background: red; */
  285. min-height: 530px;
  286. display: flex;
  287. justify-content: center;
  288. align-items: center;
  289. flex-direction: column;
  290. }
  291. .no-data span {
  292. color: #999;
  293. }
  294. </style>