AddForm.vue 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357
  1. <template>
  2. <div>
  3. <el-dialog
  4. :append-to-body="true"
  5. :before-close="handleClose"
  6. :close-on-click-modal="false"
  7. :title="title"
  8. :visible.sync="mapFormVisible"
  9. class="bs-dialog-wrap bs-el-dialog"
  10. width="700px"
  11. >
  12. <el-form
  13. ref="mapForm"
  14. :model="mapForm"
  15. :rules="rules"
  16. class="bs-el-form"
  17. label-width="120px"
  18. >
  19. <el-form-item
  20. label="上级地图"
  21. prop="parentId"
  22. >
  23. <el-input
  24. v-model="parentName"
  25. class="bs-el-input"
  26. disabled
  27. />
  28. </el-form-item>
  29. <el-form-item
  30. label="地图名称"
  31. prop="name"
  32. >
  33. <el-input
  34. v-model="mapForm.name"
  35. class="bs-el-input"
  36. placeholder="请输入"
  37. />
  38. </el-form-item>
  39. <el-form-item
  40. label="地图标识"
  41. prop="mapCode"
  42. >
  43. <template slot="label">
  44. <span>地图标识</span>
  45. <el-tooltip
  46. v-if="mapForm.parentId !== '0'"
  47. class="item"
  48. effect="light"
  49. content="子级的地图标识解析自上级地图的子区块数据"
  50. placement="top"
  51. >
  52. <i
  53. class="el-icon-warning-outline"
  54. style="color: #E3C98C;margin-left: 6px;font-size:14px"
  55. />
  56. </el-tooltip>
  57. </template>
  58. <el-input
  59. v-if="mapForm.parentId === '0'"
  60. v-model="mapForm.mapCode"
  61. class="bs-el-input"
  62. placeholder="请输入地图标识"
  63. />
  64. <el-select
  65. v-else
  66. v-model="mapForm.mapCode"
  67. class="bs-el-select"
  68. placeholder="请选择地图标识"
  69. popper-class="bs-el-select"
  70. >
  71. <el-option
  72. v-for="mapCode in mapCodeList"
  73. :key="mapCode.name"
  74. :disabled="mapCode.exist"
  75. :label="mapCode.name"
  76. :value="mapCode.name"
  77. >
  78. <span style="float: left">{{ mapCode.name }}</span>
  79. <span style="float: right; color: #8492a6; font-size: 13px">{{ mapCode.exist ? '已存在' : '' }}</span>
  80. </el-option>
  81. </el-select>
  82. </el-form-item>
  83. <el-form-item
  84. label="地图级别"
  85. prop="level"
  86. >
  87. <el-select
  88. v-model="mapForm.level"
  89. :disabled="mapForm.parentId !== '0'"
  90. class="bs-el-select"
  91. placeholder="请选择地图级别"
  92. popper-class="bs-el-select"
  93. >
  94. <el-option
  95. v-for="level in levelList"
  96. :key="level.value"
  97. :label="level.label"
  98. :value="level.value"
  99. />
  100. <el-option
  101. v-if="![0,1,2,3,4].includes(mapForm.level)"
  102. :value="mapForm.level"
  103. :label="outRangeLabel"
  104. />
  105. </el-select>
  106. </el-form-item>
  107. <el-form-item
  108. label="geoJson上传"
  109. >
  110. <vue-json-viewer
  111. v-model="mapForm.geoJson"
  112. theme="dark"
  113. :show-btns="false"
  114. mode="code"
  115. />
  116. <el-button
  117. class="bs-el-button-default"
  118. @click="upload"
  119. >
  120. <i class="el-icon-upload2" />
  121. 上传
  122. </el-button>
  123. </el-form-item>
  124. <el-form-item
  125. v-if="autoParseNextLevelShow"
  126. label="自动解析下一级"
  127. prop="autoParseNextLevel"
  128. >
  129. <el-switch
  130. v-model="mapForm.autoParseNextLevel"
  131. :active-value="1"
  132. :inactive-value="0"
  133. class="bs-el-switch"
  134. />
  135. </el-form-item>
  136. </el-form>
  137. <span
  138. slot="footer"
  139. class="dialog-footer"
  140. >
  141. <el-button
  142. class="bs-el-button-default"
  143. @click="handleClose"
  144. >
  145. 取消
  146. </el-button>
  147. <el-button
  148. type="primary"
  149. @click="submitForm"
  150. >
  151. 确定
  152. </el-button>
  153. </span>
  154. </el-dialog>
  155. <input
  156. ref="geoJsonFile"
  157. accept=".json"
  158. name="file"
  159. style="display: none"
  160. type="file"
  161. @change="handleBatchUpload"
  162. >
  163. </div>
  164. </template>
  165. <script>
  166. import vueJsonViewer from 'vue-json-viewer'
  167. import { getMapChildFromGeoJson, mapAdd, repeatCheck, nameRepeatCheck } from 'data-room-ui/js/utils/mapDataService'
  168. export default {
  169. name: 'AddForm',
  170. components: {
  171. vueJsonViewer
  172. },
  173. computed: {
  174. autoParseNextLevelShow () {
  175. // geoJson 不为空
  176. return !this.isEmpty(this.mapForm.geoJson)
  177. },
  178. outRangeLabel() {
  179. return `级别${this.mapForm.level + 1}`;
  180. }
  181. },
  182. data () {
  183. const validateCode = (rule, value, callback) => {
  184. if (this.mapForm.parentId !== '0') {
  185. // 不需要校验
  186. callback()
  187. return
  188. }
  189. repeatCheck({
  190. parentId: this.mapForm.parentId,
  191. mapCode: value
  192. }).then(res => {
  193. if (res) {
  194. callback(new Error('地图标识已存在'))
  195. } else {
  196. callback()
  197. }
  198. })
  199. }
  200. const validateName = (rule, value, callback) => {
  201. nameRepeatCheck({
  202. parentId: this.mapForm.parentId,
  203. mapName: value
  204. }).then(res => {
  205. if (res) {
  206. callback(new Error('地图名称已存在'))
  207. } else {
  208. callback()
  209. }
  210. })
  211. }
  212. return {
  213. mapFormVisible: false,
  214. geoJsonVisible: false,
  215. uploadLoading: false,
  216. title: '新增地图数据',
  217. parentName: '顶级',
  218. mapForm: {
  219. parentId: '0',
  220. mapCode: '',
  221. name: '',
  222. level: 0,
  223. geoJson: {},
  224. uploadedGeoJson: 0,
  225. autoParseNextLevel: 0
  226. },
  227. rules: {
  228. mapCode: [
  229. { required: true, message: '请选择地图标识', trigger: 'blur' },
  230. { validator: validateCode, trigger: 'blur' }
  231. ],
  232. name: [
  233. { required: true, message: '请输入地图名称', trigger: 'blur' },
  234. { validator: validateName, trigger: 'blur' }
  235. ],
  236. level: [
  237. { required: true, message: '请选择地图级别', trigger: 'change' }
  238. ]
  239. },
  240. levelList: [
  241. { value: 0, label: '世界' },
  242. { value: 1, label: '国家' },
  243. { value: 2, label: '省份' },
  244. { value: 3, label: '城市' },
  245. { value: 4, label: '区县' }
  246. ],
  247. mapCodeList: []
  248. }
  249. },
  250. methods: {
  251. init (parentMap) {
  252. this.mapForm = {
  253. parentId: '0',
  254. mapCode: `map-${new Date().getTime()}`,
  255. name: '',
  256. level: 0,
  257. geoJson: {},
  258. uploadedGeoJson: 0,
  259. autoParseNextLevel: 0
  260. }
  261. this.parentName = '顶级'
  262. if (parentMap) {
  263. this.mapForm.parentId = parentMap.id
  264. this.parentName = parentMap.name
  265. this.mapForm.level = parentMap.level + 1
  266. this.mapForm.mapCode = ''
  267. this.getMapCodeList()
  268. }
  269. },
  270. handleClose () {
  271. this.mapFormVisible = false
  272. },
  273. submitForm () {
  274. this.$refs.mapForm.validate(valid => {
  275. if (!valid) {
  276. return false
  277. }
  278. let geoJson
  279. // 如果geoJson是空的,包括空字符串,纯空格、空对象,空数组,都不允许提交
  280. if (this.isEmpty(this.mapForm.geoJson)) {
  281. geoJson = ''
  282. } else {
  283. geoJson = JSON.stringify(this.mapForm.geoJson)
  284. }
  285. mapAdd({
  286. ...this.mapForm,
  287. geoJson: geoJson
  288. }).then(res => {
  289. this.mapFormVisible = false
  290. this.$emit('refresh', {
  291. id: res,
  292. parentId: this.mapForm.parentId
  293. })
  294. })
  295. })
  296. },
  297. isEmpty (obj) {
  298. if (typeof obj === 'object') {
  299. return Object.keys(obj).length === 0 && obj.constructor === Object
  300. }
  301. if (typeof obj === 'string') {
  302. return /^\s*$/.test(obj)
  303. }
  304. return Array.isArray(obj) && obj.length === 0
  305. },
  306. getMapCodeList () {
  307. this.mapCodeList = []
  308. if (this.mapForm.parentId === '0') {
  309. this.mapCodeList = [{
  310. name: `map-${new Date().getTime()}`,
  311. exist: false
  312. }]
  313. } else {
  314. getMapChildFromGeoJson(this.mapForm.parentId).then(res => {
  315. this.mapCodeList = res
  316. })
  317. }
  318. },
  319. upload () {
  320. this.$refs.geoJsonFile.click()
  321. },
  322. handleBatchUpload (source) {
  323. this.uploadLoading = true
  324. const file = source.target.files
  325. const reader = new FileReader() // 新建一个FileReader
  326. reader.readAsText(file[0], 'UTF-8') // 读取文件
  327. reader.onload = (event) => {
  328. const jsonStr = event.target.result
  329. // 读取文件内容
  330. try {
  331. this.mapForm.geoJson = JSON.parse(jsonStr)
  332. } catch (e) {
  333. this.uploadLoading = false
  334. this.$message.error('JSON文件格式错误')
  335. return false
  336. }
  337. this.uploadLoading = false
  338. // input通过onchange事件来触发js代码的,由于两次文件是重复的,所以这个时候onchange事件是没有触发到的,所以需要手动清空input的值
  339. source.target.value = ''
  340. }
  341. }
  342. }
  343. }
  344. </script>
  345. <style lang="scss" scoped>
  346. @import '../../assets/style/bsTheme.scss';
  347. .jv-container.dark {
  348. color: aliceblue;
  349. background: #161A26;
  350. }
  351. </style>