更新 小区页面的逻辑,增加运营状态的切换。

This commit is contained in:
aaron 2025-01-08 16:49:41 +08:00
parent 4064c74f70
commit 37571ac2b4
4 changed files with 283 additions and 34 deletions

View File

@ -35,3 +35,12 @@ export function createBuilding(data) {
data data
}) })
} }
// 更新小区状态
export function updateCommunityStatus(id, status) {
return request({
url: `/api/community/${id}`,
method: 'put',
data: { status }
})
}

View File

@ -1,37 +1,33 @@
export function initAMap() { export function initAMap() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (window.AMap) { if (window.AMap) {
// 如果已经加载过,直接加载插件 resolve(window.AMap)
window.AMap.plugin(['AMap.PlaceSearch', 'AMap.AutoComplete'], () => { return
resolve(window.AMap);
});
return;
} }
// 加载高德地图脚本 const script = document.createElement('script')
const script = document.createElement('script'); script.type = 'text/javascript'
script.type = 'text/javascript'; script.async = true
script.async = true; script.src = `https://webapi.amap.com/maps?v=2.0&key=fd47f3d4f54b675693c7d59dcd2a6c5f&plugin=AMap.PlaceSearch,AMap.AutoComplete,AMap.Geocoder&callback=initAMapCallback`
script.src = `https://webapi.amap.com/maps?v=2.0&key=fd47f3d4f54b675693c7d59dcd2a6c5f&plugin=AMap.PlaceSearch,AMap.AutoComplete&callback=initAMapCallback`;
// 创建回调函数
window.initAMapCallback = () => { window.initAMapCallback = () => {
resolve(window.AMap); resolve(window.AMap)
}; }
script.onerror = () => { script.onerror = reject
reject(new Error('加载地图失败')); document.head.appendChild(script)
}; })
document.head.appendChild(script);
});
} }
// 添加地图工具函数 // 创建地图实例
export function createMap(container, options = {}) { export function createMap(container, options = {}) {
const defaultOptions = {
zoom: 15,
viewMode: '2D'
}
return new window.AMap.Map(container, { return new window.AMap.Map(container, {
zoom: 13, ...defaultOptions,
viewMode: '2D',
...options ...options
}); })
} }

View File

@ -68,6 +68,7 @@
:rules="rules" :rules="rules"
:label-col="{ span: 6 }" :label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }" :wrapper-col="{ span: 16 }"
class="building-form"
> >
<a-form-item label="所属小区" name="community_id" required> <a-form-item label="所属小区" name="community_id" required>
<a-select <a-select
@ -337,4 +338,61 @@ export default defineComponent({
margin-bottom: 0; margin-bottom: 0;
} }
} }
/* 调整表单样式 */
.building-form {
padding: 20px 0;
}
:deep(.ant-form-item) {
margin-bottom: 32px;
&:last-child {
margin-bottom: 0;
}
}
:deep(.ant-form-item-label) {
text-align: right;
padding-right: 12px;
/* 调整必填星号的样式 */
> label.ant-form-item-required:not(.ant-form-item-required-mark-optional)::before {
color: #ff4d4f;
font-size: 14px;
margin-right: 4px;
}
}
:deep(.ant-input),
:deep(.ant-select) {
height: 40px;
}
:deep(.ant-select-selector) {
height: 40px !important;
padding: 4px 11px !important;
.ant-select-selection-search-input {
height: 38px !important;
}
.ant-select-selection-item {
line-height: 38px !important;
}
}
:deep(.ant-input::placeholder),
:deep(.ant-select-selection-placeholder) {
color: #bfbfbf;
}
:deep(.ant-modal-body) {
padding: 0;
}
:deep(.ant-modal-footer) {
border-top: 1px solid #f0f0f0;
padding: 16px 24px;
}
</style> </style>

View File

