Commit 54ca3f09 authored by 郭铭瑶's avatar 郭铭瑶 🤘

增加默认页面

parent 5253dab0
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
This diff is collapsed.
......@@ -6,10 +6,10 @@
<link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>静安智慧房管</title>
<script type="module" crossorigin src="./assets/index.3fc0449e.js"></script>
<link rel="modulepreload" href="./assets/vendor.39d5f367.js">
<script type="module" crossorigin src="./assets/index.b725d4a1.js"></script>
<link rel="modulepreload" href="./assets/vendor.f402338c.js">
<link rel="stylesheet" href="./assets/vendor.db35e2cd.css">
<link rel="stylesheet" href="./assets/index.f8200f2b.css">
<link rel="stylesheet" href="./assets/index.9a62791e.css">
</head>
<body>
......
This diff is collapsed.
This diff is collapsed.
......@@ -3,6 +3,7 @@
<img :src="bgImg" class="bg" />
<div class="date">{{ date }} {{ time }}</div>
<img
v-if="editable"
src="@/assets/images/filter.png"
class="filter"
draggable="false"
......@@ -28,7 +29,7 @@ export default defineComponent({
},
editable: {
type: Boolean as PropType<boolean>,
default: false,
default: process.env.NODE_ENV !== 'production',
},
},
emits: ['touch'],
......
import { MapConfig, CallBack, BoundaryOption, MarkerOption } from './types'
import Map from './map'
declare const AMap: {
Map: any
Icon: any
DistrictSearch: any
LngLat: any
Marker: any
Polygon: any
}
export default class A_Map extends Map {
constructor(config: MapConfig) {
super(new AMap.Map(config.el, config.options))
}
onLoad(cb: CallBack): void {
this.map.on('complete', cb)
}
onZoom(cb: CallBack): void {
this.map.on('zoomend', cb)
}
onMove(cb: CallBack): void {
this.map.on('mapmove', cb)
}
onBlur(): void {
throw new Error('AMap没有blur事件!')
}
onFocus(): void {
throw new Error('AMap没有focus事件!')
}
onDrag(cb: CallBack): void {
this.map.on('dragging', cb)
}
onResize(cb: CallBack): void {
this.map.on('resize', cb)
}
onClick(cb: CallBack): void {
this.map.on('click', cb)
}
onDblclick(cb: CallBack): void {
this.map.on('dblclick', cb)
}
onMousewheel(cb: CallBack): void {
this.map.on('mousewheel', cb)
}
zoomIn(): void {
this.map.zoomIn()
}
zoomOut(): void {
this.map.zoomOut()
}
hideCommunity(): void {
throw new Error('AMap没有hideCommunity方法!')
}
showCommunity(): void {
throw new Error('AMap没有showCommunity方法!')
}
filterCommunity(): void {
throw new Error('AMap没有filterCommunity方法!')
}
focus(location: number[], zoom = this.map.getZoom()): void {
this.map.setView(location, zoom)
}
addBoundary({
name,
type,
weight = 10,
color = 'rgba(51,145,255,.6)',
maskColor = [0, 17, 33, 0.9],
}: BoundaryOption): unknown {
if (!name || !type) {
throw new Error('AMap的addBoundary方法需要name参数!')
return
}
return new AMap.DistrictSearch({
extensions: 'all',
subdistrict: 0,
}).search(name, (_: unknown, result: any) => {
// 外多边形坐标数组和内多边形坐标数组
const outer = [
new AMap.LngLat(-360, 90, true),
new AMap.LngLat(-360, -90, true),
new AMap.LngLat(360, -90, true),
new AMap.LngLat(360, 90, true),
]
const holes = result.districtList[0].boundaries
const pathArray = [outer]
pathArray.push(holes)
const polygon = new AMap.Polygon({
pathL: pathArray,
//线条颜色,使用16进制颜色代码赋值。默认值为#006600
strokeColor: color,
strokeWeight: weight,
//轮廓线透明度,取值范围[0,1],0表示完全透明,1表示不透明。默认为0.9
strokeOpacity: 0.5,
//多边形填充颜色,使用16进制颜色代码赋值,如:#FFAA00
fillColor: maskColor,
//多边形填充透明度,取值范围[0,1],0表示完全透明,1表示不透明。默认为0.9
fillOpacity: 1,
//轮廓线样式,实线:solid,虚线:dashed
strokeStyle: 'solid',
})
polygon.setPath(pathArray)
this.map.add(polygon)
return polygon
})
}
private transMarkerData(option: MarkerOption): unknown[] {
const { data = [], size, icon, key } = option
return data.map((item: any) => {
let sizeProp = Array.isArray(size) ? size : [size, size]
if (item.size) {
sizeProp = Array.isArray(item.size) ? item.size : [item.size, item.size]
}
const result = {
icon: new AMap.Icon({
size: sizeProp,
image: item.icon || icon,
}),
position: [
item.X || item.x || item.gpsx || item.lon,
item.Y || item.y || item.gpsy || item.lat,
item.Z || item.z || item.gpsz || 0,
],
extData: { key, ...item },
}
return new AMap.Marker(result)
})
}
addMarkers(option: MarkerOption): unknown {
const markers = this.transMarkerData(option)
this.map.add(markers)
return markers
}
remove(markers: unknown): void {
this.map.remove(markers)
}
}
import { MapConfig, EventListener } from './types'
import Map from './map'
import S_Map from './s-map'
import A_Map from './a-map'
export type MapType = Omit<Map, keyof EventListener>
export async function createMap(config: MapConfig): Promise<MapType> {
await _injectSource(config)
return _whichMap(config)
}
function _injectSource(config: MapConfig): Promise<unknown[]> {
if (!config.sources || config.sources.length === 0) {
return Promise.resolve([true])
}
const promises = config.sources.map((source: string, index: number) => {
return new Promise((resolve) => {
const id = `_my_map_source${index}`
if (document.getElementById(id)) return resolve(true)
const mapSource = document.createElement('script')
mapSource.type = 'text/javascript'
mapSource.src = source
mapSource.setAttribute('id', id)
document.body.appendChild(mapSource)
mapSource.onload = () => resolve(true)
})
})
return Promise.all(promises)
}
function _whichMap(config: MapConfig): Map {
const { type } = config
switch (type) {
case 'SMap':
return new S_Map(config)
case 'AMap':
return new A_Map(config)
default:
if (type) {
throw new Error(`不存在${type}类型的地图!`)
} else {
// eslint-disable-next-line
throw new Error('初始化地图需要配置\'type\'字段!')
}
}
}
import {
CallBack,
EventListener,
BoundaryOption,
MarkerOption,
EventName,
} from './types'
export default abstract class Map implements EventListener {
protected map
constructor(map: any) {
this.map = map
}
get instance(): any {
return this.map
}
on<T extends keyof EventListener>(name: EventName, cb: CallBack): this {
const eventName = `on${name.slice(0, 1).toUpperCase()}${name
.slice(1)
.toLowerCase()}` as T
if (!this[eventName]) throw new Error(`地图不存在'${name}'事件`)
this[eventName](cb)
return this
}
abstract onLoad(cb: CallBack): void
abstract onZoom(cb: CallBack): void
abstract onMove(cb: CallBack): void
abstract onBlur(cb: CallBack): void
abstract onFocus(cb: CallBack): void
abstract onDrag(cb: CallBack): void
abstract onResize(cb: CallBack): void
abstract onClick(cb: CallBack): void
abstract onDblclick(cb: CallBack): void
abstract onMousewheel(cb: CallBack): void
abstract zoomIn(): void
abstract zoomOut(): void
abstract hideCommunity(): void
abstract showCommunity(): void
abstract filterCommunity(ids: unknown[], key: string): void
abstract focus(location: number[], zoom?: number): void
abstract addBoundary(option: BoundaryOption): unknown
abstract addMarkers(option: MarkerOption): unknown
abstract remove(markers: unknown): void
}
import { MapConfig, CallBack, BoundaryOption, MarkerOption } from './types'
import Map from './map'
declare const SMap: {
Map: any
Network: any
MapEvent: any
Size: any
Icon: any
Label: any
Marker: any
}
declare const Plugins: {
MaskBoundary: any
}
export default class S_Map extends Map {
constructor(config: MapConfig) {
new SMap.Network().setNet(config.options.netType || 'internet')
super(new SMap.Map(config.el, config.options))
}
onLoad(cb: CallBack): void {
this.map.on(SMap.MapEvent.maploaded, cb)
}
onZoom(cb: CallBack): void {
this.map.on(SMap.MapEvent.zoomchanged, cb)
}
onMove(cb: CallBack): void {
this.map.on(SMap.MapEvent.centerchanged, cb)
}
private event(event: unknown, cb: CallBack) {
this.map.on(event, (view: any, eventParamter: unknown) => {
view.hitTest(eventParamter).then((res: unknown) => {
cb(res, eventParamter)
})
})
}
onBlur(cb: CallBack): void {
this.event(SMap.MapEvent.blur, cb)
}
onFocus(cb: CallBack): void {
this.event(SMap.MapEvent.focus, cb)
}
onDrag(cb: CallBack): void {
this.event(SMap.MapEvent.drag, cb)
}
onResize(cb: CallBack): void {
this.event(SMap.MapEvent.resize, cb)
}
onClick(cb: CallBack): void {
this.event(SMap.MapEvent.click, cb)
}
onDblclick(cb: CallBack): void {
this.event(SMap.MapEvent.doubleclick, cb)
}
onMousewheel(cb: CallBack): void {
this.event(SMap.MapEvent.mousewheel, cb)
}
zoomIn(): void {
this.map.zoomIn()
}
zoomOut(): void {
this.map.zoomOut()
}
hideCommunity(): void {
this.map.hideXQ_Poly()
this.map.hideMPZ()
this.map.hideXQ_Point()
}
showCommunity(): void {
this.map.showXQ_Poly()
this.map.showMPZ()
this.map.showXQ_Point()
}
filterCommunity(ids: unknown[], key = 'sect_id'): void {
if (ids.length === 0) return
const valid = ids.map((val: unknown) => {
return `${key} = '${val}'`
})
this.map.setFilter('wg_gis_xq_point', valid.join(' or '))
this.map.setFilter('wg_gis_mpz', valid.join(' or '))
this.map.setFilter('wg_gis_xq_poly', valid.join(' or '))
}
focus(location: number[], zoom = this.map.getZoom()): void {
this.map.setZoomAndCenter(zoom, location)
}
addBoundary({
name,
type,
weight = 10,
count = 10,
color = 'rgba(51,145,255,.6)',
maskColor = [0, 17, 33, 0.9],
}: BoundaryOption): unknown {
if (!name || !type) {
throw new Error('SMap的addBoundary方法需要name和type参数!')
return
}
const boundary = {
boundaryType: type,
boundaryDefinition: `name like '%${name}%'`,
boundarydistance: weight,
bounarycount: count,
boundaryColor: color,
maskColor: maskColor,
}
const Boundary = new Plugins.MaskBoundary(this.map.view)
Boundary.add(boundary)
return Boundary
}
private transMarkerData(option: MarkerOption): unknown[] {
const { data = [], size, icon, key, labelKey, color } = option
return data.map((item: any) => {
let sizeProp = Array.isArray(size)
? new SMap.Size(size[0], size[1])
: new SMap.Size(size, size)
if (item.size) {
sizeProp = Array.isArray(item.size)
? new SMap.Size(item.size[0], item.size[1])
: new SMap.Size(item.size, item.size)
}
const result = {
icon: new SMap.Icon({
size: sizeProp,
image: item.icon || icon,
}),
attributes: { key, ...item },
position: [
item.X || item.x || item.gpsx || item.lon,
item.Y || item.y || item.gpsy || item.lat,
item.Z || item.z || item.gpsz || 0,
],
label: new SMap.Label({
text: labelKey ? item[labelKey] + '' : '',
size,
color,
}),
}
return new SMap.Marker(result)
})
}
addMarkers(option: MarkerOption): unknown {
const markers = this.transMarkerData(option)
this.map.add(markers)
return markers
}
remove(markers: unknown): void {
this.map.remove(markers)
}
}
export interface EventListener {
onLoad: (cb: CallBack) => void
onZoom: (cb: CallBack) => void
onMove: (cb: CallBack) => void
onBlur: (cb: CallBack) => void
onFocus: (cb: CallBack) => void
onDrag: (cb: CallBack) => void
onResize: (cb: CallBack) => void
onClick: (cb: CallBack) => void
onDblclick: (cb: CallBack) => void
onMousewheel: (cb: CallBack) => void
}
export type EventName =
| 'load'
| 'zoom'
| 'move'
| 'blur'
| 'focus'
| 'drag'
| 'resize'
| 'click'
| 'dblclick'
| 'mousewheel'
export interface MapConfig {
el: string
type: 'SMap' | 'AMap' | 'BMap'
options: MapOptions
sources?: string[]
}
export interface MapOptions {
viewMode?: '2D' | '3D'
center?: number[]
zooms?: number[]
zoom?: number
pitch?: number
rotation?: number
mapStyle?: string
showBuildingBlock?: boolean
resizeEnable?: boolean
rotateEnable?: boolean
pitchEnable?: boolean
showLabel?: boolean
buildingAnimation?: boolean // 楼块出现是否带动画
expandZoomRange?: boolean
showIndoorMap?: boolean
features?: string[]
netType?: string
}
export type CallBack = (arg: unknown, oth?: unknown) => void
// export type CallBackDic = { [key: string]: CallBack }
export interface BoundaryOption {
name?: string
type?: string
weight?: number
count?: number
color?: string
maskColor?: number[]
}
export interface MarkerOption {
data: unknown[]
key?: string
labelKey?: string
icon?: string
size?: number | number[]
color?: string
}
This diff is collapsed.
// import * as vue from 'vue'
// import fetchComponents from 'http://127.0.0.1:8081/component-lib.min.js'
// import fetchComponents from 'http://127.0.0.1:8082/component-lib.min.js'
// const { components, eventBus } = fetchComponents(vue)('http://127.0.0.1:8082')
import { components, eventBus } from './component-lib.esm' // 未正式上生产暂时先如此代替
......
......@@ -7,7 +7,6 @@
offset-y=".2rem"
bg-color="rgba(0,0,0,0.5)"
:mask-closable="false"
@close="onClose"
>
<div class="container">
<div v-for="item in layoutOptions" :key="item.title" class="row">
......@@ -79,9 +78,8 @@ const layoutOptions = [
const curKey = ref<string | null>(null)
const onSelect = (key) => {
curKey.value = key
}
const onClose = () => {
emit('select', curKey.value)
visible.value = false
}
</script>
......
<template>
<div class="map-btns">
<img
v-for="btn in btns"
v-show="!btn.hidden"
:key="btn.key"
:src="btn.icon"
@click="onClick(btn.key)"
/>
</div>
</template>
<script lang="ts" setup>
import btn1 from '@/assets/images/btn1.png'
import btn2 from '@/assets/images/btn2.png'
import btn3 from '@/assets/images/btn3.png'
import btn4 from '@/assets/images/btn4.png'
import btn5 from '@/assets/images/btn5.png'
import btn6 from '@/assets/images/btn6.png'
import btn7 from '@/assets/images/btn7.png'
import { computed, PropType } from 'vue'
const props = defineProps({
isDefaultScreen: {
type: Boolean as PropType<boolean>,
default: true,
},
})
const emit = defineEmits(['touch'])
const btns = computed(() => [
{ key: 'home', icon: btn7, hidden: props.isDefaultScreen },
{ key: 'btn1', icon: btn1 },
{ key: 'btn2', icon: btn2 },
{ key: 'btn3', icon: btn3 },
{ key: 'btn4', icon: btn4 },
{ key: 'list', icon: btn5 },
{ key: 'btn6', icon: btn6 },
])
const onClick = (key: string) => {
emit('touch', key)
}
</script>
<style lang="stylus" scoped>
.map-btns
position fixed
z-index 9999
right 29%
bottom .05rem
>img
width .2rem
height @width
margin-bottom .05rem
display block
cursor pointer
transition transform .3s ease-in-out
&:hover
transform scale(1.2)
</style>
<template>
<div ref="mapRef" class="map" />
<div class="btn">
<button @click="zoom('in')">zoom in</button>
<button @click="zoom('out')">zoom out</button>
</div>
</template>
<script lang="ts" setup>
import { ref, nextTick, onMounted } from 'vue'
import { createMap, MapType } from '@/components/my-map'
const mapRef = ref<any>(null)
let map: MapType
onMounted(async () => {
await nextTick()
map = await createMap({
el: mapRef.value,
type: 'SMap',
options: {
viewMode: '2D',
center: [1019.614669, 54.167243],
zooms: [7, 12],
zoom: 8,
pitch: 45,
mapStyle: 'smap://styles/dark',
netType: 'internet',
},
sources: ['/SMap.min.js', '/Plugins.min.js'],
})
map.on('load', () => {
map.hideCommunity()
map
.on('click', (a, b) => {
console.log('click', a, b)
})
.on('dblclick', (a, b) => {
console.log('dblclick', a, b)
})
.on('zoom', (a, b) => {
console.log('zoom', a, b)
})
.on('focus', (a, b) => {
console.log('focus', a, b)
})
.on('move', (a, b) => {
console.log('move', a, b)
})
.on('blur', (a, b) => {
console.log('blur', a, b)
})
.on('drag', (a, b) => {
console.log('drag', a, b)
})
.on('resize', (a, b) => {
console.log('resize', a, b)
})
.on('mousewheel', (a, b) => {
console.log('mousewheel', a, b)
})
})
})
const zoom = (type: string) => {
if (type === 'in') {
map.zoomIn()
map.showCommunity()
} else {
map.zoomOut()
}
}
</script>
<style lang="stylus" scoped>
.map
position fixed
width 100vw
height 100vh
.btn
position absolute
right 20px
top 20px
</style>
<template>
<div class="main">
<m-title area="title" editable @touch="showLayoutModal = true">
<m-title area="title" @touch="showLayoutModal = true">
静安智慧房管
</m-title>
<m-grid
......@@ -34,14 +34,14 @@
>
<TrashBin />
</n-icon>
<!-- <n-icon
<n-icon
v-show="!!components[index]"
class="btn config"
size=".16rem"
@click="onSetComponent(componentList[components[index]])"
>
<Settings />
</n-icon> -->
</n-icon>
</div>
</m-grid>
</div>
......@@ -131,7 +131,6 @@ const {
onSelectComponent,
isTake2rows,
} = useComponent()
const handleMessage = (e) => {
const { type, data } = e.data
switch (type) {
......@@ -164,6 +163,9 @@ const handleMessage = (e) => {
config?.components && (components.value = config.components)
})
break
case 'layout':
showLayoutModal.value = true
break
default:
break
}
......
<template>
<div class="main">
<m-title area="title" @touch="showModal = true"> 静安智慧房管 </m-title>
<m-title area="title" :editable="false"> 静安智慧房管 </m-title>
<m-grid
v-if="layout.boxNum > 0"
:template="layout.template"
......@@ -31,14 +31,16 @@
</div>
</m-modal>
</div>
<MapBtns :isDefaultScreen="isDefaultScreen" @touch="handleMapBtnsEvents" />
</template>
<script lang="ts" setup>
import useLayout from '@/hooks/useLayout'
import useComponent from '@/hooks/useComponent'
import { ref } from 'vue'
import { onMounted, ref } from 'vue'
import { ajax, api } from '@/ajax'
import { NSpace, NButton } from 'naive-ui'
import MapBtns from './components/map-btns.vue'
const { layout } = useLayout()
const { components, componentList } = useComponent()
......@@ -49,11 +51,48 @@ ajax
list.value = res?.data?.content || []
})
const showModal = ref(false)
const defaultConfig = {
layout: {
template: ['box1 . box3', 'box2 . box4', 'box2 . box5'],
rows: '1fr 1fr 0.7fr',
boxNum: 5,
},
components: {
'0': 'A015',
'1': 'A016',
'2': 'A017',
'3': 'A018',
'4': 'A019',
},
}
function initConfig() {
layout.value = defaultConfig.layout
components.value = defaultConfig.components
isDefaultScreen.value = true
}
onMounted(initConfig)
const isDefaultScreen = ref(true)
function check({ configJson }) {
const config = JSON.parse(configJson)
config?.layout && (layout.value = config.layout)
config?.components && (components.value = config.components)
showModal.value = false
isDefaultScreen.value = false
}
function handleMapBtnsEvents(key: string) {
switch (key) {
case 'list':
showModal.value = true
break
case 'home':
initConfig()
break
default:
break
}
}
</script>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment