DurationInput,LatitudeInput,LongitudeInput

This commit is contained in:
liaoboping 2025-09-19 22:01:54 +08:00
parent 3d07a7ceb5
commit 8c3765c03d
5 changed files with 244 additions and 8 deletions

View File

@ -0,0 +1,58 @@
<template>
<div class="duration-input">
<a-input-number v-model="hour" :min="0" :step="1" :precision="0" style="width: 120px" />
<span style="margin: 0 8px">小时</span>
<a-input-number v-model="minute" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px">分钟</span>
<a-input-number v-model="second" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px"></span>
</div>
</template>
<script>
export default {
props: {
value: { type: Number, required: true },
},
computed: {
vNumber: {
get() {
return Math.floor(this.value) || 0
},
set(v) {
this.$emit('input', v)
},
},
hour: {
get() {
return Math.floor(this.vNumber / 3600)
},
set(v) {
this.$emit('input', v * 3600 + this.minute * 60 + this.second)
},
},
minute: {
get() {
return Math.floor(this.vNumber / 60) % 60
},
set(v) {
this.$emit('input', this.hour * 3600 + v * 60 + this.second)
},
},
second: {
get() {
return this.vNumber % 60
},
set(v) {
this.$emit('input', this.hour * 3600 + this.minute * 60 + v)
},
},
},
}
</script>
<style lang="less" scoped>
.duration-input {
white-space: nowrap;
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<div class="latitude-input">
<a-select v-model="latSelect" style="width: 76px; margin-right: 20px">
<a-select-option :value="1">北纬</a-select-option>
<a-select-option :value="-1">南纬</a-select-option>
</a-select>
<a-input-number v-model="latNumber" :min="0" :max="180" :precision="8" style="width: 152px" />
<span style="margin: 0 8px">°</span>
<span style="margin: 0 12px"></span>
<a-input-number v-model="latDegree" :min="0" :max="180" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px">°</span>
<a-input-number v-model="latMinute" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px"></span>
<a-input-number v-model="latSecond" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px"></span>
</div>
</template>
<script>
export default {
props: {
value: { type: Number, required: true },
},
data() {
return {
NSSelect: 1,
}
},
computed: {
latSelect: {
get() {
return this.value ? this.value / this.latNumber : this.NSSelect
},
set(v) {
this.$emit('input', this.latNumber * v)
this.NSSelect = v
},
},
latNumber: {
get() {
return Math.abs(this.value) || 0
},
set(v) {
this.$emit('input', Math.abs(v) * this.latSelect)
},
},
latDegree: {
get() {
return Math.floor(this.latNumber)
},
set(v) {
this.$emit('input', Math.abs(v) * this.latSelect + this.latMinute / 60 + this.latSecond / 3600)
},
},
latMinute: {
get() {
return Math.floor(this.latNumber * 60) % 60
},
set(v) {
this.$emit('input', this.latDegree * this.latSelect + Math.abs(v) / 60 + this.latSecond / 3600)
},
},
latSecond: {
get() {
return Math.floor(this.latNumber * 3600) % 60
},
set(v) {
this.$emit('input', this.latDegree * this.latSelect + this.latMinute / 60 + Math.abs(v) / 3600)
},
},
},
created() {
if (this.value < 0) {
this.NSSelect = 'S'
}
},
}
</script>
<style lang="less" scoped>
.latitude-input {
white-space: nowrap;
}
</style>

View File

@ -0,0 +1,84 @@
<template>
<div class="longitude-input">
<a-select v-model="lonSelect" style="width: 76px; margin-right: 20px">
<a-select-option :value="1">东经</a-select-option>
<a-select-option :value="-1">西经</a-select-option>
</a-select>
<a-input-number v-model="lonNumber" :min="0" :max="180" :precision="8" style="width: 152px" />
<span style="margin: 0 8px">°</span>
<span style="margin: 0 12px"></span>
<a-input-number v-model="lonDegree" :min="0" :max="180" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px">°</span>
<a-input-number v-model="lonMinute" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px"></span>
<a-input-number v-model="lonSecond" :min="0" :max="60" :step="1" :precision="0" style="width: 60px" />
<span style="margin: 0 8px"></span>
</div>
</template>
<script>
export default {
props: {
value: { type: Number, required: true },
},
data() {
return {
EWSelect: 1,
}
},
computed: {
lonSelect: {
get() {
return this.value ? this.value / this.lonNumber : this.EWSelect
},
set(v) {
this.$emit('input', this.lonNumber * v)
this.EWSelect = v
},
},
lonNumber: {
get() {
return Math.abs(this.value) || 0
},
set(v) {
this.$emit('input', Math.abs(v) * this.lonSelect)
},
},
lonDegree: {
get() {
return Math.floor(this.lonNumber)
},
set(v) {
this.$emit('input', Math.abs(v) * this.lonSelect + this.lonMinute / 60 + this.lonSecond / 3600)
},
},
lonMinute: {
get() {
return Math.floor(this.lonNumber * 60) % 60
},
set(v) {
this.$emit('input', this.lonDegree * this.lonSelect + Math.abs(v) / 60 + this.lonSecond / 3600)
},
},
lonSecond: {
get() {
return Math.floor(this.lonNumber * 3600) % 60
},
set(v) {
this.$emit('input', this.lonDegree * this.lonSelect + this.lonMinute / 60 + Math.abs(v) / 3600)
},
},
},
created() {
if (this.lon < 0) {
this.EWSelect = -1
}
},
}
</script>
<style lang="less" scoped>
.longitude-input {
white-space: nowrap;
}
</style>

View File

@ -3,14 +3,16 @@
<a-spin :spinning="loading">
<a-form-model ref="form" :model="formData" :rules="formRules" v-bind="_formConfig">
<a-form-model-item v-for="item in formItems" :key="item.prop" v-bind="item">
<span v-if="item.customRender">{{ item.customRender(formData[item.prop], formData) }}</span>
<component
v-else
:is="item.component || 'a-input'"
v-model="formData[item.prop]"
v-bind="item.options"
v-on="item.listeners"
/>
<slot :name="item.prop" :formData="formData" :item="item">
<span v-if="item.customRender">{{ item.customRender(formData[item.prop], formData) }}</span>
<component
v-else
:is="item.component || 'a-input'"
v-model="formData[item.prop]"
v-bind="item.options"
v-on="item.listeners"
/>
</slot>
</a-form-model-item>
</a-form-model>
</a-spin>
@ -21,6 +23,7 @@
export default {
props: {
visible: { type: Boolean, required: true },
title: { type: String, default: '' },
formConfig: { type: Object, default: () => ({}) },
formItems: { type: Array, default: () => [] },
formRules: { type: Object, default: () => ({}) },
@ -45,6 +48,7 @@ export default {
return {
maskClosable: false,
destroyOnClose: true,
title: this.title,
...this.$attrs,
}
},

View File

@ -9,6 +9,9 @@ import AntOriginTreeSelect from './Form/AntOriginTreeSelect.vue'
import DurationPicker from './Form/DurationPicker.vue'
import Image2Base64 from './Form/Image2Base64.vue'
import IconSelector from './Form/IconSelector.vue'
import LongitudeInput from './Form/LongitudeInput.vue'
import LatitudeInput from './Form/LatitudeInput.vue'
import DurationInput from './Form/DurationInput.vue'
import WangEditor from './WangEditor/Index.vue'
@ -32,6 +35,9 @@ export default {
Vue.component('DurationPicker', DurationPicker)
Vue.component('Image2Base64', Image2Base64)
Vue.component('IconSelector', IconSelector)
Vue.component('LongitudeInput', LongitudeInput)
Vue.component('LatitudeInput', LatitudeInput)
Vue.component('DurationInput', DurationInput)
Vue.component('WangEditor', WangEditor)