IndexView.vue 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. <template>
  2. <div class="home">
  3. <Header></Header>
  4. <Map ref="childRef"/>
  5. <DrawMap></DrawMap>
  6. <div class="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. };
  66. },
  67. mounted() {
  68. this.initData();
  69. },
  70. beforeDestroy() {
  71. // 在组件销毁前移除事件监听器
  72. },
  73. methods: {
  74. initData(){
  75. this.getDmsDataList();
  76. },
  77. getDmsDataList(){
  78. const that = this;
  79. let requestParams = {
  80. columnId: webConfig.columnArr[0].id,
  81. states: "0,1,2,3",
  82. orderBy: JSON.stringify([{ field: "c_xm", orderByType: 2 }]),
  83. pageSize: 99999,
  84. page: 0,
  85. };
  86. commonAPI.getDmsDataList(requestParams).then((res) => {
  87. if (res.code == 200){
  88. let data = res.content.data;
  89. data = data.map(item => {
  90. // 给每个属性名称添加 c_ 前缀
  91. const newItem = {};
  92. for (const key in item) {
  93. // 如果已经有c_
  94. if (key.includes("c_")) {
  95. let itemkey = key.replace(/c_/g, "");
  96. newItem['c_' + itemkey] = item[key];
  97. }else{
  98. newItem[key] = item[key];
  99. }
  100. }
  101. return newItem;
  102. })
  103. // console.log("data:", data);
  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. // console.log('[ setItem(guid) ] >');
  227. sessionStorage.setItem('guid', "");
  228. that.$refs.childRef.setTableShow(that.searchText)
  229. }
  230. },
  231. }
  232. };
  233. </script>
  234. <style>
  235. .el-select__wrapper{
  236. min-height: 40px !important;
  237. background: transparent !important;
  238. /* box-shadow: 0 0 0 1px #01346fe0 inset; */
  239. }
  240. .el-select__placeholder{
  241. color: #fff !important;
  242. }
  243. .el-tag.el-tag--info{
  244. --el-tag-text-color: #ffffff !important;
  245. }
  246. .el-tag.el-tag--info {
  247. --el-tag-bg-color: #f3f3f700;
  248. }
  249. .el-popper.is-light{
  250. background: #01346fe0 !important;
  251. border: 1px solid #01346fe0 !important;
  252. max-width: none !important;
  253. }
  254. .el-select-dropdown__item{
  255. color: #fff !important;
  256. }
  257. .el-select-dropdown__item.is-hovering{
  258. background: linear-gradient(to right, #01346fe0, #02a7bd, #01346fe0) !important;
  259. color: #fff !important;
  260. }
  261. </style>
  262. <style lang="less" scoped>
  263. .home {
  264. width: 100%;
  265. height: 100%;
  266. // position: relative;
  267. // user-select: none;
  268. /* Chrome, Opera, Safari */
  269. // -moz-user-select: none;
  270. /* Firefox */
  271. // -ms-user-select: none;
  272. /* Internet Explorer/Edge */
  273. // -khtml-user-select: none;
  274. /* Konqueror/Safari */
  275. // -webkit-user-select: none;
  276. /* Webkit */
  277. // user-select: none;
  278. /* 标准语法 */
  279. }
  280. .search-box {
  281. position: absolute;
  282. top: 60px;
  283. left: 42%;
  284. z-index: 999;
  285. padding: 12px 20px;
  286. width: 400px;
  287. .search-input{
  288. -webkit-backdrop-filter: blur(5px);
  289. backdrop-filter: blur(5px);
  290. background: #01346f99;
  291. border-radius: 4px;
  292. }
  293. }
  294. .map-box{
  295. position: fixed;
  296. right: 50px;
  297. bottom: 50px;
  298. display: flex;
  299. align-items: center;
  300. z-index: 10;
  301. .map-group{
  302. display: flex;
  303. gap: 5px;
  304. align-items: center;
  305. background-color: #01346f3d;
  306. border: 1px solid #01346f3d;
  307. padding: 5px;
  308. border-radius: 5px;
  309. .map-item{
  310. display: grid;
  311. // gap: 0px 10px;
  312. // align-items: center;
  313. text-align: center;
  314. border-radius: 5px;
  315. // background: white;
  316. cursor: pointer;
  317. border: 2px solid #2881f600;
  318. }
  319. .map-item:hover{
  320. color: #2880f6;
  321. border: 2px solid #2880f6;
  322. }
  323. .active{
  324. color: #2880f6;
  325. border: 2px solid #2880f6;
  326. }
  327. .map-img{
  328. width: 80px;
  329. height: 100%;
  330. border-radius: 3px 3px 0px 0px;
  331. }
  332. .map-img-name{
  333. padding-bottom: 5px;
  334. background: #fff;
  335. border-radius: 0px 0px 3px 3px;
  336. }
  337. }
  338. }
  339. </style>