select.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. <template>
  2. <div class="select-com">
  3. <div class="draw __box-shadow">
  4. <div class="tools">
  5. <div class="label">空间选择:</div>
  6. <div class="right">
  7. <div class="item __hover" :class="{active: cusTransfer.selectParams.type === 'circle'}" @click="mapDraw('circle')">
  8. <img src="@/assets/images/gis-layout/gis-layout-tools_select-circle.png" alt=""/>圆形
  9. </div>
  10. <div class="line"/>
  11. <div class="item __hover" :class="{active: cusTransfer.selectParams.type === 'rectangle'}" @click="mapDraw('rectangle')">
  12. <img src="@/assets/images/gis-layout/gis-layout-tools_select-rectangle.png" alt=""/>矩形
  13. </div>
  14. <div class="line"/>
  15. <div class="item __hover" :class="{active: cusTransfer.selectParams.type === 'polygon'}" @click="mapDraw('polygon')">
  16. <img src="@/assets/images/gis-layout/gis-layout-tools_select-polygon.png" alt=""/>多边形
  17. </div>
  18. <div class="line"/>
  19. <div class="item __hover" @click="mapClear">
  20. <img src="@/assets/images/gis-layout/gis-layout-tools_select-clear.png" alt=""/>清除
  21. </div>
  22. </div>
  23. </div>
  24. </div>
  25. <div class="result __box-shadow" v-if="cusTransfer.selectParams.wkt" v-loading="cusTransfer.result.table.loading">
  26. <div class="head">查询结果</div>
  27. <div class="chart">
  28. <SelectChartCom :data="hasTypeCpt"/>
  29. </div>
  30. <div class="data">
  31. <div class="form">
  32. <CusFormColumn
  33. labelWidth="50"
  34. :span="24"
  35. link="select"
  36. label="类型:"
  37. v-model:param="cusTransfer.result.tempForm.type"
  38. :options="hasTypeCpt"
  39. static
  40. multiple
  41. collapse-tags
  42. />
  43. <div class="two">
  44. <CusFormColumn
  45. labelWidth="50"
  46. :span="24"
  47. label="搜索:"
  48. v-model:param="cusTransfer.result.tempForm.name"
  49. />
  50. <div class="__cus-buttons-2">
  51. <div class="__cus-button-submit __hover" @click="onSearch">搜索</div>
  52. <div class="__cus-button-cancel __hover" @click="onReset">重置</div>
  53. </div>
  54. </div>
  55. </div>
  56. <div class="table">
  57. <CusTable
  58. ref="ref_cusTable"
  59. :tableData="resultTableDataCpt"
  60. :tableHead="cusTransfer.result.table.head"
  61. :total="resultTableFilterCpt.length"
  62. :page="cusTransfer.result.table.pageNum"
  63. :pageSize="cusTransfer.result.table.pageSize"
  64. @handlePage="handlePage"
  65. :row-class-name="tableRowClassName"
  66. @row-click="handleRowClick"
  67. >
  68. </CusTable>
  69. </div>
  70. </div>
  71. </div>
  72. </div>
  73. </template>
  74. <script lang="ts">
  75. import {
  76. defineComponent,
  77. computed,
  78. onMounted,
  79. ref,
  80. reactive,
  81. watch,
  82. getCurrentInstance,
  83. ComponentInternalInstance,
  84. toRefs,
  85. nextTick, onUnmounted
  86. } from 'vue'
  87. import {useStore} from 'vuex'
  88. import {useRouter, useRoute} from 'vue-router'
  89. import {ElMessage, ElMessageBox} from "element-plus";
  90. import SelectChartCom from './select-chart.vue'
  91. import axios from "axios";
  92. import SelectDraw, {SelectDrawClear} from "./select-draw";
  93. export default defineComponent({
  94. name: '',
  95. components: {
  96. SelectChartCom
  97. },
  98. props: {
  99. map: {
  100. required: true
  101. },
  102. mapFunc: <any>{
  103. required: true
  104. },
  105. transfer: {}
  106. },
  107. setup(props, {emit}) {
  108. const store = useStore();
  109. const router = useRouter();
  110. const route = useRoute();
  111. const that = (getCurrentInstance() as ComponentInternalInstance).appContext.config.globalProperties
  112. const state = reactive({
  113. transfer: <any>props.transfer,
  114. cusTransfer: <any>{
  115. selectParams: {
  116. type: '',
  117. wkt: ''
  118. },
  119. result: {
  120. form: {},
  121. tempForm: {
  122. type: [],
  123. name: ''
  124. },
  125. table: {
  126. head: [
  127. {value: "typeName", label: "类型", show: true, align: 'left', width: 100},
  128. {value: "name", label: "名称", show: true, align: 'left'},
  129. ],
  130. data: <any>[],
  131. pageNum: 1,
  132. pageSize: 10,
  133. loading: false
  134. }
  135. }
  136. }
  137. })
  138. const mapClear = () => {
  139. SelectDrawClear(props.map)
  140. state.cusTransfer.selectParams = {
  141. type: '',
  142. wkt: ''
  143. }
  144. state.cusTransfer.result.table.data = []
  145. state.cusTransfer.result.table.pageNum = 1
  146. state.cusTransfer.result.form = {
  147. type: [],
  148. name: ''
  149. }
  150. }
  151. const mapDraw = (type) => {
  152. SelectDraw(props.map, type).then(({feature, wkt}) => {
  153. state.cusTransfer.selectParams.type = type
  154. state.cusTransfer.selectParams.wkt = wkt
  155. initData()
  156. }).catch(() => {})
  157. }
  158. const initData = () => {
  159. state.cusTransfer.result.table.data = []
  160. if (store.getters['gis/elementActiveArr'].length > 0) {
  161. state.cusTransfer.result.table.loading = true
  162. axios({
  163. url: store.state.gis.element.layer.getSource().getUrls()[0],
  164. method: 'get',
  165. params: {
  166. service: 'WFS',
  167. version: '1.0.0',
  168. request: 'GetFeature',
  169. typename: store.getters['gis/elementActiveArr'].map(v => store.getters['dictionary/elementTypeMapObj'].get(v.value).geoType).join(','),
  170. srsName: 'EPSG:4326',
  171. outputFormat: 'application/json',
  172. CQL_FILTER: `INTERSECTS(location, ${state.cusTransfer.selectParams.wkt})`
  173. }
  174. }).then(res => {
  175. state.cusTransfer.result.table.data = res.data.features.map(v => {
  176. const obj = {
  177. name: v.properties.name,
  178. typeName: store.getters['dictionary/elementTypeMap'].get(v.properties.typeValue),
  179. type: v.properties.typeValue,
  180. info: v.properties,
  181. id: v.properties.dataId,
  182. typeValue: v.properties.typeValue,
  183. wkt: `POINT(${v.geometry.coordinates.join(' ')})`,
  184. featureType: '',
  185. }
  186. if (['lgszyjkscsb', 'jgzzmgs', 'lgsjkyfl'].includes(v.properties.typeValue)) {
  187. obj.featureType = 'qy'
  188. } else if (['gal', 'shl', 'myl'].includes(v.properties.typeValue)) {
  189. obj.featureType = 'sb'
  190. }
  191. return obj
  192. })
  193. state.cusTransfer.result.table.loading = false
  194. }).catch(() => {
  195. state.cusTransfer.result.table.loading = false
  196. })
  197. }
  198. }
  199. const resultTableFilterCpt = computed(() => {
  200. return state.cusTransfer.result.table.data.filter(v => (state.cusTransfer.result.form.type.length === 0 || state.cusTransfer.result.form.type.includes(v.type)) && v.name.includes(state.cusTransfer.result.form.name))
  201. })
  202. const resultTableDataCpt = computed(() => {
  203. return resultTableFilterCpt.value.slice((state.cusTransfer.result.table.pageNum - 1) * state.cusTransfer.result.table.pageSize, state.cusTransfer.result.table.pageNum * state.cusTransfer.result.table.pageSize)
  204. })
  205. const handlePage = ({page, pageSize}: any) => {
  206. state.cusTransfer.result.table.pageNum = page
  207. state.cusTransfer.result.table.pageSize = pageSize
  208. }
  209. const hasTypeCpt = computed(() => {
  210. const m = new Map()
  211. state.cusTransfer.result.table.data.forEach(v => {
  212. if (m.has(v.typeName)) {
  213. m.set(v.typeName, m.get(v.typeName) + 1)
  214. } else {
  215. m.set(v.typeName, 1)
  216. }
  217. })
  218. const arr: any = []
  219. m.forEach((v, k) => {
  220. arr.push({
  221. dictValue: k,
  222. dictLabel: k,
  223. num: v
  224. })
  225. })
  226. return arr
  227. })
  228. const onSearch = () => {
  229. state.cusTransfer.result.table.pageNum = 1
  230. state.cusTransfer.result.form = JSON.parse(JSON.stringify(state.cusTransfer.result.tempForm))
  231. }
  232. const onReset = () => {
  233. state.cusTransfer.result.tempForm = {
  234. name: '',
  235. type: []
  236. }
  237. onSearch()
  238. }
  239. const tableRowClassName = ({row}) => {
  240. if (
  241. (row.featureType === 'qy' && row.id === store.state.gis.gisParams.qy.feature?.getId()) ||
  242. (row.featureType === 'sb' && row.id === store.state.gis.gisParams.default.feature?.getId())
  243. ) {
  244. return 'row-active'
  245. }
  246. return ''
  247. }
  248. const handleRowClick = (row) => {
  249. switch (row.featureType) {
  250. case 'qy': {
  251. if (row.id === store.state.gis.gisParams.qy.feature?.getId()) {
  252. store.dispatch('gis/LOAD_GIS_PARAMS_QY_RESET')
  253. } else {
  254. store.dispatch('gis/LOAD_GIS_PARAMS_QY', {
  255. wkt: row.wkt,
  256. id: row.id,
  257. info: row.info
  258. })
  259. }
  260. } break
  261. case 'sb': {
  262. if (row.id === store.state.gis.gisParams.default.feature?.getId()) {
  263. store.dispatch('gis/LOAD_GIS_PARAMS_DEFAULT_RESET')
  264. } else {
  265. store.dispatch('gis/LOAD_GIS_PARAMS_DEFAULT_SB', {
  266. wkt: row.wkt,
  267. id: row.id,
  268. info: row.info
  269. })
  270. }
  271. } break
  272. }
  273. }
  274. watch(() => state.cusTransfer, () => {
  275. emit('update:transfer', state.cusTransfer)
  276. }, { deep: true })
  277. onMounted(() => {
  278. if (props.transfer) {
  279. state.cusTransfer = props.transfer
  280. } else {
  281. emit('update:transfer', state.cusTransfer)
  282. }
  283. state.cusTransfer.result.form = JSON.parse(JSON.stringify(state.cusTransfer.result.tempForm))
  284. const realLayer = props.map?.getLayers().getArray().filter(v => v.get('layerName') === 'selectDrawLayer')?.[0]
  285. if (realLayer) {
  286. realLayer.setVisible(true)
  287. }
  288. })
  289. onUnmounted(() => {
  290. const realLayer = props.map?.getLayers().getArray().filter(v => v.get('layerName') === 'selectDrawLayer')?.[0]
  291. if (realLayer) {
  292. realLayer.setVisible(false)
  293. }
  294. })
  295. return {
  296. ...toRefs(state),
  297. mapDraw,
  298. mapClear,
  299. resultTableFilterCpt,
  300. resultTableDataCpt,
  301. handlePage,
  302. hasTypeCpt,
  303. onSearch,
  304. onReset,
  305. tableRowClassName,
  306. handleRowClick
  307. }
  308. },
  309. })
  310. </script>
  311. <style scoped lang="scss">
  312. .select-com {
  313. position: fixed;
  314. width: 404px;
  315. display: flex;
  316. flex-direction: column;
  317. .draw {
  318. width: 100%;
  319. height: 60px;
  320. background-color: #FFFFFF;
  321. display: flex;
  322. align-items: center;
  323. padding: 0 14px;
  324. .tools {
  325. width: 100%;
  326. display: flex;
  327. align-items: center;
  328. .label {
  329. width: 72px;
  330. font-size: 14px;
  331. font-family: Microsoft YaHei;
  332. font-weight: 400;
  333. color: #4C4C4C;
  334. display: flex;
  335. align-items: center;
  336. }
  337. .right {
  338. flex: 1;
  339. height: 36px;
  340. background-color: rgba(170, 198, 238, 0.2);
  341. border-radius: 4px;
  342. display: flex;
  343. align-items: center;
  344. justify-content: space-between;
  345. padding: 0 10px;
  346. .item {
  347. display: flex;
  348. align-items: center;
  349. font-size: 14px;
  350. font-family: Microsoft YaHei;
  351. font-weight: 400;
  352. color: #4C4C4C;
  353. >img {
  354. margin-right: 8px;
  355. }
  356. &.active {
  357. color: #1174DB;
  358. }
  359. }
  360. .line {
  361. width: 1px;
  362. height: 16px;
  363. background: linear-gradient(0deg, rgba(17,116,219,0) 0%, rgba(17,116,219,0.99) 50%, rgba(17,116,219,0) 100%);
  364. }
  365. }
  366. }
  367. }
  368. .result {
  369. width: 404px;
  370. position: fixed;
  371. height: calc(100% - 100px - 60px - 2px);
  372. bottom: 10px;
  373. background-color: #FFFFFF;
  374. flex: 1;
  375. display: flex;
  376. flex-direction: column;
  377. .head {
  378. height: 40px;
  379. font-size: 16px;
  380. font-family: Microsoft YaHei;
  381. font-weight: bold;
  382. color: #0096FF;
  383. display: flex;
  384. align-items: center;
  385. padding-left: 14px;
  386. border-bottom: 1px solid #EEEEEE;
  387. }
  388. .chart {
  389. height: 212px;
  390. width: 100%;
  391. }
  392. .data {
  393. flex: 1;
  394. padding: 0 12px 12px 12px;
  395. display: flex;
  396. flex-direction: column;
  397. .form {
  398. :deep(.el-form-item) {
  399. margin-bottom: 7px;
  400. }
  401. .two {
  402. display: flex;
  403. align-items: flex-start;
  404. .cus-form-column {
  405. flex: 1;
  406. margin-right: 8px;
  407. }
  408. }
  409. }
  410. .table {
  411. flex: 1;
  412. :deep(.row-active) {
  413. >td {
  414. background: rgba(16,140,243,0.1);
  415. }
  416. }
  417. }
  418. }
  419. }
  420. }
  421. </style>