上传
This commit is contained in:
@@ -87,7 +87,22 @@
|
||||
:prop="item.field"
|
||||
:label="item.label"
|
||||
min-width="120px"
|
||||
/>
|
||||
>
|
||||
<template #default="{ row }">
|
||||
<el-popover
|
||||
placement="top"
|
||||
width="500px"
|
||||
trigger="click"
|
||||
v-if="item.form?.component == 'Editor' && row[item.field]"
|
||||
>
|
||||
<template #reference>
|
||||
<el-button type="primary" style="padding: 0" text>点击查看</el-button>
|
||||
</template>
|
||||
<div v-dompurify-html="row.remark"></div>
|
||||
</el-popover>
|
||||
<span v-else>{{ row[item.field] }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="240px" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
|
||||
@@ -47,15 +47,15 @@
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane v-if="appStore.getAppInfo?.instanceType == 1" label="位置信息" name="map">
|
||||
<div class="flex justify-between">
|
||||
<div class="flex justify-between items-center">
|
||||
<el-select
|
||||
v-model="areaValue"
|
||||
filterable
|
||||
clearable
|
||||
remote
|
||||
style="width: 350px"
|
||||
style="width: 250px"
|
||||
reserve-keyword
|
||||
placeholder="请输入关键词"
|
||||
placeholder="输入并搜索位置"
|
||||
:remote-method="remoteMethod"
|
||||
@change="currentSelect"
|
||||
>
|
||||
@@ -70,17 +70,44 @@
|
||||
<span style="float: right; color: #8492a6; font-size: 13px">{{ item.district }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
<div class="flex-1 flex items-center ml-10px mr-10px">
|
||||
<div class="w-100px">线索位置:</div>
|
||||
<el-input v-model="address" disabled placeholder="请输入线索位置" clearable />
|
||||
</div>
|
||||
<el-checkbox v-model="showSchool" :label="true" @change="handleShowSchool">
|
||||
展示场地
|
||||
</el-checkbox>
|
||||
</div>
|
||||
<div id="dialogMap" class="mt-20px" style="height: 400px; width: 100%"></div>
|
||||
<div class="flex items-center mt-10px mb-10px">
|
||||
<div class="w-100px">线索位置:</div>
|
||||
<el-input v-model="address" placeholder="请输入线索位置" clearable />
|
||||
<el-collapse v-model="collaspeKey" class="box-card">
|
||||
<el-collapse-item title="附近驾校" name="nearbySchool">
|
||||
<template #header>附近驾校</template>
|
||||
<div style="padding: 10px">
|
||||
<div v-if="nearbySchoolSearching">正在搜索中...</div>
|
||||
<template v-else>
|
||||
<div v-for="p in nearbySchoolList" :key="p.index">
|
||||
<div
|
||||
class="hover-pointer"
|
||||
style="font-size: 14px; color: blue"
|
||||
@click="getClassType(p)"
|
||||
>
|
||||
<i v-if="p.recommend" class="el-icon-star-off"></i>
|
||||
驾校: {{ p.deptName }}-{{ p.name }}
|
||||
</div>
|
||||
<div class="mt5">地址:{{ p.address }}</div>
|
||||
<div class="mt5">
|
||||
直线距离: {{ p.distance }} 公里;
|
||||
<span class="ml0">步行距离:{{ p.walkdistance }}</span>
|
||||
</div>
|
||||
<el-divider style="margin: 6px 0 !important" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<DialogSchoolInfo ref="schoolInfoDialog" />
|
||||
<template #footer>
|
||||
<span>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
@@ -97,7 +124,10 @@ import * as ClueApi from '@/api/clue'
|
||||
import { getDiyFieldList } from '@/api/clue/clueField'
|
||||
import { formatDate } from '@/utils/formatTime'
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
import ImgPostion from '@/assets/imgs/flag/flag_red.png'
|
||||
|
||||
import DialogSchoolInfo from './DialogSchoolInfo.vue'
|
||||
|
||||
import ImgPostion from '@/assets/imgs/flag/position_blue.png'
|
||||
import FlagRed from '@/assets/imgs/flag/flag_red.png'
|
||||
import FlagYellow from '@/assets/imgs/flag/flag_yellow.png'
|
||||
import FlagPurple from '@/assets/imgs/flag/flag_purple.png'
|
||||
@@ -201,8 +231,8 @@ const open = async (type, id) => {
|
||||
}
|
||||
}
|
||||
if (appStore.getAppInfo?.instanceType == 1 && !dialogMap.value) {
|
||||
nextTick(() => {
|
||||
getSchoolPlace()
|
||||
nextTick(async () => {
|
||||
await getSchoolPlace()
|
||||
initMap(info.value)
|
||||
remoteMethod(address.value)
|
||||
})
|
||||
@@ -220,10 +250,9 @@ function resetForm() {
|
||||
}
|
||||
|
||||
const placeList = ref([])
|
||||
function getSchoolPlace() {
|
||||
getPlaceList().then((data) => {
|
||||
async function getSchoolPlace() {
|
||||
const data = await getPlaceList()
|
||||
placeList.value = data.placeList
|
||||
})
|
||||
}
|
||||
|
||||
const emit = defineEmits(['success'])
|
||||
@@ -237,6 +266,10 @@ async function handleSave() {
|
||||
message.info('请将跟进人填写完整!')
|
||||
return
|
||||
}
|
||||
if (!address.value) {
|
||||
message.info('请选择学员位置!')
|
||||
return
|
||||
}
|
||||
// 提交请求
|
||||
formLoading.value = true
|
||||
try {
|
||||
@@ -299,7 +332,7 @@ function initMap(data) {
|
||||
}
|
||||
}
|
||||
dialogMap.value = new AMap.Map('dialogMap', {
|
||||
zoom: 12,
|
||||
zoom: 14,
|
||||
zooms: [2, 22],
|
||||
center: [defaultLatLng.value.lng, defaultLatLng.value.lat]
|
||||
})
|
||||
@@ -321,6 +354,74 @@ function initMap(data) {
|
||||
})
|
||||
}
|
||||
|
||||
const collaspeKey = ref('nearbySchool')
|
||||
const nearbySchoolSearching = ref(false)
|
||||
const nearbySchoolList = ref([])
|
||||
function getNearbySchool(info) {
|
||||
if (info.lng && info.lat) {
|
||||
nearbySchoolList.value = []
|
||||
nearbySchoolSearching.value = true
|
||||
// 推荐的场地
|
||||
let places1 = []
|
||||
// 普通的场地
|
||||
let places2 = []
|
||||
|
||||
const p2 = [info.lng, info.lat]
|
||||
for (let i = 0; i < placeList.value.length; i++) {
|
||||
const element = placeList.value[i]
|
||||
const p1 = [element.lng, element.lat]
|
||||
// 计算直线距离
|
||||
element.distance = (aMap.value.GeometryUtil.distance(p1, p2) / 1000).toFixed(2)
|
||||
element.recommend ? places1.push(element) : places2.push(element)
|
||||
}
|
||||
// 按直线距离排序
|
||||
// 排序
|
||||
if (places1.length > 1) {
|
||||
places1 = places1.sort((a, b) => a.distance - b.distance)
|
||||
}
|
||||
// 排序
|
||||
if (places2.length > 1) {
|
||||
places2 = places2.sort((a, b) => a.distance - b.distance)
|
||||
}
|
||||
// 取普通场地和推荐场地,组合, 取四个
|
||||
nearbySchoolList.value = []
|
||||
for (let i = 0; i < 4; i++) {
|
||||
places1.length > i && nearbySchoolList.value.push(places1[i])
|
||||
places2.length > i && nearbySchoolList.value.push(places2[i])
|
||||
if (nearbySchoolList.value.length === 4) {
|
||||
break
|
||||
}
|
||||
}
|
||||
// 计算步行距离
|
||||
nearbySchoolList.value.map(async (item) => {
|
||||
const p1 = [item.lng, item.lat]
|
||||
const resp = await getWalkingDistance(p1, p2)
|
||||
item.walkdistance = resp
|
||||
})
|
||||
nearbySchoolSearching.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取两点之间的步行距离
|
||||
async function getWalkingDistance(start, end) {
|
||||
return new Promise((resolve) => {
|
||||
aMap.value.plugin('AMap.Walking', () => {
|
||||
const walking = new aMap.value.Walking()
|
||||
let num = 0
|
||||
walking.search(start, end, (status, result) => {
|
||||
if (status === 'complete') {
|
||||
result.routes.forEach((item) => {
|
||||
num += item.distance
|
||||
})
|
||||
resolve(num > 1000 ? `${(num / 1000).toFixed(2)} 公里` : `${num} 米`)
|
||||
} else {
|
||||
resolve('步行数据无法确定')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
function regeoCode(lng, lat) {
|
||||
try {
|
||||
geoCoder.value.getAddress([lng, lat], (status, result) => {
|
||||
@@ -345,6 +446,7 @@ function addmark(lat, lng, AMap) {
|
||||
})
|
||||
dialogMap.value.add(marker.value)
|
||||
dialogMap.value.setCenter([lat, lng], '', 500)
|
||||
getNearbySchool({ lat: lng, lng: lat })
|
||||
}
|
||||
function removeMarker() {
|
||||
dialogMap.value.remove(marker.value)
|
||||
@@ -376,6 +478,7 @@ function handleShowSchool() {
|
||||
extData: place,
|
||||
clickable: true
|
||||
})
|
||||
marker.on('click', (ev) => showSchoolInfo(ev.target.getExtData()))
|
||||
schoolMarkers.value.push(marker)
|
||||
}
|
||||
} else {
|
||||
@@ -383,6 +486,11 @@ function handleShowSchool() {
|
||||
}
|
||||
}
|
||||
|
||||
const schoolInfoDialog = ref()
|
||||
function showSchoolInfo(val) {
|
||||
schoolInfoDialog.value.open(val)
|
||||
}
|
||||
|
||||
function remoteMethod(searchValue) {
|
||||
if (searchValue !== '') {
|
||||
setTimeout(() => {
|
||||
|
||||
23
src/views/Clue/Pool/Comp/DialogSchoolInfo.vue
Normal file
23
src/views/Clue/Pool/Comp/DialogSchoolInfo.vue
Normal file
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<el-dialog width="800px" :title="title" v-model="show" append-to-body>
|
||||
<div v-dompurify-html="detail" class="mb-20px"></div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup name="DialogSchoolInfo">
|
||||
const title = ref('')
|
||||
const show = ref(false)
|
||||
const detail = ref('')
|
||||
|
||||
function open(info) {
|
||||
title.value = `【${info.schoolName}】详细信息`
|
||||
show.value = true
|
||||
detail.value = info.schoolRemark || '该驾校暂未配置详细信息'
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
@@ -83,6 +83,32 @@
|
||||
展示场地
|
||||
</el-checkbox>
|
||||
<div id="dialogMap" class="mt-20px" style="height: 400px; width: 100%"></div>
|
||||
<el-collapse v-model="collaspeKey" class="box-card">
|
||||
<el-collapse-item title="附近驾校" name="nearbySchool">
|
||||
<template #header>附近驾校</template>
|
||||
<div style="padding: 10px">
|
||||
<div v-if="nearbySchoolSearching">正在搜索中...</div>
|
||||
<template v-else>
|
||||
<div v-for="p in nearbySchoolList" :key="p.index">
|
||||
<div
|
||||
class="hover-pointer"
|
||||
style="font-size: 14px; color: blue"
|
||||
@click="getClassType(p)"
|
||||
>
|
||||
<i v-if="p.recommend" class="el-icon-star-off"></i>
|
||||
驾校: {{ p.deptName }}-{{ p.name }}
|
||||
</div>
|
||||
<div class="mt5">地址:{{ p.address }}</div>
|
||||
<div class="mt5">
|
||||
直线距离: {{ p.distance }} 公里;
|
||||
<span class="ml0">步行距离:{{ p.walkdistance }}</span>
|
||||
</div>
|
||||
<el-divider style="margin: 6px 0 !important" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</el-collapse-item>
|
||||
</el-collapse>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="操作记录" name="operateRecord">
|
||||
@@ -114,6 +140,7 @@
|
||||
</el-tabs>
|
||||
<!-- 新建编辑跟进信息 -->
|
||||
<DialogFollow ref="followRef" @success="getFollowList" />
|
||||
<DialogSchoolInfo ref="schoolInfoDialog" />
|
||||
</el-drawer>
|
||||
</template>
|
||||
|
||||
@@ -124,6 +151,7 @@ import * as FollowApi from '@/api/clue/followRecord'
|
||||
import { getPlaceList } from '@/api/school/place'
|
||||
|
||||
import DialogFollow from './DialogFollow.vue'
|
||||
import DialogSchoolInfo from './DialogSchoolInfo.vue'
|
||||
import AMapLoader from '@amap/amap-jsapi-loader'
|
||||
import { formatDate, dateFormatter } from '@/utils/formatTime'
|
||||
|
||||
@@ -214,8 +242,8 @@ async function open(id) {
|
||||
infoIndex.value = 'followRecord'
|
||||
|
||||
if (appStore.getAppInfo?.instanceType == 1 && !dialogMap.value) {
|
||||
nextTick(() => {
|
||||
getSchoolPlace()
|
||||
nextTick(async () => {
|
||||
await getSchoolPlace()
|
||||
initMap(info.value)
|
||||
})
|
||||
}
|
||||
@@ -225,10 +253,9 @@ async function open(id) {
|
||||
}
|
||||
|
||||
const placeList = ref([])
|
||||
function getSchoolPlace() {
|
||||
getPlaceList().then((data) => {
|
||||
async function getSchoolPlace() {
|
||||
const data = await getPlaceList()
|
||||
placeList.value = data.placeList
|
||||
})
|
||||
}
|
||||
|
||||
const defaultLatLng = ref({
|
||||
@@ -249,7 +276,7 @@ function initMap(data) {
|
||||
}
|
||||
}
|
||||
dialogMap.value = new AMap.Map('dialogMap', {
|
||||
zoom: 12,
|
||||
zoom: 14,
|
||||
zooms: [2, 22],
|
||||
center: [defaultLatLng.value.lng, defaultLatLng.value.lat]
|
||||
})
|
||||
@@ -285,6 +312,7 @@ function handleShowSchool() {
|
||||
extData: place,
|
||||
clickable: true
|
||||
})
|
||||
marker.on('click', (ev) => showSchoolInfo(ev.target.getExtData()))
|
||||
schoolMarkers.value.push(marker)
|
||||
}
|
||||
} else {
|
||||
@@ -302,7 +330,82 @@ function addmark(lat, lng, AMap) {
|
||||
})
|
||||
dialogMap.value.add(marker.value)
|
||||
dialogMap.value.setCenter([lat, lng], '', 500)
|
||||
getNearbySchool({ lat: lng, lng: lat })
|
||||
}
|
||||
|
||||
const collaspeKey = ref('nearbySchool')
|
||||
const nearbySchoolSearching = ref(false)
|
||||
const nearbySchoolList = ref([])
|
||||
function getNearbySchool(info) {
|
||||
if (info.lng && info.lat) {
|
||||
nearbySchoolList.value = []
|
||||
nearbySchoolSearching.value = true
|
||||
// 推荐的场地
|
||||
let places1 = []
|
||||
// 普通的场地
|
||||
let places2 = []
|
||||
|
||||
const p2 = [info.lng, info.lat]
|
||||
for (let i = 0; i < placeList.value.length; i++) {
|
||||
const element = placeList.value[i]
|
||||
const p1 = [element.lng, element.lat]
|
||||
// 计算直线距离
|
||||
element.distance = (aMap.value.GeometryUtil.distance(p1, p2) / 1000).toFixed(2)
|
||||
element.recommend ? places1.push(element) : places2.push(element)
|
||||
}
|
||||
// 按直线距离排序
|
||||
// 排序
|
||||
if (places1.length > 1) {
|
||||
places1 = places1.sort((a, b) => a.distance - b.distance)
|
||||
}
|
||||
// 排序
|
||||
if (places2.length > 1) {
|
||||
places2 = places2.sort((a, b) => a.distance - b.distance)
|
||||
}
|
||||
// 取普通场地和推荐场地,组合, 取四个
|
||||
nearbySchoolList.value = []
|
||||
for (let i = 0; i < 4; i++) {
|
||||
places1.length > i && nearbySchoolList.value.push(places1[i])
|
||||
places2.length > i && nearbySchoolList.value.push(places2[i])
|
||||
if (nearbySchoolList.value.length === 4) {
|
||||
break
|
||||
}
|
||||
}
|
||||
// 计算步行距离
|
||||
nearbySchoolList.value.map(async (item) => {
|
||||
const p1 = [item.lng, item.lat]
|
||||
const resp = await getWalkingDistance(p1, p2)
|
||||
item.walkdistance = resp
|
||||
})
|
||||
nearbySchoolSearching.value = false
|
||||
}
|
||||
}
|
||||
|
||||
// 获取两点之间的步行距离
|
||||
async function getWalkingDistance(start, end) {
|
||||
return new Promise((resolve) => {
|
||||
aMap.value.plugin('AMap.Walking', () => {
|
||||
const walking = new aMap.value.Walking()
|
||||
let num = 0
|
||||
walking.search(start, end, (status, result) => {
|
||||
if (status === 'complete') {
|
||||
result.routes.forEach((item) => {
|
||||
num += item.distance
|
||||
})
|
||||
resolve(num > 1000 ? `${(num / 1000).toFixed(2)} 公里` : `${num} 米`)
|
||||
} else {
|
||||
resolve('步行数据无法确定')
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const schoolInfoDialog = ref()
|
||||
function showSchoolInfo(val) {
|
||||
schoolInfoDialog.value.open(val)
|
||||
}
|
||||
|
||||
function removeMarker() {
|
||||
dialogMap.value.remove(marker.value)
|
||||
}
|
||||
|
||||
@@ -539,7 +539,7 @@ async function changePlaceStatus(row) {
|
||||
const text = row.status == 0 ? '启用' : '停用'
|
||||
await message.confirm('确认要"' + text + '""' + row.name + '"场地吗?')
|
||||
// 发起修改状态
|
||||
await PlaceApi.updatePlaceStatus({ placeId: row.placeId, status: row.status })
|
||||
await PlaceApi.updatePlaceStatus(row.placeId, row.status)
|
||||
message.success('修改成功')
|
||||
// 刷新列表
|
||||
// await getList()
|
||||
|
||||
Reference in New Issue
Block a user