Explorar el Código

添加水系

jiexi1_1
YF-yuan hace 3 años
padre
commit
1cd74d43db
Se han modificado 15 ficheros con 12465 adiciones y 0 borrados
  1. BIN
      src/assets/img/gisdemo/top.png
  2. +50
    -0
      src/config/axios.js
  3. +59
    -0
      src/config/plugins.js
  4. +5
    -0
      src/config/service.js
  5. +39
    -0
      src/config/setting.js
  6. +10617
    -0
      src/utils/cityData.js
  7. +64
    -0
      src/utils/fullScreen.js
  8. +285
    -0
      src/utils/length.js
  9. +4
    -0
      src/utils/myCharts.js
  10. +104
    -0
      src/utils/permission.js
  11. +587
    -0
      src/utils/printer.js
  12. +122
    -0
      src/utils/service.js
  13. +386
    -0
      src/utils/util.js
  14. +128
    -0
      src/utils/validate.js
  15. +15
    -0
      src/views/Home.vue

BIN
src/assets/img/gisdemo/top.png Ver fichero

Antes Después
Anchura: 1920  |  Altura: 70  |  Tamaño: 14KB Anchura: 1904  |  Altura: 70  |  Tamaño: 19KB

+ 50
- 0
src/config/axios.js Ver fichero

@@ -0,0 +1,50 @@
/**
* 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

+ 59
- 0
src/config/plugins.js Ver fichero

@@ -0,0 +1,59 @@
/**
* 引用框架
*/
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);
});

+ 5
- 0
src/config/service.js Ver fichero

@@ -0,0 +1,5 @@
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"
}

+ 39
- 0
src/config/setting.js Ver fichero

@@ -0,0 +1,39 @@
/**
* 项目统一配置
*/
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 // 侧边栏是否只保持一个子菜单展开
}

+ 10617
- 0
src/utils/cityData.js
La diferencia del archivo ha sido suprimido porque es demasiado grande
Ver fichero


+ 64
- 0
src/utils/fullScreen.js Ver fichero

@@ -0,0 +1,64 @@
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();
}
}
}
}
}

+ 285
- 0
src/utils/length.js Ver fichero

@@ -0,0 +1,285 @@
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
}

+ 4
- 0
src/utils/myCharts.js Ver fichero

@@ -0,0 +1,4 @@
import echarts from 'echarts'
export default {
}

+ 104
- 0
src/utils/permission.js Ver fichero

@@ -0,0 +1,104 @@
/**
* 角色权限控制组件 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;
}
}

+ 587
- 0
src/utils/printer.js Ver fichero

@@ -0,0 +1,587 @@
/**
* 打印插件 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
}

+ 122
- 0
src/utils/service.js Ver fichero

@@ -0,0 +1,122 @@
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 })
})
}

}

+ 386
- 0
src/utils/util.js Ver fichero

@@ -0,0 +1,386 @@
/**
* 常用工具方法 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, '&amp;')
.replace(/</g, '&lt;').replace(/>/g, '&gt;')
.replace(/'/g, '&#39;').replace(/"/g, '&quot;');
},
/**
* 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(/&nbsp;/ig, ''); // 去掉所有&nbsp;
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)'
]
}

+ 128
- 0
src/utils/validate.js Ver fichero

@@ -0,0 +1,128 @@
/**
* 格式校验工具方法 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 '身份证号码最后一位错误';
}
}
}

+ 15
- 0
src/views/Home.vue Ver fichero

@@ -234,6 +234,7 @@ import LandUse from "./leftCompoents/landUse.vue";
import WMSGetFeatureInfo from "ol/format/WMSGetFeatureInfo";
// 全屏
import { FullScreen } from "ol/control";
import { getService } from "@/utils/service";
axios.defaults.baseURL = process.env.VUE_APP_BASE_URL;
export default {
name: "gisdemo-index",
@@ -472,6 +473,20 @@ export default {
});
},
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({});
axios

Cargando…
Cancelar
Guardar