@ -16,9 +16,18 @@
> >
<template #bodyCell="{ column, record }"> <template #bodyCell="{ column, record }">
<template v-if="column.key === 'status'"> <template v-if="column.key === 'status'">
<a-tag :color="getStatusColor(record.status)"> <a-dropdown>
{{ getStatusText(record.status) }} <a-tag :color="getStatusColor(record.status)" class="status-tag">
</a-tag> {{ getStatusText(record.status) }}
<down-outlined />
</a-tag>
<template #overlay>
<a-menu @click="({ key }) => handleStatusChange(record, key)">
<a-menu-item key="OPENING">运营中</a-menu-item>
<a-menu-item key="UNOPEN">未启用</a-menu-item>
</a-menu>
</template>
</a-dropdown>
</template> </template>
<template v-if="column.key === 'location'"> <template v-if="column.key === 'location'">
<a @click="showMap(record)">查看位置</a> <a @click="showMap(record)">查看位置</a>
@ -62,6 +71,7 @@
:rules="rules" :rules="rules"
:label-col="{ span: 6 }" :label-col="{ span: 6 }"
:wrapper-col="{ span: 16 }" :wrapper-col="{ span: 16 }"
class="community-form"
> >
<a-form-item label="地址搜索"> <a-form-item label="地址搜索">
<a-auto-complete <a-auto-complete
@ -124,15 +134,17 @@
<script> <script>
import { defineComponent, ref, onMounted, nextTick } from 'vue' import { defineComponent, ref, onMounted, nextTick } from 'vue'
import { message, Tag } from 'ant-design-vue' import { message, Tag } from 'ant-design-vue'
import { getCommunityList, createCommunity } from '@/api/community' import { getCommunityList, createCommunity, updateCommunityStatus } from '@/api/community'
import { initAMap, createMap } from '@/utils/amap' import { initAMap, createMap } from '@/utils/amap'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import PageContainer from '@/components/PageContainer.vue' import PageContainer from '@/components/PageContainer.vue'
import { DownOutlined } from '@ant-design/icons-vue'
export default defineComponent({ export default defineComponent({
components: { components: {
PageContainer, PageContainer,
[Tag.name]: Tag [Tag.name]: Tag,
DownOutlined
}, },
setup() { setup() {
const loading = ref(false) const loading = ref(false)
@ -341,7 +353,7 @@ export default defineComponent({
// //
const initAddMap = async () => { const initAddMap = async () => {
try { try {
await initAMap(); const AMap = await initAMap();
if (!addMap.value) { if (!addMap.value) {
addMap.value = createMap('add-map-container', { addMap.value = createMap('add-map-container', {
@ -352,15 +364,42 @@ export default defineComponent({
addMap.value.on('click', (e) => { addMap.value.on('click', (e) => {
const { lng, lat } = e.lnglat; const { lng, lat } = e.lnglat;
// 使 // 使
const geocoder = new window.AMap.Geocoder(); const geocoder = new AMap.Geocoder({
radius: 100, //
extensions: 'all' //
});
geocoder.getAddress([lng, lat], (status, result) => { geocoder.getAddress([lng, lat], (status, result) => {
if (status === 'complete' && result.info === 'OK') { if (status === 'complete' && result.info === 'OK') {
const address = result.regeocode; const address = result.regeocode;
formState.value.address = address.formattedAddress; formState.value.address = address.formattedAddress;
// 使POI
if (!formState.value.name && address.pois && address.pois.length > 0) { // 使 POI
formState.value.name = address.pois[0].name; if (address.pois && address.pois.length > 0) {
// """""" POI
const residentialPoi = address.pois.find(poi =>
poi.type.includes('住宅区') ||
poi.type.includes('小区') ||
poi.type.includes('住宅小区')
);
if (residentialPoi) {
formState.value.name = residentialPoi.name;
} else {
// POI使 POI
formState.value.name = address.pois[0].name;
}
} else if (address.aois && address.aois.length > 0) {
// POI使 AOI
formState.value.name = address.aois[0].name;
} else {
// POI AOI使
const township = address.addressComponent.township || '';
const street = address.addressComponent.street || '';
formState.value.name = `${township}${street}`;
} }
//
updateMarkerPosition(lng, lat); updateMarkerPosition(lng, lat);
} }
}); });
@ -481,6 +520,26 @@ export default defineComponent({
} }
} }
//
const handleStatusChange = async (record, status) => {
try {
const res = await updateCommunityStatus(record.id, status)
if (res.code === 200) {
message.success('状态更新成功')
//
const index = tableData.value.findIndex(item => item.id === record.id)
if (index !== -1) {
tableData.value[index].status = status
}
} else {
message.error(res.message || '状态更新失败')
}
} catch (error) {
console.error('更新小区状态失败:', error)
message.error('状态更新失败')
}
}
onMounted(() => { onMounted(() => {
fetchData() fetchData()
}) })
@ -509,7 +568,8 @@ export default defineComponent({
handleCancel, handleCancel,
handleSearch, handleSearch,
searchOptions, searchOptions,
handleSelect handleSelect,
handleStatusChange
} }
} }
}) })
@ -646,4 +706,130 @@ export default defineComponent({
padding: 16px 24px; padding: 16px 24px;
border-top: 1px solid #f0f0f0; border-top: 1px solid #f0f0f0;
} }
/* 调整表单样式 */
.community-form {
padding: 8px 0;
}
:deep(.ant-form-item) {
margin-bottom: 24px !important;
}
:deep(.ant-form-item-label) {
height: 32px;
line-height: 32px;
text-align: right;
padding-right: 12px;
/* 调整必填星号的样式 */
> label.ant-form-item-required:not(.ant-form-item-required-mark-optional)::before {
color: #ff4d4f;
font-size: 14px;
margin-right: 4px;
}
}
:deep(.ant-form-item-control-input) {
min-height: 32px;
}
:deep(.ant-input),
:deep(.ant-select),
:deep(.ant-auto-complete),
:deep(.ant-input-number) {
height: 32px;
}
:deep(.ant-select-selector),
:deep(.ant-auto-complete .ant-input) {
height: 32px !important;
line-height: 32px !important;
padding: 0 11px !important;
.ant-select-selection-search-input {
height: 30px !important;
}
.ant-select-selection-item {
line-height: 30px !important;
}
}
:deep(.ant-input-number-input) {
height: 30px;
line-height: 30px;
}
:deep(.ant-input::placeholder),
:deep(.ant-select-selection-placeholder),
:deep(.ant-input-number-input::placeholder) {
color: #bfbfbf;
}
:deep(.ant-modal-body) {
padding: 0;
}
:deep(.ant-modal-footer) {
border-top: 1px solid #f0f0f0;
padding: 16px 24px;
}
.map-container {
border: 1px solid #f0f0f0;
border-radius: 2px;
overflow: hidden;
margin-bottom: 24px;
}
/* 移除重复的样式定义 */
:deep(.ant-form) {
max-width: 600px;
margin: 0 auto;
}
/* 清理和合并重复的样式 */
:deep(.ant-input-group) {
display: flex;
.ant-input-number {
border-radius: 0;
&:first-child {
border-top-left-radius: 2px;
border-bottom-left-radius: 2px;
}
&:last-child {
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
}
}
/* 清理重复的样式 */
:deep(.ant-modal-body),
:deep(.ant-form),
:deep(.ant-form-item) {
padding-right: 0;
padding-left: 0;
}
:deep(.ant-col) {
padding-right: 0;
padding-left: 0;
}
.status-tag {
cursor: pointer;
user-select: none;
display: inline-flex;
align-items: center;
gap: 4px;
}
:deep(.anticon) {
font-size: 12px;
}
</style> </style>