This commit is contained in:
aaron 2025-03-16 10:43:45 +08:00
parent bb4d562346
commit 619d17f9a1
2 changed files with 310 additions and 143 deletions

View File

@ -1,5 +1,5 @@
<template>
<div class="map-picker">
<div class="map-picker-container">
<a-form-item :label="label">
<a-auto-complete
v-model:value="searchAddress"
@ -9,6 +9,7 @@
@select="handleSelect"
:loading="searchLoading"
allow-clear
class="map-picker-input"
/>
</a-form-item>
@ -16,37 +17,24 @@
<div class="map-container">
<div :id="mapContainerId" style="height: 300px;"></div>
</div>
<div class="form-item-tip">在地图上点击选择准确位置或通过上方搜索框搜索地址</div>
</a-form-item>
<a-form-item label="详细地址" required>
<a-input v-model:value="address" placeholder="请输入详细地址" />
<div class="form-item-tip">地址将用于配送员导航和定位请确保准确</div>
</a-form-item>
<a-form-item label="经纬度" required>
<a-input-group compact>
<a-input-number
v-model:value="longitude"
:min="-180"
:max="180"
style="width: 50%"
placeholder="经度"
disabled
/>
<a-input-number
v-model:value="latitude"
:min="-90"
:max="90"
style="width: 50%"
placeholder="纬度"
disabled
/>
</a-input-group>
</a-form-item>
<!-- 隐藏经纬度输入字段但保持功能不变 -->
<div style="display: none;">
<a-input-number v-model:value="longitude" :min="-180" :max="180" disabled />
<a-input-number v-model:value="latitude" :min="-90" :max="90" disabled />
</div>
</div>
</template>
<script>
import { ref, onMounted, nextTick } from 'vue'
import { ref, onMounted, nextTick, watch } from 'vue'
import { message } from 'ant-design-vue'
import { loadAMap, createMap, createAutoComplete, createGeocoder } from '@/utils/amap.js'
@ -80,29 +68,88 @@ export default {
const longitude = ref(props.modelValue.longitude)
const latitude = ref(props.modelValue.latitude)
//
// props
watch(() => props.modelValue, (newVal, oldVal) => {
console.log('props变化:', newVal, oldVal)
//
if (
newVal.address !== address.value ||
newVal.longitude !== longitude.value ||
newVal.latitude !== latitude.value
) {
console.log('更新本地值:', newVal)
address.value = newVal.address
longitude.value = newVal.longitude
latitude.value = newVal.latitude
//
if (map.value && newVal.longitude && newVal.latitude) {
console.log('更新地图标记和中心点:', newVal.longitude, newVal.latitude)
// 使nextTickDOM
nextTick(() => {
try {
if (marker.value) {
marker.value.setPosition([newVal.longitude, newVal.latitude])
} else {
marker.value = new window.AMap.Marker({
position: [newVal.longitude, newVal.latitude],
map: map.value
})
}
map.value.setCenter([newVal.longitude, newVal.latitude])
} catch (error) {
console.error('更新地图标记失败:', error)
}
})
}
}
}, { deep: true, immediate: true })
//
watch([address, longitude, latitude], () => {
updateValue()
})
//
const updateValue = () => {
//
if (
address.value !== props.modelValue.address ||
longitude.value !== props.modelValue.longitude ||
latitude.value !== props.modelValue.latitude
) {
emit('update:modelValue', {
address: address.value,
longitude: longitude.value,
latitude: latitude.value
})
}
}
//
const updateMarkerPosition = (lng, lat) => {
//
if (lng === longitude.value && lat === latitude.value && marker.value) {
return
}
console.log('更新标记位置:', lng, lat)
longitude.value = lng
latitude.value = lat
try {
if (marker.value) {
marker.value.setPosition([lng, lat])
} else {
} else if (map.value) {
marker.value = new window.AMap.Marker({
position: [lng, lat],
map: map.value
})
}
updateValue()
} catch (error) {
console.error('更新标记位置失败:', error)
}
// updateValuewatch
}
//
@ -111,6 +158,7 @@ export default {
await loadAMap()
if (!map.value) {
console.log('初始化地图,初始位置:', props.modelValue)
map.value = createMap(mapContainerId, {
zoom: 13,
viewMode: '2D'
@ -135,6 +183,14 @@ export default {
//
if (props.modelValue.longitude && props.modelValue.latitude) {
console.log('MapPicker初始化设置初始位置', props.modelValue)
//
map.value.on('complete', () => {
updateMarkerPosition(props.modelValue.longitude, props.modelValue.latitude)
map.value.setCenter([props.modelValue.longitude, props.modelValue.latitude])
})
//
updateMarkerPosition(props.modelValue.longitude, props.modelValue.latitude)
map.value.setCenter([props.modelValue.longitude, props.modelValue.latitude])
}
@ -223,10 +279,26 @@ export default {
</script>
<style scoped>
.map-picker-container {
width: 100%;
}
.map-picker-input {
width: 100%;
}
.map-container {
border: 1px solid #d9d9d9;
border-radius: 2px;
border-radius: 4px;
overflow: hidden;
margin-bottom: 16px;
margin-bottom: 8px;
width: 100%;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
}
.form-item-tip {
margin-top: 8px;
font-size: 0.8em;
color: #999;
}
</style>

View File

@ -79,15 +79,27 @@
<a-tag v-else color="orange">未设置</a-tag>
</template>
<template v-if="column.key === 'action'">
<div class="action-buttons">
<a-dropdown>
<a class="ant-dropdown-link" @click.prevent>
操作 <down-outlined />
</a>
<template #overlay>
<a-menu>
<a-menu-item key="edit">
<a @click="handleEdit(record)">编辑</a>
<a-divider type="vertical" />
</a-menu-item>
<a-menu-item key="deliveryPrice">
<a @click="handleEditDeliveryPrice(record)">配送定价</a>
<a-divider type="vertical" />
</a-menu-item>
<a-menu-item key="profitSharing">
<a @click="handleEditProfitSharing(record)">设置分润</a>
<a-divider type="vertical" />
</a-menu-item>
<a-menu-item key="admin">
<a @click="handleSetAdmin(record)">{{ record.admin ? '修改服务商' : '设置服务商' }}</a>
</div>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template>
</template>
</a-table>
@ -109,7 +121,7 @@
@ok="handleSubmit"
@cancel="handleCancel"
:confirmLoading="confirmLoading"
width="680px"
width="900px"
>
<template #footer>
<a-space>
@ -124,25 +136,20 @@
ref="formRef"
:model="formState"
:rules="rules"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }"
layout="vertical"
class="community-form"
>
<div class="form-content">
<div class="form-left">
<a-form-item label="小区名称" name="name" required>
<a-input v-model:value="formState.name" placeholder="请输入小区名称" />
</a-form-item>
<map-picker
v-model="formState.location"
label="地址搜索"
/>
<a-form-item
label="企业微信Webhook"
name="webot_webhook"
required
:rules="[
{ required: true, message: '请输入Webhook地址' },
{ required: false },
{ type: 'url', message: '请输入正确的URL地址' }
]"
>
@ -152,7 +159,7 @@
:maxLength="500"
/>
<div class="form-item-tip">
小区相关通知将推送到此企业微信群
小区相关通知将推送到此企业微信群选填
</div>
</a-form-item>
@ -180,6 +187,16 @@
</a-upload>
</div>
</a-form-item>
</div>
<div class="form-right">
<map-picker
v-model="formState.location"
label="地址搜索"
:key="`map-picker-${currentId || 'new'}-${modalVisible}`"
/>
</div>
</div>
</a-form>
</a-modal>
@ -660,7 +677,7 @@ export default defineComponent({
'location.longitude': [{ required: true, message: '请在地图上选择位置' }],
'location.latitude': [{ required: true, message: '请在地图上选择位置' }],
webot_webhook: [
{ required: true, message: '请输入Webhook地址' },
{ required: false },
{ type: 'url', message: '请输入正确的URL地址' }
],
qy_group_qrcode: [
@ -678,18 +695,27 @@ export default defineComponent({
const handleEdit = (record) => {
isEdit.value = true
currentId.value = record.id
modalVisible.value = true
//
if (formRef.value) {
formRef.value.resetFields()
}
// location
const locationData = {
address: record.address || '',
longitude: parseFloat(record.longitude) || null,
latitude: parseFloat(record.latitude) || null
}
console.log('编辑小区,处理后的地址信息:', locationData)
//
formState.value = {
name: record.name,
location: {
address: record.address,
longitude: record.longitude,
latitude: record.latitude
},
qy_group_qrcode: record.qy_group_qrcode,
status: record.status,
name: record.name || '',
location: locationData,
qy_group_qrcode: record.qy_group_qrcode || '',
status: record.status || 'UNOPEN',
webot_webhook: record.webot_webhook || ''
}
@ -704,13 +730,27 @@ export default defineComponent({
} else {
fileList.value = []
}
//
modalVisible.value = true
// DOMMapPicker
nextTick(() => {
console.log('编辑小区,表单数据:', formState.value)
})
}
//
const showAddModal = () => {
isEdit.value = false
currentId.value = null
modalVisible.value = true
//
if (formRef.value) {
formRef.value.resetFields()
}
// location
formState.value = {
name: '',
location: {
@ -722,7 +762,11 @@ export default defineComponent({
status: 'UNOPEN',
webot_webhook: ''
}
fileList.value = []
//
modalVisible.value = true
}
//
@ -1445,9 +1489,7 @@ export default defineComponent({
}
:deep(.ant-form-item-label) {
height: 28px;
line-height: 28px;
padding-bottom: 0;
padding-bottom: 4px;
}
:deep(.ant-form-item-control) {
@ -1458,27 +1500,54 @@ export default defineComponent({
:deep(.ant-select),
:deep(.ant-auto-complete),
:deep(.ant-input-number) {
height: 30px;
height: 32px;
}
/* 垂直布局表单项样式优化 */
.community-form :deep(.ant-form-item-label) {
text-align: left;
line-height: 1.5;
margin-bottom: 4px;
}
.community-form :deep(.ant-form-item-label > label) {
height: auto;
}
/* 地图组件样式优化 */
:deep(.map-picker-container) {
height: 100%;
display: flex;
flex-direction: column;
}
:deep(.map-picker-input) {
margin-bottom: 8px;
}
:deep(.map-container) {
height: 250px !important;
min-height: auto !important;
}
:deep(.ant-select-selector),
:deep(.ant-auto-complete .ant-input) {
height: 30px !important;
line-height: 30px !important;
height: 32px !important;
line-height: 32px !important;
padding: 0 11px !important;
.ant-select-selection-search-input {
height: 28px !important;
height: 30px !important;
}
.ant-select-selection-item {
line-height: 28px !important;
line-height: 30px !important;
}
}
:deep(.ant-input-number-input) {
height: 28px;
line-height: 28px;
height: 30px;
line-height: 30px;
}
.form-item-tip {
@ -1508,19 +1577,6 @@ export default defineComponent({
}
}
/* 调整地图组件样式 */
:deep(.map-picker-container) {
margin-bottom: 12px;
}
:deep(.map-picker-input) {
margin-bottom: 8px;
}
:deep(.map-container) {
height: 200px !important; /* 减少地图高度 */
}
.status-tag {
cursor: pointer;
user-select: none;
@ -1534,17 +1590,6 @@ export default defineComponent({
}
/* 调整 Select 组件的样式 */
:deep(.ant-select-selector) {
height: 32px !important;
.ant-select-selection-item {
line-height: 30px !important; /* 调整文字行高 */
padding-top: 0 !important; /* 移除顶部内边距 */
padding-bottom: 0 !important; /* 移除底部内边距 */
}
}
/* 调整选项的样式 */
:deep(.ant-select-dropdown) {
.ant-select-item {
padding: 5px 12px; /* 调整选项内边距 */
@ -1844,4 +1889,54 @@ export default defineComponent({
.admin-phone {
color: rgba(0, 0, 0, 0.65);
}
/* 调整选项的样式 */
:deep(.ant-select-dropdown) {
.ant-select-item {
padding: 5px 12px; /* 调整选项内边距 */
line-height: 22px; /* 调整选项行高 */
}
}
/* 确保输入框内的文字垂直居中 */
:deep(.ant-select-selection-search-input) {
height: 30px !important;
line-height: 30px !important;
}
/* 确保占位符文字垂直居中 */
:deep(.ant-select-selection-placeholder) {
line-height: 30px !important;
}
.delivery-price-info {
line-height: 1.5;
font-size: 13px;
> div {
margin-bottom: 2px;
&:last-child {
margin-bottom: 0;
color: rgba(0, 0, 0, 0.65);
font-size: 12px;
}
}
}
/* 左右布局样式 */
.form-content {
display: flex;
gap: 20px;
}
.form-left {
flex: 1;
max-width: 50%;
}
.form-right {
flex: 1;
max-width: 50%;
}
</style>