You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

336 lines
9.1 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div>
<el-dialog
:append-to-body="true"
:before-close="handleClose"
:close-on-click-modal="false"
:title="title"
:visible.sync="mapFormVisible"
class="bs-dialog-wrap bs-el-dialog"
width="700px"
>
<el-form
ref="mapForm"
:model="mapForm"
:rules="rules"
class="bs-el-form"
label-width="120px"
>
<el-form-item
label="上级地图"
prop="parentId"
>
<el-input
v-model="parentName"
class="bs-el-input"
disabled
/>
</el-form-item>
<el-form-item
label="地图名称"
prop="name"
>
<el-input
v-model="mapForm.name"
class="bs-el-input"
placeholder="请输入"
/>
</el-form-item>
<el-form-item
label="地图标识"
prop="mapCode"
>
<template slot="label">
<span>地图标识</span>
<el-tooltip
v-if="mapForm.parentId !== '0'"
class="item"
effect="light"
content="地图标识取自上级地图JSON数据中的properties.name值用于在地图中显示地区名称"
placement="top"
>
<i
class="el-icon-warning-outline"
style="color: #E3C98C;margin-left: 6px;font-size:14px"
/>
</el-tooltip>
</template>
<el-input
v-model="mapForm.mapCode"
class="bs-el-input"
placeholder="请输入地图标识"
/>
</el-form-item>
<el-form-item
label="地图级别"
prop="level"
>
<template slot="label">
<span>地图级别</span>
<el-tooltip
v-if="mapForm.parentId !== '0'"
class="item"
effect="light"
content="子级地图的级别根据上级地图自动递增,不可修改"
placement="top"
>
<i
class="el-icon-warning-outline"
style="color: #E3C98C;margin-left: 6px;font-size:14px"
/>
</el-tooltip>
</template>
<el-select
v-model="mapForm.level"
disabled
class="bs-el-select"
placeholder="请选择地图级别"
popper-class="bs-el-select"
>
<el-option
v-for="level in levelList"
:key="level.value"
:label="level.label"
:value="level.value"
/>
<el-option
v-if="![0,1,2,3,4].includes(mapForm.level)"
:value="mapForm.level"
:label="outRangeLabel"
/>
</el-select>
</el-form-item>
<el-form-item
label="geoJson"
>
<vue-json-viewer
v-model="mapForm.geoJson"
theme="dark"
:show-btns="false"
mode="code"
/>
<el-button
v-if="mapForm.uploadedGeoJson !== 1"
class="bs-el-button-default"
@click="upload"
>
<i class="el-icon-upload2" />
上传
</el-button>
</el-form-item>
<el-form-item
v-if="autoParseNextLevelShow"
label="自动解析下一级"
prop="autoParseNextLevel"
>
<el-switch
v-model="mapForm.autoParseNextLevel"
:active-value="1"
:inactive-value="0"
class="bs-el-switch"
/>
</el-form-item>
</el-form>
<span
slot="footer"
class="dialog-footer"
>
<el-button
class="bs-el-button-default"
@click="handleClose"
>
取消
</el-button>
<el-button
type="primary"
@click="submitForm"
>
确定
</el-button>
</span>
</el-dialog>
<input
ref="geoJsonFile"
accept=".json"
name="file"
style="display: none"
type="file"
@change="handleBatchUpload"
>
</div>
</template>
<script>
import _ from 'lodash'
import vueJsonViewer from 'vue-json-viewer'
import { mapUpdate, getMapChildFromGeoJson, nameRepeatCheck } from 'data-room-ui/js/utils/mapDataService'
export default {
name: 'EditForm',
components: {
vueJsonViewer
},
computed: {
autoParseNextLevelShow () {
// geoJson 不为空,且未上传过(说明是刚上传的)
return !this.isWhitespace(this.mapForm.geoJson) && this.mapForm.uploadedGeoJson === 0
},
outRangeLabel() {
return `级别${this.mapForm.level}`;
}
},
data () {
const validateCode = (rule, value, callback) => {
if (this.mapForm.parentId === '0' || this.mapForm.parentId === 0) {
// 不需要校验
callback()
return
}
getMapChildFromGeoJson(this.mapForm.parentId).then(children => {
let repeat = false
children.forEach(child => {
if (child.exist && child.name === value && child.existId !== this.mapForm.id) {
repeat = true
}
})
if (repeat) {
callback(new Error('地图标识已存在'))
} else {
callback()
}
})
}
const validateName = (rule, value, callback) => {
if (this.mapForm.parentId !== '0') {
// 不需要校验
callback()
return
}
nameRepeatCheck({
id: this.mapForm.id,
parentId: this.mapForm.parentId,
mapName: value
}).then(res => {
if (res) {
callback(new Error('地图名称已存在'))
} else {
callback()
}
})
}
return {
mapFormVisible: false,
geoJsonVisible: false,
uploadLoading: false,
title: '编辑地图数据',
parentName: '顶级',
mapForm: {
parentId: '0',
mapCode: '',
name: '',
level: 0,
geoJson: '',
uploadedGeoJson: 0,
autoParseNextLevel: 0
},
rules: {
mapCode: [
{ required: true, message: '请输入地图标识', trigger: 'blur' },
{ validator: validateCode, trigger: 'blur' }
],
name: [
{ required: true, message: '请输入地图名称', trigger: 'blur' },
{ validator: validateName, trigger: 'blur' }
],
level: [
{ required: true, message: '请选择地图级别', trigger: 'change' }
],
geoJson: [
{ required: true, message: '请上传地图数据', trigger: 'change' }
]
},
levelList: [
{ value: 0, label: '世界' },
{ value: 1, label: '国家' },
{ value: 2, label: '省份' },
{ value: 3, label: '城市' },
{ value: 4, label: '区县' }
],
mapCodeList: []
}
},
methods: {
init (map) {
this.mapForm = _.cloneDeep(map)
if (!this.isWhitespace(this.mapForm.geoJson)) {
this.mapForm.geoJson = JSON.parse(this.mapForm.geoJson)
}
},
handleClose () {
this.mapFormVisible = false
},
submitForm () {
this.$refs.mapForm.validate(valid => {
if (!valid) {
return false
}
let geoJson
// 如果geoJson是空的包括空字符串纯空格、空对象空数组都不允许提交
if (this.isWhitespace(this.mapForm.geoJson) || this.mapForm.geoJson === '{}' || this.mapForm.geoJson === '[]') {
geoJson = ''
} else {
geoJson = JSON.stringify(this.mapForm.geoJson)
}
mapUpdate({
...this.mapForm,
geoJson: geoJson
}).then(res => {
this.mapFormVisible = false
this.$emit('refresh')
})
})
},
isWhitespace (str) {
// 如果是null、undefined返回true
if (str == null) {
return true
}
return /^\s*$/.test(str)
},
upload () {
this.$refs.geoJsonFile.click()
},
handleBatchUpload (source) {
this.uploadLoading = true
const file = source.target.files
const reader = new FileReader() // 新建一个FileReader
reader.readAsText(file[0], 'UTF-8') // 读取文件
reader.onload = (event) => {
const jsonStr = event.target.result
// 读取文件内容
try {
this.mapForm.geoJson = JSON.parse(jsonStr)
} catch (e) {
this.uploadLoading = false
this.$message.error('JSON文件格式错误')
return false
}
this.uploadLoading = false
// input通过onchange事件来触发js代码的由于两次文件是重复的所以这个时候onchange事件是没有触发到的所以需要手动清空input的值
source.target.value = ''
}
}
}
}
</script>
<style lang="scss" scoped>
@import '../../assets/style/bsTheme.scss';
.jv-container.dark {
color: aliceblue;
background: #161A26;
}
</style>