7 changed files with 630 additions and 51 deletions
-
29src/api/map/index.js
-
10src/assets/styles/yxk-admin.scss
-
224src/views/deviceManage/area/areaClassifyRelated.vue
-
174src/views/deviceManage/floor/index.vue
-
37src/views/deviceManage/map3d/index.vue
-
33src/views/deviceManage/map3d/map.vue
-
174src/views/deviceManage/map3d/mapRight.vue
@ -0,0 +1,224 @@ |
|||||
|
<template> |
||||
|
<div class="app-container"> |
||||
|
<div class="venue-header"> |
||||
|
<h4><i class="iconfont icon-hangzhengquyuguanli" />区域列表</h4> |
||||
|
<p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p> |
||||
|
</div> |
||||
|
<div class="venue-content"> |
||||
|
<div class="venue-left"> |
||||
|
<div class="head-container"> |
||||
|
<div class="head-search"> |
||||
|
<!-- 搜索 --> |
||||
|
<el-select v-model="query.floorId" clearable size="small" placeholder="楼层" class="filter-item" style="width: 80px" @change="changeInitFloorValue($event)"> |
||||
|
<el-option v-for="item in floorOptions" :key="item.id" :label="item.floorName" :value="item.id" /> |
||||
|
</el-select> |
||||
|
<el-input v-model="query.search" clearable size="small" placeholder="输入关键字搜索" prefix-icon="el-icon-search" style="width: 200px;" class="filter-item" @clear="crud.toQuery" @keyup.enter.native="crud.toQuery" /> |
||||
|
<rrOperation /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div> |
||||
|
<el-table |
||||
|
ref="table" |
||||
|
v-loading="crud.loading" |
||||
|
:data="crud.data" |
||||
|
style="width: 100%;" |
||||
|
height="506" |
||||
|
@selection-change="crud.selectionChangeHandler" |
||||
|
@row-click="clickRowHandler" |
||||
|
> |
||||
|
<el-table-column type="selection" align="center" width="55" /> |
||||
|
<el-table-column type="index" label="排序" /> |
||||
|
<el-table-column prop="regionName" label="区域名称" /> |
||||
|
<el-table-column prop="regionCode" label="区域编码" /> |
||||
|
<el-table-column prop="floorName" label="所在楼层" /> |
||||
|
<el-table-column prop="booksheflCount" label="书架" /> |
||||
|
<el-table-column prop="signPoint" label="关联分类" /> |
||||
|
</el-table> |
||||
|
<!--分页组件--> |
||||
|
<pagination v-if="crud.data.length!==0" /> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="venue-right"> |
||||
|
<div class="container-right tab-content"> |
||||
|
<span class="right-top-line" /> |
||||
|
<span class="left-bottom-line" /> |
||||
|
<ul class="tab-nav"> |
||||
|
<li :class="{ 'active-tab-nav': activeIndex == 0 }" @click="changeActiveTab(0)">关联列表<i /></li> |
||||
|
<!-- 最右侧装饰img --> |
||||
|
<span class="tab-right-img" /> |
||||
|
<el-button size="mini" class="venue-mark"> |
||||
|
<i class="iconfont icon-bendiguajie" /> |
||||
|
关联设置 |
||||
|
</el-button> |
||||
|
</ul> |
||||
|
<div v-if="activeIndex == 0" class="venue-preview"> |
||||
|
111 |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<!-- form --> |
||||
|
<el-dialog :close-on-click-modal="false" :append-to-body="true" title="关联图书分类" :visible.sync="relatedVisible"> |
||||
|
<span class="dialog-right-top" /> |
||||
|
<span class="dialog-left-bottom" /> |
||||
|
<div class="setting-dialog"> |
||||
|
<el-table :data="relatedTableData" class="file-sort" style="width: 100%;max-height: 70vh;" row-key="id"> |
||||
|
<el-table-column type="index" label="序号" width="100" align="center" /> |
||||
|
<el-table-column prop="regionName" label="图书分类"> |
||||
|
<template slot-scope="scope"> |
||||
|
<span>{{ scope.row.regionName +' [ '+ scope.row.floorName+' ] ' }}</span> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<div slot="footer" class="dialog-footer"> |
||||
|
<el-button type="text" @click="handleCloseDialog">取消</el-button> |
||||
|
<el-button type="primary" @click="crud.submitCU">保存</el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</el-dialog> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { FetchLibraryFloorListAll } from '@/api/floor/index' |
||||
|
import crudRegion from '@/api/area/index' |
||||
|
import CRUD, { presenter, header, form, crud } from '@crud/crud' |
||||
|
import rrOperation from '@crud/RR.operation' |
||||
|
import pagination from '@crud/Pagination' |
||||
|
import { mapGetters } from 'vuex' |
||||
|
|
||||
|
const defaultForm = { id: null } |
||||
|
export default { |
||||
|
name: 'Bookshelf', |
||||
|
components: { rrOperation, pagination }, |
||||
|
cruds() { |
||||
|
return CRUD({ title: '区域', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: { |
||||
|
add: true, |
||||
|
edit: true, |
||||
|
del: false, |
||||
|
download: false, |
||||
|
group: false, |
||||
|
reset: false |
||||
|
}}) |
||||
|
}, |
||||
|
mixins: [presenter(), header(), form(defaultForm), crud()], |
||||
|
data() { |
||||
|
return { |
||||
|
floorOptions: [], |
||||
|
permission: { |
||||
|
add: ['admin', 'floor:add'], |
||||
|
edit: ['admin', 'floor:edit'], |
||||
|
del: ['admin', 'floor:del'] |
||||
|
}, |
||||
|
activeIndex: 0, |
||||
|
relatedTableData: [], // 排序data |
||||
|
relatedVisible: false, // 排序dialog |
||||
|
currentData: null |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
...mapGetters([ |
||||
|
'user', |
||||
|
'baseApi' |
||||
|
]) |
||||
|
}, |
||||
|
watch: { |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
window.removeEventListener('beforeunload', this.clearLocalStorage) |
||||
|
}, |
||||
|
methods: { |
||||
|
clearLocalStorage() { |
||||
|
const key = 'formFloor' |
||||
|
if (localStorage.getItem(key)) { |
||||
|
localStorage.removeItem(key) |
||||
|
} |
||||
|
}, |
||||
|
[CRUD.HOOK.beforeRefresh]() { |
||||
|
this.getLibraryFloorListAll() |
||||
|
if (this.$route.query.formFloor) { |
||||
|
const formFloor = JSON.parse(localStorage.getItem('formFloor')) |
||||
|
if (formFloor) { |
||||
|
this.crud.query.floorId = formFloor.id |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
[CRUD.HOOK.afterRefresh](crud) { |
||||
|
console.log('crud.data', crud.data) |
||||
|
if (crud.data.length !== 0) { |
||||
|
this.clickRowHandler(crud.data[0]) |
||||
|
this.activeIndex = 0 |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
// 提交前的验证 |
||||
|
[CRUD.HOOK.afterValidateCU](crud) { |
||||
|
this.$refs.uploadCoverRefs.fileNames = '' |
||||
|
return true |
||||
|
}, |
||||
|
// 获取楼层数据 |
||||
|
getLibraryFloorListAll() { |
||||
|
FetchLibraryFloorListAll().then(res => { |
||||
|
this.floorOptions = res |
||||
|
}).catch(() => { |
||||
|
}) |
||||
|
}, |
||||
|
changeInitFloorValue(value) { |
||||
|
if (this.$route.query.formFloor) { |
||||
|
localStorage.removeItem('formFloor') |
||||
|
} |
||||
|
|
||||
|
this.crud.query.floorId = value |
||||
|
this.crud.toQuery() |
||||
|
console.log('value', value) |
||||
|
}, |
||||
|
clickRowHandler(row) { |
||||
|
this.$refs.table.clearSelection() |
||||
|
this.$refs.table.toggleRowSelection(row) |
||||
|
this.currentData = row |
||||
|
if (this.activeIndex === 0) { |
||||
|
console.log('列表数据', row) |
||||
|
} |
||||
|
}, |
||||
|
changeActiveTab(data) { |
||||
|
this.activeIndex = data |
||||
|
}, |
||||
|
toDelete(datas) { |
||||
|
this.$confirm('此操作将删除当前所选区域<span>你是否还要继续?</span>', '提示', { |
||||
|
confirmButtonText: '继续', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning', |
||||
|
dangerouslyUseHTMLString: true |
||||
|
}).then(() => { |
||||
|
this.crud.delAllLoading = true |
||||
|
const ids = [] |
||||
|
datas.forEach(val => { |
||||
|
ids.push(val.id) |
||||
|
}) |
||||
|
console.log(ids) |
||||
|
crudRegion.del(ids).then(res => { |
||||
|
console.log(res) |
||||
|
this.$message({ message: res, type: 'success', offset: 8 }) |
||||
|
this.crud.delAllLoading = false |
||||
|
this.crud.refresh() |
||||
|
}).catch(err => { |
||||
|
this.crud.delAllLoading = false |
||||
|
console.log(err) |
||||
|
}) |
||||
|
}).catch(() => { |
||||
|
this.crud.delAllLoading = false |
||||
|
}) |
||||
|
}, |
||||
|
handleCloseDialog() { |
||||
|
this.relatedVisible = false |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.tab-content{ |
||||
|
min-height: calc(100vh - 232px) !important; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,174 @@ |
|||||
|
<template> |
||||
|
<div :style="{position: 'relative', width: '100%', height: '640px'}"> |
||||
|
<div id="fengmapRight" /> |
||||
|
<div class="rightMask" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import fengmap from '@/assets/fengmap/fengmap.map.min' |
||||
|
import { FMControlPosition, FMToolbar, FMScaleBar } from '@/assets/fengmap/fengmap.plugin.ui.min.js' |
||||
|
|
||||
|
export default { |
||||
|
name: 'FengMap', |
||||
|
props: { |
||||
|
mapData: { |
||||
|
type: Object, |
||||
|
require: true, |
||||
|
default: function() { |
||||
|
return {} |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
map: null, |
||||
|
level: null, |
||||
|
levelName: null, |
||||
|
levels: null, |
||||
|
marker: null, |
||||
|
scrollFloorControl: null, |
||||
|
scaleBar: null |
||||
|
} |
||||
|
}, |
||||
|
watch: { |
||||
|
mapData: { |
||||
|
handler(newVal, oldVal) { |
||||
|
if (!newVal) { |
||||
|
console.log('newVal-null') |
||||
|
return |
||||
|
} |
||||
|
}, |
||||
|
deep: true |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
console.log('mapData', this.mapData) |
||||
|
}, |
||||
|
methods: { |
||||
|
dispose() { |
||||
|
if (this.scrollFloorControl) { |
||||
|
this.scrollFloorControl.remove() |
||||
|
} |
||||
|
if (this.map) { |
||||
|
this.map.dispose() |
||||
|
this.map = null |
||||
|
} |
||||
|
}, |
||||
|
initMap() { |
||||
|
window.vueInstance = null |
||||
|
try { |
||||
|
console.log('this.level', this.level) |
||||
|
console.log('开始初始化地图') |
||||
|
const options = { |
||||
|
container: document.getElementById('fengmapRight'), |
||||
|
appName: this.mapData && this.mapData.appName, |
||||
|
key: this.mapData && this.mapData.mapKey, |
||||
|
mapID: this.mapData && this.mapData.appId, |
||||
|
// mapURL: '/fengmap/data/', |
||||
|
// themeID: '1574346301450625025', |
||||
|
// themeURL: '/fengmap/data/theme/', |
||||
|
level: this.level, |
||||
|
mapZoom: 19.5, |
||||
|
backgroundColor: '#fff' |
||||
|
} |
||||
|
console.log('地图配置:', options) |
||||
|
|
||||
|
this.map = new fengmap.FMMap(options) |
||||
|
console.log('地图实例已创建') |
||||
|
|
||||
|
// this.map.on('loadingProcess', (event) => { |
||||
|
// console.log('加载进度:', event.progress) |
||||
|
// this.debugInfo = `加载进度: ${event.progress}%` |
||||
|
// }) |
||||
|
|
||||
|
this.map.on('loaded', () => { |
||||
|
console.log('地图加载完成') |
||||
|
this.map.setViewMode(fengmap.FMViewMode.MODE_3D) |
||||
|
|
||||
|
// 楼层控件 |
||||
|
const scrollFloorCtlOpt = { |
||||
|
position: FMControlPosition.RIGHT_TOP, |
||||
|
floorButtonCount: 5, |
||||
|
offset: { |
||||
|
x: -20, |
||||
|
y: 150 |
||||
|
}, |
||||
|
viewModeControl: true, |
||||
|
floorModeControl: true, |
||||
|
needAllLayerBtn: true |
||||
|
} |
||||
|
this.scrollFloorControl = new FMToolbar(scrollFloorCtlOpt) |
||||
|
this.scrollFloorControl.addTo(this.map) |
||||
|
|
||||
|
// 比例尺控件 |
||||
|
const scrollScaleBarCtlOpt = { |
||||
|
fontSize: 18, |
||||
|
height: 30, |
||||
|
position: FMControlPosition.LEFT_BOTTOM, |
||||
|
offset: { |
||||
|
x: 20, |
||||
|
y: -20 |
||||
|
} |
||||
|
} |
||||
|
this.scaleBar = new FMScaleBar(scrollScaleBarCtlOpt) |
||||
|
this.scaleBar.addTo(this.map) |
||||
|
window.vueInstance = this |
||||
|
console.log('Vue实例已全局挂载:', window.vueInstance) |
||||
|
}, { passive: true }) |
||||
|
|
||||
|
this.map.on('click', (e) => { |
||||
|
this.marker && this.marker.remove() |
||||
|
this.marker = null |
||||
|
}, { passive: true }) |
||||
|
|
||||
|
this.map.on('mapInitError', (err) => { |
||||
|
console.error('地图初始化错误:', err) |
||||
|
this.debugInfo = `地图初始化错误: ${err.message}` |
||||
|
}) |
||||
|
|
||||
|
this.map.on('levelChanged', function(event) { |
||||
|
console.log('levelChanged:', event) |
||||
|
console.log('当前楼层:', event.level) |
||||
|
console.log('楼层name2', window.vueInstance.map.getFloor(event.level).name) |
||||
|
}) |
||||
|
} catch (error) { |
||||
|
console.error('初始化地图失败:', error) |
||||
|
this.debugInfo = `初始化失败: ${error.message}` |
||||
|
} |
||||
|
}, |
||||
|
getCurrentLevel() { |
||||
|
this.level = this.map.getLevel() |
||||
|
this.levelName = this.map.getFloor(this.level).name |
||||
|
// floorID level name |
||||
|
console.log('楼层info', this.map.getFloor(this.level)) |
||||
|
console.log('楼层name1', this.map.getFloor(this.level).name) |
||||
|
// 所有 |
||||
|
console.log('getFloorInfos', this.map.getFloorInfos()) |
||||
|
window.vueInstance.$emit('refreshLevel', this.level, this.levelName) |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
@import "~@/assets/fengmap/toolBarStyle.css"; |
||||
|
|
||||
|
#fengmapRight { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
background: #f5f5f5; |
||||
|
} |
||||
|
.rightMask{ |
||||
|
width: 162px; |
||||
|
height: 42px; |
||||
|
position: absolute; |
||||
|
bottom: 0; |
||||
|
right: 0; |
||||
|
background: #fff; |
||||
|
} |
||||
|
</style> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue