IndexView.vue 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <template>
  2. <div class="home">
  3. <Header v-if="loginType != 'AUTO'"></Header>
  4. <Map ref="childRef"/>
  5. <DrawMap></DrawMap>
  6. <div :class="loginType == 'AUTO' ? 'search-box-auto': 'search-box'">
  7. <div class="search-input">
  8. <el-autocomplete
  9. v-model="searchText"
  10. popper-class="custom-dropdown"
  11. :popper-append-to-body="false"
  12. :fetch-suggestions="querySearchAsync"
  13. :placeholder="selectType == '0' ? '请输入地址' : '请输入员工'"
  14. clearable :clear-icon="CloseBold"
  15. @select="handleSelect"
  16. >
  17. <template #append>
  18. <el-select v-model="selectType" placeholder="请选择搜索类型" style="width: 80px">
  19. <el-option label="地址" value="0" />
  20. <el-option label="员工" value="1" />
  21. </el-select>
  22. </template>
  23. </el-autocomplete>
  24. </div>
  25. </div>
  26. <div class="map-box">
  27. <div class="map-group">
  28. <div :class="{'map-item':true,'active':baseMap=='zwb'}" @click="selectMap('zwb')">
  29. <div style="height: 52px;"><img src="../../public/static/image/zwb.png" class="map-img" mode="scaleToFill" /></div>
  30. <div class="map-img-name">浅色地图</div>
  31. </div>
  32. <div :class="{'map-item':true,'active':baseMap=='asb'}" @click="selectMap('asb')">
  33. <div style="height: 52px;"><img src="../../public/static/image/asb.png" class="map-img" mode="scaleToFill" /></div>
  34. <div class="map-img-name">深色地图</div>
  35. </div>
  36. <div :class="{'map-item':true,'active':baseMap=='yxt'}" @click="selectMap('yxt')">
  37. <div style="height: 52px;"><img src="../../public/static/image/yxt.png" class="map-img" mode="scaleToFill" /></div>
  38. <div class="map-img-name">影像地图</div>
  39. </div>
  40. </div>
  41. </div>
  42. </div>
  43. </template>
  44. <script>
  45. import mapCommonApi from "@/api/mapCommon";
  46. import commonAPI from "@/api/common";
  47. import Map from "@/components/Map.vue";
  48. import Header from "@/components/Header.vue";
  49. import DrawMap from "@/components/DrawMap.vue";
  50. import { showLoading, hideLoading } from "@/utils/loading";
  51. export default {
  52. name: "IndexView",
  53. components: {
  54. Map,
  55. Header,
  56. DrawMap
  57. },
  58. data() {
  59. return {
  60. baseMap:'zwb',
  61. searchText: '',
  62. timeout: null,
  63. selectType:'0',
  64. ygDataList:[],
  65. loginType: sessionStorage.getItem("gisLoginType") || '',
  66. };
  67. },
  68. mounted() {
  69. this.initData();
  70. },
  71. beforeDestroy() {
  72. // 在组件销毁前移除事件监听器
  73. },
  74. methods: {
  75. initData(){
  76. this.getDmsDataList();
  77. },
  78. getDmsDataList(){
  79. const that = this;
  80. let requestParams = {
  81. columnId: webConfig.columnArr[0].id,
  82. states: "0,1,2,3",
  83. orderBy: JSON.stringify([{ field: "c_xm", orderByType: 2 }]),
  84. pageSize: 99999,
  85. page: 0,
  86. };
  87. commonAPI.getDmsDataList(requestParams).then((res) => {
  88. if (res.code == 200){
  89. let data = res.content.data;
  90. data = data.map(item => {
  91. // 给每个属性名称添加 c_ 前缀
  92. const newItem = {};
  93. for (const key in item) {
  94. // 如果已经有c_
  95. if (key.includes("c_")) {
  96. let itemkey = key.replace(/c_/g, "");
  97. newItem['c_' + itemkey] = item[key];
  98. }else{
  99. newItem[key] = item[key];
  100. }
  101. }
  102. return newItem;
  103. })
  104. that.ygDataList = data;
  105. }else{
  106. // that.$message({ message: '无员工数据', type: 'info' })
  107. }
  108. });
  109. },
  110. selectMap(map){
  111. this.baseMap = map;
  112. if(map == 'zwb'){
  113. //切换底图后重新绑定
  114. window.mapboxMap.on('style.load', this.$refs.childRef.initBaseMap("zwb"));
  115. }else if(map == 'asb'){
  116. //切换底图后重新绑定
  117. window.mapboxMap.on('style.load', this.$refs.childRef.initBaseMap("asb"));
  118. }else if(map == 'yxt'){
  119. //切换底图后重新绑定
  120. window.mapboxMap.on('style.load', this.$refs.childRef.initBaseMap("yxt"));
  121. }
  122. },
  123. querySearchAsync(queryString, cb) {
  124. let that = this;
  125. if(queryString == ''){
  126. if(window.mapboxMap.getSource('point-source')){
  127. let jsondata = {type: "FeatureCollection",features: []};
  128. window.mapboxMap.getSource('point-source').setData(jsondata);
  129. }
  130. clearTimeout(that.timeout);
  131. that.timeout = setTimeout(() => {
  132. cb([]);
  133. }, 0);
  134. }else{
  135. if(that.selectType == "0"){
  136. that.querySearchAddr(queryString,cb);
  137. }else{
  138. that.queryTableData(queryString,cb);
  139. }
  140. }
  141. },
  142. queryTableData(text,cb){
  143. const that = this;
  144. let results = [];
  145. that.ygDataList.filter(item => {
  146. if(item.c_xm.includes(text)){
  147. item.value = item.c_xm;
  148. results.push(item);
  149. }
  150. })
  151. cb(results);
  152. },
  153. querySearchAddr(text,cb){
  154. let that = this;
  155. mapCommonApi.getSerachAddress3({
  156. "address": text
  157. }).then((res) => {
  158. let results = res.content.data;
  159. results.forEach(item => {
  160. item.value = item.address;
  161. })
  162. clearTimeout(that.timeout);
  163. that.timeout = setTimeout(() => {
  164. cb(results);
  165. }, 1000 * Math.random());
  166. }).catch((err) => {
  167. clearTimeout(that.timeout);
  168. that.timeout = setTimeout(() => {
  169. cb([]);
  170. }, 0);
  171. });
  172. },
  173. handleSelect(item) {
  174. let that = this;
  175. if(that.selectType == "0"){
  176. if(item){
  177. let Lon = item.location.split(',')[0]
  178. let Lat = item.location.split(',')[1]
  179. let center = [parseFloat(Lon), parseFloat(Lat)]
  180. window.mapboxMap.flyTo({
  181. center: center,
  182. zoom: 18,
  183. pitch: 0,
  184. });
  185. let jsondata = {
  186. type: 'FeatureCollection',
  187. features: [
  188. {
  189. type: 'Feature',
  190. properties: {
  191. title: item.address,
  192. icon: 'location-icon'
  193. },
  194. geometry: {
  195. type: 'Point',
  196. coordinates: center
  197. }
  198. }
  199. ]
  200. };
  201. if(window.mapboxMap.getSource('point-source')){
  202. window.mapboxMap.getSource('point-source').setData(jsondata);
  203. }else{
  204. window.mapboxMap.addSource('point-source', {
  205. type: 'geojson',
  206. data: jsondata
  207. });
  208. window.mapboxMap.addLayer({
  209. id: 'location-layer',
  210. type: 'symbol', // symbol = 图标/文字图层
  211. source: 'point-source',
  212. layout: {
  213. 'icon-image': 'location-icon', // 使用自定义图标
  214. 'icon-size': 1.5, // 图标大小
  215. 'icon-allow-overlap': true, // 允许图标重叠
  216. 'icon-rotate': 0, // 旋转角度
  217. 'icon-offset': [0, -20] // 图标偏移(上下左右)
  218. },
  219. paint: {
  220. 'icon-opacity': 1 // 透明度
  221. }
  222. });
  223. }
  224. }
  225. }else{
  226. sessionStorage.setItem('guid', "");
  227. that.$refs.childRef.setTableShow(that.searchText)
  228. }
  229. },
  230. }
  231. };
  232. </script>
  233. <style>
  234. .el-select__wrapper{
  235. min-height: 40px !important;
  236. background: transparent !important;
  237. /* box-shadow: 0 0 0 1px #01346fe0 inset; */
  238. }
  239. .el-select__placeholder{
  240. color: #fff !important;
  241. }
  242. .el-tag.el-tag--info{
  243. --el-tag-text-color: #ffffff !important;
  244. }
  245. .el-tag.el-tag--info {
  246. --el-tag-bg-color: #f3f3f700;
  247. }
  248. .el-popper.is-light{
  249. background: #01346fe0 !important;
  250. border: 1px solid #01346fe0 !important;
  251. max-width: none !important;
  252. }
  253. .el-select-dropdown__item{
  254. color: #fff !important;
  255. }
  256. .el-select-dropdown__item.is-hovering{
  257. background: linear-gradient(to right, #01346fe0, #02a7bd, #01346fe0) !important;
  258. color: #fff !important;
  259. }
  260. </style>
  261. <style lang="less" scoped>
  262. .home {
  263. width: 100%;
  264. height: 100%;
  265. // position: relative;
  266. // user-select: none;
  267. /* Chrome, Opera, Safari */
  268. // -moz-user-select: none;
  269. /* Firefox */
  270. // -ms-user-select: none;
  271. /* Internet Explorer/Edge */
  272. // -khtml-user-select: none;
  273. /* Konqueror/Safari */
  274. // -webkit-user-select: none;
  275. /* Webkit */
  276. // user-select: none;
  277. /* 标准语法 */
  278. }
  279. .search-box {
  280. position: absolute;
  281. top: 60px;
  282. left: 42%;
  283. z-index: 999;
  284. padding: 12px 20px;
  285. width: 400px;
  286. .search-input{
  287. -webkit-backdrop-filter: blur(5px);
  288. backdrop-filter: blur(5px);
  289. background: #01346f99;
  290. border-radius: 4px;
  291. }
  292. }
  293. .search-box-auto {
  294. position: absolute;
  295. top: 0px;
  296. left: 42%;
  297. z-index: 999;
  298. padding: 12px 20px;
  299. width: 400px;
  300. .search-input{
  301. -webkit-backdrop-filter: blur(5px);
  302. backdrop-filter: blur(5px);
  303. background: #01346f99;
  304. border-radius: 4px;
  305. }
  306. }
  307. .map-box{
  308. position: fixed;
  309. right: 50px;
  310. bottom: 50px;
  311. display: flex;
  312. align-items: center;
  313. z-index: 10;
  314. .map-group{
  315. display: flex;
  316. gap: 5px;
  317. align-items: center;
  318. background-color: #01346f3d;
  319. border: 1px solid #01346f3d;
  320. padding: 5px;
  321. border-radius: 5px;
  322. .map-item{
  323. display: grid;
  324. // gap: 0px 10px;
  325. // align-items: center;
  326. text-align: center;
  327. border-radius: 5px;
  328. // background: white;
  329. cursor: pointer;
  330. border: 2px solid #2881f600;
  331. }
  332. .map-item:hover{
  333. color: #2880f6;
  334. border: 2px solid #2880f6;
  335. }
  336. .active{
  337. color: #2880f6;
  338. border: 2px solid #2880f6;
  339. }
  340. .map-img{
  341. width: 80px;
  342. height: 100%;
  343. border-radius: 3px 3px 0px 0px;
  344. }
  345. .map-img-name{
  346. padding-bottom: 5px;
  347. background: #fff;
  348. border-radius: 0px 0px 3px 3px;
  349. }
  350. }
  351. }
  352. </style>