对接户外媒体数据

This commit is contained in:
wangchengming 2025-09-13 12:16:07 +08:00
parent b9bcee1385
commit 0e4d4a83f0
4 changed files with 210 additions and 157 deletions

View File

@ -135,3 +135,12 @@ export function mediaByMap(query) {
params: query
})
}
// 获取户外媒介媒体分页列表
export function outMediaPageList(query) {
return request({
url: '/media/outdoors/pageList',
method: 'get',
params: query
})
}

View File

@ -5,8 +5,6 @@
<el-col :span="12">
<el-form :model="queryParams" ref="queryRef" :inline="true" class="searchInputForm">
<el-form-item label="" prop="templateName">
<!-- <el-input v-model="queryParams.keyword" placeholder="请输入媒体名称/媒体编号/关键字" :prefix-icon="Search"
style="width: 400px;" /> -->
<el-select class="filterSelect" v-model="queryParams.keyword" filterable remote
reserve-keyword :remote-method="getLocaleListList" :loading="selectLoading"
@change="currentSelect" placeholder="请输入关键字" remote-show-suffix clearable
@ -338,11 +336,8 @@ const loadMap = () => {
mapInstance.value = new AMap.Map("mapContainer", {
resizeEnable: true,
// center: [116.397428, 39.90923], //
pitch: initialPitch, // 2D/3D
rotation: initialRotation, //
// buildingAnimation: true,
// expandZoomRange: true,
zoom: 16,
zooms: [3, 16],
viewMode: mapMode.value // 3D

View File

@ -5,21 +5,21 @@
<div class="search-where-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" class="searchPanelForm">
<el-form-item label="媒体类型:">
<el-select v-model="queryParams.mediaTypeOne" placeholder="请选择" @change="getMediaTypeTwo"
<el-select v-model="queryParams.mediaType" placeholder="请选择" @change="getMediaTypeTwo"
clearable style="min-width: 30px">
<el-option v-for="item in mediaTypeOne" :key="item.id" :label="item.name"
:value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="媒体大类:">
<el-select v-model="queryParams.mediaTypeTwo" placeholder="请选择" @change="getMediaTypeThree"
<el-select v-model="queryParams.mediaCategory" placeholder="请选择" @change="getMediaTypeThree"
clearable style="min-width: 30px">
<el-option v-for="item in mediaTypeTwo" :key="item.id" :label="item.name"
:value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="展示形式:">
<el-select v-model="queryParams.mediaTypeThree" placeholder="请选择" clearable
<el-select v-model="queryParams.displayForm" placeholder="请选择" clearable
style="min-width: 30px">
<el-option v-for="item in mediaTypeThree" :key="item.id" :label="item.name"
:value="item.id" />
@ -40,33 +40,34 @@
<div class="searchSmallPanel" v-show="unfoldFlag">
<el-form :model="queryParams" ref="queryRef" :inline="true" class="searchSmallPanelForm">
<el-form-item label="城市:">
<el-select v-model="queryParams.provinceId" placeholder="请选择" @change="getCityList" clearable
<el-select v-model="queryParams.provinceCode" placeholder="请选择" @change="getCityList" clearable
style="min-width: 30px">
<el-option v-for="item in province" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="">
<el-select v-model="queryParams.cityId" placeholder="请选择" @change="getCountyList" clearable
<el-select v-model="queryParams.cityCode" placeholder="请选择" @change="getCountyList" clearable
style="min-width: 30px">
<el-option v-for="item in city" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="">
<el-select v-model="queryParams.countyId" placeholder="请选择" @change="getTownList" clearable
<el-select v-model="queryParams.areaCode" placeholder="请选择" @change="getTownList" clearable
style="min-width: 30px">
<el-option v-for="item in county" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="">
<el-select v-model="queryParams.townId" placeholder="请选择" clearable style="min-width: 30px">
<el-select v-model="queryParams.townCode" placeholder="请选择" @change="getbusinessAreaList" clearable
style="min-width: 30px">
<el-option v-for="item in town" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="商圈:">
<el-select v-model="queryParams.approval_document_status" placeholder="请选择" clearable
<el-select v-model="queryParams.businessDistrictId" placeholder="请选择" clearable
style="min-width: 30px;">
<el-option v-for="dict in approval_document_status" :key="dict.value" :label="dict.label"
:value="dict.value" />
<el-option v-for="item in businessAreaList" :key="item.id" :label="item.name"
:value="item.id" />
</el-select>
</el-form-item>
</el-form>
@ -90,7 +91,7 @@
<el-col :span="8">
<el-form :model="queryParams" ref="queryRef" :inline="true" class="searchInputForm">
<el-form-item label="">
<el-input v-model="queryParams.postCode" placeholder="请输入媒体名称/媒体编号" :prefix-icon="Search"
<el-input v-model="queryParams.keyword" placeholder="请输入媒体名称/媒体编号" :prefix-icon="Search"
style="width: 400px;" />
</el-form-item>
</el-form>
@ -99,7 +100,7 @@
<el-button type="primary" class="primaryBtn" @click="handleQuery">查询</el-button>
<el-button type="primary" class="primaryBtn" @click="resetQuery">重置</el-button>
<el-button type="primary" class="primaryBtn">PPT批量导出</el-button>
<el-button type="primary" class="primaryBtn">清空所选媒体</el-button>
<el-button type="primary" class="primaryBtn" @click="handleClearChoseMedia">清空所选媒体</el-button>
</el-col>
</el-row>
<el-row :gutter="10" class="my_row" style="margin-bottom: 0;">
@ -107,15 +108,17 @@
<el-table v-loading="loading" :data="outdoorMediaList" @selection-change="handleSelectionChange"
:height="unfoldFlag ? 'calc(100vh - 372px)' : 'calc(100vh - 338px)'">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="实景图片" align="left" prop="mediaName" width="170">
<el-table-column label="实景图片" align="left" prop="mediaFileList" width="170">
<template #default="scope">
<img :src="otherbg" fit="fill" style="width: 138px;height: 78px; border-radius: 4px" />
<img v-if="scope.row.mediaFileList.length > 0"
:src="baseUrl + scope.row.mediaFileList[0].fileName" fit="fill"
style="width: 138px;height: 78px; border-radius: 4px" />
</template>
</el-table-column>
<el-table-column label="媒体名称" align="left" prop="mediaName" width="150" />
<el-table-column label="商圈" align="left" prop="postCode" width="150" />
<el-table-column label="媒体大类" align="left" prop="postCode" width="150" />
<el-table-column label="展示形式" align="left" prop="postCode" width="150" />
<el-table-column label="商圈" align="left" prop="businessDistrictName" width="150" />
<el-table-column label="媒体大类" align="left" prop="mediaCategoryStr" width="150" />
<el-table-column label="展示形式" align="left" prop="displayFormStr" width="150" />
<el-table-column label="操作" width="58" align="center" fixed="right">
<template #default="scope">
<el-popover popper-class="my_popover" placement="left-start">
@ -135,7 +138,7 @@
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize"
@pagination="getList" />
@pagination="getOutMediaPageList" />
</el-col>
<el-col :span="12">
<div id="mapContainer" class="mapContainer"></div>
@ -149,6 +152,8 @@ import { onMounted, onUnmounted, ref } from 'vue';
import { Search } from '@element-plus/icons-vue'
import { sysRegionListByPid } from "@/api/system/administrativeRegion"
import { sysMediaTypeListByPid } from "@/api/system/mediaType"
import { busTradingAreaPage } from "@/api/system/businessArea"
import { outMediaPageList } from "@/api/mediaLibrary"
import AMapLoader from "@amap/amap-jsapi-loader"; //
import optionIcon from '@/assets/images/optionIcon.png'
import optionIconHover from '@/assets/images/optionIconHover.png'
@ -157,84 +162,55 @@ import otherbg from '@/assets/images/otherbg.png'
const bgStore = useBackgroundStore()
const { proxy } = getCurrentInstance()
const { approval_document_status } = proxy.useDict("approval_document_status")
const baseUrl = import.meta.env.VITE_APP_BASE_API
const { apiKey, secretKey } = window._CONFIG
//
const defaultImageSrc = ref(optionIcon);
const hoverImageSrc = ref(optionIconHover);
//
const province = ref([])
const city = ref([])
const county = ref([])
const town = ref([])
//
const businessAreaList = ref([])
//
const mediaTypeOne = ref([])
const mediaTypeTwo = ref([])
const mediaTypeThree = ref([])
//
const supplierList = ref([])
//
//
const multipleChoseArr = ref([])
//
const outdoorMediaList = ref([])
//
const unfoldFlag = ref(false)
const loading = ref(true)
const total = ref(0)
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10,
keyword: undefined,
mediaType: undefined,
mediaCategory: undefined,
displayForm: undefined,
provinceCode: undefined,
cityCode: undefined,
areaCode: undefined,
townCode: undefined,
businessDistrictId: undefined
}
})
const { queryParams } = toRefs(data)
//
const defaultImageSrc = ref(optionIcon);
const hoverImageSrc = ref(optionIconHover);
//
const outdoorMediaList = ref([
{ id: 1, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 2, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 3, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 4, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 5, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 6, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 7, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 8, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 9, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value },
{ id: 10, mediaName: '遵义市海风井铁路桥', currentImageSrc: defaultImageSrc.value }
])
//
const unfoldFlag = ref(false)
const handleFlod = () => {
unfoldFlag.value = !unfoldFlag.value
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1
getList()
}
/** 重置按钮操作 */
const resetQuery = () => {
proxy.resetForm("queryRef")
handleQuery()
}
//
const handleSelectionChange = (selection) => {
multipleChoseArr.value = selection
}
//
const handleCloseTag = (tag) => {
}
//
const getList = () => {
loading.value = false
// listPost(proxy.addDateRange(queryParams.value, dateRange.value)).then(response => {
// postList.value = response.rows
// total.value = response.total
// loading.value = false
// })
}
// map
const mapInstance = ref(null)
const massMarks = ref(null)
// 2D/3D
const mapMode = ref('2D')
//
const isFullscreen = ref(false)
//
const points = ref([])
//
const getMediaTypeOne = () => {
@ -271,6 +247,7 @@ const getCityList = (value) => {
queryParams.value.townId = undefined
city.value = res.data
})
getbusinessAreaList()
}
// /
const getCountyList = (value) => {
@ -279,6 +256,7 @@ const getCountyList = (value) => {
queryParams.value.townId = undefined
county.value = res.data
})
getbusinessAreaList()
}
//
const getTownList = (value) => {
@ -286,14 +264,79 @@ const getTownList = (value) => {
queryParams.value.townId = undefined
town.value = res.data
})
getbusinessAreaList()
}
// map
const mapInstance = ref(null)
const massMarks = ref(null)
// 2D/3D
const mapMode = ref('2D')
//
const isFullscreen = ref(false)
//
const getbusinessAreaList = (val) => {
const _params = {
pageIndex: 1,
pageSize: 200,
provinceId: queryParams.value.provinceCode,
cityId: queryParams.value.cityCode,
countyId: queryParams.value.areaCode,
townId: queryParams.value.townCode,
}
busTradingAreaPage(_params).then(res => {
if (res.code == 200) {
businessAreaList.value = res.data.list
}
})
}
//
const handleFlod = () => {
unfoldFlag.value = !unfoldFlag.value
}
//
const getOutMediaPageList = () => {
loading.value = true
outMediaPageList(queryParams.value).then(res => {
res.data.rows.forEach(element => {
element.currentImageSrc = defaultImageSrc.value;
});
outdoorMediaList.value = res.data.rows
total.value = res.data.total
loading.value = false
})
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1
getOutMediaPageList()
}
/** 重置按钮操作 */
const resetQuery = () => {
queryParams.value = {
pageNum: 1,
pageSize: 10,
keyword: undefined,
mediaType: undefined,
mediaCategory: undefined,
displayForm: undefined,
provinceCode: undefined,
cityCode: undefined,
areaCode: undefined,
townCode: undefined,
businessDistrictId: undefined
}
handleQuery()
}
//
const handleSelectionChange = (selection) => {
multipleChoseArr.value = selection
}
//
const handleCloseTag = (tag) => {
const rowIndex = multipleChoseArr.value.findIndex(item => item.id == tag.id)
multipleChoseArr.value.splice(rowIndex, 1)
}
//
const handleClearChoseMedia = () => {
multipleChoseArr.value = []
}
//
const loadMap = () => {
return new Promise((resolve, reject) => {
@ -304,7 +347,7 @@ const loadMap = () => {
AMapLoader.load({
key: apiKey,
plugins: [],
plugins: ["AMap.PlaceSearch"],
AMapUI: {
plugins: []
}
@ -315,18 +358,15 @@ const loadMap = () => {
mapInstance.value = new AMap.Map("mapContainer", {
resizeEnable: true,
zoom: 14,
center: [116.397428, 39.90923],
pitch: initialPitch, // 2D/3D
rotation: initialRotation, //
buildingAnimation: true,
expandZoomRange: true,
zooms: [3, 20],
zoom: 16,
zooms: [3, 16],
viewMode: mapMode.value // 3D
});
//
mapInstance.value.setZoom(14);
// //
mapInstance.value.setZoom(16);
//
addCustomControls(AMap);
@ -339,17 +379,29 @@ const loadMap = () => {
//
mapInstance.value.on('render', hideAmapLogo);
//
mapInstance.value.on('zoomchange', handleZoomChange);
//
renderMassMarks();
resolve();
}).catch(e => {
console.log(e, "高德地图加载失败");
reject(e);
});
});
}
//
const handleZoomChange = () => {
const currentZoomLevel = mapInstance.value.getZoom();
// 1616
if (currentZoomLevel > 16) {
mapInstance.value.setZoom(16);
return;
}
}
//
const addCustomControls = (AMap) => {
//
@ -372,7 +424,6 @@ const addCustomControls = (AMap) => {
//
document.getElementById('mapContainer').appendChild(controlContainer);
}
// 2D/3D
const toggle2D3DMode = () => {
if (!mapInstance.value) return;
@ -392,8 +443,8 @@ const toggle2D3DMode = () => {
mapMode.value = '2D';
loadMap()
}
}
}
//
const toggleFullscreen = () => {
const mapContainer = document.getElementById('mapContainer');
@ -420,14 +471,12 @@ const toggleFullscreen = () => {
}
}
}
//
document.addEventListener('fullscreenchange', () => {
if (!document.fullscreenElement) {
isFullscreen.value = false;
}
});
//
const createPointStyle = (color, size, styleType) => {
const canvas = document.createElement('canvas');
@ -504,53 +553,16 @@ const renderMassMarks = () => {
anchor: new AMap.Pixel(18, 18),
size: new AMap.Size(18, 18)
},
// {
// url: createPointStyle('#FFA200', 18, 'circle').toDataURL(),
// anchor: new AMap.Pixel(18, 18),
// size: new AMap.Size(18, 18)
// },
// {
// url: createPointStyle('#00C272', 18, 'circle').toDataURL(),
// anchor: new AMap.Pixel(18, 18),
// size: new AMap.Size(18, 18)
// }
];
//
const points = [
{ "lnglat": [116.258446, 37.686622], "name": "景县", "style": 1 },
{ "lnglat": [113.559954, 22.124049], "name": "圣方济各堂区", "style": 1 },
{ "lnglat": [116.366794, 39.915309], "name": "西城区", "style": 1 },
{ "lnglat": [116.486409, 39.921489], "name": "朝阳区", "style": 1 },
{ "lnglat": [116.286968, 39.863642], "name": "丰台区", "style": 1 },
{ "lnglat": [116.195445, 39.914601], "name": "石景山区", "style": 1 },
{ "lnglat": [116.310316, 39.956074], "name": "海淀区", "style": 1 },
{ "lnglat": [116.105381, 39.937183], "name": "门头沟区", "style": 0 },
{ "lnglat": [116.139157, 39.735535], "name": "房山区", "style": 0 },
{ "lnglat": [116.658603, 39.902486], "name": "通州区", "style": 0 },
{ "lnglat": [116.653525, 40.128936], "name": "顺义区", "style": 0 },
{ "lnglat": [116.235906, 40.218085], "name": "昌平区", "style": 0 },
{ "lnglat": [116.338033, 39.728908], "name": "大兴区", "style": 0 },
{ "lnglat": [116.637122, 40.324272], "name": "怀柔区", "style": 0 },
{ "lnglat": [117.112335, 40.144783], "name": "平谷区", "style": 0 },
{ "lnglat": [116.843352, 40.377362], "name": "密云区", "style": 0 },
{ "lnglat": [115.985006, 40.465325], "name": "延庆区", "style": 1 },
{ "lnglat": [113.56925, 22.136546], "name": "路凼填海区", "style": 1 },
{ "lnglat": [117.195907, 39.118327], "name": "和平区", "style": 1 },
{ "lnglat": [117.226568, 39.122125], "name": "河东区", "style": 1 },
{ "lnglat": [117.217536, 39.101897], "name": "河西区", "style": 1 },
{ "lnglat": [117.164143, 39.120474], "name": "南开区", "style": 1 },
{ "lnglat": [117.201569, 39.156632], "name": "河北区", "style": 0 },
{ "lnglat": [117.163301, 39.175066], "name": "红桥区", "style": 1 },
{ "lnglat": [117.313967, 39.087764], "name": "东丽区", "style": 0 },
{ "lnglat": [117.012247, 39.139446], "name": "西青区", "style": 0 },
{ "lnglat": [117.382549, 38.989577], "name": "津南区", "style": 0 },
{ "lnglat": [117.13482, 39.225555], "name": "北辰区", "style": 0 },
{ "lnglat": [117.057959, 39.376925], "name": "武清区", "style": 0 },
{ "lnglat": [116.405285, 39.904989], "name": "北京市", "style": 0 }
]
//
points.value = []
// outdoorMediaList.value.forEach(itemPoint => {
// if (itemPoint.businessType == 1) points.value.push({ "lnglat": [itemPoint.x, itemPoint.y], "name": itemPoint.mediaId, "style": 0 })
// if (itemPoint.businessType == 2) points.value.push({ "lnglat": [itemPoint.x, itemPoint.y], "name": itemPoint.mediaId, "style": 1 })
// });
console.log('points', points.value)
// MassMarks
massMarks.value = new AMap.MassMarks(points, {
massMarks.value = new AMap.MassMarks(points.value, {
opacity: 1,
zIndex: 111,
cursor: 'pointer',
@ -565,7 +577,6 @@ const renderMassMarks = () => {
console.log('点击了节点', e.data)
});
}
// Logo
const hideAmapLogo = () => {
const logos = document.querySelectorAll('.amap-logo, .amap-copyright');
@ -577,12 +588,14 @@ const hideAmapLogo = () => {
}
onUnmounted(() => {
mapInstance.value?.destroy()
if (mapInstance.value) {
mapInstance.value.destroy();
}
})
//
onMounted(() => {
bgStore.setBgImage(otherbg)
getList()
getOutMediaPageList()
getMediaTypeOne()
getProvinceList()
loadMap()

View File

@ -86,7 +86,12 @@
</el-col>
<el-col :span="12">
<el-form-item label="负责人" prop="leaderId">
<!-- <el-input v-model="form.leader" placeholder="请输入负责人" maxlength="20" /> -->
<el-select class="filterSelect" v-model="form.leaderId" @change="handleChoseLeader" filterable
remote reserve-keyword :remote-method="getLeaderList" :loading="selectLoading"
placeholder="请输入负责人" remote-show-suffix clearable style="min-width: 70px;">
<el-option v-for="item in leaderList" :key="item.userId" :label="item.realName"
:value="item.userId" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
@ -103,7 +108,7 @@
<el-form-item label="部门状态">
<el-radio-group v-model="form.status">
<el-radio v-for="dict in sys_normal_disable" :key="dict.value" :value="dict.value">{{ dict.label
}}</el-radio>
}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
@ -131,6 +136,7 @@
import { onMounted, ref } from 'vue';
import { Search } from '@element-plus/icons-vue'
import { listDept, getDept, delDept, addDept, updateDept, listDeptExcludeChild } from "@/api/system/dept"
import { listUser, getUser } from "@/api/system/user"
import { useBackgroundStore } from '@/store/modules/background'
import otherbg from '@/assets/images/otherbg.png'
const bgStore = useBackgroundStore()
@ -138,6 +144,8 @@ const bgStore = useBackgroundStore()
const { proxy } = getCurrentInstance()
const { sys_normal_disable } = proxy.useDict("sys_normal_disable")
const leaderList = ref([])
const selectLoading = ref(false)
const deptList = ref([])
const open = ref(false)
const loading = ref(true)
@ -173,6 +181,27 @@ function getList() {
})
}
//
const getLeaderList = (queryText) => {
if (queryText) {
selectLoading.value = true
listUser({ realName: queryText }).then(res => {
leaderList.value = res.rows
selectLoading.value = false
})
} else {
selectLoading.value = false
leaderList.value = []
}
}
const handleChoseLeader = (val) => {
const choseUser = leaderList.value.filter(item => item.userId == val)[0]
form.value.leaderId = choseUser?.userId
form.value.leader = choseUser?.realName
form.value.phone = choseUser?.phonenumber
form.value.email = choseUser?.email
}
/** 取消按钮 */
function cancel() {
open.value = false
@ -230,7 +259,13 @@ function toggleExpandAll() {
refreshTable.value = true
})
}
const getUserInfo = () => {
getUser(form.value.leaderId).then(res => {
leaderList.value = [
{ userId: res.data.userId, realName: res.data.realName }
]
})
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset()
@ -239,6 +274,7 @@ function handleUpdate(row) {
})
getDept(row.deptId).then(response => {
form.value = response.data
if (form.value.leaderId) getUserInfo()
open.value = true
title.value = "修改部门"
})