generated from Leo_Ding/web-template
服务对象列表
This commit is contained in:
parent
11ed08bc39
commit
cb4e899d82
3
package-lock.json
generated
3
package-lock.json
generated
@ -244,7 +244,8 @@
|
|||||||
"node_modules/@amap/amap-jsapi-loader": {
|
"node_modules/@amap/amap-jsapi-loader": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
|
"resolved": "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz",
|
||||||
"integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw=="
|
"integrity": "sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==",
|
||||||
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@ant-design/colors": {
|
"node_modules/@ant-design/colors": {
|
||||||
"version": "7.0.0",
|
"version": "7.0.0",
|
||||||
|
|||||||
@ -13,5 +13,6 @@ export const updateItem = (id, params) => request.basic.put(`/api/v1/customers/$
|
|||||||
// 删除数据
|
// 删除数据
|
||||||
export const delItem = (id) => request.basic.delete(`/api/v1/customers/${id}`)
|
export const delItem = (id) => request.basic.delete(`/api/v1/customers/${id}`)
|
||||||
|
|
||||||
|
//获取用户数量
|
||||||
|
export const getCount=()=>request.basic.get('/api/v1/customers/count')
|
||||||
|
|
||||||
|
|||||||
262
src/components/GxMap/index.vue
Normal file
262
src/components/GxMap/index.vue
Normal file
@ -0,0 +1,262 @@
|
|||||||
|
<template>
|
||||||
|
<div class="map-container">
|
||||||
|
<!-- 地图容器 -->
|
||||||
|
<a-form-item :label="'输入地址'">
|
||||||
|
<a-input-search v-model:value="searchValue" placeholder="输入需要查找的地址" enter-button @search="searchLocation" />
|
||||||
|
</a-form-item>
|
||||||
|
<a-form-item :label="'搜索结果'">
|
||||||
|
<a-select ref="select" v-model:value="selectValue" style="width: 100%" @focus="focus" @change="handleChange" >
|
||||||
|
<a-select-option v-for="item in searchList" :value="item.id">{{ item.name }}</a-select-option>
|
||||||
|
</a-select>
|
||||||
|
</a-form-item>
|
||||||
|
<div id="map" ref="mapContainer" style="height: calc(100% - 100px);"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, onMounted, onUnmounted,defineEmits } from 'vue'
|
||||||
|
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||||
|
defineOptions({
|
||||||
|
name: 'GxMap',
|
||||||
|
})
|
||||||
|
// 地图实例引用
|
||||||
|
const map = ref(null)
|
||||||
|
const mapContainer = ref(null)
|
||||||
|
const searchValue = ref('')
|
||||||
|
const searchResult = ref(null);
|
||||||
|
const markers = ref([]);
|
||||||
|
const locationMode = ref()
|
||||||
|
const locationData = ref({});
|
||||||
|
const infoWindow = ref(null);
|
||||||
|
const geocoder = ref(null);
|
||||||
|
const selectValue = ref('')
|
||||||
|
const searchList = ref([])
|
||||||
|
|
||||||
|
const emit = defineEmits(['handleGetLng']) //
|
||||||
|
onMounted(() => {
|
||||||
|
initMap()
|
||||||
|
})
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (map.value) {
|
||||||
|
map.value.destroy()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const initMap = async () => {
|
||||||
|
try {
|
||||||
|
// 安全密钥配置(必须放在插件初始化前!)
|
||||||
|
window._AMapSecurityConfig = {
|
||||||
|
securityJsCode: 'df197447a4adc77f0cb376a44462272c' // 替换为你的jscode
|
||||||
|
};
|
||||||
|
// 加载地图 SDK
|
||||||
|
const AMap = await AMapLoader.load({
|
||||||
|
key: "38b334d84b1f89aa39d4efae76f0b341", // 替换你的高德Key
|
||||||
|
version: "2.0", // SDK 版本
|
||||||
|
plugins: ['AMap.ToolBar', 'AMap.Scale', 'AMap.Geocoder'] // 需要加载的插件
|
||||||
|
})
|
||||||
|
|
||||||
|
// 初始化地图
|
||||||
|
map.value = new AMap.Map(mapContainer.value, {
|
||||||
|
zoom: 13, // 缩放级别
|
||||||
|
center: [120.894522,31.981269], // 中心点坐标(北京)
|
||||||
|
viewMode: "3D" // 使用3D视图
|
||||||
|
})
|
||||||
|
|
||||||
|
// 添加控件
|
||||||
|
map.value.addControl(new AMap.ToolBar())
|
||||||
|
map.value.addControl(new AMap.Scale())
|
||||||
|
// 初始化地理编码器
|
||||||
|
geocoder.value = new AMap.Geocoder({
|
||||||
|
city: "全国"
|
||||||
|
});
|
||||||
|
// 添加标记点
|
||||||
|
const marker = new AMap.Marker({
|
||||||
|
position: [120.894522,31.981269],
|
||||||
|
title: "南通市人民政府"
|
||||||
|
})
|
||||||
|
|
||||||
|
map.value.add(marker)
|
||||||
|
// 添加地图点击事件
|
||||||
|
map.value.on('click', handleMapClick);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("地图加载失败:", error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理地图点击事件
|
||||||
|
const handleMapClick = (e) => {
|
||||||
|
// 清除之前的标记
|
||||||
|
clearMarkers();
|
||||||
|
|
||||||
|
// 获取点击位置的经纬度
|
||||||
|
const lng = e.lnglat.getLng();
|
||||||
|
const lat = e.lnglat.getLat();
|
||||||
|
|
||||||
|
// 设置定位模式
|
||||||
|
locationMode.value = "点击定位";
|
||||||
|
|
||||||
|
// 存储坐标
|
||||||
|
locationData.value = {
|
||||||
|
lng: lng,
|
||||||
|
lat: lat,
|
||||||
|
name: "点击位置",
|
||||||
|
address: "正在获取地址..."
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建标记
|
||||||
|
const marker = new AMap.Marker({
|
||||||
|
position: [lng, lat],
|
||||||
|
title: "点击位置"
|
||||||
|
});
|
||||||
|
|
||||||
|
map.value.add(marker);
|
||||||
|
markers.value.push(marker);
|
||||||
|
|
||||||
|
// 设置地图中心
|
||||||
|
map.value.setCenter([lng, lat]);
|
||||||
|
|
||||||
|
// 使用逆地理编码获取地址信息
|
||||||
|
geocoder.value.getAddress([lng, lat], (status, result) => {
|
||||||
|
if (status === 'complete' && result.regeocode) {
|
||||||
|
const address = result.regeocode.formattedAddress;
|
||||||
|
locationData.value.address = address;
|
||||||
|
|
||||||
|
// 添加信息窗口
|
||||||
|
infoWindow.value = new AMap.InfoWindow({
|
||||||
|
content: `<div style="padding:10px;min-width:200px;">
|
||||||
|
<div style="font-weight:bold;margin-bottom:5px;">点击位置</div>
|
||||||
|
<div>${address}</div>
|
||||||
|
<div style="margin-top:8px;color:#666;">
|
||||||
|
<div>经度: ${lng.toFixed(6)}</div>
|
||||||
|
<div>纬度: ${lat.toFixed(6)}</div>
|
||||||
|
</div>
|
||||||
|
</div>`,
|
||||||
|
offset: new AMap.Pixel(0, -35)
|
||||||
|
});
|
||||||
|
const obj={address:address,lng:lng,lat:lat}
|
||||||
|
|
||||||
|
infoWindow.value.open(map.value, [lng, lat]);
|
||||||
|
emit('handleGetLng', obj)
|
||||||
|
} else {
|
||||||
|
locationData.value.address = "无法获取地址信息";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
// 搜索地点
|
||||||
|
const searchLocation = () => {
|
||||||
|
if (!searchValue.value.trim()) {
|
||||||
|
alert('请输入搜索关键词');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除之前的标记
|
||||||
|
clearMarkers();
|
||||||
|
|
||||||
|
// 使用高德地图的搜索插件
|
||||||
|
AMap.plugin('AMap.PlaceSearch', () => {
|
||||||
|
const placeSearch = new AMap.PlaceSearch({
|
||||||
|
pageSize: 10,
|
||||||
|
pageIndex: 1,
|
||||||
|
city: '全国'
|
||||||
|
});
|
||||||
|
|
||||||
|
placeSearch.search(searchValue.value, (status, result) => {
|
||||||
|
if (status === 'complete' && result.poiList.pois.length) {
|
||||||
|
searchList.value = result.poiList.pois.map(item => {
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
address: item.address,
|
||||||
|
location: {
|
||||||
|
lng: item.location.lng,
|
||||||
|
lat: item.location.lat
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log(searchList.value)
|
||||||
|
const poi = result.poiList.pois[0];
|
||||||
|
|
||||||
|
// 存储搜索结果
|
||||||
|
searchResult.value = {
|
||||||
|
id: poi.id,
|
||||||
|
name: poi.name,
|
||||||
|
address: poi.address,
|
||||||
|
location: {
|
||||||
|
lng: poi.location.lng,
|
||||||
|
lat: poi.location.lat
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建标记
|
||||||
|
const marker = new AMap.Marker({
|
||||||
|
position: [poi.location.lng, poi.location.lat],
|
||||||
|
title: poi.name
|
||||||
|
});
|
||||||
|
|
||||||
|
map.value.add(marker);
|
||||||
|
markers.value.push(marker);
|
||||||
|
|
||||||
|
// 设置地图中心
|
||||||
|
map.value.setCenter([poi.location.lng, poi.location.lat]);
|
||||||
|
|
||||||
|
// 添加信息窗口
|
||||||
|
const infoWindow = new AMap.InfoWindow({
|
||||||
|
content: `<div style="padding:5px;min-width:150px;">
|
||||||
|
<div style="font-weight:bold;">${poi.name}</div>
|
||||||
|
<div>${poi.address}</div>
|
||||||
|
<div>经度: ${poi.location.lng.toFixed(6)}</div>
|
||||||
|
<div>纬度: ${poi.location.lat.toFixed(6)}</div>
|
||||||
|
</div>`,
|
||||||
|
offset: new AMap.Pixel(0, -30)
|
||||||
|
});
|
||||||
|
|
||||||
|
infoWindow.open(map.value, marker.getPosition());
|
||||||
|
|
||||||
|
// 点击标记打开信息窗口
|
||||||
|
marker.on('click', () => {
|
||||||
|
infoWindow.open(map.value, marker.getPosition());
|
||||||
|
});
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert('未找到相关地点,请尝试其他关键词');
|
||||||
|
searchResult.value = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清除所有标记
|
||||||
|
const clearMarkers = () => {
|
||||||
|
markers.value.forEach(marker => {
|
||||||
|
map.value.remove(marker);
|
||||||
|
});
|
||||||
|
markers.value = [];
|
||||||
|
searchResult.value = null;
|
||||||
|
};
|
||||||
|
const handleChange=(e)=>{
|
||||||
|
const item = searchList.value.find(item=>item.id===e)
|
||||||
|
const obj={
|
||||||
|
lng:item.location.lng,
|
||||||
|
lat:item.location.lat,
|
||||||
|
addres:item.address
|
||||||
|
}
|
||||||
|
emit('handleGetLng', obj)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.map-container {
|
||||||
|
width: 100%;
|
||||||
|
height: 500px;
|
||||||
|
background-color: #eee;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#map {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 1px solid #eee;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,49 +1,20 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal
|
<a-modal :open="visible" :title="title" :width="width" :maskClosable="false" @ok="handleOk" @cancel="handleCancel">
|
||||||
:open="visible"
|
|
||||||
:title="title"
|
|
||||||
:width="width"
|
|
||||||
:maskClosable="false"
|
|
||||||
@ok="handleOk"
|
|
||||||
@cancel="handleCancel"
|
|
||||||
>
|
|
||||||
<!-- 错误提示区域 -->
|
<!-- 错误提示区域 -->
|
||||||
<a-alert
|
<a-alert v-if="errorMessage" :message="errorMessage" :description="errorDetails" type="error" show-icon
|
||||||
v-if="errorMessage"
|
style="margin-bottom: 12px" closable @close="clearError" />
|
||||||
:message="errorMessage"
|
|
||||||
:description="errorDetails"
|
|
||||||
type="error"
|
|
||||||
show-icon
|
|
||||||
style="margin-bottom: 12px"
|
|
||||||
closable
|
|
||||||
@close="clearError"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 搜索区域 -->
|
<!-- 搜索区域 -->
|
||||||
<div class="search-section">
|
<div class="search-section">
|
||||||
<a-form layout="vertical" :model="searchForm">
|
<a-form layout="vertical" :model="searchForm">
|
||||||
<a-form-item label="输入地址">
|
<a-form-item label="输入地址">
|
||||||
<a-input-search
|
<a-input-search v-model:value="searchForm.keyword" placeholder="输入需要查找的地址" enter-button @search="handleSearch"
|
||||||
v-model:value="searchForm.keyword"
|
:disabled="!mapLoaded || isSearching" allow-clear />
|
||||||
placeholder="输入需要查找的地址"
|
|
||||||
enter-button
|
|
||||||
@search="handleSearch"
|
|
||||||
:disabled="!mapLoaded || isSearching"
|
|
||||||
allow-clear
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="搜索结果" v-if="searchList.length > 0">
|
<a-form-item label="搜索结果" v-if="searchList.length > 0">
|
||||||
<a-select
|
<a-select v-model:value="selectedPlaceId" style="width: 100%" placeholder="请选择搜索结果"
|
||||||
v-model:value="selectedPlaceId"
|
@change="handlePlaceSelect">
|
||||||
style="width: 100%"
|
<a-select-option v-for="item in searchList" :key="item.id" :value="item.id">
|
||||||
placeholder="请选择搜索结果"
|
|
||||||
@change="handlePlaceSelect"
|
|
||||||
>
|
|
||||||
<a-select-option
|
|
||||||
v-for="item in searchList"
|
|
||||||
:key="item.id"
|
|
||||||
:value="item.id"
|
|
||||||
>
|
|
||||||
{{ item.name }} - {{ item.address }}
|
{{ item.name }} - {{ item.address }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
@ -57,34 +28,26 @@
|
|||||||
<a-spin size="large" />
|
<a-spin size="large" />
|
||||||
<div class="loading-text">{{ loadingText }}</div>
|
<div class="loading-text">{{ loadingText }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 调试信息 (仅开发环境显示) -->
|
<!-- 调试信息 (仅开发环境显示) -->
|
||||||
<!-- <div v-if="debugMode && mapLoaded" class="debug-info">
|
<!-- <div v-if="debugMode && mapLoaded" class="debug-info">
|
||||||
<div class="debug-header">调试信息</div>
|
<div class="debug-header">调试信息</div>
|
||||||
<pre>{{ debugInfo }}</pre>
|
<pre>{{ debugInfo }}</pre>
|
||||||
</div> -->
|
</div> -->
|
||||||
|
|
||||||
<div id="amap-container" class="amap-instance" ref="mapContainer"></div>
|
<div id="amap-container" class="amap-instance" ref="mapContainer"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<a-form :model="formState" layout="vertical" style="margin-top: 16px">
|
<a-form :model="formState" layout="vertical" style="margin-top: 16px">
|
||||||
<a-form-item label="经纬度">
|
<a-form-item label="经纬度">
|
||||||
<a-input
|
<a-input v-model:value="formState.lnglat" readonly placeholder="点击地图或搜索地点选择位置">
|
||||||
v-model:value="formState.lnglat"
|
|
||||||
readonly
|
|
||||||
placeholder="点击地图或搜索地点选择位置"
|
|
||||||
>
|
|
||||||
<template #suffix>
|
<template #suffix>
|
||||||
<a-spin v-if="isGeocoding" size="small" />
|
<a-spin v-if="isGeocoding" size="small" />
|
||||||
</template>
|
</template>
|
||||||
</a-input>
|
</a-input>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="详细地址">
|
<a-form-item label="详细地址">
|
||||||
<a-input
|
<a-input v-model:value="formState.address" readonly placeholder="地址信息将自动显示" />
|
||||||
v-model:value="formState.address"
|
|
||||||
readonly
|
|
||||||
placeholder="地址信息将自动显示"
|
|
||||||
/>
|
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
@ -202,7 +165,7 @@ const logDebug = (message: string) => {
|
|||||||
if (props.debugMode) {
|
if (props.debugMode) {
|
||||||
const timestamp = new Date().toLocaleTimeString()
|
const timestamp = new Date().toLocaleTimeString()
|
||||||
debugInfo.value = `[${timestamp}] ${message}\n${debugInfo.value}`
|
debugInfo.value = `[${timestamp}] ${message}\n${debugInfo.value}`
|
||||||
|
|
||||||
if (debugInfo.value.length > 5000) {
|
if (debugInfo.value.length > 5000) {
|
||||||
debugInfo.value = debugInfo.value.substring(0, 5000)
|
debugInfo.value = debugInfo.value.substring(0, 5000)
|
||||||
}
|
}
|
||||||
@ -239,9 +202,9 @@ const cleanupMap = () => {
|
|||||||
logDebug('开始清理地图资源')
|
logDebug('开始清理地图资源')
|
||||||
debouncedSearch.cancel()
|
debouncedSearch.cancel()
|
||||||
isSearching.value = false
|
isSearching.value = false
|
||||||
|
|
||||||
clearMarkers()
|
clearMarkers()
|
||||||
|
|
||||||
if (placeSearch) {
|
if (placeSearch) {
|
||||||
try {
|
try {
|
||||||
placeSearch.clear()
|
placeSearch.clear()
|
||||||
@ -252,15 +215,15 @@ const cleanupMap = () => {
|
|||||||
logDebug(`清理搜索服务时出错: ${e instanceof Error ? e.message : String(e)}`)
|
logDebug(`清理搜索服务时出错: ${e instanceof Error ? e.message : String(e)}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (infoWindow) {
|
if (infoWindow) {
|
||||||
infoWindow.close()
|
infoWindow.close()
|
||||||
infoWindow = null
|
infoWindow = null
|
||||||
logDebug('信息窗口已关闭')
|
logDebug('信息窗口已关闭')
|
||||||
}
|
}
|
||||||
|
|
||||||
clearMarker()
|
clearMarker()
|
||||||
|
|
||||||
if (map) {
|
if (map) {
|
||||||
try {
|
try {
|
||||||
map.destroy()
|
map.destroy()
|
||||||
@ -270,11 +233,11 @@ const cleanupMap = () => {
|
|||||||
logDebug(`清理地图时出错: ${e instanceof Error ? e.message : String(e)}`)
|
logDebug(`清理地图时出错: ${e instanceof Error ? e.message : String(e)}`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mapLoaded.value = false
|
mapLoaded.value = false
|
||||||
isGeocoding.value = false
|
isGeocoding.value = false
|
||||||
clearError()
|
clearError()
|
||||||
|
|
||||||
Object.assign(formState, {
|
Object.assign(formState, {
|
||||||
lnglat: '',
|
lnglat: '',
|
||||||
address: '',
|
address: '',
|
||||||
@ -331,10 +294,10 @@ const showLocationInfo = (place: SearchPlace, isSearchResult: boolean = false) =
|
|||||||
if (infoWindow) {
|
if (infoWindow) {
|
||||||
infoWindow.close()
|
infoWindow.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
const escapedName = escapeHtml(place.name)
|
const escapedName = escapeHtml(place.name)
|
||||||
const escapedAddress = escapeHtml(place.address || '地址不详')
|
const escapedAddress = escapeHtml(place.address || '地址不详')
|
||||||
|
|
||||||
const content = `
|
const content = `
|
||||||
<div style="padding: 8px; max-width: 200px;">
|
<div style="padding: 8px; max-width: 200px;">
|
||||||
<div style="font-weight: bold; margin-bottom: 4px;">${escapedName}</div>
|
<div style="font-weight: bold; margin-bottom: 4px;">${escapedName}</div>
|
||||||
@ -344,13 +307,13 @@ const showLocationInfo = (place: SearchPlace, isSearchResult: boolean = false) =
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
|
|
||||||
infoWindow = new AMap.InfoWindow({
|
infoWindow = new AMap.InfoWindow({
|
||||||
content: content,
|
content: content,
|
||||||
offset: new AMap.Pixel(0, -30),
|
offset: new AMap.Pixel(0, -30),
|
||||||
position: [place.location.lng, place.location.lat]
|
position: [place.location.lng, place.location.lat]
|
||||||
})
|
})
|
||||||
|
|
||||||
infoWindow.open(map, [place.location.lng, place.location.lat])
|
infoWindow.open(map, [place.location.lng, place.location.lat])
|
||||||
logDebug(`显示位置信息: ${place.name}`)
|
logDebug(`显示位置信息: ${place.name}`)
|
||||||
}
|
}
|
||||||
@ -359,10 +322,10 @@ const showLocationInfo = (place: SearchPlace, isSearchResult: boolean = false) =
|
|||||||
const handleSearchComplete = (result: AMap.PlaceSearchResult) => {
|
const handleSearchComplete = (result: AMap.PlaceSearchResult) => {
|
||||||
isSearching.value = false
|
isSearching.value = false
|
||||||
logDebug(`搜索完成: ${result.info}, 结果数: ${result.poiList?.pois?.length || 0}`)
|
logDebug(`搜索完成: ${result.info}, 结果数: ${result.poiList?.pois?.length || 0}`)
|
||||||
|
|
||||||
if (result.info === 'OK' && result.poiList?.pois?.length > 0) {
|
if (result.info === 'OK' && result.poiList?.pois?.length > 0) {
|
||||||
const pois = result.poiList.pois
|
const pois = result.poiList.pois
|
||||||
|
|
||||||
// 更新搜索结果列表
|
// 更新搜索结果列表
|
||||||
searchList.value = pois.map((poi: any) => ({
|
searchList.value = pois.map((poi: any) => ({
|
||||||
id: poi.id,
|
id: poi.id,
|
||||||
@ -373,10 +336,10 @@ const handleSearchComplete = (result: AMap.PlaceSearchResult) => {
|
|||||||
lat: poi.location.lat
|
lat: poi.location.lat
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// 清除之前的标记
|
// 清除之前的标记
|
||||||
clearMarkers()
|
clearMarkers()
|
||||||
|
|
||||||
// 为每个结果添加标记
|
// 为每个结果添加标记
|
||||||
pois.forEach((poi: any, index: number) => {
|
pois.forEach((poi: any, index: number) => {
|
||||||
const position = [poi.location.lng, poi.location.lat]
|
const position = [poi.location.lng, poi.location.lat]
|
||||||
@ -387,7 +350,7 @@ const handleSearchComplete = (result: AMap.PlaceSearchResult) => {
|
|||||||
content: createMarkerContent(poi.name, index + 1),
|
content: createMarkerContent(poi.name, index + 1),
|
||||||
offset: new AMap.Pixel(-15, -42)
|
offset: new AMap.Pixel(-15, -42)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 点击标记事件
|
// 点击标记事件
|
||||||
poiMarker.on('click', () => {
|
poiMarker.on('click', () => {
|
||||||
const place: SearchPlace = {
|
const place: SearchPlace = {
|
||||||
@ -400,10 +363,10 @@ const handleSearchComplete = (result: AMap.PlaceSearchResult) => {
|
|||||||
showLocationInfo(place, true)
|
showLocationInfo(place, true)
|
||||||
selectedPlaceId.value = poi.id
|
selectedPlaceId.value = poi.id
|
||||||
})
|
})
|
||||||
|
|
||||||
markers.push(poiMarker)
|
markers.push(poiMarker)
|
||||||
})
|
})
|
||||||
|
|
||||||
// 自动选中第一个结果
|
// 自动选中第一个结果
|
||||||
if (pois.length > 0) {
|
if (pois.length > 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -420,7 +383,7 @@ const handleSearchComplete = (result: AMap.PlaceSearchResult) => {
|
|||||||
map?.setZoom(16)
|
map?.setZoom(16)
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
|
|
||||||
map?.setFitView()
|
map?.setFitView()
|
||||||
} else {
|
} else {
|
||||||
message.info('未找到相关地点')
|
message.info('未找到相关地点')
|
||||||
@ -435,17 +398,17 @@ const performSearch = (keyword: string) => {
|
|||||||
setError('搜索服务未初始化', '请等待地图加载完成后再试')
|
setError('搜索服务未初始化', '请等待地图加载完成后再试')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mapLoaded.value) {
|
if (!mapLoaded.value) {
|
||||||
setError('地图未加载完成', '请等待地图加载完成后再试')
|
setError('地图未加载完成', '请等待地图加载完成后再试')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
isSearching.value = true
|
isSearching.value = true
|
||||||
searchList.value = []
|
searchList.value = []
|
||||||
selectedPlaceId.value = ''
|
selectedPlaceId.value = ''
|
||||||
logDebug(`执行搜索: ${keyword}`)
|
logDebug(`执行搜索: ${keyword}`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
placeSearch.clear()
|
placeSearch.clear()
|
||||||
clearMarkers()
|
clearMarkers()
|
||||||
@ -461,9 +424,9 @@ const performSearch = (keyword: string) => {
|
|||||||
// 创建搜索服务
|
// 创建搜索服务
|
||||||
const createPlaceSearch = () => {
|
const createPlaceSearch = () => {
|
||||||
if (!map) return
|
if (!map) return
|
||||||
|
|
||||||
logDebug(`创建PlaceSearch实例,城市限制: ${props.searchCity}`)
|
logDebug(`创建PlaceSearch实例,城市限制: ${props.searchCity}`)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
placeSearch = new AMap.PlaceSearch({
|
placeSearch = new AMap.PlaceSearch({
|
||||||
map: map,
|
map: map,
|
||||||
@ -477,11 +440,11 @@ const createPlaceSearch = () => {
|
|||||||
placeSearch.on('error', (error: any) => {
|
placeSearch.on('error', (error: any) => {
|
||||||
isSearching.value = false
|
isSearching.value = false
|
||||||
logDebug(`搜索错误: 代码=${error.errorCode}, 信息=${error.errorMsg}, 状态=${error.status}`)
|
logDebug(`搜索错误: 代码=${error.errorCode}, 信息=${error.errorMsg}, 状态=${error.status}`)
|
||||||
|
|
||||||
let userMsg = '搜索服务出错,请重试'
|
let userMsg = '搜索服务出错,请重试'
|
||||||
let details = `错误代码: ${error.errorCode}, 信息: ${error.errorMsg}`
|
let details = `错误代码: ${error.errorCode}, 信息: ${error.errorMsg}`
|
||||||
|
|
||||||
switch(error.errorCode) {
|
switch (error.errorCode) {
|
||||||
case 10001:
|
case 10001:
|
||||||
userMsg = 'API Key错误或已过期'
|
userMsg = 'API Key错误或已过期'
|
||||||
details += '\n解决方案: 检查并更新高德地图API Key'
|
details += '\n解决方案: 检查并更新高德地图API Key'
|
||||||
@ -503,7 +466,7 @@ const createPlaceSearch = () => {
|
|||||||
details += '\n解决方案: 稍后重试或联系高德技术支持'
|
details += '\n解决方案: 稍后重试或联系高德技术支持'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
setError(userMsg, details)
|
setError(userMsg, details)
|
||||||
message.error(userMsg)
|
message.error(userMsg)
|
||||||
})
|
})
|
||||||
@ -533,19 +496,19 @@ const createGeocoder = () => {
|
|||||||
// 初始化地图插件
|
// 初始化地图插件
|
||||||
const initPlugins = async (): Promise<void> => {
|
const initPlugins = async (): Promise<void> => {
|
||||||
logDebug('初始化地图插件')
|
logDebug('初始化地图插件')
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
AMap.plugin(['AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.ToolBar', 'AMap.Scale'], () => {
|
AMap.plugin(['AMap.PlaceSearch', 'AMap.Geocoder', 'AMap.ToolBar', 'AMap.Scale'], () => {
|
||||||
logDebug('插件加载回调触发')
|
logDebug('插件加载回调触发')
|
||||||
|
|
||||||
try {
|
try {
|
||||||
createPlaceSearch()
|
createPlaceSearch()
|
||||||
createGeocoder()
|
createGeocoder()
|
||||||
|
|
||||||
// 添加控件
|
// 添加控件
|
||||||
map?.addControl(new AMap.ToolBar())
|
map?.addControl(new AMap.ToolBar())
|
||||||
map?.addControl(new AMap.Scale())
|
map?.addControl(new AMap.Scale())
|
||||||
|
|
||||||
logDebug('插件加载成功')
|
logDebug('插件加载成功')
|
||||||
resolve()
|
resolve()
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -563,20 +526,20 @@ const updateSelectedLocation = async (position: [number, number], place?: Search
|
|||||||
formState.lnglat = `${lng.toFixed(6)}, ${lat.toFixed(6)}`
|
formState.lnglat = `${lng.toFixed(6)}, ${lat.toFixed(6)}`
|
||||||
formState.location = { lng, lat }
|
formState.location = { lng, lat }
|
||||||
logDebug(`位置更新: ${formState.lnglat}`)
|
logDebug(`位置更新: ${formState.lnglat}`)
|
||||||
|
|
||||||
// 更新标记
|
// 更新标记
|
||||||
updateMarker(position)
|
updateMarker(position)
|
||||||
|
|
||||||
// 地址反查
|
// 地址反查
|
||||||
if (geocoder) {
|
if (geocoder) {
|
||||||
isGeocoding.value = true
|
isGeocoding.value = true
|
||||||
geocoder.getAddress(position, (status, result) => {
|
geocoder.getAddress(position, (status, result) => {
|
||||||
isGeocoding.value = false
|
isGeocoding.value = false
|
||||||
|
|
||||||
if (status === 'complete' && result.regeocode) {
|
if (status === 'complete' && result.regeocode) {
|
||||||
formState.address = result.regeocode.formattedAddress
|
formState.address = result.regeocode.formattedAddress
|
||||||
logDebug(`地址反查成功: ${formState.address}`)
|
logDebug(`地址反查成功: ${formState.address}`)
|
||||||
|
|
||||||
// 触发 handleGetLng 事件
|
// 触发 handleGetLng 事件
|
||||||
const locationData: LocationData = {
|
const locationData: LocationData = {
|
||||||
lng,
|
lng,
|
||||||
@ -588,7 +551,7 @@ const updateSelectedLocation = async (position: [number, number], place?: Search
|
|||||||
} else if (place?.address) {
|
} else if (place?.address) {
|
||||||
formState.address = place.address
|
formState.address = place.address
|
||||||
logDebug(`使用POI地址: ${formState.address}`)
|
logDebug(`使用POI地址: ${formState.address}`)
|
||||||
|
|
||||||
const locationData: LocationData = {
|
const locationData: LocationData = {
|
||||||
lng,
|
lng,
|
||||||
lat,
|
lat,
|
||||||
@ -599,7 +562,7 @@ const updateSelectedLocation = async (position: [number, number], place?: Search
|
|||||||
} else {
|
} else {
|
||||||
formState.address = '地址不详'
|
formState.address = '地址不详'
|
||||||
logDebug('地址反查失败')
|
logDebug('地址反查失败')
|
||||||
|
|
||||||
const locationData: LocationData = {
|
const locationData: LocationData = {
|
||||||
lng,
|
lng,
|
||||||
lat,
|
lat,
|
||||||
@ -611,7 +574,7 @@ const updateSelectedLocation = async (position: [number, number], place?: Search
|
|||||||
} else if (place?.address) {
|
} else if (place?.address) {
|
||||||
formState.address = place.address
|
formState.address = place.address
|
||||||
logDebug(`使用POI地址: ${formState.address}`)
|
logDebug(`使用POI地址: ${formState.address}`)
|
||||||
|
|
||||||
const locationData: LocationData = {
|
const locationData: LocationData = {
|
||||||
lng,
|
lng,
|
||||||
lat,
|
lat,
|
||||||
@ -625,9 +588,9 @@ const updateSelectedLocation = async (position: [number, number], place?: Search
|
|||||||
// 更新标记位置
|
// 更新标记位置
|
||||||
const updateMarker = (position: [number, number]) => {
|
const updateMarker = (position: [number, number]) => {
|
||||||
if (!map) return
|
if (!map) return
|
||||||
|
|
||||||
clearMarker()
|
clearMarker()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
marker = new AMap.Marker({
|
marker = new AMap.Marker({
|
||||||
position: position,
|
position: position,
|
||||||
@ -639,12 +602,12 @@ const updateMarker = (position: [number, number]) => {
|
|||||||
imageSize: new AMap.Size(36, 36)
|
imageSize: new AMap.Size(36, 36)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
marker.on('dragend', (event) => {
|
marker.on('dragend', (event) => {
|
||||||
const newPosition = [event.lnglat.lng, event.lnglat.lat] as [number, number]
|
const newPosition = [event.lnglat.lng, event.lnglat.lat] as [number, number]
|
||||||
updateSelectedLocation(newPosition)
|
updateSelectedLocation(newPosition)
|
||||||
})
|
})
|
||||||
|
|
||||||
logDebug(`标记已更新到: ${position.join(', ')}`)
|
logDebug(`标记已更新到: ${position.join(', ')}`)
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const errorMsg = e instanceof Error ? e.message : '创建标记失败'
|
const errorMsg = e instanceof Error ? e.message : '创建标记失败'
|
||||||
@ -657,25 +620,25 @@ const updateMarker = (position: [number, number]) => {
|
|||||||
const handleMapClick = (e: any) => {
|
const handleMapClick = (e: any) => {
|
||||||
const lng = e.lnglat.getLng()
|
const lng = e.lnglat.getLng()
|
||||||
const lat = e.lnglat.getLat()
|
const lat = e.lnglat.getLat()
|
||||||
|
|
||||||
// 清除搜索结果
|
// 清除搜索结果
|
||||||
clearMarkers()
|
clearMarkers()
|
||||||
searchList.value = []
|
searchList.value = []
|
||||||
selectedPlaceId.value = ''
|
selectedPlaceId.value = ''
|
||||||
|
|
||||||
updateSelectedLocation([lng, lat])
|
updateSelectedLocation([lng, lat])
|
||||||
|
|
||||||
// 使用逆地理编码获取地址信息
|
// 使用逆地理编码获取地址信息
|
||||||
if (geocoder) {
|
if (geocoder) {
|
||||||
geocoder.getAddress([lng, lat], (status, result) => {
|
geocoder.getAddress([lng, lat], (status, result) => {
|
||||||
if (status === 'complete' && result.regeocode) {
|
if (status === 'complete' && result.regeocode) {
|
||||||
const address = result.regeocode.formattedAddress
|
const address = result.regeocode.formattedAddress
|
||||||
|
|
||||||
// 添加信息窗口
|
// 添加信息窗口
|
||||||
if (infoWindow) {
|
if (infoWindow) {
|
||||||
infoWindow.close()
|
infoWindow.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
infoWindow = new AMap.InfoWindow({
|
infoWindow = new AMap.InfoWindow({
|
||||||
content: `
|
content: `
|
||||||
<div style="padding:10px;min-width:200px;">
|
<div style="padding:10px;min-width:200px;">
|
||||||
@ -689,7 +652,7 @@ const handleMapClick = (e: any) => {
|
|||||||
`,
|
`,
|
||||||
offset: new AMap.Pixel(0, -35)
|
offset: new AMap.Pixel(0, -35)
|
||||||
})
|
})
|
||||||
|
|
||||||
infoWindow.open(map, [lng, lat])
|
infoWindow.open(map, [lng, lat])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -700,7 +663,7 @@ const handleMapClick = (e: any) => {
|
|||||||
const initMap = async () => {
|
const initMap = async () => {
|
||||||
logDebug('开始初始化地图')
|
logDebug('开始初始化地图')
|
||||||
clearError()
|
clearError()
|
||||||
|
|
||||||
if (!mapContainer.value) {
|
if (!mapContainer.value) {
|
||||||
const errorMsg = '地图容器元素未找到'
|
const errorMsg = '地图容器元素未找到'
|
||||||
setError('初始化失败', errorMsg)
|
setError('初始化失败', errorMsg)
|
||||||
@ -710,7 +673,7 @@ const initMap = async () => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
loadingText.value = '正在初始化地图...'
|
loadingText.value = '正在初始化地图...'
|
||||||
|
|
||||||
// 安全密钥配置
|
// 安全密钥配置
|
||||||
window._AMapSecurityConfig = {
|
window._AMapSecurityConfig = {
|
||||||
securityJsCode: 'df197447a4adc77f0cb376a44462272c'
|
securityJsCode: 'df197447a4adc77f0cb376a44462272c'
|
||||||
@ -735,7 +698,7 @@ const initMap = async () => {
|
|||||||
logDebug('地图加载完成')
|
logDebug('地图加载完成')
|
||||||
mapLoaded.value = true
|
mapLoaded.value = true
|
||||||
loadingText.value = '地图加载中...'
|
loadingText.value = '地图加载中...'
|
||||||
|
|
||||||
initPlugins().catch(error => {
|
initPlugins().catch(error => {
|
||||||
console.error('插件初始化失败:', error)
|
console.error('插件初始化失败:', error)
|
||||||
setError('功能初始化失败', error.message)
|
setError('功能初始化失败', error.message)
|
||||||
@ -763,7 +726,7 @@ const initMap = async () => {
|
|||||||
// 处理搜索
|
// 处理搜索
|
||||||
const handleSearch = (keyword: string) => {
|
const handleSearch = (keyword: string) => {
|
||||||
clearError()
|
clearError()
|
||||||
|
|
||||||
if (!keyword?.trim()) {
|
if (!keyword?.trim()) {
|
||||||
message.warning('请输入搜索关键词')
|
message.warning('请输入搜索关键词')
|
||||||
debouncedSearch.cancel()
|
debouncedSearch.cancel()
|
||||||
@ -776,7 +739,7 @@ const handleSearch = (keyword: string) => {
|
|||||||
if (!placeSearch) {
|
if (!placeSearch) {
|
||||||
message.warning('搜索服务初始化中,请稍后重试')
|
message.warning('搜索服务初始化中,请稍后重试')
|
||||||
logDebug('搜索服务尚未初始化,等待初始化后重试')
|
logDebug('搜索服务尚未初始化,等待初始化后重试')
|
||||||
|
|
||||||
initPlugins().then(() => {
|
initPlugins().then(() => {
|
||||||
handleSearch(keyword)
|
handleSearch(keyword)
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
@ -810,13 +773,13 @@ const handleOk = () => {
|
|||||||
message.warning('请先在地图上选择一个位置')
|
message.warning('请先在地图上选择一个位置')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('select', {
|
emit('select', {
|
||||||
lnglat: formState.lnglat,
|
lnglat: formState.lnglat,
|
||||||
address: formState.address,
|
address: formState.address,
|
||||||
location: formState.location
|
location: formState.location
|
||||||
})
|
})
|
||||||
|
|
||||||
handleCancel()
|
handleCancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import Scrollbar from './Scrollbar/Scrollbar.vue'
|
|||||||
import Cascader from './Cascader/Cascader.vue'
|
import Cascader from './Cascader/Cascader.vue'
|
||||||
import { setupLoadingDirective } from './Loading/directive'
|
import { setupLoadingDirective } from './Loading/directive'
|
||||||
import GxUpload from './GxUpload/index.vue'
|
import GxUpload from './GxUpload/index.vue'
|
||||||
|
import GxMap from './GxMap/index.vue'
|
||||||
|
|
||||||
const componentList = [
|
const componentList = [
|
||||||
ActionBar,
|
ActionBar,
|
||||||
@ -43,6 +44,7 @@ const componentList = [
|
|||||||
Scrollbar,
|
Scrollbar,
|
||||||
Cascader,
|
Cascader,
|
||||||
GxUpload,
|
GxUpload,
|
||||||
|
GxMap
|
||||||
]
|
]
|
||||||
|
|
||||||
export const loading = Loading
|
export const loading = Loading
|
||||||
|
|||||||
@ -333,4 +333,41 @@ export const spliceUrl=(fullUrl)=>{
|
|||||||
if(!fullUrl) return null
|
if(!fullUrl) return null
|
||||||
const pathOnly = fullUrl.replace(/^https?:\/\/[^\/]+/, '');
|
const pathOnly = fullUrl.replace(/^https?:\/\/[^\/]+/, '');
|
||||||
return pathOnly
|
return pathOnly
|
||||||
|
}
|
||||||
|
/**根据身份证识别出生日期 */
|
||||||
|
export const getBirthDate=(value)=>{
|
||||||
|
|
||||||
|
let year, month, day;
|
||||||
|
|
||||||
|
// 15位身份证:YYMMDD
|
||||||
|
if (value.length === 15) {
|
||||||
|
year = '19' + value.substring(6, 8); // 默认1900年代
|
||||||
|
month = value.substring(8, 10);
|
||||||
|
day = value.substring(10, 12);
|
||||||
|
}
|
||||||
|
// 18位身份证:YYYYMMDD
|
||||||
|
else if (value.length === 18) {
|
||||||
|
year = value.substring(6, 10);
|
||||||
|
month = value.substring(10, 12);
|
||||||
|
day = value.substring(12, 14);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证是否为合法日期
|
||||||
|
const date = new Date(year, month - 1, day); // 注意:月份从0开始
|
||||||
|
if (
|
||||||
|
date.getFullYear() !== parseInt(year, 10) ||
|
||||||
|
date.getMonth() + 1 !== parseInt(month, 10) ||
|
||||||
|
date.getDate() !== parseInt(day, 10)
|
||||||
|
) {
|
||||||
|
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式化为 YYYY-MM-DD
|
||||||
|
const formattedDate = `${year}-${String(month).padStart(2, '0')}-${String(day).padStart(2, '0')}`;
|
||||||
|
return formattedDate;
|
||||||
}
|
}
|
||||||
@ -34,7 +34,8 @@
|
|||||||
{{ item.introduction }}
|
{{ item.introduction }}
|
||||||
</a-select-option>
|
</a-select-option>
|
||||||
</a-select>
|
</a-select>
|
||||||
<a-input v-model:value="formData.idNumber" placeholder="请输入证件号码" style="flex: 1;" />
|
<a-input v-model:value="formData.idNumber" placeholder="请输入证件号码" style="flex: 1;"
|
||||||
|
@change="extractBirthDateFromIdCard" />
|
||||||
</span>
|
</span>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
@ -181,7 +182,7 @@
|
|||||||
<!-- 经度 -->
|
<!-- 经度 -->
|
||||||
<a-col :span="12">
|
<a-col :span="12">
|
||||||
<a-form-item label="经度" name="log">
|
<a-form-item label="经度" name="log">
|
||||||
<a-input v-model:value="formData.log" placeholder="请输入经度" />
|
<a-input v-model:value="formData.lng" placeholder="请输入经度" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
|
||||||
@ -191,6 +192,7 @@
|
|||||||
<a-input v-model:value="formData.lat" placeholder="请输入纬度" />
|
<a-input v-model:value="formData.lat" placeholder="请输入纬度" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
<gx-map @handleGetLng="handleGetLng" />
|
||||||
</a-row>
|
</a-row>
|
||||||
|
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
@ -458,6 +460,9 @@ import { useForm, useModal } from '@/hooks'
|
|||||||
import { useDicsStore } from '@/store'
|
import { useDicsStore } from '@/store'
|
||||||
import AreaCascader from '@/components/AreaCascader/index.vue'
|
import AreaCascader from '@/components/AreaCascader/index.vue'
|
||||||
import { validatePhone, validateEmail, validateIdCard } from '@/utils/validate'
|
import { validatePhone, validateEmail, validateIdCard } from '@/utils/validate'
|
||||||
|
import { getBirthDate } from '@/utils/util'
|
||||||
|
import dayjs from 'dayjs'
|
||||||
|
import { message } from 'ant-design-vue'
|
||||||
const emit = defineEmits(['ok'])
|
const emit = defineEmits(['ok'])
|
||||||
const activeKey = ref('1')
|
const activeKey = ref('1')
|
||||||
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
|
const { modal, showModal, hideModal, showLoading, hideLoading } = useModal()
|
||||||
@ -474,12 +479,13 @@ formRules.value = {
|
|||||||
serviceStatus: [{ required: true, message: '请选择服务状态', trigger: 'change' }],
|
serviceStatus: [{ required: true, message: '请选择服务状态', trigger: 'change' }],
|
||||||
homeDetailAddress: [{ required: true, message: '请输入详细地址', trigger: 'change' }],
|
homeDetailAddress: [{ required: true, message: '请输入详细地址', trigger: 'change' }],
|
||||||
}
|
}
|
||||||
formData.value.gender = '1'
|
|
||||||
const dicsStore = useDicsStore()
|
const dicsStore = useDicsStore()
|
||||||
/**
|
/**
|
||||||
* 新建
|
* 新建
|
||||||
*/
|
*/
|
||||||
function handleCreate() {
|
function handleCreate() {
|
||||||
|
formData.value.gender = '1'
|
||||||
showModal({
|
showModal({
|
||||||
type: 'create',
|
type: 'create',
|
||||||
title: '新建项',
|
title: '新建项',
|
||||||
@ -489,13 +495,17 @@ function handleCreate() {
|
|||||||
/**
|
/**
|
||||||
* 编辑
|
* 编辑
|
||||||
*/
|
*/
|
||||||
function handleEdit(record = {}) {
|
async function handleEdit(record = {}) {
|
||||||
showModal({
|
showModal({
|
||||||
type: 'edit',
|
type: 'edit',
|
||||||
title: '编辑项',
|
title: '编辑对象'
|
||||||
})
|
})
|
||||||
formRecord.value = record
|
const { data, success } = await apis.serverObj.getItem(record.id).catch()
|
||||||
formData.value = cloneDeep(record)
|
if (!success) {
|
||||||
|
hideModal()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
formData.value = { ...data }
|
||||||
}
|
}
|
||||||
// utils/idCard.js
|
// utils/idCard.js
|
||||||
function isValidIdCard(value) {
|
function isValidIdCard(value) {
|
||||||
@ -561,9 +571,9 @@ function handleOk() {
|
|||||||
...formData.value,
|
...formData.value,
|
||||||
}
|
}
|
||||||
// 单独封装一个同步校验函数
|
// 单独封装一个同步校验函数
|
||||||
console.log('params.identityType', isValidIdCard(params.idNumber));
|
|
||||||
if (params.identityType === '1' && !isValidIdCard(params.idNumber)) {
|
if (params.identityType === '1' && !isValidIdCard(params.idNumber)) {
|
||||||
throw new Error('请输入正确的身份证号码');
|
throw new Error('请输入正确的身份证号码');
|
||||||
|
|
||||||
}
|
}
|
||||||
let result = null
|
let result = null
|
||||||
switch (modal.value.type) {
|
switch (modal.value.type) {
|
||||||
@ -571,6 +581,7 @@ function handleOk() {
|
|||||||
result = await apis.serverObj.createItem(params).catch(() => {
|
result = await apis.serverObj.createItem(params).catch(() => {
|
||||||
throw new Error()
|
throw new Error()
|
||||||
})
|
})
|
||||||
|
console.log('result', result.code)
|
||||||
break
|
break
|
||||||
case 'edit':
|
case 'edit':
|
||||||
result = await apis.serverObj.updateItem(params).catch(() => {
|
result = await apis.serverObj.updateItem(params).catch(() => {
|
||||||
@ -585,12 +596,24 @@ function handleOk() {
|
|||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
hideLoading()
|
hideLoading()
|
||||||
|
message.error(error.message)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
hideLoading()
|
hideLoading()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
// 提取出生日期方法
|
||||||
|
const extractBirthDateFromIdCard = () => {
|
||||||
|
console.log(111)
|
||||||
|
const { idNumber } = formData.value;
|
||||||
|
if (!idNumber) {
|
||||||
|
formData.value.birthDate = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
console.log(getBirthDate(idNumber))
|
||||||
|
formData.value.birthDate = dayjs(getBirthDate(idNumber));
|
||||||
|
};
|
||||||
function onAreaChange(value, labels) {
|
function onAreaChange(value, labels) {
|
||||||
console.log(formData.value.homeAreaCodes);
|
console.log(formData.value.homeAreaCodes);
|
||||||
formData.value.homeAreaLabels = [...labels]
|
formData.value.homeAreaLabels = [...labels]
|
||||||
@ -599,6 +622,10 @@ function onAreaHoldChange(value, labels) {
|
|||||||
console.log(formData.value.houseAreaCodes);
|
console.log(formData.value.houseAreaCodes);
|
||||||
formData.value.houseAreaLabels = [...labels]
|
formData.value.houseAreaLabels = [...labels]
|
||||||
}
|
}
|
||||||
|
function handleGetLng(obj) {
|
||||||
|
formData.value.lat = obj.lat
|
||||||
|
formData.value.lng = obj.lng
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 取消
|
* 取消
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2,29 +2,34 @@
|
|||||||
<a-modal :open="modal.open" :title="modal.title" :width="1000" :confirm-loading="modal.confirmLoading"
|
<a-modal :open="modal.open" :title="modal.title" :width="1000" :confirm-loading="modal.confirmLoading"
|
||||||
:after-close="onAfterClose" :cancel-text="cancelText" @ok="handleOk" @cancel="handleCancel">
|
:after-close="onAfterClose" :cancel-text="cancelText" @ok="handleOk" @cancel="handleCancel">
|
||||||
<a-card>
|
<a-card>
|
||||||
<div style="display: flex;justify-content: space-around;">
|
<div style="display: flex;justify-content: space-around;">
|
||||||
<div style="width:200px;margin-top: 20px;border-right: 1px solid #f0f0f0;display: flex;flex-direction: column;align-items: center;">
|
<div
|
||||||
<gx-upload v-model="formData.imgList" accept-types=".jpg,.png,.webp" :fileNumber="1" />
|
style="width:280px;margin-top: 20px;border-right: 1px solid #f0f0f0;display: flex;flex-direction: column;align-items: center;">
|
||||||
<p>{{ formData.name }}{{ formData.gender }}{{ formData.age }}</p>
|
<gx-upload v-model="formData.imgList" accept-types=".jpg,.png,.webp" :fileNumber="1" />
|
||||||
<p>身份证号:{{ formData.idNumber }}</p>
|
<div>
|
||||||
<p>手机号:{{ formData.contact1 }}</p>
|
<p>{{ formData.name }}{{ formData.gender }}{{ formData.age }}</p>
|
||||||
<p>联系人:{{ formData.contactman }}</p>
|
<p>身份证号:{{ formData.idNumber }}</p>
|
||||||
<p>联系方式:{{ formData.contact1 }}</p>
|
<p>手机号:{{ formData.contact1 }}</p>
|
||||||
<p><a-tag color="#2db7f5">#2db7f5</a-tag></p>
|
<!-- <p>联系人:{{ formData.contactman }}</p>
|
||||||
</div>
|
<p>联系方式:{{ formData.contact1 }}</p> -->
|
||||||
<div style="width: calc(100% - 200px);padding: 20px;">
|
<p><a-tag color="#2db7f5">#2db7f5</a-tag></p>
|
||||||
<!-- Tab 页签 -->
|
</div>
|
||||||
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange" >
|
|
||||||
<a-tab-pane v-for="(tab, index) in tabsList" :key="index" :tab="tab" />
|
</div>
|
||||||
</a-tabs>
|
<div style="width: calc(100% - 280px);padding: 20px;">
|
||||||
<!-- 动态组件区域 -->
|
<!-- Tab 页签 -->
|
||||||
<div style="flex: 1; padding: 16px; overflow-y: auto;">
|
<a-tabs v-model:activeKey="activeKey" @change="handleTabChange">
|
||||||
<keep-alive>
|
<a-tab-pane v-for="(tab, index) in tabsList" :key="index" :tab="tab" />
|
||||||
<component v-if="currentComponent" :is="currentComponent" :ref="activeKey" :key="activeKey" />
|
</a-tabs>
|
||||||
</keep-alive>
|
<!-- 动态组件区域 -->
|
||||||
|
<div style="flex: 1; padding: 16px; overflow-y: auto;">
|
||||||
|
<keep-alive>
|
||||||
|
<component v-if="currentComponent" :is="currentComponent" :ref="activeKey"
|
||||||
|
:key="activeKey" />
|
||||||
|
</keep-alive>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</a-card>
|
</a-card>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
@ -32,7 +37,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import GxUpload from '@/components/GxUpload/index.vue'
|
import GxUpload from '@/components/GxUpload/index.vue'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { ref, computed, defineAsyncComponent,defineExpose,getCurrentInstance,nextTick } from 'vue'
|
import { ref, computed, defineAsyncComponent, defineExpose, getCurrentInstance, nextTick } from 'vue'
|
||||||
import { config } from '@/config'
|
import { config } from '@/config'
|
||||||
import apis from '@/apis'
|
import apis from '@/apis'
|
||||||
import { useForm, useModal } from '@/hooks'
|
import { useForm, useModal } from '@/hooks'
|
||||||
@ -89,11 +94,12 @@ const { proxy } = getCurrentInstance();
|
|||||||
/**
|
/**
|
||||||
* 新建
|
* 新建
|
||||||
*/
|
*/
|
||||||
function handleCreate() {
|
function handleCreate(record) {
|
||||||
showModal({
|
showModal({
|
||||||
type: 'create',
|
type: 'create',
|
||||||
title: '新建项',
|
title: '新建项',
|
||||||
})
|
})
|
||||||
|
formData.value = record
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -109,8 +115,8 @@ function handleEdit(record = {}) {
|
|||||||
formData.value = cloneDeep(record)
|
formData.value = cloneDeep(record)
|
||||||
}
|
}
|
||||||
const callback = (val) => {
|
const callback = (val) => {
|
||||||
console.log(val);
|
console.log(val);
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* 确定
|
* 确定
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -225,7 +225,7 @@
|
|||||||
placeholder="请选择" tree-default-expand-all>
|
placeholder="请选择" tree-default-expand-all>
|
||||||
<template #title="{ key, value }">
|
<template #title="{ key, value }">
|
||||||
<span style="color: #08c" v-if="key === '0-0-1'">Child Node1 {{ value
|
<span style="color: #08c" v-if="key === '0-0-1'">Child Node1 {{ value
|
||||||
}}</span>
|
}}</span>
|
||||||
</template>
|
</template>
|
||||||
</a-tree-select>
|
</a-tree-select>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
@ -290,7 +290,7 @@
|
|||||||
</template>
|
</template>
|
||||||
<a-table :columns="columns" :data-source="listData" bordered="true" :loading="loading"
|
<a-table :columns="columns" :data-source="listData" bordered="true" :loading="loading"
|
||||||
:pagination="paginationState" :scroll="{ x: 'max-content' }" @change="onTableChange">
|
:pagination="paginationState" :scroll="{ x: 'max-content' }" @change="onTableChange">
|
||||||
<template #bodyCell="{ index,column, record }">
|
<template #bodyCell="{ index, column, record }">
|
||||||
<template v-if="column.key === 'serialNumber'">
|
<template v-if="column.key === 'serialNumber'">
|
||||||
<span>{{ index + 1 }}</span>
|
<span>{{ index + 1 }}</span>
|
||||||
</template>
|
</template>
|
||||||
@ -301,7 +301,7 @@
|
|||||||
<x-action-button @click="checkHandler(record)">
|
<x-action-button @click="checkHandler(record)">
|
||||||
<span>线下工单</span>
|
<span>线下工单</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button @click="$refs.detailRef.handleCreate(record)">
|
<x-action-button @click="$refs.editDialogRef.handleEdit(record)">
|
||||||
<span>编辑</span>
|
<span>编辑</span>
|
||||||
</x-action-button>
|
</x-action-button>
|
||||||
<x-action-button @click="checkHandler(record)">
|
<x-action-button @click="checkHandler(record)">
|
||||||
@ -660,6 +660,18 @@ const options = ref([
|
|||||||
},])
|
},])
|
||||||
|
|
||||||
getPageList()
|
getPageList()
|
||||||
|
getCount()
|
||||||
|
async function getCount(params) {
|
||||||
|
try {
|
||||||
|
const { success, data } = await apis.serverObj.getCount({serviceNodeCodes:searchFormData.value.serviceNodeCodes})
|
||||||
|
if (config('http.code.success') === success) {
|
||||||
|
totalCount.value = data
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 获取表格数据
|
* 获取表格数据
|
||||||
* @returns {Promise<void>}
|
* @returns {Promise<void>}
|
||||||
|
|||||||
@ -138,6 +138,11 @@
|
|||||||
"@algolia/logger-common" "4.19.1"
|
"@algolia/logger-common" "4.19.1"
|
||||||
"@algolia/requester-common" "4.19.1"
|
"@algolia/requester-common" "4.19.1"
|
||||||
|
|
||||||
|
"@amap/amap-jsapi-loader@^1.0.1":
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.npmmirror.com/@amap/amap-jsapi-loader/-/amap-jsapi-loader-1.0.1.tgz"
|
||||||
|
integrity sha512-nPyLKt7Ow/ThHLkSvn2etQlUzqxmTVgK7bIgwdBRTg2HK5668oN7xVxkaiRe3YZEzGzfV2XgH5Jmu2T73ljejw==
|
||||||
|
|
||||||
"@ant-design/colors@^6.0.0":
|
"@ant-design/colors@^6.0.0":
|
||||||
version "6.0.0"
|
version "6.0.0"
|
||||||
resolved "https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz"
|
resolved "https://registry.npmmirror.com/@ant-design/colors/-/colors-6.0.0.tgz"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user