/** | |||||
* axios配置 | |||||
*/ | |||||
import Vue from 'vue' | |||||
import axios from 'axios' | |||||
import VueAxios from 'vue-axios' | |||||
import store from '@/store' | |||||
import router from '@/router' | |||||
import setting from './setting' | |||||
import { MessageBox } from 'element-ui' | |||||
Vue.use(VueAxios, axios); | |||||
axios.defaults.baseURL = setting.baseURL; | |||||
axios.defaults.withCredentials = true; | |||||
axios.defaults.headers.common[setting.tokenHeaderName] = store.state.user.token; | |||||
/* 响应拦截器 */ | |||||
axios.interceptors.response.use((res) => { | |||||
if (res.data.code === 401) { // 登录过期处理 | |||||
if (res.config.url === setting.menuUrl) { | |||||
store.dispatch('user/setToken').then(() => { | |||||
location.replace('/'); | |||||
}); | |||||
return; | |||||
} | |||||
MessageBox.alert('登录状态已过期,请退出重新登录!', '系统提示', { | |||||
confirmButtonText: '重新登录', | |||||
callback: action => { | |||||
if (action === 'confirm') { | |||||
store.dispatch('user/setToken').then(() => { | |||||
router.push({ path: '/login' }); | |||||
}); | |||||
} | |||||
}, | |||||
beforeClose: () => { | |||||
MessageBox.close(); | |||||
} | |||||
}); | |||||
return Promise.reject(new Error(res.data.msg)); | |||||
} | |||||
// token自动续期 | |||||
let access_token = res.headers[setting.tokenHeaderName]; | |||||
if (access_token) store.dispatch('user/setToken', access_token); | |||||
return res; | |||||
}, (error) => { | |||||
return Promise.reject(error); | |||||
}); | |||||
export default axios |
/** | |||||
* 引用框架 | |||||
*/ | |||||
import Vue from 'vue' | |||||
import './axios' | |||||
import setting from './setting' | |||||
import util from '@/utils/util' | |||||
import permission from '@/utils/permission' // 角色权限控制 | |||||
// 第三方组件 | |||||
import NProgress from 'nprogress' // 顶部进度条 | |||||
import 'nprogress/nprogress.css' | |||||
import VueClipboard from 'vue-clipboard2' // 剪切板 | |||||
// 扩展组件 | |||||
import EleDataTable from '@/components/EleDataTable' // 数据表格 | |||||
import EleIconPicker from '@/components/EleIconPicker' // 图标选择器 | |||||
import EleAvatarList from '@/components/EleAvatarList' // 头像列表 | |||||
import EleDot from '@/components/EleDot' // 状态文字 | |||||
import EleResult from '@/components/EleResult' // 操作结果 | |||||
import EleTagsInput from '@/components/EleTagsInput' // 标签输入框 | |||||
import EleEmpty from '@/components/EleEmpty' // 空视图 | |||||
// UI框架 | |||||
import ElementUI from 'element-ui' // ElementUI | |||||
import 'element-ui/lib/theme-chalk/display.css' | |||||
import '@/styles/eleadmin/icon.scss' // EleAdmin图标 | |||||
import '@/styles/eleadmin/index.scss' // EleAdmin样式 | |||||
import "@/styles/global.css" | |||||
Vue.prototype.$util = util; | |||||
Vue.prototype.$setting = setting; | |||||
Vue.use(ElementUI, {size: 'medium'}); | |||||
Vue.use(permission); | |||||
Vue.use(VueClipboard); | |||||
NProgress.configure({showSpinner: false}); | |||||
/* 全局注册常用组件 */ | |||||
Vue.component(EleDataTable.name, EleDataTable); | |||||
Vue.component(EleIconPicker.name, EleIconPicker); | |||||
Vue.component(EleAvatarList.name, EleAvatarList); | |||||
Vue.component(EleDot.name, EleDot); | |||||
Vue.component(EleResult.name, EleResult); | |||||
Vue.component(EleTagsInput.name, EleTagsInput); | |||||
Vue.component(EleEmpty.name, EleEmpty); | |||||
/** 添加全局过滤器 */ | |||||
Vue.filter('timeAgo', (value, onlyDate) => { | |||||
return util.timeAgo(value, onlyDate); | |||||
}); | |||||
Vue.filter('digit', (value, length) => { | |||||
return util.digit(value, length); | |||||
}); | |||||
Vue.filter('toDateString', (value, format) => { | |||||
return util.toDateString(value, format); | |||||
}); | |||||
Vue.filter('escape', (value) => { | |||||
return util.escape(value); | |||||
}); | |||||
Vue.filter('htmlToText', (value) => { | |||||
return util.htmlToText(value); | |||||
}); |
export default { | |||||
'tms':"http://121.4.38.11:6080/arcgis/rest/services/demo/photo/MapServer", | |||||
'wfs':'http://gisvector.yunhengzhizao.cn:8080/geoserver/demo/wms', | |||||
"ImageArcGIS":"http://e9r5x7df.dongtaiyuming.net/arcgis/rest/services/demo/rrr/MapServer" | |||||
} |
/** | |||||
* 项目统一配置 | |||||
*/ | |||||
export default { | |||||
version: '1.0', | |||||
name: 'GIS综合管理平台', // 项目名称 | |||||
baseURL: 'http://47.98.157.120:9032/api/', // 接口地址 | |||||
// baseURL: 'http://127.0.0.1:9032/api/', // 接口地址 | |||||
whiteList: ['/login', '/forget'], // 路由白名单(不需要登录的) | |||||
keepAliveList: [], // 需要缓存的组件名称 | |||||
menuUrl: '/index/getMenuList', // 菜单数据接口 | |||||
parseMenu: null, // 自定义解析接口菜单数据 | |||||
parseMenuItem: null, // 自定义解析接口菜单每一个数据格式 | |||||
userUrl: '/index/getUserInfo', // 用户信息接口 | |||||
parseUser: (res) => { // 自定义解析接口用户信息 | |||||
res.data.roles = res.data.roles.map(d => d.roleCode); | |||||
res.data.authorities = res.data.authorities.map(d => d.authority); | |||||
return res; | |||||
}, | |||||
tokenHeaderName: 'Authorization', // token传递的header名称 | |||||
tokenStoreName: 'access_token', // token存储的名称 | |||||
userStoreName: 'user', // 用户信息存储的名称 | |||||
themeStoreName: 'theme', // 主题配置存储的名称 | |||||
homeTitle: '主页', // 首页Tab显示标题,null会根据菜单自动获取 | |||||
watchResize: true, // 是否监听屏幕尺寸改变 | |||||
showSetting: true, // 是否显示主题设置抽屉 | |||||
/* 主题默认配置 */ | |||||
sideStyle: 1, // 侧边栏风格,0默认,1暗色 | |||||
headStyle: 0, // 顶栏风格,0默认,1暗色,2主色 | |||||
tabStyle: 1, // 标签页风格,0默认(下划线),1圆点,2卡片 | |||||
bodyFull: true, // 内容区域宽度铺满 | |||||
layoutStyle: 0, // 布局风格,0默认,1顶部菜单风格,2混合菜单风格 | |||||
theme: null, // 默认主题 | |||||
showTabs: true, // 是否开启多标签 | |||||
logoAutoSize: false, // logo是否自适应宽度 | |||||
fixedLayout: true, // 是否固定顶栏和侧栏 | |||||
colorfulIcon: false, // 侧栏是否多彩图标 | |||||
sideUniqueOpen: true // 侧边栏是否只保持一个子菜单展开 | |||||
} |
export default function fullScreen(id,prop){ | |||||
let element; | |||||
return { | |||||
methods:{ | |||||
changeScreen(){ | |||||
element=element||document.getElementById(id) | |||||
if(!this[prop]){ | |||||
this.fullScreen(); | |||||
this[prop]=true; | |||||
}else{ | |||||
this.fullExit() | |||||
this[prop]=false | |||||
} | |||||
}, | |||||
fullScreen() { | |||||
//IE 10及以下ActiveXObject | |||||
// if (window.ActiveXObject) { | |||||
// var WsShell = new ActiveXObject('WScript.Shell') | |||||
// WsShell.SendKeys('{F11}'); | |||||
// } | |||||
//HTML W3C 提议 | |||||
if (element.requestFullScreen) { | |||||
element.requestFullScreen(); | |||||
} | |||||
//IE11 | |||||
else if (element.msRequestFullscreen) { | |||||
element.msRequestFullscreen(); | |||||
} | |||||
// Webkit (works in Safari5.1 and Chrome 15) | |||||
else if (element.webkitRequestFullScreen) { | |||||
element.webkitRequestFullScreen(); | |||||
} | |||||
// Firefox (works in nightly) | |||||
else if (element.mozRequestFullScreen) { | |||||
element.mozRequestFullScreen(); | |||||
} | |||||
}, | |||||
//退出全屏 | |||||
fullExit() { | |||||
if (window.ActiveXObject) { | |||||
var WsShell = new ActiveXObject('WScript.Shell') | |||||
WsShell.SendKeys('{F11}'); | |||||
} | |||||
//HTML5 W3C 提议 | |||||
else if (element.requestFullScreen) { | |||||
document.exitFullscreen(); | |||||
} | |||||
//IE 11 | |||||
else if (element.msRequestFullscreen) { | |||||
document.msExitFullscreen(); | |||||
} | |||||
// Webkit (works in Safari5.1 and Chrome 15) | |||||
else if (element.webkitRequestFullScreen) { | |||||
document.webkitCancelFullScreen(); | |||||
} | |||||
// Firefox (works in nightly) | |||||
else if (element.mozRequestFullScreen) { | |||||
document.mozCancelFullScreen(); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} |
import 'ol/ol.css'; | |||||
import Draw from 'ol/interaction/Draw'; | |||||
import Map from 'ol/Map'; | |||||
import Overlay from 'ol/Overlay'; | |||||
import View from 'ol/View'; | |||||
import { Circle as CircleStyle, Fill, Stroke, Style } from 'ol/style'; | |||||
import { LineString, Polygon } from 'ol/geom'; | |||||
import { OSM, Vector as VectorSource } from 'ol/source'; | |||||
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'; | |||||
import { getArea, getLength } from 'ol/sphere'; | |||||
import { unByKey } from 'ol/Observable'; | |||||
import { DoubleClickZoom } from "ol/interaction" | |||||
export default function length(context, map, type,select) { | |||||
const dblClickInteraction = map | |||||
.getInteractions() | |||||
.getArray() | |||||
.find(interaction => { | |||||
return interaction instanceof DoubleClickZoom; | |||||
}); | |||||
map.removeInteraction(dblClickInteraction); | |||||
var source = new VectorSource(); | |||||
var vector = new VectorLayer({ | |||||
source: source, | |||||
style: new Style({ | |||||
fill: new Fill({ | |||||
color: 'rgba(255, 255, 255, 0.2)', | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: 'rgb(1 145 255)', | |||||
width: 3, | |||||
}), | |||||
image: new CircleStyle({ | |||||
radius: 7, | |||||
fill: new Fill({ | |||||
color: '#ffcc33', | |||||
}), | |||||
}), | |||||
}), | |||||
}); | |||||
map.addLayer(vector) | |||||
/** | |||||
* Currently drawn feature. | |||||
* @type {import("../src/ol/Feature.js").default} | |||||
*/ | |||||
var sketch; | |||||
/** | |||||
* The help tooltip element. | |||||
* @type {HTMLElement} | |||||
*/ | |||||
var helpTooltipElement; | |||||
/** | |||||
* Overlay to show the help messages. | |||||
* @type {Overlay} | |||||
*/ | |||||
var helpTooltip; | |||||
/** | |||||
* The measure tooltip element. | |||||
* @type {HTMLElement} | |||||
*/ | |||||
var measureTooltipElement; | |||||
/** | |||||
* Overlay to show the measurement. | |||||
* @type {Overlay} | |||||
*/ | |||||
var measureTooltip; | |||||
var cancelElement | |||||
var pointerMoveHandler = function (evt) { | |||||
if (evt.dragging) { | |||||
return; | |||||
} | |||||
helpTooltip.setPosition(evt.coordinate); | |||||
helpTooltipElement.classList.remove('hidden'); | |||||
}; | |||||
var draw; // global so we can remove it later | |||||
/** | |||||
* Format length output. | |||||
* @param {LineString} line The line. | |||||
* @return {string} The formatted length. | |||||
*/ | |||||
var formatLength = function (line) { | |||||
var length = getLength(line); | |||||
var output; | |||||
if (length > 100) { | |||||
output = Math.round((length / 1000) * 100) / 100 + ' ' + 'km'; | |||||
} else { | |||||
output = Math.round(length * 100) / 100 + ' ' + 'm'; | |||||
} | |||||
return output; | |||||
}; | |||||
/** | |||||
* Format area output. | |||||
* @param {Polygon} polygon The polygon. | |||||
* @return {string} Formatted area. | |||||
*/ | |||||
var formatArea = function (polygon) { | |||||
var area = getArea(polygon); | |||||
var output; | |||||
if (area > 10000) { | |||||
output = Math.round((area / 1000000) * 100) / 100 + ' ' + 'km<sup>2</sup>'; | |||||
} else { | |||||
output = Math.round(area * 100) / 100 + ' ' + 'm<sup>2</sup>'; | |||||
} | |||||
return output; | |||||
}; | |||||
let add = false; | |||||
function addInteraction() { | |||||
map.removeInteraction(select) | |||||
let overlays = []; | |||||
function createHelpTooltip() { | |||||
if (helpTooltipElement) { | |||||
helpTooltipElement.parentNode.removeChild(helpTooltipElement); | |||||
} | |||||
helpTooltipElement = document.createElement('div'); | |||||
helpTooltipElement.className = 'ol-tooltip hidden'; | |||||
helpTooltipElement.innerHTML = '双击结束'; | |||||
helpTooltip = new Overlay({ | |||||
element: helpTooltipElement, | |||||
offset: [15, 0], | |||||
positioning: 'center-left', | |||||
}); | |||||
map.addOverlay(helpTooltip); | |||||
overlays.push(helpTooltip) | |||||
} | |||||
/** | |||||
* Creates a new measure tooltip | |||||
*/ | |||||
function createMeasureTooltip() { | |||||
if (measureTooltipElement) { | |||||
measureTooltipElement.parentNode.removeChild(measureTooltipElement); | |||||
} | |||||
measureTooltipElement = document.createElement('div'); | |||||
measureTooltipElement.className = 'ol-tooltip ol-tooltip-measure'; | |||||
measureTooltipElement.innerHTML = "双击结束" | |||||
measureTooltip = new Overlay({ | |||||
element: measureTooltipElement, | |||||
offset: [0, -15], | |||||
positioning: 'bottom-center', | |||||
}); | |||||
map.addOverlay(measureTooltip); | |||||
overlays.push(measureTooltip) | |||||
} | |||||
function createTooltip(output, coordinate) { | |||||
let element = document.createElement('div') | |||||
element.className = "ol-tooltip ol-tooltip-measure" | |||||
element.innerHTML = output | |||||
let overlay = new Overlay({ | |||||
element, | |||||
offset: [-30, -30], | |||||
position: "bottom-center" | |||||
}) | |||||
overlay.setPosition(coordinate) | |||||
map.addOverlay(overlay) | |||||
overlays.push(overlay) | |||||
return overlay | |||||
} | |||||
function createdCancel(coordinate) { | |||||
cancelElement = document.createElement('div'); | |||||
cancelElement.style.cursor = "pointer" | |||||
cancelElement.addEventListener('click', () => { | |||||
overlays.forEach(item => { | |||||
map.removeOverlay(item) | |||||
}) | |||||
vector.getSource().removeFeature(feature) | |||||
}) | |||||
cancelElement.innerHTML = "<span class='el-icon-delete-solid' style='color:red;font-size:18px;'></span>" | |||||
let overlay = new Overlay({ | |||||
element: cancelElement, | |||||
position: "top-center", | |||||
offset: [-10, 20] | |||||
}) | |||||
overlay.setPosition(coordinate) | |||||
map.addOverlay(overlay) | |||||
overlays.push(overlay) | |||||
} | |||||
let feature; | |||||
this.$refs.map.classList.add('cursor') | |||||
if (add) { | |||||
return | |||||
} | |||||
add = true | |||||
let movein = map.on('pointermove', pointerMoveHandler); | |||||
let moveout = map.getViewport().addEventListener('mouseout', function () { | |||||
helpTooltipElement.classList.add('hidden'); | |||||
}); | |||||
draw = new Draw({ | |||||
source: source, | |||||
type, | |||||
style: new Style({ | |||||
fill: new Fill({ | |||||
color: 'rgba(255, 255, 255, 0.2)', | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: 'rgba(0, 0, 0, 0.5)', | |||||
width: 3, | |||||
}), | |||||
}), | |||||
}); | |||||
map.addInteraction(draw); | |||||
createMeasureTooltip(); | |||||
createHelpTooltip(); | |||||
var listener; | |||||
let showLength = false; | |||||
let clickListener; | |||||
draw.on('drawstart', function (evt) { | |||||
console.log('ddddd') | |||||
showLength = false; | |||||
clickListener = map.on('singleclick', function (e) { | |||||
if (showLength) { | |||||
if (geom instanceof LineString) { | |||||
console.log(formatLength(geom)) | |||||
createTooltip(formatLength(geom), e.coordinate) | |||||
} | |||||
} | |||||
}) | |||||
sketch = evt.feature; | |||||
let geom = sketch.getGeometry(); | |||||
var tooltipCoord = evt.coordinate; | |||||
listener = sketch.getGeometry().on('change', function (evt) { | |||||
var output; | |||||
if (geom instanceof Polygon) { | |||||
output = formatArea(geom); | |||||
tooltipCoord = geom.getInteriorPoint().getCoordinates(); | |||||
} else if (geom instanceof LineString) { | |||||
output = formatLength(geom); | |||||
if (geom.getCoordinates().length > 2) { | |||||
showLength = true | |||||
} | |||||
tooltipCoord = geom.getLastCoordinate(); | |||||
} | |||||
measureTooltipElement.innerHTML = output; | |||||
measureTooltip.setPosition(tooltipCoord); | |||||
}); | |||||
}); | |||||
draw.on('drawend', (e) => { | |||||
unByKey('dbclick') | |||||
measureTooltip.setOffset([0, -7]); | |||||
// unset sketch | |||||
sketch = null; | |||||
// unset tooltip so that a new one can be created | |||||
measureTooltipElement = null; | |||||
createMeasureTooltip() | |||||
unByKey([listener, clickListener, movein, moveout]); | |||||
feature = e.feature; | |||||
let geom = e.feature.getGeometry(); | |||||
let center; | |||||
if (geom instanceof LineString) { | |||||
center = e.feature.getGeometry().getLastCoordinate(); | |||||
} else if (geom instanceof Polygon) { | |||||
center = e.feature.getGeometry().getInteriorPoint().getCoordinates(); | |||||
} | |||||
createdCancel(center) | |||||
map.removeOverlay(helpTooltip) | |||||
map.removeOverlay(measureTooltip) | |||||
map.removeInteraction(draw) | |||||
add = false | |||||
this.$refs.map.classList.remove('cursor') | |||||
map.addInteraction(select) | |||||
}); | |||||
} | |||||
addInteraction = addInteraction.bind(context) | |||||
/** | |||||
* Creates a new help tooltip | |||||
*/ | |||||
return addInteraction | |||||
} |
import echarts from 'echarts' | |||||
export default { | |||||
} |
/** | |||||
* 角色权限控制组件 License By http://eleadmin.com | |||||
*/ | |||||
import store from '@/store' | |||||
export default { | |||||
install(Vue) { | |||||
// 添加全局方法 | |||||
Vue.prototype.$hasRole = this.hasRole; | |||||
Vue.prototype.$hasAnyRole = this.hasAnyRole; | |||||
Vue.prototype.$hasPermission = this.hasPermission; | |||||
Vue.prototype.$hasAnyPermission = this.hasAnyPermission; | |||||
// 添加自定义指令 | |||||
Vue.directive('role', { | |||||
inserted: (el, binding) => { | |||||
if (!this.hasRole(binding)) el.parentNode.removeChild(el); | |||||
} | |||||
}); | |||||
Vue.directive('any-role', { | |||||
inserted: (el, binding) => { | |||||
if (!this.hasAnyRole(binding)) el.parentNode.removeChild(el); | |||||
} | |||||
}); | |||||
Vue.directive('permission', { | |||||
inserted: (el, binding) => { | |||||
if (!this.hasPermission(binding)) el.parentNode.removeChild(el); | |||||
} | |||||
}); | |||||
Vue.directive('any-permission', { | |||||
inserted: (el, binding) => { | |||||
if (!this.hasAnyPermission(binding)) el.parentNode.removeChild(el); | |||||
} | |||||
}); | |||||
}, | |||||
/** | |||||
* 是否有某些角色 | |||||
* @param role 字符或字符数组 | |||||
* @returns {boolean} | |||||
*/ | |||||
hasRole(role) { | |||||
if (!role) return true; | |||||
let roles = store.state.user.roles; | |||||
if (!roles) return false; | |||||
if (Array.isArray(role)) { | |||||
for (let i = 0; i < role.length; i++) { | |||||
if (roles.indexOf(role[i]) === -1) return false; | |||||
} | |||||
return true; | |||||
} | |||||
return roles.indexOf(role) !== -1; | |||||
}, | |||||
/** | |||||
* 是否有任意角色 | |||||
* @param role 字符或字符数组 | |||||
* @returns {boolean} | |||||
*/ | |||||
hasAnyRole(role) { | |||||
if (!role) return true; | |||||
let roles = store.state.user.roles; | |||||
if (!roles) return false; | |||||
if (Array.isArray(role)) { | |||||
for (let i = 0; i < role.length; i++) { | |||||
if (roles.indexOf(role[i]) !== -1) return true; | |||||
} | |||||
return false; | |||||
} | |||||
return roles.indexOf(role) !== -1; | |||||
}, | |||||
/** | |||||
* 是否有某些权限 | |||||
* @param auth 字符或字符数组 | |||||
* @returns {boolean} | |||||
*/ | |||||
hasPermission(auth) { | |||||
if (!auth) return true; | |||||
let authorities = store.state.user.authorities; | |||||
if (!authorities) return false; | |||||
if (Array.isArray(auth)) { | |||||
for (let i = 0; i < auth.length; i++) { | |||||
if (authorities.indexOf(auth[i]) === -1) return false; | |||||
} | |||||
return true; | |||||
} | |||||
return authorities.indexOf(auth) !== -1; | |||||
}, | |||||
/** | |||||
* 是否有任意权限 | |||||
* @param auth 字符或字符数组 | |||||
* @returns {boolean} | |||||
*/ | |||||
hasAnyPermission(auth) { | |||||
if (!auth) return true; | |||||
let authorities = store.state.user.authorities; | |||||
if (!authorities) return false; | |||||
if (Array.isArray(auth)) { | |||||
for (let i = 0; i < auth.length; i++) { | |||||
if (authorities.indexOf(auth[i]) !== -1) return true; | |||||
} | |||||
return false; | |||||
} | |||||
return authorities.indexOf(auth) !== -1; | |||||
} | |||||
} |
/** | |||||
* 打印插件 License By http://eleadmin.com | |||||
*/ | |||||
export default { | |||||
/** | |||||
* 打印当前页面 | |||||
* @param hide 需要隐藏的元素 | |||||
* @param horizontal 是否横向打印 | |||||
* @param iePreview 是否支持ie打印预览 | |||||
* @param blank 是否在新窗口打印 | |||||
* @param close 如果在新窗口打印,打印完是否关闭新窗口 | |||||
* @param margin 页间距 | |||||
* @param title 页面标题 | |||||
* @returns {Window} 打印的窗口对象 | |||||
*/ | |||||
print({hide, horizontal, iePreview = true, blank, close, margin, title}) { | |||||
if (close === undefined && blank && !this.isIE()) close = true; | |||||
window.focus(); // 让当前窗口获取焦点 | |||||
this.addCommonCss(); // 加入核心样式 | |||||
// 打印方向控制 | |||||
let setElem = document.getElementById(this.pSetId); | |||||
if (setElem) setElem.parentNode.removeChild(setElem); | |||||
let sizeHtml = '', marginHtml = ''; | |||||
if (horizontal !== undefined) sizeHtml = `size: ${horizontal ? 'landscape' : 'portrait'};`; // 打印方向 | |||||
if (margin === 0 || margin) marginHtml = `margin: ${margin};`; // 页间距 | |||||
if (sizeHtml || marginHtml) { | |||||
let elem = document.createElement('style'); | |||||
elem.id = this.pSetId; | |||||
elem.setAttribute('type', 'text/css'); | |||||
elem.setAttribute('media', 'print'); | |||||
elem.innerHTML = `@page {${sizeHtml}${marginHtml}}`; | |||||
document.body.appendChild(elem); | |||||
} | |||||
this.hideElem(hide); // 隐藏打印时需要隐藏的内容 | |||||
// 打印 | |||||
let oldTitle = document.title; | |||||
if (title) document.title = title; | |||||
let pWin; | |||||
if (blank) { // 新窗口打印 | |||||
// 创建打印窗口 | |||||
pWin = window.open('', '_blank'); | |||||
pWin.focus(); // 让打印窗口获取焦点 | |||||
// 写入内容到打印窗口 | |||||
const pDoc = pWin.document; | |||||
pDoc.open(); | |||||
const closeJs = close ? 'window.close();' : ''; | |||||
let html = '<!DOCTYPE html>' + document.getElementsByTagName('html')[0].outerHTML; | |||||
html = html.replace(/<script[^>]+>/g, ''); // 去除js | |||||
if (iePreview && this.isIE()) { | |||||
if (!document.getElementById('WebBrowser')) { | |||||
html = html.replace(/<\/html>/, `${this.ieWebBrowser}</html>`); | |||||
} | |||||
let pjs = `<script>window.onload=function(){window.WebBrowser.ExecWB?(window.WebBrowser.ExecWB(7,1)):window.print();${closeJs}}</script>`; | |||||
html = html.replace(/<\/html>/, `${pjs}</html>`); | |||||
} else { | |||||
let pjs = `<script>window.onload=function(){window.print();${closeJs}}</script>`; | |||||
html = html.replace(/<\/html>/, `${pjs}</html>`); | |||||
} | |||||
pDoc.write(html); | |||||
pDoc.close(); | |||||
} else { // 当前窗口打印 | |||||
pWin = window; | |||||
if (iePreview && this.isIE()) { | |||||
if (!document.getElementById('WebBrowser')) { | |||||
let elem = document.createElement('object'); | |||||
elem.id = 'WebBrowser'; | |||||
elem.setAttribute('classid', 'clsid:8856F961-340A-11D0-A96B-00C04FD705A2'); | |||||
elem.style.display = 'none'; | |||||
document.body.appendChild(elem); | |||||
} | |||||
try { | |||||
window.WebBrowser.ExecWB(7, 1); | |||||
} catch (e) { | |||||
console.error(e); | |||||
pWin.print(); | |||||
} | |||||
} else { | |||||
pWin.print(); | |||||
} | |||||
} | |||||
if (title) document.title = oldTitle; | |||||
this.showElem(hide); // 打印完恢复隐藏的内容 | |||||
return pWin; | |||||
}, | |||||
/** | |||||
* 打印任意内容 | |||||
* @param html 要打印的html内容 | |||||
* @param blank 是否在新窗口打印 | |||||
* @param close 如果在新窗口打印,打印完是否关闭新窗口 | |||||
* @param print 是否立即打印 | |||||
* @param horizontal 纸张是否是横向 | |||||
* @param iePreview 是否兼容ie打印预览 | |||||
* @param loading 是否显示加载层 | |||||
* @param before 打印开始的回调 | |||||
* @param done 打印完成的回调 | |||||
* @param margin 页间距 | |||||
* @param header 页眉 | |||||
* @param footer 页脚 | |||||
* @returns {Window} 打印的窗口对象 | |||||
*/ | |||||
printHtml({html, blank, close, print = true, horizontal, iePreview = true, loading = true, before, done, margin, header, footer}) { | |||||
if (blank === undefined && this.isIE() && iePreview) blank = true; | |||||
if (close === undefined && blank && !this.isIE()) close = true; | |||||
if (loading && !blank) this.showLoading(); | |||||
// 创建打印窗口 | |||||
let pWin, pDoc; | |||||
if (blank) { // 新窗口打印 | |||||
pWin = window.open('', '_blank'); | |||||
pDoc = pWin.document; | |||||
} else { // 当前窗口打印 | |||||
let pFrame = this.getPFrame(); | |||||
pWin = pFrame.contentWindow; | |||||
pDoc = pFrame.contentDocument || pFrame.contentWindow.document; | |||||
} | |||||
pWin.focus(); // 让打印窗口获取焦点 | |||||
// 写入内容到打印窗口 | |||||
if (html) { | |||||
if (header || footer) html = this.addHeaderFooter(html, header, footer); // 添加页眉页脚 | |||||
html += `<style>${this.getCommonCss(true)}</style>`; // 加入公共css | |||||
html += this.getPrintHtml(horizontal, close, print, iePreview, before, done, margin); | |||||
pDoc.open(); | |||||
pDoc.write(`<!DOCTYPE html><html lang="zh">${html}</html>`); // 写入html | |||||
pDoc.close(); | |||||
} | |||||
return pWin; | |||||
}, | |||||
/** | |||||
* 分页打印 | |||||
* @param htmls 要打印的内容 | |||||
* @param horizontal 纸张是否是横向 | |||||
* @param style 打印的自定义样式 | |||||
* @param padding 每一页的边距 | |||||
* @param blank 是否在新窗口打印 | |||||
* @param close 如果在新窗口打印,打印完是否关闭新窗口 | |||||
* @param print 是否立即打印 | |||||
* @param width 每一页宽度 | |||||
* @param height 每一页高度 | |||||
* @param iePreview 是否兼容ie打印预览 | |||||
* @param isDebug 是否开启调试模式 | |||||
* @param loading 是否显示加载层 | |||||
* @param before 打印开始的回调 | |||||
* @param done 打印完成的回调 | |||||
* @param margin 页间距 | |||||
* @param header 页眉 | |||||
* @param footer 页脚 | |||||
* @param title 页面标题 | |||||
* @returns {Window} 打印的窗口对象 | |||||
*/ | |||||
printPage({htmls, horizontal, style, padding, blank, close, print = true, width, height, iePreview = true, isDebug, loading = true, before, done, margin, header, footer, title}) { | |||||
if (blank === undefined && this.isIE() && iePreview) blank = true; | |||||
if (close === undefined && blank && !this.isIE()) close = true; | |||||
if (loading && !blank) this.showLoading(); | |||||
// 创建打印窗口 | |||||
let pWin, pDoc; | |||||
if (blank) { // 新窗口打印 | |||||
pWin = window.open('', '_blank'); | |||||
pDoc = pWin.document; | |||||
} else { // 当前窗口打印 | |||||
let pFrame = this.getPFrame(); | |||||
pWin = pFrame.contentWindow; | |||||
pDoc = pFrame.contentDocument || pFrame.contentWindow.document; | |||||
} | |||||
pWin.focus(); // 让打印窗口获取焦点 | |||||
// 拼接打印内容 | |||||
let html = `<!DOCTYPE html><html lang="zh"><head><meta charset="UTF-8"><title>${title || ''}</title>`; | |||||
html += this.getPageCss(padding, width, height) + (style || '') + '</head><body>'; // 控制分页的css | |||||
// 拼接分页内容 | |||||
let contentHtml = ''; | |||||
if (htmls) { | |||||
contentHtml += `<div class="ele-printer-page ${isDebug ? 'ele-printer-debug' : ''}">`; | |||||
contentHtml += htmls.map(h => `<div class="ele-printer-page-item">${h}</div>`).join(''); | |||||
contentHtml += '</div>'; | |||||
} | |||||
if (header || footer) html += this.addHeaderFooter(contentHtml, header, footer); // 添加页眉页脚 | |||||
else html += contentHtml; | |||||
html += this.getPrintHtml(horizontal, close, print, iePreview, before, done, margin); | |||||
html += '</body></html>'; | |||||
pDoc.open(); | |||||
pDoc.write(html); // 写入打印内容 | |||||
pDoc.close(); | |||||
return pWin; | |||||
}, | |||||
/* 生成控制打印的html */ | |||||
getPrintHtml(horizontal, close, print, iePreview, before, done, margin) { | |||||
let {beforeJs, doneJs} = this.addCallback(before, done); | |||||
let html = '', sizeHtml = '', marginHtml = ''; | |||||
if (horizontal !== undefined) sizeHtml = `size: ${horizontal ? 'landscape' : 'portrait'};`; // 打印方向 | |||||
if (margin === 0 || margin) marginHtml = `margin: ${margin};`; // 页间距 | |||||
html += `<style type="text/css" media="print" id="${this.pSetId}">@page{${sizeHtml}${marginHtml}</style>`; | |||||
// 兼容ie打印预览 | |||||
const closeJs = (close ? 'window.close();' : '') + doneJs; | |||||
const hideLoadJs = `${beforeJs};parent.hideElePrinterLoading&&parent.hideElePrinterLoading();`; | |||||
if (iePreview && this.isIE()) { | |||||
html += this.ieWebBrowser; | |||||
if (print) html += `<script>window.onload=function(){${hideLoadJs}window.WebBrowser.ExecWB?(window.WebBrowser.ExecWB(7,1)):window.print();${closeJs}}</script>`; | |||||
} else if (print) { | |||||
html += `<script>window.onload=function(){${hideLoadJs}window.print();${closeJs}}</script>`; | |||||
} | |||||
return html; | |||||
}, | |||||
/* 增加页眉页脚 */ | |||||
addHeaderFooter(html, header, footer) { | |||||
let result = '<table class="ele-printer-table-page">'; | |||||
if (header) result += `<thead><tr><td>${header}</td></tr></thead>`; | |||||
result += `<tbody><tr><td>${html}</td></tr></tbody>`; | |||||
if (footer) result += `<tfoot><tr><td>${footer}</td></tr></tfoot>`; | |||||
return result + '</table>'; | |||||
}, | |||||
/* 隐藏元素 */ | |||||
hideElem(elems) { | |||||
document.getElementsByClassName(this.hideClass).forEach(elem => { | |||||
elem.classList.add(this.printingClass); | |||||
}); | |||||
if (!elems) return; | |||||
if (!Array.isArray(elems)) elems = [elems]; | |||||
elems.forEach(elem => { | |||||
if (typeof elem === 'string') elem = document.querySelector(elem); | |||||
elem.classList.add(this.hideClass); | |||||
elem.classList.add(this.printingClass); | |||||
}); | |||||
}, | |||||
/* 取消隐藏 */ | |||||
showElem(elems) { | |||||
document.getElementsByClassName(this.hideClass).forEach(elem => { | |||||
elem.classList.remove(this.printingClass); | |||||
}); | |||||
if (!elems) return; | |||||
if (!Array.isArray(elems)) elems = [elems]; | |||||
elems.forEach(elem => { | |||||
if (typeof elem === 'string') elem = document.querySelector(elem); | |||||
elem.classList.remove(this.hideClass); | |||||
elem.classList.remove(this.printingClass); | |||||
}); | |||||
}, | |||||
/** | |||||
* 获取打印核心样式 | |||||
* @param isPrinting 是否已开始打印 | |||||
* @returns {String} | |||||
*/ | |||||
getCommonCss(isPrinting) { | |||||
return ` | |||||
.${this.hideClass}.${this.printingClass} { | |||||
visibility: hidden !important; | |||||
} | |||||
.${this.hideClass} { | |||||
${isPrinting ? 'visibility: hidden !important;' : ''} | |||||
} | |||||
.${this.hideClass}.${this.printingClass}.${this.hideNoneClass}, | |||||
.${this.hideClass}.${this.hideNoneClass}${isPrinting ? '' : '-no'} { | |||||
display: none !important; | |||||
} | |||||
/* 表格样式 */ | |||||
.ele-printer-table { | |||||
width: 100%; | |||||
border-collapse: collapse; | |||||
border: none; | |||||
} | |||||
.ele-printer-table td, .ele-printer-table th { | |||||
color: #333; | |||||
padding: 9px 15px; | |||||
border: 1px solid #333; | |||||
word-break: break-all; | |||||
} | |||||
/* loading样式 */ | |||||
#ele-printer-loading { | |||||
position: fixed; | |||||
top: 0; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 0; | |||||
background-color: hsla(0,0%,100%,.9); | |||||
z-index: 19000000 ; | |||||
} | |||||
#ele-printer-loading:after { | |||||
content: ""; | |||||
width: 40px; | |||||
height: 40px; | |||||
position: absolute; | |||||
top: 50%; | |||||
left: 50%; | |||||
margin: -20px auto auto -20px; | |||||
border: 2px solid #3296FA; | |||||
border-right-color: transparent; | |||||
border-bottom-color: transparent; | |||||
border-radius: 50%; | |||||
animation: ele-printer-loading-anim .8s linear infinite; | |||||
} | |||||
@keyframes ele-printer-loading-anim { | |||||
from { | |||||
transform: rotate(0deg); | |||||
} | |||||
to { | |||||
transform: rotate(360deg); | |||||
} | |||||
} | |||||
/* 带页眉页脚页面样式 */ | |||||
.ele-printer-table-page { | |||||
width: 100%; | |||||
} | |||||
`; | |||||
}, | |||||
/** | |||||
* 获取分页打印的样式 | |||||
* @param padding 每一页边距 | |||||
* @param width 每一页宽度 | |||||
* @param height 每一页高度 | |||||
* @returns {String} | |||||
*/ | |||||
getPageCss(padding, width, height) { | |||||
return ` | |||||
<style> | |||||
body { margin: 0 !important; } | |||||
/* 自定义边距竖屏样式 */ | |||||
.ele-printer-page .ele-printer-page-item { | |||||
width: ${width || 'auto'}; | |||||
height: ${height || 'auto'}; | |||||
padding: ${padding || '0'}; | |||||
page-break-after: always !important; | |||||
box-sizing: border-box !important; | |||||
border: none !important; | |||||
position: relative; | |||||
} | |||||
/* 调试模式样式 */ | |||||
.ele-printer-page.ele-printer-debug .ele-printer-page-item { | |||||
border: 1px solid red !important; | |||||
} | |||||
/* 核心样式 */ | |||||
${this.getCommonCss(true)} | |||||
</style> | |||||
`; | |||||
}, | |||||
/** | |||||
* 打印pdf | |||||
* @param url pdf链接地址 | |||||
* @param arraybuffer 直接指定arraybuffer数据 | |||||
* @param error 错误回调 | |||||
* @param loading 是否显示加载层 | |||||
* @param before 打印开始的回调 | |||||
* @param done 打印完成的回调 | |||||
* @returns {Window} 打印的窗口对象 | |||||
*/ | |||||
printPdf({url, arraybuffer, error, loading = true, before, done}) { | |||||
if (loading) this.showLoading(); | |||||
let pWin; | |||||
let pFrame = this.getPFrame(); | |||||
pWin = pFrame.contentWindow; | |||||
pFrame.onload = () => { | |||||
if (!pFrame.getAttribute('src')) return; | |||||
pFrame.focus(); | |||||
before && before(); | |||||
pWin.print(); | |||||
this.hideLoading(); | |||||
done && done(); | |||||
}; | |||||
// 开始打印 | |||||
function doPrint(hideLoading) { | |||||
let localPdf = new window.Blob([arraybuffer], {type: 'application/pdf'}); | |||||
// 兼容IE | |||||
if (window.navigator && window.navigator.msSaveOrOpenBlob) { | |||||
window.navigator.msSaveOrOpenBlob(localPdf, 'print.pdf'); | |||||
hideLoading(); | |||||
} else { | |||||
localPdf = window.URL.createObjectURL(localPdf); | |||||
pFrame.setAttribute('src', localPdf); | |||||
} | |||||
} | |||||
// 请求pdf数据 | |||||
if (!arraybuffer) { | |||||
let req = new window.XMLHttpRequest(); | |||||
req.open('GET', url, true); | |||||
req.responseType = 'arraybuffer'; | |||||
req.onload = () => { | |||||
if ([200, 201].indexOf(req.status) === -1) return error && error(req.status, req.statusText); | |||||
arraybuffer = req.response; | |||||
doPrint(() => { | |||||
this.hideLoading(); | |||||
}); | |||||
}; | |||||
req.send(); | |||||
} else { | |||||
doPrint(() => { | |||||
this.hideLoading(); | |||||
}); | |||||
} | |||||
return pWin; | |||||
}, | |||||
/* 获取隐藏的打印iframe */ | |||||
getPFrame() { | |||||
let pFrame = document.getElementById(this.pFrameId); | |||||
if (pFrame) pFrame.parentNode.removeChild(pFrame); | |||||
let elem = document.createElement('iframe'); | |||||
elem.id = this.pFrameId; | |||||
elem.style.width = 0; | |||||
elem.style.height = 0; | |||||
elem.style.position = 'fixed'; | |||||
elem.style.visibility = 'hidden'; | |||||
document.body.appendChild(elem); | |||||
pFrame = document.getElementById(this.pFrameId); | |||||
pFrame.focus(); | |||||
return pFrame; | |||||
}, | |||||
/** | |||||
* 生成表格html | |||||
* @param data 数据 | |||||
* @param cols 列配置 | |||||
* @returns {string} | |||||
*/ | |||||
makeTable(data, cols) { | |||||
// 恢复cols参数初始状态 | |||||
cols.forEach(col => { | |||||
col.forEach(c => { | |||||
c.INIT_OK = undefined; | |||||
c.key = undefined; | |||||
c.colGroup = undefined; | |||||
c.HAS_PARENT = undefined; | |||||
c.parentKey = undefined; | |||||
c.PARENT_COL_INDEX = undefined; | |||||
}); | |||||
}); | |||||
// cols转为嵌套结构 | |||||
let colArrays = [], colIndex = 0; | |||||
for (let i1 = 0; i1 < cols.length; i1++) { | |||||
let item1 = cols[i1]; | |||||
for (let i2 = 0; i2 < item1.length; i2++) { | |||||
let item2 = item1[i2]; | |||||
if (!item2) { | |||||
item1.splice(i2, 1); | |||||
continue; | |||||
} | |||||
// 合并单元格处理 | |||||
item2.key = i1 + '-' + i2; | |||||
let CHILD_COLS = undefined; | |||||
if (item2.colGroup || item2.colspan > 1) { | |||||
item2.colGroup = true; | |||||
CHILD_COLS = []; | |||||
colIndex++; | |||||
let childIndex = 0; | |||||
for (let i22 = 0; i22 < cols[i1 + 1].length; i22++) { | |||||
let item22 = Object.assign({}, cols[i1 + 1][i22]); | |||||
if (item22.HAS_PARENT || (childIndex > 1 && childIndex == item2.colspan)) { | |||||
cols[i1 + 1][i22] = item22; | |||||
continue; | |||||
} | |||||
item22.HAS_PARENT = true; | |||||
item22.parentKey = i1 + '-' + i2; | |||||
item22.key = (i1 + 1) + '-' + i22; | |||||
item22.PARENT_COL_INDEX = colIndex; | |||||
CHILD_COLS.push(item22); | |||||
childIndex = childIndex + parseInt(item22.colspan > 1 ? item22.colspan : 1); | |||||
cols[i1 + 1][i22] = item22; | |||||
} | |||||
} | |||||
item2.CHILD_COLS = CHILD_COLS; | |||||
if (!item2.PARENT_COL_INDEX) colArrays.push(item2); | |||||
cols[i1][i2] = item2; | |||||
} | |||||
} | |||||
// 遍历嵌套结构cols的方法 | |||||
function eachCols(callback, obj) { | |||||
if (!obj) obj = colArrays; | |||||
for (let i = 0; i < obj.length; i++) { | |||||
let item = obj[i]; | |||||
callback && callback(i, item); | |||||
if (item.CHILD_COLS) eachCols(callback, item.CHILD_COLS); | |||||
} | |||||
} | |||||
// 计算表格宽度 | |||||
let width = 1, needSetWidth = true, colgroup = []; | |||||
eachCols((i, c) => { | |||||
if (c.colGroup) return; | |||||
colgroup.push('<col'); | |||||
if (c.width) colgroup.push(` width="${c.width}"`); | |||||
colgroup.push('/>'); | |||||
if (c.width && !/\d+%$/.test(width)) width += (c.width + 1); | |||||
else needSetWidth = false; | |||||
}); | |||||
width += 'px'; | |||||
// 生成html | |||||
let html = `<table style="width:${needSetWidth ? width : '100%'};" class="ele-printer-table">`; | |||||
html += `<colgroup>${colgroup.join('')}</colgroup>`; | |||||
// 表头 | |||||
let trs = cols.map(col => { | |||||
let ths = col.map(c => `<th colspan="${c.colspan || 1}" rowspan="${c.rowspan || 1}" | |||||
align="${c.thAlign || c.align || 'left'}" style="${c.thStyle}">${c.title || ''}</th>`); | |||||
return `<tr>${ths.join('')}</tr>`; | |||||
}); | |||||
html += `<thead>${trs.join('')}</thead>`; | |||||
// 主体 | |||||
html += '<tbody>'; | |||||
data.forEach((d, index) => { | |||||
html += '<tr>'; | |||||
let colIndex = 0; | |||||
eachCols((i, c) => { | |||||
if (c.colGroup) return; | |||||
let content = c.templet ? c.templet(d, index, colIndex) : d[c.field]; | |||||
html += `<td align="${c.align || 'left'}" style="${c.style}">${content}</td>`; | |||||
colIndex++; | |||||
}); | |||||
html += '</tr>'; | |||||
}); | |||||
return html + '</tbody></table>'; | |||||
}, | |||||
/* 加入核心样式 */ | |||||
addCommonCss() { | |||||
if (!document.getElementById(this.pStyleId)) { | |||||
let elem = document.createElement('style'); | |||||
elem.id = this.pStyleId; | |||||
elem.setAttribute('type', 'text/css'); | |||||
elem.innerHTML = this.getCommonCss(); | |||||
document.body.appendChild(elem); | |||||
} | |||||
}, | |||||
/* 检查并补全隐藏元素的class */ | |||||
checkHideClass() { | |||||
document.getElementsByClassName(this.hideNoneClass).forEach(elem => { | |||||
elem.classList.add(this.hideClass); | |||||
}); | |||||
}, | |||||
/* 显示加载层 */ | |||||
showLoading() { | |||||
this.addCommonCss(); | |||||
let elem = document.getElementById('ele-printer-loading'); | |||||
if (!elem) { | |||||
elem = document.createElement('div'); | |||||
elem.id = 'ele-printer-loading'; | |||||
document.body.appendChild(elem); | |||||
} | |||||
elem.style.display = 'block'; | |||||
window.hideElePrinterLoading = () => { | |||||
this.hideLoading(); | |||||
}; | |||||
return elem; | |||||
}, | |||||
/* 关闭加载层 */ | |||||
hideLoading() { | |||||
setTimeout(() => { | |||||
let elem = document.getElementById('ele-printer-loading'); | |||||
if (elem) elem.style.display = 'none'; | |||||
}, 1500); | |||||
}, | |||||
/* 添加回调监听 */ | |||||
addCallback(before, done) { | |||||
let taskId = 'p' + this.uuid(); | |||||
if (!window.elePrinterBefore) window.elePrinterBefore = {}; | |||||
if (!window.elePrinterDone) window.elePrinterDone = {}; | |||||
if (before) window.elePrinterBefore[taskId] = before; | |||||
if (done) window.elePrinterDone[taskId] = done; | |||||
let beforeJs = `;parent.elePrinterBefore&&parent.elePrinterBefore.${taskId}&&parent.elePrinterBefore.${taskId}();`; | |||||
let doneJs = `;parent.elePrinterDone&&parent.elePrinterDone.${taskId}&&parent.elePrinterDone.${taskId}();`; | |||||
return {taskId, beforeJs, doneJs}; | |||||
}, | |||||
/* 生成随机id */ | |||||
uuid(length = 8) { | |||||
const num = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; | |||||
let str = 'p_'; | |||||
for (let i = 0; i < length; i++) str += num.charAt(Math.floor(Math.random() * num.length)); | |||||
return str; | |||||
}, | |||||
/* 是否是ie */ | |||||
isIE() { | |||||
return !!window.ActiveXObject || 'ActiveXObject' in window; | |||||
}, | |||||
/* 是否是Edge */ | |||||
isEdge() { | |||||
return navigator.userAgent.indexOf('Edge') !== -1; | |||||
}, | |||||
/* 是否是Firefox */ | |||||
isFirefox() { | |||||
return navigator.userAgent.indexOf('Firefox') !== -1; | |||||
}, | |||||
// 支持ie打印预览控件 | |||||
ieWebBrowser: '<object id="WebBrowser" classid="clsid:8856F961-340A-11D0-A96B-00C04FD705A2" width="0" height="0"></object>', | |||||
pFrameId: 'ele-printer-frame', // 当前窗口打印隐藏的iframe的id | |||||
pStyleId: 'ele-printer-style', // 打印核心样式的style的id | |||||
pSetId: 'ele-printer-set', // 打印方向设置的style的id | |||||
printingClass: 'ele-printer-printing', // 正在打印标识的class | |||||
hideClass: 'ele-printer-hide', // 打印时隐藏的class | |||||
hideNoneClass: 'ele-printer-hide-none' // 打印时隐藏不占位置的class | |||||
} |
import axios from "axios" | |||||
import service from "@/config/service" | |||||
import { | |||||
OSM, | |||||
ImageArcGISRest, | |||||
XYZ, | |||||
TileArcGISRest, | |||||
Vector as VectorSource, | |||||
ImageWMS, | |||||
TileWMS, | |||||
} from "ol/source"; | |||||
import { | |||||
Tile as TileLayer, | |||||
Image as ImageLayer, | |||||
Vector as VectorLayer, | |||||
} from "ol/layer"; | |||||
import TileGrid from "ol/tilegrid/TileGrid"; | |||||
import WMSGetFeatureInfo from "ol/format/WMSGetFeatureInfo"; | |||||
import GeoJSON from "ol/format/GeoJSON"; | |||||
import { WFS } from "ol/format" | |||||
import { Fill, Stroke, Style, Circle, Icon } from "ol/style"; | |||||
export function getService(type, params) { | |||||
let url = service[type]; | |||||
if (type == 'tms') { | |||||
return axios.get(url + "?f=pjson").then(res => { | |||||
let data = res.data | |||||
console.log(data) | |||||
let extent = [data.fullExtent.xmin, data.fullExtent.ymin, data.fullExtent.xmax, data.fullExtent.ymax] | |||||
let origin = [data.tileInfo.origin.x, data.tileInfo.origin.y]; | |||||
let resolutions = []; | |||||
data.tileInfo.lods.forEach(item => { | |||||
resolutions.push(item.resolution) | |||||
}) | |||||
let tileGrid = new TileGrid({ | |||||
tileSize: data.tileInfo.rows, | |||||
resolutions, | |||||
origin, | |||||
extent | |||||
}) | |||||
let source = new XYZ({ // 切片服务 | |||||
crossOrigin: "Anonymous", | |||||
tileUrlFunction: function (coordinate) { | |||||
return ( | |||||
url + '/tile' + | |||||
coordinate[0] + | |||||
"/" + | |||||
coordinate[2] + | |||||
"/" + | |||||
coordinate[1] | |||||
); | |||||
}, | |||||
tileGrid: tileGrid, | |||||
}); | |||||
let layer = new TileLayer({ | |||||
maxZoom: 13, | |||||
source, | |||||
}) | |||||
return { layer } | |||||
}) | |||||
} else if (type == 'wfs') { // 矢量图层 | |||||
let style = params.style || new Style({ | |||||
fill: new Fill({ | |||||
color: "rgba(1 ,145, 255,0.8)" | |||||
}), | |||||
circle: new Circle({ | |||||
fill: new Fill({ | |||||
color: 'red', | |||||
}), | |||||
radius: 10000, | |||||
stroke: new Stroke({ | |||||
color: "blue" | |||||
}) | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: "red" | |||||
}), | |||||
}) | |||||
let source = new VectorSource(); | |||||
let layer = new VectorLayer({ | |||||
source, | |||||
style, | |||||
opacity: params.opacity || 1 | |||||
}); | |||||
var featureRequest = new WFS().writeGetFeature({ | |||||
srsName: "EPSG:3857", // 坐标系 | |||||
featureNS: "http://192.168.1.82:8888//demo", // 命名空间 | |||||
featurePrefix: "demo", // 工作区 | |||||
featureTypes: params.layers, // 图层 | |||||
outputFormat: "application/json", // 输出格式 | |||||
filter: params.filter || null // 过滤条件 | |||||
}) | |||||
return fetch(url, { | |||||
body: new XMLSerializer().serializeToString(featureRequest), | |||||
method: "POST" | |||||
}).then(res => { | |||||
return res.json() | |||||
}).then(res => { | |||||
let features = new GeoJSON().readFeatures(res) | |||||
source.addFeatures(features); | |||||
return { features, layer } | |||||
}) | |||||
} else if (type == 'ImageArcGIS') { // 反演图层 | |||||
return new Promise((resolve, reject) => { | |||||
let source = new ImageArcGISRest({ | |||||
ratio: 1, | |||||
url, | |||||
params: { // 设置显示的图层 | |||||
layers: "show:" + params.layers | |||||
} | |||||
}) | |||||
let layer = new ImageLayer({ | |||||
opacity: 0.8, | |||||
source: source, | |||||
visible: true, | |||||
}); | |||||
resolve({ layer }) | |||||
}) | |||||
} | |||||
} |
/** | |||||
* 常用工具方法 License By http://eleadmin.com | |||||
*/ | |||||
export default { | |||||
/** | |||||
* 倒计时 | |||||
* @param endTime 结束时间 | |||||
* @param serverTime 服务端当前时间 | |||||
* @param callback 回调 | |||||
* @returns {number} 定时器实例 | |||||
*/ | |||||
countdown(endTime, serverTime, callback) { | |||||
let type = typeof serverTime === 'function', end = new Date(endTime).getTime(), | |||||
now = new Date((!serverTime || type) ? new Date().getTime() : serverTime).getTime(), | |||||
count = end - now, time = [ | |||||
Math.floor(count / (1000 * 60 * 60 * 24)), // 天 | |||||
Math.floor(count / (1000 * 60 * 60)) % 24, // 时 | |||||
Math.floor(count / (1000 * 60)) % 60, // 分 | |||||
Math.floor(count / 1000) % 60 // 秒 | |||||
]; | |||||
if (type) callback = serverTime; | |||||
let timer = setTimeout(() => { | |||||
this.countdown(endTime, now + 1000, callback); | |||||
}, 1000); | |||||
callback && callback(count > 0 ? time : [0, 0, 0, 0], serverTime, timer); | |||||
if (count <= 0) clearTimeout(timer); | |||||
return timer; | |||||
}, | |||||
/** | |||||
* 某个时间在当前时间的多久前 | |||||
* @param time 需要语义化的时间 | |||||
* @param onlyDate 超过30天是否仅返回日期 | |||||
* @returns {string} 语义化后的时间 | |||||
*/ | |||||
timeAgo(time, onlyDate) { | |||||
if (!time) return ''; | |||||
if (typeof time === 'string') time = time.replace(/-/g, '/'); | |||||
let arr = [[], []], stamp = new Date().getTime() - new Date(time).getTime(); | |||||
// 30天以上返回具体日期 | |||||
if (stamp > 1000 * 60 * 60 * 24 * 31) { | |||||
stamp = new Date(time); | |||||
arr[0][0] = this.digit(stamp.getFullYear(), 4); | |||||
arr[0][1] = this.digit(stamp.getMonth() + 1); | |||||
arr[0][2] = this.digit(stamp.getDate()); | |||||
if (!onlyDate) { // 是否输出时间 | |||||
arr[1][0] = this.digit(stamp.getHours()); | |||||
arr[1][1] = this.digit(stamp.getMinutes()); | |||||
arr[1][2] = this.digit(stamp.getSeconds()); | |||||
} | |||||
return arr[0].join('-') + ' ' + arr[1].join(':'); | |||||
} | |||||
// 30天以内,返回“多久前” | |||||
if (stamp >= 1000 * 60 * 60 * 24) { | |||||
return ((stamp / 1000 / 60 / 60 / 24) | 0) + '天前'; | |||||
} else if (stamp >= 1000 * 60 * 60) { | |||||
return ((stamp / 1000 / 60 / 60) | 0) + '小时前'; | |||||
} else if (stamp >= 1000 * 60 * 3) { // 3分钟以内为:刚刚 | |||||
return ((stamp / 1000 / 60) | 0) + '分钟前'; | |||||
} else if (stamp < 0) { | |||||
return '未来'; | |||||
} else { | |||||
return '刚刚'; | |||||
} | |||||
}, | |||||
/** | |||||
* 数字前置补零 | |||||
* @param num 数字 | |||||
* @param length 位数 | |||||
* @returns {string} | |||||
*/ | |||||
digit(num, length) { | |||||
let str = ''; | |||||
num = String(num); | |||||
length = length || 2; | |||||
for (let i = num.length; i < length; i++) str += '0'; | |||||
return num < Math.pow(10, length) ? str + (num | 0) : num; | |||||
}, | |||||
/** | |||||
* 转化为日期格式字符 | |||||
* @param time 时间 | |||||
* @param format 格式 | |||||
* @returns {string} | |||||
*/ | |||||
toDateString(time, format) { | |||||
if (!time) return ''; | |||||
if (typeof time === 'string') time = time.replace(/-/g, '/'); | |||||
let date = new Date(time || new Date()), | |||||
ymd = [ | |||||
this.digit(date.getFullYear(), 4), | |||||
this.digit(date.getMonth() + 1), | |||||
this.digit(date.getDate()) | |||||
], | |||||
hms = [ | |||||
this.digit(date.getHours()), | |||||
this.digit(date.getMinutes()), | |||||
this.digit(date.getSeconds()) | |||||
]; | |||||
format = format || 'yyyy-MM-dd HH:mm:ss'; | |||||
return format.replace(/yyyy/g, ymd[0]) | |||||
.replace(/MM/g, ymd[1]) | |||||
.replace(/dd/g, ymd[2]) | |||||
.replace(/HH/g, hms[0]) | |||||
.replace(/mm/g, hms[1]) | |||||
.replace(/ss/g, hms[2]); | |||||
}, | |||||
/** | |||||
* html转义, 防止xss攻击 | |||||
* @param html 需要转义的字符串 | |||||
* @returns {string} | |||||
*/ | |||||
escape(html) { | |||||
return String(html || '').replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&') | |||||
.replace(/</g, '<').replace(/>/g, '>') | |||||
.replace(/'/g, ''').replace(/"/g, '"'); | |||||
}, | |||||
/** | |||||
* pid形式数据转children形式 | |||||
* @param data 需要转换的数组 | |||||
* @param idKey id字段名 | |||||
* @param pidKey pid字段名 | |||||
* @param childKey 生成的children字段名 | |||||
* @param pid 顶级的pid | |||||
* @returns {[]} | |||||
*/ | |||||
toTreeData(data, idKey, pidKey, childKey, pid) { | |||||
if (!childKey) childKey = 'children'; | |||||
if (pid === undefined) { | |||||
pid = []; | |||||
data.forEach(d => { | |||||
let flag = true; | |||||
for (let i = 0; i < data.length; i++) { | |||||
if (d[pidKey] == data[i][idKey]) { | |||||
flag = false; | |||||
break; | |||||
} | |||||
} | |||||
if (flag) pid.push(d[pidKey]); | |||||
}); | |||||
} | |||||
let result = []; | |||||
data.forEach(d => { | |||||
if (d[idKey] == d[pidKey]) return console.error('data error: ', d); | |||||
if (Array.isArray(pid) ? (pid.indexOf(d[pidKey]) !== -1) : (d[pidKey] == pid)) { | |||||
let children = this.toTreeData(data, idKey, pidKey, childKey, d[idKey]); | |||||
if (children.length > 0) d[childKey] = children; | |||||
result.push(d); | |||||
} | |||||
}); | |||||
return result; | |||||
}, | |||||
/** | |||||
* 遍历children形式数据 | |||||
* @param data 需要遍历的数组 | |||||
* @param callback 回调 | |||||
* @param childKey children字段名 | |||||
*/ | |||||
eachTreeData(data, callback, childKey) { | |||||
if (!childKey) childKey = 'children'; | |||||
data.forEach(d => { | |||||
if (callback(d) !== false && d[childKey]) this.eachTreeData(d[childKey], callback, childKey); | |||||
}); | |||||
}, | |||||
/** | |||||
* 让浏览器全屏切换 | |||||
* @returns {Element|*|boolean} 是否是全屏状态 | |||||
*/ | |||||
fullScreen() { | |||||
let isFull = document.fullscreenElement || document.msFullscreenElement || document.mozFullScreenElement | |||||
|| document.webkitFullscreenElement || false; | |||||
if (isFull) { | |||||
let efs = document.exitFullscreen || document.webkitExitFullscreen || document.mozCancelFullScreen | |||||
|| document.msExitFullscreen; | |||||
if (efs) { | |||||
efs.call(document); | |||||
} else if (window.ActiveXObject) { | |||||
let ws = new window.ActiveXObject('WScript.Shell'); | |||||
ws && ws.SendKeys('{F11}'); | |||||
} | |||||
} else { | |||||
let el = document.documentElement; | |||||
let rfs = el.requestFullscreen || el.webkitRequestFullscreen || el.mozRequestFullScreen | |||||
|| el.msRequestFullscreen; | |||||
if (rfs) { | |||||
rfs.call(el); | |||||
} else if (window.ActiveXObject) { | |||||
let wss = new window.ActiveXObject('WScript.Shell'); | |||||
wss && wss.SendKeys('{F11}'); | |||||
} | |||||
} | |||||
return isFull; | |||||
}, | |||||
/** | |||||
* 获取屏幕宽度 | |||||
* @returns {number} | |||||
*/ | |||||
screenWidth() { | |||||
return document.documentElement.clientWidth || document.body.clientWidth; | |||||
}, | |||||
/** | |||||
* 获取屏幕高度 | |||||
* @returns {number} | |||||
*/ | |||||
screenHeight() { | |||||
return document.documentElement.clientHeight || document.body.clientHeight; | |||||
}, | |||||
/** | |||||
* html转text, 获取html的纯文本 | |||||
* @param html | |||||
* @returns {*} | |||||
*/ | |||||
htmlToText(html) { | |||||
/*let elem = document.createElement('div'); | |||||
elem.innerHTML = html; | |||||
return elem.innerText;*/ | |||||
return html.replace(/<[^>]+>/g, ''); | |||||
}, | |||||
/** | |||||
* 获取设备信息 | |||||
* @param key 自定义的agent | |||||
* @returns {{weixin: *, os: (string|undefined), ie: boolean}} | |||||
*/ | |||||
device(key) { | |||||
let agent = navigator.userAgent.toLowerCase(), | |||||
// 获取版本号 | |||||
getVersion = function (label) { | |||||
const exp = new RegExp(label + '/([^\\s\\_\\-]+)'); | |||||
label = (agent.match(exp) || [])[1]; | |||||
return label || false; | |||||
}, | |||||
// 返回结果集 | |||||
result = { | |||||
os: function () { // 底层操作系统 | |||||
if (/windows/.test(agent)) { | |||||
return 'windows'; | |||||
} else if (/linux/.test(agent)) { | |||||
return 'linux'; | |||||
} else if (/iphone|ipod|ipad|ios/.test(agent)) { | |||||
return 'ios'; | |||||
} else if (/mac/.test(agent)) { | |||||
return 'mac'; | |||||
} else if (/android/.test(agent)) { | |||||
return 'android'; | |||||
} | |||||
}(), | |||||
ie: function () { // ie版本 | |||||
return (!!window.ActiveXObject || 'ActiveXObject' in window) ? ( | |||||
(agent.match(/msie\s(\d+)/) || [])[1] || '11' // 由于ie11并没有msie的标识 | |||||
) : false; | |||||
}(), | |||||
weixin: getVersion('micromessenger') // 是否微信 | |||||
}; | |||||
// 任意的key | |||||
if (key && !result[key]) { | |||||
result[key] = getVersion(key); | |||||
} | |||||
// 移动设备 | |||||
result.android = /android/.test(agent); | |||||
result.ios = result.os === 'ios'; | |||||
result.mobile = (result.android || result.ios) ? true : false; | |||||
return result; | |||||
}, | |||||
/** | |||||
* 生成随机id | |||||
* @param length 长度 | |||||
* @returns {string} | |||||
*/ | |||||
uuid(length = 32) { | |||||
const num = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; | |||||
let str = ''; | |||||
for (let i = 0; i < length; i++) { | |||||
str += num.charAt(Math.floor(Math.random() * num.length)); | |||||
} | |||||
return str; | |||||
}, | |||||
/** | |||||
* 生成m到n的随机数,不包含n | |||||
* @param m 最小值 | |||||
* @param n 最大值 | |||||
* @returns {number} | |||||
*/ | |||||
random(m, n) { | |||||
return Math.floor(Math.random() * (m - n) + n); | |||||
}, | |||||
/** | |||||
* 百度地图坐标转高德地图坐标 | |||||
* @param point 坐标 | |||||
* @returns {{lng: number, lat: number}} | |||||
*/ | |||||
bd09ToGcj02: function (point) { | |||||
const x_pi = (3.14159265358979324 * 3000.0) / 180.0; | |||||
const x = point.lng - 0.0065, y = point.lat - 0.006; | |||||
const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi); | |||||
const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi); | |||||
return {lng: z * Math.cos(theta), lat: z * Math.sin(theta)}; | |||||
}, | |||||
/** | |||||
* 高德地图坐标转百度地图坐标 | |||||
* @param point 坐标 | |||||
* @returns {{lng: number, lat: number}} | |||||
*/ | |||||
gcj02ToBd09: function (point) { | |||||
const x_pi = (3.14159265358979324 * 3000.0) / 180.0; | |||||
const x = point.lng, y = point.lat; | |||||
const z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * x_pi); | |||||
const theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * x_pi); | |||||
return {lng: z * Math.cos(theta) + 0.0065, lat: z * Math.sin(theta) + 0.006}; | |||||
}, | |||||
/** | |||||
* 深度克隆对象 | |||||
* @param obj | |||||
* @returns {{}|*} | |||||
*/ | |||||
deepClone: function (obj) { | |||||
let result; | |||||
const type = this.typeOf(obj); | |||||
if (type === 'Object') result = {}; | |||||
else if (type === 'Array') result = []; | |||||
else return obj; | |||||
Object.keys(obj).forEach(key => { | |||||
const copy = obj[key], cType = this.typeOf(copy); | |||||
if (cType === 'Object' || cType === 'Array') result[key] = this.deepClone(copy); | |||||
else result[key] = obj[key]; | |||||
}); | |||||
return result; | |||||
}, | |||||
/** | |||||
* 获取变量类型 | |||||
* @param obj | |||||
* @returns {string} | |||||
*/ | |||||
typeOf(obj) { | |||||
if (obj === null) return 'Null'; | |||||
if (obj === undefined) return 'Undefined'; | |||||
return Object.prototype.toString.call(obj).slice(8, -1); | |||||
}, | |||||
/** | |||||
* 播放音频 | |||||
* @param url 音频地址 | |||||
*/ | |||||
play(url) { | |||||
return new Audio(url).play(); | |||||
}, | |||||
/** | |||||
* 判断富文本是否为空 | |||||
* @param html | |||||
*/ | |||||
htmlIsBlank(html) { | |||||
if (!html) return true; | |||||
const media = ['img', 'audio', 'video', 'iframe', 'object']; | |||||
for (let i = 0; i < media.length; i++) { | |||||
if (html.indexOf('<' + media[i]) > -1) return false; | |||||
} | |||||
let str = html.replace(/\s*/g, ''); // 去掉所有空格 | |||||
if (!str) return true; | |||||
str = str.replace(/ /ig, ''); // 去掉所有 | |||||
if (!str) return true; | |||||
str = str.replace(/<[^>]+>/g, ''); // 去掉所有html标签 | |||||
return !str; | |||||
}, | |||||
/** | |||||
* 导出excel | |||||
* @param XLSX XLSX对象 | |||||
* @param sheet 数组或sheet对象 | |||||
* @param sheetname 文件名称 | |||||
* @param type 文件格式 | |||||
*/ | |||||
exportSheet(XLSX, sheet, sheetname, type) { | |||||
if (!sheetname) sheetname = 'sheet1'; | |||||
if (!type) type = 'xlsx'; | |||||
if (Array.isArray(sheet)) sheet = XLSX.utils.aoa_to_sheet(sheet); | |||||
let workbook = {SheetNames: [sheetname], Sheets: {}}; | |||||
workbook.Sheets[sheetname] = sheet; | |||||
XLSX.writeFile(workbook, sheetname + '.' + type); | |||||
}, | |||||
/** | |||||
* 常用颜色 | |||||
*/ | |||||
beautifulColors: [ | |||||
'rgb(24,144,255)', 'rgb(102,181,255)', 'rgb(65, 217, 199)', 'rgb(47, 194, 91)', | |||||
'rgb(110, 219, 143)', 'rgb(154, 230, 92)', 'rgb(250, 204, 20)', 'rgb(230, 150, 92)', | |||||
'rgb(87, 173, 113)', 'rgb(34, 50, 115)', 'rgb(115, 138, 230)', 'rgb(117, 100, 204)', | |||||
'rgb(133, 67, 224)', 'rgb(168, 119, 237)', 'rgb(92, 142, 230)', 'rgb(19, 194, 194)', | |||||
'rgb(112, 224, 224)', 'rgb(92, 163, 230)', 'rgb(52, 54, 199)', 'rgb(128, 130, 255)', | |||||
'rgb(221, 129, 230)', 'rgb(240, 72, 100)', 'rgb(250, 125, 146)', 'rgb(213, 152, 217)' | |||||
] | |||||
} |
/** | |||||
* 格式校验工具方法 License By http://eleadmin.com | |||||
*/ | |||||
export default { | |||||
/* 是否是手机号 */ | |||||
isPhone(value) { | |||||
const reg = /^1\d{10}$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否为固话 */ | |||||
isTel(value) { | |||||
const reg = /^(400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))?$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是邮箱 */ | |||||
isEmail(value) { | |||||
const reg = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+\.)+([a-zA-Z0-9]{2,4})+$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是网址 */ | |||||
isUrl(value) { | |||||
const reg = /(^#)|(^http(s*):\/\/[^\s]+\.[^\s]+)/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是数字 */ | |||||
isNumber(value) { | |||||
/*const reg = /^1\d{10}$/; | |||||
return reg.test(value);*/ | |||||
return !isNaN(value); | |||||
}, | |||||
/* 是否是日期 */ | |||||
isDate(value) { | |||||
const reg = /^(\d{4})[-/](\d{1}|0\d{1}|1[0-2])([-/](\d{1}|0\d{1}|[1-2][0-9]|3[0-1]))*$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是身份证 */ | |||||
isIdentity(value) { | |||||
const reg = /(^\d{15}$)|(^\d{17}(x|X|\d)$)/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是整数 */ | |||||
isDigits(value) { | |||||
const reg = /^-?\d+$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是正整数 */ | |||||
isDigitsP(value) { | |||||
const reg = /^[1-9]\d*$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是负整数 */ | |||||
isDigitsN(value) { | |||||
const reg = /^-[1-9]\d*$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是非负整数(正整数或0) */ | |||||
isDigitsPZ(value) { | |||||
const reg = /^\d+$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是非正整数(负整数或0) */ | |||||
isDigitsNZ(value) { | |||||
const reg = /^-[1-9]\d*|0/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 验证最小长度、最大长度 */ | |||||
maxMinLength(value, minLength, maxLength) { | |||||
if (value === undefined || value === null) return !minLength; | |||||
if (minLength && value.toString().length < minLength) return false; | |||||
return !(maxLength !== undefined && maxLength !== null && value.toString().length > maxLength); | |||||
}, | |||||
/* 验证最小值、最大值 */ | |||||
maxMin(value, min, max) { | |||||
if (value === undefined || value === null) return min === undefined || min === null; | |||||
if (min !== undefined && min !== null && value < min) return false; | |||||
return !(max !== undefined && max !== null && value > max); | |||||
}, | |||||
/* 是否是中文 */ | |||||
isChina(value) { | |||||
const reg = /^[\u4E00-\u9FA5]{2,4}$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是端口号 */ | |||||
isPort(value) { | |||||
const reg = /^([0-9]|[1-9]\d|[1-9]\d{2}|[1-9]\d{3}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是IP */ | |||||
isIP(value) { | |||||
const reg = /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是经度 -180.0~+180.0(整数部分为0~180,必须输入1到5位小数) */ | |||||
isLongitude(value) { | |||||
const reg = /^[-|+]?(0?\d{1,2}\.\d{1,5}|1[0-7]?\d{1}\.\d{1,5}|180\.0{1,5})$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是纬度 -90.0~+90.0(整数部分为0~90,必须输入1到5位小数) */ | |||||
isLatitude(value) { | |||||
const reg = /^[-|+]?([0-8]?\d{1}\.\d{1,5}|90\.0{1,5})$/; | |||||
return reg.test(value); | |||||
}, | |||||
/* 是否是身份证(强校验) */ | |||||
isIdentityStrong(value) { | |||||
if (!this.isIdentity(value)) return '身份证号码格式错误'; | |||||
const ai = value.length === 18 ? value.substring(0, 17) : (value.substring(0, 6) + '19' + value.substring(6, 15)); | |||||
// 验证出生年月 | |||||
const year = ai.substring(6, 10); // 年 | |||||
const birthday = year + '/' + ai.substring(10, 12) + '/' + ai.substring(12, 14); | |||||
if (!this.isDate(birthday)) return '身份证号码出生日期无效'; | |||||
const now = new Date(); | |||||
if ((now.getFullYear() - parseInt(year)) > 150 || (now.getTime() - new Date(birthday).getTime()) < 0) | |||||
return '身份证号码出生日期不在有效范围'; | |||||
// 验证地区码 | |||||
const areaCodes = ['11', '12', '13', '14', '15', '21', '22', '23', | |||||
'31', '32', '33', '34', '35', '36', '37', '41', '42', '43', '44', '45', '46', | |||||
'50', '51', '52', '53', '54', '61', '62', '63', '64', '65', '71', '81', '82', '91']; | |||||
if (areaCodes.indexOf(ai.substring(0, 2)) === -1) return '身份证号码地区编码错误'; | |||||
// 验证最后一位 | |||||
if (value.length === 18) { | |||||
const valCode = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; | |||||
const wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; | |||||
let totalMulAiWi = 0; | |||||
for (let i = 0; i < 17; i++) totalMulAiWi += parseInt(ai.charAt(i)) * wi[i]; | |||||
if (value !== (ai + valCode[totalMulAiWi % 11])) return '身份证号码最后一位错误'; | |||||
} | |||||
} | |||||
} |
import WMSGetFeatureInfo from "ol/format/WMSGetFeatureInfo"; | import WMSGetFeatureInfo from "ol/format/WMSGetFeatureInfo"; | ||||
// 全屏 | // 全屏 | ||||
import { FullScreen } from "ol/control"; | import { FullScreen } from "ol/control"; | ||||
import { getService } from "@/utils/service"; | |||||
axios.defaults.baseURL = process.env.VUE_APP_BASE_URL; | axios.defaults.baseURL = process.env.VUE_APP_BASE_URL; | ||||
export default { | export default { | ||||
name: "gisdemo-index", | name: "gisdemo-index", | ||||
}); | }); | ||||
}, | }, | ||||
mounted() { | mounted() { | ||||
// 南京市水系图 | |||||
getService("wfs", { | |||||
// filter: equalToFilter("admincode", "320100"), | |||||
layers: ["rivers"], | |||||
style: new Style({ | |||||
fill: new Stroke({ | |||||
color: "#2495A2", | |||||
}), | |||||
}), | |||||
opacity: 0.8 | |||||
}).then((res) => { | |||||
let { layer } = res; | |||||
this.map.addLayer(layer); | |||||
}); | |||||
// 排口数据 | // 排口数据 | ||||
let adrainage = new VectorSource({}); | let adrainage = new VectorSource({}); | ||||
axios | axios |