index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. <template>
  2. <div class="bs-container">
  3. <div class="inner-container">
  4. <el-form
  5. :inline="true"
  6. class="filter-container"
  7. >
  8. <el-form-item class="filter-input filter-item">
  9. <el-input
  10. v-model="searchForm.searchKey"
  11. class="bs-el-input"
  12. clearable
  13. maxlength="200"
  14. placeholder="请输入地图名称或编码"
  15. />
  16. </el-form-item>
  17. <el-form-item class="filter-item">
  18. <el-select
  19. v-model="searchForm.level"
  20. class="bs-el-select"
  21. clearable
  22. placeholder="请选择地图级别"
  23. popper-class="bs-el-select"
  24. @change="getDataList"
  25. >
  26. <el-option
  27. v-for="level in levelList"
  28. :key="level.value"
  29. :label="level.label"
  30. :value="level.value"
  31. />
  32. </el-select>
  33. </el-form-item>
  34. <el-form-item class="filter-item">
  35. <el-button
  36. :loading="searchLoading"
  37. icon="el-icon-search"
  38. type="primary"
  39. @click="getDataList"
  40. >
  41. 查询
  42. </el-button>
  43. </el-form-item>
  44. <el-form-item class="filter-item">
  45. <el-button
  46. class="bs-el-button-default"
  47. @click="addMap"
  48. >
  49. 新增
  50. </el-button>
  51. </el-form-item>
  52. </el-form>
  53. <div class="bs-table-box">
  54. <el-table
  55. v-loading="searchLoading"
  56. ref="table"
  57. v-table
  58. :data="mapList"
  59. :element-loading-text="loadingText"
  60. :load="load"
  61. :tree-props="{children: 'children', hasChildren: 'hasChildren'}"
  62. class="bs-el-table bs-scrollbar"
  63. height="0"
  64. lazy
  65. row-key="id"
  66. >
  67. <el-empty slot="empty"/>
  68. <el-table-column
  69. align="left"
  70. label="名称"
  71. prop="name"
  72. show-overflow-tooltip
  73. />
  74. <el-table-column
  75. align="center"
  76. label="编码"
  77. prop="mapCode"
  78. show-overflow-tooltip
  79. />
  80. <el-table-column
  81. align="center"
  82. label="级别"
  83. prop="level"
  84. show-overflow-tooltip
  85. >
  86. <template slot-scope="scope">
  87. <span v-if="scope.row.level === 0">世界</span>
  88. <span v-else-if="scope.row.level === 1">国家</span>
  89. <span v-else-if="scope.row.level === 2">省份</span>
  90. <span v-else-if="scope.row.level === 3">城市</span>
  91. <span v-else-if="scope.row.level === 4">区县</span>
  92. </template>
  93. </el-table-column>
  94. <el-table-column
  95. align="center"
  96. label="开启下钻"
  97. prop="enableDown"
  98. show-overflow-tooltip
  99. >
  100. <template slot-scope="scope">
  101. <span v-if="scope.row.enableDown === 1">是</span>
  102. <span v-else>否</span>
  103. </template>
  104. </el-table-column>
  105. <el-table-column
  106. align="center"
  107. label="已上传配置JSON"
  108. prop="uploadedGeoJson"
  109. show-overflow-tooltip
  110. >
  111. <template slot-scope="scope">
  112. <span v-if="scope.row.uploadedGeoJson === 1">是</span>
  113. <span v-else>否</span>
  114. </template>
  115. </el-table-column>
  116. <el-table-column
  117. align="center"
  118. label="操作"
  119. width="200"
  120. >
  121. <template slot-scope="scope">
  122. <el-button
  123. class="bs-el-button-default"
  124. @click="editMap(scope.row)"
  125. >
  126. 编辑
  127. </el-button>
  128. <el-button
  129. class="bs-el-button-default"
  130. @click="deleteMap(scope.row)"
  131. >
  132. 删除
  133. </el-button>
  134. <el-button
  135. v-if="scope.row.uploadedGeoJson === 1"
  136. class="bs-el-button-default"
  137. @click="addChild(scope.row)"
  138. >
  139. 添加下级
  140. </el-button>
  141. <el-button
  142. v-if="scope.row.uploadedGeoJson === 0"
  143. class="bs-el-button-default"
  144. @click="uploadGeoJson(scope.row)"
  145. >
  146. 上传配置
  147. </el-button>
  148. </template>
  149. </el-table-column>
  150. </el-table>
  151. </div>
  152. </div>
  153. <add-form
  154. ref="addForm"
  155. @refresh="getDataList"
  156. />
  157. <edit-form
  158. ref="editForm"
  159. @refresh="getDataList"
  160. />
  161. <el-dialog
  162. :close-on-click-modal="false"
  163. :visible.sync="geoJsonVisible"
  164. append-to-body
  165. class="bs-dialog-wrap bs-el-dialog"
  166. height="1000px"
  167. title="geoJson数据"
  168. width="1000px"
  169. >
  170. <vue-json-viewer
  171. v-model="currentMapGeoJSon"
  172. theme="dark"
  173. :show-btns="false"
  174. mode="code"
  175. />
  176. <el-button
  177. class="bs-el-button-default"
  178. @click="upload()"
  179. >
  180. <i class="el-icon-upload2"></i>
  181. 上传
  182. </el-button>
  183. <span
  184. slot="footer"
  185. class="dialog-footer"
  186. >
  187. <el-button
  188. class="bs-el-button-default"
  189. @click="submitUpload"
  190. >提交</el-button>
  191. </span>
  192. </el-dialog>
  193. <input
  194. ref="geoJsonFileUpload"
  195. accept=".json"
  196. name="file"
  197. style="display: none"
  198. type="file"
  199. @change="handleBatchUpload"
  200. >
  201. </div>
  202. </template>
  203. <script>
  204. import table from 'data-room-ui/js/utils/table.js'
  205. import {mapList, mapDelete, uploadGeoJson, mapCascadeDelete} from 'data-room-ui/js/utils/mapDataService'
  206. import AddForm from "./AddForm"
  207. import EditForm from "./EditForm"
  208. import vueJsonViewer from 'vue-json-viewer'
  209. export default {
  210. name: "MapManagement",
  211. directives: {
  212. table // 注册自定义指令
  213. },
  214. components: {
  215. AddForm,
  216. EditForm,
  217. vueJsonViewer
  218. },
  219. data() {
  220. return {
  221. currentMap: {}, // 当前操作的地图
  222. currentMapGeoJSon: {}, // 当前操作的地图geoJson
  223. loadingText: '',
  224. searchLoading: false,
  225. geoJsonVisible: false,
  226. lazyResolveIds: [],
  227. searchForm: {
  228. searchKey: '',
  229. level: null,
  230. enableDown: null,
  231. uploadedGeoJson: null,
  232. parentId: '0'
  233. },
  234. levelList: [
  235. {
  236. label: '世界',
  237. value: 0
  238. },
  239. {
  240. label: '国家',
  241. value: 1
  242. },
  243. {
  244. label: '省份',
  245. value: 2
  246. },
  247. {
  248. label: '城市',
  249. value: 3
  250. },
  251. {
  252. label: '区县',
  253. value: 4
  254. }
  255. ],
  256. mapList: []
  257. }
  258. },
  259. mounted() {
  260. this.init()
  261. },
  262. methods: {
  263. init() {
  264. this.searchLoading = true
  265. this.loadingText = '正在加载地图数据...'
  266. mapList(this.searchForm).then(res => {
  267. this.mapList = res
  268. this.searchLoading = false
  269. }).catch(err => {
  270. this.searchLoading = false
  271. })
  272. },
  273. getDataList() {
  274. this.searchLoading = true
  275. this.loadingText = '正在加载地图数据...'
  276. mapList(this.searchForm).then(res => {
  277. this.mapList = res
  278. this.searchLoading = false
  279. }).catch(err => {
  280. this.searchLoading = false
  281. })
  282. // 清除展开状态
  283. for (let i = 0; i < this.lazyResolveIds.length; i++) {
  284. this.$refs.table.store.states.treeData[this.lazyResolveIds[i]].loaded = false;
  285. this.$refs.table.store.states.treeData[this.lazyResolveIds[i]].expanded = false
  286. }
  287. },
  288. addMap() {
  289. this.$refs.addForm.mapFormVisible = true
  290. this.$refs.addForm.init()
  291. },
  292. load(data, treeNode, resolve) {
  293. this.lazyResolveIds.push(data.id)
  294. mapList({
  295. parentId: data.id
  296. }).then(res => {
  297. resolve(res)
  298. }).catch(err => {
  299. resolve([])
  300. })
  301. },
  302. deleteMap(map) {
  303. this.$confirm('确定删除该地图?', '提示', {
  304. confirmButtonText: '确定',
  305. cancelButtonText: '取消',
  306. type: 'warning',
  307. customClass: 'bs-el-message-box'
  308. }).then(async () => {
  309. mapDelete(map.id).then(() => {
  310. this.$message({
  311. type: 'success',
  312. message: '删除成功'
  313. })
  314. this.getDataList()
  315. }).catch(() => {
  316. this.deleteMapCascade(map)
  317. })
  318. }).catch(() => {
  319. })
  320. },
  321. deleteMapCascade(map) {
  322. this.$confirm('该地图存在子级,是否直接删除该地图以及其所有子级?', '提示', {
  323. confirmButtonText: '确定',
  324. cancelButtonText: '取消',
  325. type: 'warning',
  326. customClass: 'bs-el-message-box'
  327. }).then(async () => {
  328. mapCascadeDelete(map.id).then(() => {
  329. this.$message({
  330. type: 'success',
  331. message: '删除成功'
  332. })
  333. this.getDataList()
  334. }).catch(() => {
  335. })
  336. }).catch(() => {
  337. })
  338. },
  339. addChild(map) {
  340. this.$refs.addForm.mapFormVisible = true
  341. this.$refs.addForm.init(map)
  342. },
  343. editMap(map) {
  344. this.$refs.editForm.mapFormVisible = true
  345. this.$refs.editForm.init(map)
  346. },
  347. uploadGeoJson(map) {
  348. this.currentMap = map
  349. this.currentMapGeoJSon = {}
  350. this.geoJsonVisible = true
  351. },
  352. upload() {
  353. this.$refs.geoJsonFileUpload.click()
  354. },
  355. handleBatchUpload(source) {
  356. this.uploadLoading = true
  357. const file = source.target.files
  358. const reader = new FileReader() // 新建一个FileReader
  359. reader.readAsText(file[0], 'UTF-8') // 读取文件
  360. reader.onload = (event) => {
  361. let jsonStr = event.target.result
  362. // 读取文件内容
  363. try {
  364. this.currentMapGeoJSon = JSON.parse(jsonStr)
  365. } catch (e) {
  366. this.uploadLoading = false
  367. this.$message.error('JSON文件格式错误')
  368. return false
  369. }
  370. this.uploadLoading = false
  371. // input通过onchange事件来触发js代码的,由于两次文件是重复的,所以这个时候onchange事件是没有触发到的,所以需要手动清空input的值
  372. source.target.value = ''
  373. }
  374. },
  375. submitUpload() {
  376. // 先检查JSON是否合法
  377. if (typeof this.currentMapGeoJSon === 'string') {
  378. this.$message.error('JSON文件格式错误')
  379. return false
  380. }
  381. if (this.currentMapGeoJSon === {}) {
  382. this.$message.error('JSON数据不能为空')
  383. return false
  384. }
  385. // 调接口保存
  386. uploadGeoJson({
  387. id: this.currentMap.id,
  388. geoJson: JSON.stringify(this.currentMapGeoJSon)
  389. }).then(res => {
  390. this.$message({
  391. type: 'success',
  392. message: '上传成功'
  393. })
  394. this.geoJsonVisible = false
  395. this.getDataList()
  396. }).catch(err => {
  397. this.$message({
  398. type: 'error',
  399. message: '上传失败'
  400. })
  401. })
  402. this.geoJsonVisible = false
  403. },
  404. isWhitespace(str) {
  405. // 如果是null、undefined,返回true
  406. if (str == null) {
  407. return true
  408. }
  409. return /^\s*$/.test(str);
  410. },
  411. },
  412. }
  413. </script>
  414. <style lang="scss" scoped>
  415. @import '../../assets/style/bsTheme.scss';
  416. .jv-container.dark {
  417. color: aliceblue;
  418. background: #161A26;
  419. height: 150px;
  420. }
  421. </style>