7 changed files with 1138 additions and 53 deletions
@ -0,0 +1,289 @@ |
|||
<template> |
|||
<div v-if="value" class="external-params-dialog"> |
|||
<div class="dialog-content"> |
|||
<div class="dialog-header"> |
|||
<h3>外部参数设置</h3> |
|||
<div class="close-btn" @click="closeDialog">×</div> |
|||
</div> |
|||
|
|||
<div class="dialog-body"> |
|||
<el-form :model="formData" ref="formRef" label-width="100px" size="small"> |
|||
<el-divider content-position="left">数据卡数据</el-divider> |
|||
|
|||
<el-form-item label="数据卡路径"> |
|||
<el-input v-model="formData.dataCardPath" placeholder="请选择数据卡路径"> |
|||
<el-button slot="append" icon="el-icon-folder-opened" @click="selectDataCardPath">浏览</el-button> |
|||
</el-input> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="数据格式"> |
|||
<el-select v-model="formData.dataCardFormat" placeholder="请选择数据格式" style="width: 100%;"> |
|||
<el-option label="XML" value="xml"></el-option> |
|||
<el-option label="JSON" value="json"></el-option> |
|||
<el-option label="CSV" value="csv"></el-option> |
|||
<el-option label="TXT" value="txt"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-divider content-position="left">GPS数据</el-divider> |
|||
|
|||
<el-form-item label="GPS数据源"> |
|||
<el-select v-model="formData.gpsDataSource" placeholder="请选择GPS数据源" style="width: 100%;"> |
|||
<el-option label="内置GPS" value="internal"></el-option> |
|||
<el-option label="外部GPS设备" value="external"></el-option> |
|||
<el-option label="网络GPS服务" value="network"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="GPS端口"> |
|||
<el-input v-model="formData.gpsPort" placeholder="请输入GPS端口"></el-input> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="波特率"> |
|||
<el-select v-model="formData.gpsBaudRate" placeholder="请选择波特率" style="width: 100%;"> |
|||
<el-option label="9600" value="9600"></el-option> |
|||
<el-option label="19200" value="19200"></el-option> |
|||
<el-option label="38400" value="38400"></el-option> |
|||
<el-option label="57600" value="57600"></el-option> |
|||
<el-option label="115200" value="115200"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="刷新频率"> |
|||
<el-input-number |
|||
v-model="formData.gpsRefreshRate" |
|||
:min="1" |
|||
:max="60" |
|||
placeholder="请输入刷新频率" |
|||
style="width: 100%;" |
|||
suffix="秒" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-divider content-position="left">导入设置</el-divider> |
|||
|
|||
<el-form-item label="导入机场"> |
|||
<div class="import-section"> |
|||
<el-input v-model="formData.airportPath" placeholder="请选择机场数据文件"> |
|||
<el-button slot="append" icon="el-icon-folder-opened" @click="selectAirportPath">浏览</el-button> |
|||
</el-input> |
|||
<el-button type="primary" size="small" @click="importAirport" style="margin-top: 8px;">导入机场</el-button> |
|||
</div> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="导入航路"> |
|||
<div class="import-section"> |
|||
<el-input v-model="formData.routePath" placeholder="请选择航路数据文件"> |
|||
<el-button slot="append" icon="el-icon-folder-opened" @click="selectRoutePath">浏览</el-button> |
|||
</el-input> |
|||
<el-button type="primary" size="small" @click="importRoute" style="margin-top: 8px;">导入航路</el-button> |
|||
</div> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="导入地标"> |
|||
<div class="import-section"> |
|||
<el-input v-model="formData.landmarkPath" placeholder="请选择地标数据文件"> |
|||
<el-button slot="append" icon="el-icon-folder-opened" @click="selectLandmarkPath">浏览</el-button> |
|||
</el-input> |
|||
<el-button type="primary" size="small" @click="importLandmark" style="margin-top: 8px;">导入地标</el-button> |
|||
</div> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
|
|||
<div class="dialog-footer"> |
|||
<el-button @click="closeDialog">取消</el-button> |
|||
<el-button type="primary" @click="saveExternalParams">保存</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'ExternalParamsDialog', |
|||
props: { |
|||
value: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
externalParams: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
formData: { |
|||
dataCardPath: '', |
|||
dataCardFormat: 'xml', |
|||
gpsDataSource: 'internal', |
|||
gpsPort: '', |
|||
gpsBaudRate: '9600', |
|||
gpsRefreshRate: 1, |
|||
airportPath: '', |
|||
routePath: '', |
|||
landmarkPath: '' |
|||
} |
|||
}; |
|||
}, |
|||
watch: { |
|||
value(newVal) { |
|||
if (newVal && this.externalParams) { |
|||
this.initFormData(); |
|||
} |
|||
}, |
|||
externalParams(newVal) { |
|||
if (this.value && newVal) { |
|||
this.initFormData(); |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
initFormData() { |
|||
this.formData = { |
|||
dataCardPath: this.externalParams.dataCardPath || '', |
|||
dataCardFormat: this.externalParams.dataCardFormat || 'xml', |
|||
gpsDataSource: this.externalParams.gpsDataSource || 'internal', |
|||
gpsPort: this.externalParams.gpsPort || '', |
|||
gpsBaudRate: this.externalParams.gpsBaudRate || '9600', |
|||
gpsRefreshRate: this.externalParams.gpsRefreshRate || 1, |
|||
airportPath: this.externalParams.airportPath || '', |
|||
routePath: this.externalParams.routePath || '', |
|||
landmarkPath: this.externalParams.landmarkPath || '' |
|||
}; |
|||
}, |
|||
selectDataCardPath() { |
|||
this.$message.info('选择数据卡路径'); |
|||
}, |
|||
selectAirportPath() { |
|||
this.$message.info('选择机场数据文件'); |
|||
}, |
|||
selectRoutePath() { |
|||
this.$message.info('选择航路数据文件'); |
|||
}, |
|||
selectLandmarkPath() { |
|||
this.$message.info('选择地标数据文件'); |
|||
}, |
|||
importAirport() { |
|||
if (!this.formData.airportPath) { |
|||
this.$message.warning('请先选择机场数据文件'); |
|||
return; |
|||
} |
|||
this.$message.success('机场数据导入成功'); |
|||
this.$emit('import-airport', this.formData.airportPath); |
|||
}, |
|||
importRoute() { |
|||
if (!this.formData.routePath) { |
|||
this.$message.warning('请先选择航路数据文件'); |
|||
return; |
|||
} |
|||
this.$message.success('航路数据导入成功'); |
|||
this.$emit('import-route', this.formData.routePath); |
|||
}, |
|||
importLandmark() { |
|||
if (!this.formData.landmarkPath) { |
|||
this.$message.warning('请先选择地标数据文件'); |
|||
return; |
|||
} |
|||
this.$message.success('地标数据导入成功'); |
|||
this.$emit('import-landmark', this.formData.landmarkPath); |
|||
}, |
|||
closeDialog() { |
|||
this.$emit('input', false); |
|||
}, |
|||
saveExternalParams() { |
|||
this.$emit('save', { |
|||
...this.externalParams, |
|||
...this.formData |
|||
}); |
|||
this.closeDialog(); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.external-params-dialog { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
z-index: 1000; |
|||
display: flex; |
|||
align-items: flex-start; |
|||
justify-content: center; |
|||
padding-top: 80px; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.dialog-content { |
|||
position: relative; |
|||
background: white; |
|||
border-radius: 8px; |
|||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); |
|||
width: 90%; |
|||
max-width: 600px; |
|||
max-height: 90vh; |
|||
overflow-y: auto; |
|||
animation: dialog-fade-in 0.3s ease; |
|||
pointer-events: auto; |
|||
} |
|||
|
|||
@keyframes dialog-fade-in { |
|||
from { |
|||
opacity: 0; |
|||
transform: translateY(-20px); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
|
|||
.dialog-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 16px 20px; |
|||
border-bottom: 1px solid #e8e8e8; |
|||
} |
|||
|
|||
.dialog-header h3 { |
|||
margin: 0; |
|||
font-size: 16px; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
.close-btn { |
|||
font-size: 20px; |
|||
color: #999; |
|||
cursor: pointer; |
|||
transition: color 0.3s; |
|||
} |
|||
|
|||
.close-btn:hover { |
|||
color: #666; |
|||
} |
|||
|
|||
.dialog-body { |
|||
padding: 20px; |
|||
} |
|||
|
|||
.import-section { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 8px; |
|||
} |
|||
|
|||
.dialog-footer { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
padding: 16px 20px; |
|||
border-top: 1px solid #e8e8e8; |
|||
gap: 10px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,341 @@ |
|||
<template> |
|||
<div v-if="value" class="power-zone-dialog"> |
|||
<div class="dialog-content"> |
|||
<div class="dialog-header"> |
|||
<h3>威力区编辑</h3> |
|||
<div class="close-btn" @click="closeDialog">×</div> |
|||
</div> |
|||
|
|||
<div class="dialog-body"> |
|||
<el-form :model="formData" :rules="rules" ref="formRef" label-width="80px" size="small"> |
|||
<el-form-item label="名称" prop="name"> |
|||
<el-input v-model="formData.name" placeholder="请输入威力区名称"></el-input> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="字体" prop="font"> |
|||
<el-select v-model="formData.font" placeholder="请选择字体" style="width: 100%;"> |
|||
<el-option label="微软雅黑" value="Microsoft YaHei"></el-option> |
|||
<el-option label="宋体" value="SimSun"></el-option> |
|||
<el-option label="黑体" value="SimHei"></el-option> |
|||
<el-option label="楷体" value="KaiTi"></el-option> |
|||
<el-option label="Arial" value="Arial"></el-option> |
|||
<el-option label="Times New Roman" value="Times New Roman"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="图形类型" prop="shapeType"> |
|||
<el-radio-group v-model="formData.shapeType" @change="handleShapeChange"> |
|||
<el-radio-button label="rectangle">矩形</el-radio-button> |
|||
<el-radio-button label="circle">圆形</el-radio-button> |
|||
<el-radio-button label="sector">扇形</el-radio-button> |
|||
<el-radio-button label="double180">双180°</el-radio-button> |
|||
<el-radio-button label="polygon">任意图形</el-radio-button> |
|||
<el-radio-button label="point">圆点</el-radio-button> |
|||
</el-radio-group> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="位置" prop="location"> |
|||
<div class="location-inputs"> |
|||
<el-input v-model="formData.location.lat" placeholder="纬度" style="width: 120px;"></el-input> |
|||
<span class="location-separator">,</span> |
|||
<el-input v-model="formData.location.lng" placeholder="经度" style="width: 120px;"></el-input> |
|||
</div> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="半径" prop="radius" v-if="formData.shapeType === 'circle' || formData.shapeType === 'sector' || formData.shapeType === 'double180'"> |
|||
<el-input-number |
|||
v-model="formData.radius" |
|||
:min="0" |
|||
placeholder="请输入半径" |
|||
style="width: 100%;" |
|||
suffix="km" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="角度" prop="angle" v-if="formData.shapeType === 'sector'"> |
|||
<el-input-number |
|||
v-model="formData.angle" |
|||
:min="0" |
|||
:max="360" |
|||
placeholder="请输入角度" |
|||
style="width: 100%;" |
|||
suffix="°" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="方向" prop="direction" v-if="formData.shapeType === 'sector' || formData.shapeType === 'double180'"> |
|||
<el-input-number |
|||
v-model="formData.direction" |
|||
:min="0" |
|||
:max="360" |
|||
placeholder="请输入方向" |
|||
style="width: 100%;" |
|||
suffix="°" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="宽度" prop="width" v-if="formData.shapeType === 'rectangle'"> |
|||
<el-input-number |
|||
v-model="formData.width" |
|||
:min="0" |
|||
placeholder="请输入宽度" |
|||
style="width: 100%;" |
|||
suffix="km" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="高度" prop="height" v-if="formData.shapeType === 'rectangle'"> |
|||
<el-input-number |
|||
v-model="formData.height" |
|||
:min="0" |
|||
placeholder="请输入高度" |
|||
style="width: 100%;" |
|||
suffix="km" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="旋转角度" prop="rotation" v-if="formData.shapeType === 'rectangle'"> |
|||
<el-input-number |
|||
v-model="formData.rotation" |
|||
:min="0" |
|||
:max="360" |
|||
placeholder="请输入旋转角度" |
|||
style="width: 100%;" |
|||
suffix="°" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="填充颜色" prop="fillColor"> |
|||
<el-color-picker v-model="formData.fillColor" show-alpha></el-color-picker> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="边框颜色" prop="borderColor"> |
|||
<el-color-picker v-model="formData.borderColor" show-alpha></el-color-picker> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="边框宽度" prop="borderWidth"> |
|||
<el-input-number |
|||
v-model="formData.borderWidth" |
|||
:min="0" |
|||
:max="10" |
|||
placeholder="请输入边框宽度" |
|||
style="width: 100%;" |
|||
suffix="px" |
|||
></el-input-number> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="透明度" prop="opacity"> |
|||
<el-slider |
|||
v-model="formData.opacity" |
|||
:min="0" |
|||
:max="1" |
|||
:step="0.1" |
|||
style="width: 100%;" |
|||
></el-slider> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
|
|||
<div class="dialog-footer"> |
|||
<el-button @click="closeDialog">取消</el-button> |
|||
<el-button type="primary" @click="savePowerZone">保存</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'PowerZoneDialog', |
|||
props: { |
|||
value: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
powerZone: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
formData: { |
|||
name: '', |
|||
font: 'Microsoft YaHei', |
|||
shapeType: 'circle', |
|||
location: { |
|||
lat: '', |
|||
lng: '' |
|||
}, |
|||
radius: 0, |
|||
angle: 0, |
|||
direction: 0, |
|||
width: 0, |
|||
height: 0, |
|||
rotation: 0, |
|||
fillColor: 'rgba(255, 0, 0, 0.3)', |
|||
borderColor: 'rgba(255, 0, 0, 1)', |
|||
borderWidth: 2, |
|||
opacity: 0.3 |
|||
}, |
|||
rules: { |
|||
name: [ |
|||
{ required: true, message: '请输入威力区名称', trigger: 'blur' } |
|||
], |
|||
font: [ |
|||
{ required: true, message: '请选择字体', trigger: 'change' } |
|||
], |
|||
shapeType: [ |
|||
{ required: true, message: '请选择图形类型', trigger: 'change' } |
|||
], |
|||
location: [ |
|||
{ required: true, message: '请输入位置', trigger: 'blur' } |
|||
] |
|||
} |
|||
}; |
|||
}, |
|||
watch: { |
|||
value(newVal) { |
|||
if (newVal && this.powerZone) { |
|||
this.initFormData(); |
|||
} |
|||
}, |
|||
powerZone(newVal) { |
|||
if (this.value && newVal) { |
|||
this.initFormData(); |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
initFormData() { |
|||
this.formData = { |
|||
name: this.powerZone.name || '', |
|||
font: this.powerZone.font || 'Microsoft YaHei', |
|||
shapeType: this.powerZone.shapeType || 'circle', |
|||
location: { |
|||
lat: this.powerZone.lat || '', |
|||
lng: this.powerZone.lng || '' |
|||
}, |
|||
radius: this.powerZone.radius || 0, |
|||
angle: this.powerZone.angle || 0, |
|||
direction: this.powerZone.direction || 0, |
|||
width: this.powerZone.width || 0, |
|||
height: this.powerZone.height || 0, |
|||
rotation: this.powerZone.rotation || 0, |
|||
fillColor: this.powerZone.fillColor || 'rgba(255, 0, 0, 0.3)', |
|||
borderColor: this.powerZone.borderColor || 'rgba(255, 0, 0, 1)', |
|||
borderWidth: this.powerZone.borderWidth || 2, |
|||
opacity: this.powerZone.opacity || 0.3 |
|||
}; |
|||
}, |
|||
handleShapeChange() { |
|||
}, |
|||
closeDialog() { |
|||
this.$emit('input', false); |
|||
}, |
|||
savePowerZone() { |
|||
this.$refs.formRef.validate((valid) => { |
|||
if (valid) { |
|||
this.$emit('save', { |
|||
...this.powerZone, |
|||
...this.formData, |
|||
lat: this.formData.location.lat, |
|||
lng: this.formData.location.lng |
|||
}); |
|||
this.closeDialog(); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.power-zone-dialog { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
z-index: 1000; |
|||
display: flex; |
|||
align-items: flex-start; |
|||
justify-content: center; |
|||
padding-top: 80px; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.dialog-content { |
|||
position: relative; |
|||
background: white; |
|||
border-radius: 8px; |
|||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); |
|||
width: 90%; |
|||
max-width: 500px; |
|||
max-height: 90vh; |
|||
overflow-y: auto; |
|||
animation: dialog-fade-in 0.3s ease; |
|||
pointer-events: auto; |
|||
} |
|||
|
|||
@keyframes dialog-fade-in { |
|||
from { |
|||
opacity: 0; |
|||
transform: translateY(-20px); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
|
|||
.dialog-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 16px 20px; |
|||
border-bottom: 1px solid #e8e8e8; |
|||
} |
|||
|
|||
.dialog-header h3 { |
|||
margin: 0; |
|||
font-size: 16px; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
.close-btn { |
|||
font-size: 20px; |
|||
color: #999; |
|||
cursor: pointer; |
|||
transition: color 0.3s; |
|||
} |
|||
|
|||
.close-btn:hover { |
|||
color: #666; |
|||
} |
|||
|
|||
.dialog-body { |
|||
padding: 20px; |
|||
} |
|||
|
|||
.location-inputs { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 10px; |
|||
} |
|||
|
|||
.location-separator { |
|||
color: #999; |
|||
margin: 0 5px; |
|||
} |
|||
|
|||
.dialog-footer { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
padding: 16px 20px; |
|||
border-top: 1px solid #e8e8e8; |
|||
gap: 10px; |
|||
} |
|||
</style> |
|||
@ -0,0 +1,223 @@ |
|||
<template> |
|||
<div v-if="value" class="scale-dialog"> |
|||
<div class="dialog-content"> |
|||
<div class="dialog-header"> |
|||
<h3>比例尺设置</h3> |
|||
<div class="close-btn" @click="closeDialog">×</div> |
|||
</div> |
|||
|
|||
<div class="dialog-body"> |
|||
<el-form :model="formData" :rules="rules" ref="formRef" label-width="80px" size="small"> |
|||
<el-form-item label="比例尺" prop="scale"> |
|||
<div class="scale-inputs"> |
|||
<el-input-number |
|||
v-model="formData.scaleNumerator" |
|||
:min="1" |
|||
placeholder="分子" |
|||
style="width: 150px;" |
|||
></el-input-number> |
|||
<span class="scale-separator">:</span> |
|||
<el-input-number |
|||
v-model="formData.scaleDenominator" |
|||
:min="1" |
|||
placeholder="分母" |
|||
style="width: 150px;" |
|||
></el-input-number> |
|||
</div> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="单位" prop="unit"> |
|||
<el-select v-model="formData.unit" placeholder="请选择单位" style="width: 100%;"> |
|||
<el-option label="米" value="m"></el-option> |
|||
<el-option label="千米" value="km"></el-option> |
|||
<el-option label="英尺" value="ft"></el-option> |
|||
<el-option label="英里" value="mi"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
|
|||
<el-form-item label="显示位置" prop="position"> |
|||
<el-select v-model="formData.position" placeholder="请选择显示位置" style="width: 100%;"> |
|||
<el-option label="左下角" value="bottom-left"></el-option> |
|||
<el-option label="右下角" value="bottom-right"></el-option> |
|||
<el-option label="左上角" value="top-left"></el-option> |
|||
<el-option label="右上角" value="top-right"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
</el-form> |
|||
</div> |
|||
|
|||
<div class="dialog-footer"> |
|||
<el-button @click="closeDialog">取消</el-button> |
|||
<el-button type="primary" @click="saveScale">保存</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
|
|||
<script> |
|||
export default { |
|||
name: 'ScaleDialog', |
|||
props: { |
|||
value: { |
|||
type: Boolean, |
|||
default: false |
|||
}, |
|||
scale: { |
|||
type: Object, |
|||
default: () => ({}) |
|||
} |
|||
}, |
|||
data() { |
|||
return { |
|||
formData: { |
|||
scaleNumerator: 1, |
|||
scaleDenominator: 1000, |
|||
unit: 'km', |
|||
position: 'bottom-right' |
|||
}, |
|||
rules: { |
|||
scaleNumerator: [ |
|||
{ required: true, message: '请输入分子', trigger: 'blur' } |
|||
], |
|||
scaleDenominator: [ |
|||
{ required: true, message: '请输入分母', trigger: 'blur' } |
|||
], |
|||
unit: [ |
|||
{ required: true, message: '请选择单位', trigger: 'change' } |
|||
], |
|||
position: [ |
|||
{ required: true, message: '请选择显示位置', trigger: 'change' } |
|||
] |
|||
} |
|||
}; |
|||
}, |
|||
watch: { |
|||
value(newVal) { |
|||
if (newVal && this.scale) { |
|||
this.initFormData(); |
|||
} |
|||
}, |
|||
scale(newVal) { |
|||
if (this.value && newVal) { |
|||
this.initFormData(); |
|||
} |
|||
} |
|||
}, |
|||
methods: { |
|||
initFormData() { |
|||
this.formData = { |
|||
scaleNumerator: this.scale.scaleNumerator || 1, |
|||
scaleDenominator: this.scale.scaleDenominator || 1000, |
|||
unit: this.scale.unit || 'km', |
|||
position: this.scale.position || 'bottom-right' |
|||
}; |
|||
}, |
|||
closeDialog() { |
|||
this.$emit('input', false); |
|||
}, |
|||
saveScale() { |
|||
this.$refs.formRef.validate((valid) => { |
|||
if (valid) { |
|||
this.$emit('save', { |
|||
...this.scale, |
|||
...this.formData |
|||
}); |
|||
this.closeDialog(); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
</script> |
|||
|
|||
<style scoped> |
|||
.scale-dialog { |
|||
position: fixed; |
|||
top: 0; |
|||
left: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
z-index: 1000; |
|||
display: flex; |
|||
align-items: flex-start; |
|||
justify-content: center; |
|||
padding-top: 80px; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.dialog-content { |
|||
position: relative; |
|||
background: white; |
|||
border-radius: 8px; |
|||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); |
|||
width: 90%; |
|||
max-width: 500px; |
|||
max-height: 90vh; |
|||
overflow-y: auto; |
|||
animation: dialog-fade-in 0.3s ease; |
|||
pointer-events: auto; |
|||
} |
|||
|
|||
@keyframes dialog-fade-in { |
|||
from { |
|||
opacity: 0; |
|||
transform: translateY(-20px); |
|||
} |
|||
to { |
|||
opacity: 1; |
|||
transform: translateY(0); |
|||
} |
|||
} |
|||
|
|||
.dialog-header { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: space-between; |
|||
padding: 16px 20px; |
|||
border-bottom: 1px solid #e8e8e8; |
|||
} |
|||
|
|||
.dialog-header h3 { |
|||
margin: 0; |
|||
font-size: 16px; |
|||
font-weight: 600; |
|||
color: #333; |
|||
} |
|||
|
|||
.close-btn { |
|||
font-size: 20px; |
|||
color: #999; |
|||
cursor: pointer; |
|||
transition: color 0.3s; |
|||
} |
|||
|
|||
.close-btn:hover { |
|||
color: #666; |
|||
} |
|||
|
|||
.dialog-body { |
|||
padding: 20px; |
|||
} |
|||
|
|||
.scale-inputs { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 10px; |
|||
} |
|||
|
|||
.scale-separator { |
|||
font-size: 20px; |
|||
font-weight: bold; |
|||
color: #333; |
|||
margin: 0 5px; |
|||
} |
|||
|
|||
.dialog-footer { |
|||
display: flex; |
|||
align-items: center; |
|||
justify-content: flex-end; |
|||
padding: 16px 20px; |
|||
border-top: 1px solid #e8e8e8; |
|||
gap: 10px; |
|||
} |
|||
</style> |
|||
Loading…
Reference in new issue