Автор | SHA1 | Съобщение | Дата |
---|---|---|---|
|
dac4df1580 | 资金支出分析 | преди 2 дни |
|
c9493b9b97 | 饼图和线图 | преди 2 дни |
|
84eb6adbd5 | 滚动图标封装 | преди 2 дни |
|
f2a4491d45 | 货币资金分析 | преди 3 дни |
|
f607bfa181 | 组件布局 | преди 3 дни |
|
f91cb02b7f | 项目初始化 | преди 3 дни |
@@ -0,0 +1,7 @@ | |||||
rongxin_credit_expo.js | |||||
/utils | |||||
/config | |||||
/routes | |||||
/services | |||||
/src/assets | |||||
/loader |
@@ -0,0 +1,35 @@ | |||||
module.exports = { | |||||
root: true, | |||||
parserOptions: { | |||||
parser: "babel-eslint", | |||||
}, | |||||
env: { | |||||
browser: true, | |||||
}, | |||||
extends: ["plugin:vue/essential"], | |||||
// required to lint *.vue files | |||||
plugins: ["vue"], | |||||
// add your custom rules here | |||||
rules: { | |||||
// quotes: [2, "single"], | |||||
// "default-case": "error", | |||||
// semi: [2, "always"], // 语句强制分号结尾 | |||||
// "key-spacing": [1, { beforeColon: false, afterColon: true }], // 对象字面量中冒号的前后空格 | |||||
// "no-multiple-empty-lines": [1, { max: 1 }], // 空行最多不能超过2行 | |||||
// "no-dupe-keys": 2, // 在创建对象字面量时不允许键重复 {a:1,a:1} | |||||
// "no-spaced-func": 2, // 函数调用时 函数名与()之间不能有空格 | |||||
// "no-trailing-spaces": 1, // 一行结束后面不要有空格 | |||||
// "no-unreachable": 2, // 不能有无法执行的代码 | |||||
// "no-unused-vars": [2, { vars: "all", args: "after-used" }], // 不能有声明后未被使用的变量或参数 | |||||
// "no-var": 0, // 禁用var,用let和const代替 | |||||
// "comma-dangle": [2, "never"], // 对象字面量项尾不能有逗号 | |||||
// "comma-spacing": 1, // 逗号前后的空格 | |||||
// "comma-style": [2, "last"], // 逗号风格,换行时在行首还是行尾 | |||||
// eqeqeq: 2, // 必须使用全等 | |||||
// indent: [2, 2], // 缩进风格 | |||||
// "spaced-comment": 1, // 注释风格要不要有空格 | |||||
// "eol-last": 2, // 文件以单一的换行符结束 | |||||
// "semi-spacing": [2, { before: false, after: true }], // 分号前后空格 | |||||
// "arrow-spacing": 2, // =>的前/后括号 | |||||
}, | |||||
}; |
@@ -0,0 +1,24 @@ | |||||
.DS_Store | |||||
node_modules | |||||
/dist | |||||
.editorconfig | |||||
output.js | |||||
package-lock.json | |||||
# local env files | |||||
.env.local | |||||
.env.*.local | |||||
# Log files | |||||
npm-debug.log* | |||||
yarn-debug.log* | |||||
yarn-error.log* | |||||
# Editor directories and files | |||||
.idea | |||||
.vscode | |||||
*.suo | |||||
*.ntvs* | |||||
*.njsproj | |||||
*.sln | |||||
*.sw? |
@@ -0,0 +1,3 @@ | |||||
module.exports = { | |||||
presets: ['@vue/app'] | |||||
}; |
@@ -0,0 +1,96 @@ | |||||
{ | |||||
"name": "rongxin.nongjing.expo", | |||||
"version": "0.1.0", | |||||
"private": true, | |||||
"scripts": { | |||||
"serve": "vue-cli-service serve --open", | |||||
"clean": "echo 'do nothing right now'", | |||||
"install": "npm update && npm rebuild", | |||||
"codegen": "echo 'do nothing right now'", | |||||
"build": "vue-cli-service build", | |||||
"clean:dev": "echo 'do nothing right now'", | |||||
"install:dev": "npm run install", | |||||
"codegen:dev": "echo 'do nothing right now'", | |||||
"build:dev": "npm run build", | |||||
"clean:test": "echo 'do nothing right now'", | |||||
"install:test": "npm run install", | |||||
"codegen:test": "echo 'do nothing right now'", | |||||
"build:test": "npm run build", | |||||
"clean:stage": "echo 'do nothing right now'", | |||||
"install:stage": "npm run install", | |||||
"codegen:stage": "echo 'do nothing right now'", | |||||
"build:stage": "npm run build", | |||||
"clean:prod": "echo 'do nothing right now'", | |||||
"install:prod": "npm run install", | |||||
"codegen:prod": "echo 'do nothing right now'", | |||||
"build:prod": "npm run build", | |||||
"lint": "vue-cli-service lint" | |||||
}, | |||||
"dependencies": { | |||||
"@antv/data-set": "0.11.1", | |||||
"@antv/g2": "3.5.9", | |||||
"@antv/g6": "2.1.3", | |||||
"@turf/turf": "^6.5.0", | |||||
"config": "1.30.0", | |||||
"connect-redis": "3.3.3", | |||||
"core-js": "3.19.1", | |||||
"d3-force": "1.1.2", | |||||
"echarts": "5.5.1", | |||||
"echarts-gl": "2.0.8", | |||||
"element-resize-detector": "1.2.4", | |||||
"element-ui": "2.13.0", | |||||
"ezuikit-js": "^0.6.1", | |||||
"jquery": "3.4.1", | |||||
"ol": "6.1.1", | |||||
"proj4": "2.5.0", | |||||
"v-scale-screen": "^1.0.2", | |||||
"vue": "2.6.10", | |||||
"vue-awesome-swiper": "3.1.3", | |||||
"vue-baidu-map": "0.21.22", | |||||
"vue-router": "3.0.6", | |||||
"vuex": "3.1.2", | |||||
"vuex-persist": "2.2.0" | |||||
}, | |||||
"devDependencies": { | |||||
"@vue/cli-plugin-babel": "4.0.0", | |||||
"@vue/cli-plugin-eslint": "4.0.0", | |||||
"@vue/cli-plugin-router": "4.0.0", | |||||
"@vue/cli-service": "4.0.0", | |||||
"@vue/eslint-config-standard": "4.0.0", | |||||
"axios": "0.19.0", | |||||
"babel-cli": "^6.26.0", | |||||
"babel-eslint": "10.0.1", | |||||
"babel-preset-es2015": "^6.24.1", | |||||
"eslint": "5.16.0", | |||||
"eslint-plugin-vue": "5.0.0", | |||||
"lodash.debounce": "4.0.8", | |||||
"node-sass": "^4.14.1", | |||||
"sass-loader": "8.0.0", | |||||
"vue-axios": "2.1.4", | |||||
"vue-seamless-scroll": "^1.1.23", | |||||
"vue-template-compiler": "2.6.10" | |||||
}, | |||||
"eslintConfig": { | |||||
"root": true, | |||||
"env": { | |||||
"node": true | |||||
}, | |||||
"extends": [ | |||||
"plugin:vue/essential", | |||||
"@vue/standard" | |||||
], | |||||
"rules": {}, | |||||
"parserOptions": { | |||||
"parser": "babel-eslint" | |||||
} | |||||
}, | |||||
"postcss": { | |||||
"plugins": { | |||||
"autoprefixer": {} | |||||
} | |||||
}, | |||||
"browserslist": [ | |||||
"> 1%", | |||||
"last 2 versions" | |||||
] | |||||
} |
@@ -0,0 +1,61 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="utf-8"> | |||||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||||
<meta name="viewport" content="width=device-width,initial-scale=0.8"> | |||||
<!-- <link rel="icon" href="./zyic.ico"> --> | |||||
<title>农村资源资产清查监管系统</title> | |||||
<script> | |||||
</script> | |||||
<style> | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<noscript> | |||||
<strong>We're sorry but mine doesn't work properly without JavaScript enabled. Please enable it to | |||||
continue.</strong> | |||||
</noscript> | |||||
<div id="app"></div> | |||||
<script> | |||||
</script> | |||||
<script id="vertexShader" type="x-shader/x-vertex"> | |||||
varying vec2 vUv; | |||||
attribute float percent; | |||||
uniform float u_time; | |||||
uniform float number; | |||||
uniform float speed; | |||||
uniform float length; | |||||
varying float opacity; | |||||
uniform float size; | |||||
void main() | |||||
{ | |||||
vUv = uv; | |||||
vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 ); | |||||
float l = clamp(1.0-length,0.0,1.0); | |||||
gl_PointSize = clamp(fract(percent*number + l - u_time*number*speed)-l ,0.0,1.) * size * (1./length); | |||||
opacity = gl_PointSize/size; | |||||
gl_Position = projectionMatrix * mvPosition; | |||||
} | |||||
</script> | |||||
<!-- fragment shader a.k.a. pixel shader --> | |||||
<script id="fragmentShader" type="x-shader/x-vertex"> | |||||
#ifdef GL_ES | |||||
precision mediump float; | |||||
#endif | |||||
varying float opacity; | |||||
uniform vec3 color; | |||||
void main(){ | |||||
if(opacity <=0.2){ | |||||
discard; | |||||
} | |||||
gl_FragColor = vec4(color,1.0); | |||||
} | |||||
</script> | |||||
<!-- built files will be auto injected --> | |||||
</body> | |||||
</html> |
@@ -0,0 +1,15 @@ | |||||
<template> | |||||
<v-scale-screen width="1920" height="1080"> | |||||
<div id="app"> | |||||
<router-view /> | |||||
</div> | |||||
</v-scale-screen> | |||||
</template> | |||||
<script> | |||||
export default { | |||||
}; | |||||
</script> | |||||
<style lang='scss' scoped> | |||||
</style> |
@@ -0,0 +1,130 @@ | |||||
import request from '@/utils/request'; | |||||
// 用户信息 | |||||
export function GetInfoByRole () { | |||||
return request({ | |||||
url: '/api/v1.0/admin/GetInfoByRole', | |||||
method: 'get', | |||||
}); | |||||
} | |||||
export function GetLayerInfoByAreaCode (query) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/area/selectOneAreaCode', | |||||
method: 'get', | |||||
params: query | |||||
}); | |||||
} | |||||
// 地区字典 | |||||
export function getAreaList (query) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/area/areaLevel', | |||||
method: 'get', | |||||
params: query | |||||
}); | |||||
} | |||||
// 保存承包人信息 | |||||
export function cbhtxx (params) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cbhtxx', | |||||
method: 'post', | |||||
data: { | |||||
...params | |||||
} | |||||
}); | |||||
} | |||||
// 保存地块基本信息 | |||||
export function cwdjbxx (params) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cwdjbxx', | |||||
method: 'post', | |||||
data: { | |||||
...params | |||||
} | |||||
}); | |||||
} | |||||
// 修改地块基本信息 | |||||
export function putcwdjbxx (params) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cwdjbxx', | |||||
method: 'put', | |||||
data: { | |||||
...params | |||||
} | |||||
}); | |||||
} | |||||
// 查询地块基本信息 | |||||
export function cwdjbxxinfo (id) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cwdjbxx/' + id, | |||||
method: 'get', | |||||
}); | |||||
} | |||||
// 查询承包人信息列表 | |||||
export function cbrxxList (query) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cbhtxx/list', | |||||
method: 'get', | |||||
params: query | |||||
}); | |||||
} | |||||
// 查询基本信息列表 | |||||
export function cwdjbxxList (query) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cwdjbxx/list', | |||||
method: 'get', | |||||
params: query | |||||
}); | |||||
} | |||||
// 删除承包人信息 | |||||
export function cbrxxdelete (id) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cbhtxx/' + id, | |||||
method: 'delete', | |||||
}); | |||||
} | |||||
// 查询承包人信息 | |||||
export function cbhtxxinfo (id) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cbhtxx/' + id, | |||||
method: 'get', | |||||
}); | |||||
} | |||||
// 修改承包人信息 | |||||
export function putcbhtxx (params) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/web/cbhtxx', | |||||
method: 'put', | |||||
data: { | |||||
...params | |||||
} | |||||
}); | |||||
} | |||||
// 字典 | |||||
export function dictdata (type) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/system/dict/data/type/' + type, | |||||
method: 'get', | |||||
}); | |||||
} | |||||
export function get (url, params) { | |||||
return request({ | |||||
url, | |||||
params: { | |||||
...params | |||||
} | |||||
}) | |||||
} | |||||
export function post (url, params) { | |||||
return request({ | |||||
headers: { | |||||
'Content-Type': 'application/xml' | |||||
}, | |||||
url, | |||||
method: 'post', | |||||
data: params | |||||
}) | |||||
} |
@@ -0,0 +1,13 @@ | |||||
import request from '@/utils/request'; | |||||
// 登录系统 | |||||
export function login (params) { | |||||
return request({ | |||||
url: '/api/v1.0/admin/login', | |||||
method: 'post', | |||||
data: { | |||||
...params | |||||
} | |||||
}); | |||||
} | |||||
@@ -0,0 +1,3 @@ | |||||
import Vue from 'vue'; | |||||
export const eventBus = new Vue(); |
@@ -0,0 +1,7 @@ | |||||
<div class="block"> | |||||
<img :src="data.icon" class="icon"> | |||||
<div class="right col"> | |||||
<p class="value">{{data.value}}</p> | |||||
<p class="name">{{data.name}}</p> | |||||
</div> | |||||
</div> |
@@ -0,0 +1,24 @@ | |||||
export default { | |||||
props: { | |||||
data: { | |||||
type: Object, | |||||
default: function () { | |||||
return { | |||||
name: '标题', | |||||
value: '值', | |||||
icon: require('./icon.png') | |||||
} | |||||
} | |||||
}, | |||||
}, | |||||
data () { | |||||
return { | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
methods: { | |||||
} | |||||
}; |
@@ -0,0 +1,30 @@ | |||||
.block { | |||||
display: block; | |||||
width: 100px; | |||||
height: 40px; | |||||
align-items: center; | |||||
display: flex; | |||||
.icon { | |||||
width: 80px; | |||||
height: 100px; | |||||
} | |||||
.right { | |||||
flex: 1; | |||||
display: flex; | |||||
flex-direction: column; | |||||
.value { | |||||
font-weight: bold; | |||||
font-size: 24px; | |||||
color: #FFFFFF; | |||||
text-shadow: 0px 3px 2px #05357D; | |||||
} | |||||
.name { | |||||
color: rgba(185, 211, 235, 1); | |||||
font-size: 12px; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1 @@ | |||||
<div :id="id" class="chart"></div> |
@@ -0,0 +1,184 @@ | |||||
import * as echarts from 'echarts'; | |||||
import elementResizeDetectorMaker from 'element-resize-detector'; | |||||
export default { | |||||
props: { | |||||
id: { | |||||
type: String, | |||||
default: 'line' | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: function () { | |||||
return [ | |||||
{ | |||||
name: '1月', | |||||
value: '10' | |||||
}, | |||||
{ | |||||
name: '2月', | |||||
value: '19' | |||||
} | |||||
]; | |||||
} | |||||
} | |||||
}, | |||||
data () { | |||||
return { | |||||
chart: null | |||||
}; | |||||
}, | |||||
mounted () { | |||||
this.initChart(); | |||||
}, | |||||
computed: { | |||||
}, | |||||
methods: { | |||||
// 设置监听器 页面尺寸变化重新绘制图表 | |||||
initResizeCallBack () { | |||||
const erd = elementResizeDetectorMaker(); | |||||
erd.listenTo(document.getElementById(this.id), () => { | |||||
this.$nextTick(() => { | |||||
this.chart.resize(); | |||||
}); | |||||
}); | |||||
}, | |||||
initChart () { | |||||
this.chart = echarts.init(document.getElementById(this.id)); | |||||
this.chartSetOption(); | |||||
}, | |||||
chartSetOption () { | |||||
let xAxisData = []; | |||||
let data = []; | |||||
this.data.forEach(item => { | |||||
xAxisData.push(item.name) | |||||
data.push(item.value) | |||||
}); | |||||
const option = { | |||||
grid: { | |||||
left: "5%", | |||||
right: "10%", | |||||
top: "15%", | |||||
bottom: "10%", | |||||
containLabel: true, | |||||
}, | |||||
tooltip: { | |||||
show: true, | |||||
trigger: "item", | |||||
}, | |||||
legend: { | |||||
show: false | |||||
}, | |||||
color: { | |||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [ | |||||
{ | |||||
offset: 1, | |||||
color: "rgba(134, 91, 252, 1)", | |||||
}, | |||||
{ | |||||
offset: 0.5, | |||||
color: "rgba(26, 106, 226, 0.5)", | |||||
}, | |||||
{ | |||||
offset: 0, | |||||
color: "rgba(26, 106, 226, 0)", | |||||
}, | |||||
]), | |||||
}, | |||||
xAxis: [ | |||||
{ | |||||
type: "category", | |||||
boundaryGap: false, | |||||
axisLabel: { | |||||
color: 'rgba(185, 211, 235, 1)', | |||||
}, | |||||
axisLine: { | |||||
show: false | |||||
}, | |||||
axisTick: { | |||||
show: false | |||||
}, | |||||
splitLine: { | |||||
show: false | |||||
}, | |||||
data: xAxisData | |||||
}, | |||||
], | |||||
yAxis: [ | |||||
{ | |||||
type: "value", | |||||
name: "单位:万元", | |||||
nameTextStyle: { | |||||
color: 'rgba(185, 211, 235, 1)' | |||||
}, | |||||
axisLabel: { | |||||
formatter: "{value}", | |||||
textStyle: { | |||||
color: "rgba(185, 211, 235, 1)", | |||||
}, | |||||
}, | |||||
axisLine: { | |||||
lineStyle: { | |||||
color: "#27b4c2", | |||||
}, | |||||
}, | |||||
axisTick: { | |||||
show: false, | |||||
}, | |||||
splitLine: { | |||||
show: true, | |||||
lineStyle: { | |||||
color: "#11366e", | |||||
}, | |||||
}, | |||||
} | |||||
], | |||||
series: [ | |||||
{ | |||||
name: "", | |||||
type: "line", | |||||
smooth: true, | |||||
// symbol: "circle", | |||||
symbolSize: 12, | |||||
itemStyle: { | |||||
normal: { | |||||
color: "#0092f6", | |||||
lineStyle: { | |||||
color: "#0092f6", | |||||
width: 1, | |||||
}, | |||||
areaStyle: { | |||||
color: new echarts.graphic.LinearGradient(0, 1, 0, 0, [ | |||||
{ | |||||
offset: 1, | |||||
color: "rgba(134, 91, 252, 1)", | |||||
}, | |||||
{ | |||||
offset: 0.5, | |||||
color: "rgba(26, 106, 226, 0.5)", | |||||
}, | |||||
{ | |||||
offset: 0, | |||||
color: "rgba(26, 106, 226, 0)", | |||||
}, | |||||
]), | |||||
}, | |||||
}, | |||||
}, | |||||
markPoint: { | |||||
itemStyle: { | |||||
normal: { | |||||
color: "red", | |||||
}, | |||||
}, | |||||
}, | |||||
data: data | |||||
} | |||||
], | |||||
};; | |||||
this.chart.setOption(option); | |||||
this.initResizeCallBack(); | |||||
} | |||||
} | |||||
}; |
@@ -0,0 +1,6 @@ | |||||
.chart { | |||||
overflow: visible; | |||||
width: 100%; | |||||
height: 100%; | |||||
z-index: 2; | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1,5 @@ | |||||
<div class="pie_full"> | |||||
<div :id="id" class="chart"></div> | |||||
<div class="cir"></div> | |||||
</div> | |||||
@@ -0,0 +1,163 @@ | |||||
import * as echarts from 'echarts'; | |||||
import elementResizeDetectorMaker from 'element-resize-detector'; | |||||
export default { | |||||
props: { | |||||
id: { | |||||
type: String, | |||||
default: 'pie' | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: function () { | |||||
return [ | |||||
{ | |||||
value: 2154, | |||||
unit: '万元', | |||||
name: "项目一", | |||||
}, | |||||
{ | |||||
value: 3854, | |||||
unit: '万元', | |||||
name: "项目二", | |||||
}, | |||||
{ | |||||
value: 3854, | |||||
unit: '万吨', | |||||
name: "项目三", | |||||
}, | |||||
{ | |||||
value: 3854, | |||||
unit: '万吨', | |||||
name: "项目四", | |||||
} | |||||
]; | |||||
} | |||||
} | |||||
}, | |||||
data () { | |||||
return { | |||||
chart: null | |||||
}; | |||||
}, | |||||
mounted () { | |||||
this.initChart(); | |||||
}, | |||||
computed: { | |||||
}, | |||||
methods: { | |||||
// 设置监听器 页面尺寸变化重新绘制图表 | |||||
initResizeCallBack () { | |||||
const erd = elementResizeDetectorMaker(); | |||||
erd.listenTo(document.getElementById(this.id), () => { | |||||
this.$nextTick(() => { | |||||
this.chart.resize(); | |||||
}); | |||||
}); | |||||
}, | |||||
initChart () { | |||||
this.chart = echarts.init(document.getElementById(this.id)); | |||||
this.chartSetOption(); | |||||
}, | |||||
chartSetOption () { | |||||
var scale = 1; | |||||
var echartData = [ | |||||
...this.data | |||||
]; | |||||
var rich = { | |||||
yellow: { | |||||
color: "rgba(185, 211, 235, 1)", | |||||
fontSize: 18 * scale, | |||||
padding: [5, 4], | |||||
align: "center", | |||||
}, | |||||
total: { | |||||
color: "#ffc72b", | |||||
fontSize: 40 * scale, | |||||
align: "center", | |||||
}, | |||||
white: { | |||||
color: "rgba(185, 211, 235, 1)", | |||||
align: "center", | |||||
fontSize: 18 * scale, | |||||
padding: [0, 0], | |||||
}, | |||||
blue: { | |||||
color: "rgba(185, 211, 235, 1)", | |||||
fontSize: 16 * scale, | |||||
align: "center", | |||||
}, | |||||
hr: { | |||||
// borderColor: "#0b5263", | |||||
width: "100%", | |||||
borderWidth: 1, | |||||
height: 0, | |||||
}, | |||||
}; | |||||
const option = { | |||||
title: [ | |||||
{ | |||||
text: "总库存量", | |||||
left: "center", | |||||
top: "40%", | |||||
padding: [0, 0], | |||||
textStyle: { | |||||
color: "#fff", | |||||
fontSize: 18 * scale, | |||||
align: "center", | |||||
}, | |||||
}, | |||||
{ | |||||
text: "1000 万吨", | |||||
left: "center", | |||||
top: "50%", | |||||
padding: [0, 0], | |||||
textStyle: { | |||||
color: "#fff", | |||||
fontSize: 18 * scale, | |||||
align: "center", | |||||
}, | |||||
} | |||||
], | |||||
series: [ | |||||
{ | |||||
name: "", | |||||
type: "pie", | |||||
radius: ["48%", "70%"], | |||||
color: ["rgba(15, 252, 252, 1)", "rgba(134, 91, 252, 1)", "rgba(49, 129, 246, 1)", "rgba(29, 197, 104, 1)"], | |||||
label: { | |||||
normal: { | |||||
formatter: function (params, ticket, callback) { | |||||
var total = 0; //考生总数量 | |||||
var percent = 0; //考生占比 | |||||
echartData.forEach(function (value, index, array) { | |||||
total += value.value; | |||||
}); | |||||
percent = ((params.value / total) * 100).toFixed(1); | |||||
return ( | |||||
"{white|" + | |||||
percent + "%" + | |||||
"}\n{blue|" + | |||||
params.name + | |||||
"}\n{hr|}\n{yellow|" + | |||||
params.value + params.data.unit + '}' | |||||
); | |||||
}, | |||||
rich: rich, | |||||
}, | |||||
}, | |||||
labelLine: { | |||||
normal: { | |||||
length: 10 * scale, | |||||
length2: 20 * scale, | |||||
}, | |||||
}, | |||||
data: echartData, | |||||
}, | |||||
], | |||||
}; | |||||
this.chart.setOption(option); | |||||
this.initResizeCallBack(); | |||||
} | |||||
} | |||||
}; |
@@ -0,0 +1,25 @@ | |||||
.pie_full { | |||||
width: 100%; | |||||
height: 100%; | |||||
position: relative; | |||||
.chart { | |||||
overflow: visible; | |||||
width: 100%; | |||||
height: 100%; | |||||
z-index: 2; | |||||
} | |||||
.cir { | |||||
position: absolute; | |||||
top: 50%; | |||||
left: 50%; | |||||
transform: translate(-50%, -50%); | |||||
width: 200px; | |||||
height: 200px; | |||||
border-radius: 50%; | |||||
border: 1px solid rgba(49, 129, 246, 1); | |||||
box-shadow: inset 0 0 10px 2px rgba(27, 123, 204, 0.8); | |||||
/* 添加内发光效果 */ | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1,6 @@ | |||||
<div class="header"> | |||||
<div class="left border"> | |||||
<slot name="left"></slot> | |||||
</div> | |||||
<p class="title">{{title}}</p> | |||||
</div> |
@@ -0,0 +1,28 @@ | |||||
export default { | |||||
computed: { | |||||
}, | |||||
props: { | |||||
title: { | |||||
type: String, | |||||
default: '我是标题' | |||||
}, | |||||
back: { | |||||
type: Boolean, | |||||
default: false | |||||
}, | |||||
backName: { | |||||
type: String, | |||||
default: '返回' | |||||
} | |||||
}, | |||||
data () { | |||||
return { | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
methods: { | |||||
} | |||||
}; |
@@ -0,0 +1,28 @@ | |||||
.header { | |||||
position: relative; | |||||
background: url('./header_bk.png'); | |||||
background-size: 100% 100%; | |||||
width: 100%; | |||||
height: 90px; | |||||
.title { | |||||
overflow: visible; | |||||
padding: 0 20px; | |||||
position: absolute; | |||||
top: 50%; | |||||
left: 50%; | |||||
transform: translate(-50%, -50%); | |||||
font-size: 40px; | |||||
font-style: italic; | |||||
font-weight: 600; | |||||
background: linear-gradient(180deg, #FFFFFF 38.330078125%, #99BAEC 100%); | |||||
-webkit-background-clip: text; | |||||
-webkit-text-fill-color: transparent; | |||||
} | |||||
.left { | |||||
position: absolute; | |||||
left: 20px; | |||||
top: 20px; | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1,3 @@ | |||||
<div class="pannel_tabs row"> | |||||
<div v-for="(item) in data" class="tab hover_pointer" :class="[item.id === currentClick ? 'active' : '']" @click="tabClick(item)">{{item.name}}</div> | |||||
</div> |
@@ -0,0 +1,34 @@ | |||||
export default { | |||||
props: { | |||||
data: { | |||||
type: Array, | |||||
default: function () { | |||||
return [ | |||||
{ | |||||
id: '1', | |||||
name: '趋势' | |||||
}, | |||||
{ | |||||
id: '2', | |||||
name: '类型' | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
}, | |||||
data () { | |||||
return { | |||||
currentClick: '1' | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
methods: { | |||||
tabClick (info) { | |||||
this.currentClick = info.id | |||||
this.$emit('change', info) | |||||
} | |||||
} | |||||
}; |
@@ -0,0 +1,26 @@ | |||||
.tab { | |||||
margin-right: 4px; | |||||
font-size: 12px; | |||||
line-height: 23px; | |||||
text-align: center; | |||||
border-radius: 10px; | |||||
width: 55px; | |||||
height: 23px; | |||||
background: RGBA(0, 0, 0, 0); | |||||
border: 1px solid rgba(43, 108, 206, 0.66); | |||||
} | |||||
.pannel_tabs { | |||||
height: 23px !important; | |||||
width: auto; | |||||
display: flex; | |||||
justify-content: flex-end; | |||||
} | |||||
.active { | |||||
background: linear-gradient(-90deg, #1c4ca5 0%, #215AC3 98%); | |||||
font-size: 12px; | |||||
width: 55px; | |||||
height: 23px; | |||||
text-align: center; | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1,27 @@ | |||||
<div class="pannel" :style="style" :class="[bkClass]"> | |||||
<div class="header_box"> | |||||
<div class="top_line"> | |||||
<div class="left_sign"></div> | |||||
<div class="right_sign"></div> | |||||
</div> | |||||
<div class="header row align_item_center"> | |||||
<div v-if="title" class="title_bk row align_item_center"> | |||||
<i class="icon"></i> | |||||
<p>{{title}}</p> | |||||
</div> | |||||
<div class="more"> | |||||
<slot name="header"></slot> | |||||
</div> | |||||
</div> | |||||
<div class="light"></div> | |||||
</div> | |||||
<div class="body"> | |||||
<div> | |||||
<slot></slot> | |||||
</div> | |||||
<div class="bottom_line"> | |||||
<div class="left_sign"></div> | |||||
<div class="right_sign"></div> | |||||
</div> | |||||
</div> | |||||
</div> |
@@ -0,0 +1,42 @@ | |||||
export default { | |||||
props: { | |||||
// 定义标题 | |||||
title: { | |||||
type: String, | |||||
default: '我是标题' | |||||
}, | |||||
bkClass: { | |||||
type: String, | |||||
default: 'bk_normal' | |||||
}, | |||||
// 定义跳转页面url | |||||
uri: { | |||||
type: String, | |||||
default: '' | |||||
}, | |||||
// 定义组件高度 | |||||
height: { | |||||
type: String, | |||||
default: '300' | |||||
}, | |||||
// 定义组件高度 | |||||
width: { | |||||
type: String, | |||||
default: '430' | |||||
} | |||||
}, | |||||
computed: { | |||||
style: function () { | |||||
return { | |||||
height: this.height + 'px', | |||||
width: this.width + 'px' | |||||
}; | |||||
} | |||||
}, | |||||
data () { | |||||
return { | |||||
}; | |||||
}, | |||||
methods: { | |||||
} | |||||
}; |
@@ -0,0 +1,132 @@ | |||||
.pannel { | |||||
box-sizing: border-box; | |||||
display: flex; | |||||
flex-direction: column; | |||||
// 頭部區域 | |||||
.header_box { | |||||
position: relative; | |||||
height: 35px; | |||||
overflow: visible !important; | |||||
.top_line { | |||||
display: flex; | |||||
justify-content: space-between; | |||||
background-color: rgba(22, 60, 114, 1); | |||||
width: 100%; | |||||
height: 2px; | |||||
.left_sign { | |||||
height: 2px; | |||||
width: 13px; | |||||
background-color: rgba(53, 143, 255, 1); | |||||
} | |||||
.right_sign { | |||||
height: 2px; | |||||
width: 13px; | |||||
background-color: rgba(53, 143, 255, 1); | |||||
} | |||||
} | |||||
.header { | |||||
margin-top: 2px; | |||||
height: 32px; | |||||
background: rgba(8, 33, 71, 1); | |||||
.title_bk { | |||||
font-style: italic; | |||||
font-weight: 600; | |||||
height: 50px; | |||||
margin-left: 20px; | |||||
line-height: 32px; | |||||
text-align: center; | |||||
.icon { | |||||
display: block; | |||||
background: url('./icon.png'); | |||||
background-size: 100% 100%; | |||||
width: 18px; | |||||
height: 18px; | |||||
} | |||||
} | |||||
.more { | |||||
margin-right: 20px; | |||||
} | |||||
} | |||||
.light { | |||||
position: absolute; | |||||
bottom: -15px; | |||||
left: 30px; | |||||
background: url('./light.png'); | |||||
background-size: 100% 100%; | |||||
width: 280px; | |||||
height: 30px; | |||||
animation: lightmove 4s infinite; | |||||
} | |||||
} | |||||
// 内容区域 | |||||
.body { | |||||
margin: 2px; | |||||
padding: 10px; | |||||
width: 100%; | |||||
position: relative; | |||||
flex: 1; | |||||
background-color: rgba(11, 28, 58, 1); | |||||
overflow: hidden; | |||||
.bottom_line { | |||||
position: absolute; | |||||
left: 0; | |||||
right: 0; | |||||
bottom: 0; | |||||
display: flex; | |||||
justify-content: space-between; | |||||
background-color: rgba(22, 60, 114, 1); | |||||
width: 100%; | |||||
height: 2px; | |||||
.left_sign { | |||||
height: 2px; | |||||
width: 13px; | |||||
background-color: rgba(53, 143, 255, 1); | |||||
} | |||||
.right_sign { | |||||
height: 2px; | |||||
width: 13px; | |||||
background-color: rgba(53, 143, 255, 1); | |||||
} | |||||
} | |||||
div { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
} | |||||
} | |||||
@keyframes lightmove { | |||||
/* 动画关键帧 */ | |||||
0% { | |||||
opacity: 1; | |||||
transform: translateX(0px); | |||||
/* 样式 */ | |||||
} | |||||
50% { | |||||
opacity: 0.2; | |||||
transform: translateX(170px); | |||||
} | |||||
/* 。。。 */ | |||||
100% { | |||||
opacity: 1; | |||||
transform: translateX(0px); | |||||
/* 样式 */ | |||||
} | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1,65 @@ | |||||
export default [ | |||||
{ | |||||
area: '长春', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '松原', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '通化', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '四平', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '吉林', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '辽源', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '通化', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '白山', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
}, | |||||
{ | |||||
area: '延边', | |||||
count: 233, | |||||
money: 534534, | |||||
dealCount: 564, | |||||
dealMoney: 31 | |||||
} | |||||
]; |
@@ -0,0 +1,14 @@ | |||||
<div :style="[style]"> | |||||
<div class="table_show"> | |||||
<div class="table_header table_one clearfix"> | |||||
<div v-for="header in headers" :key="header" class="item test_center">{{header}}</div> | |||||
</div> | |||||
<div class="table_bodyer"> | |||||
<scroll :data="data" class="seamless-warp" :class-option="swiperOption"> | |||||
<div v-for="(line, index) in data" class="table_one clearfix item_height"> | |||||
<div v-for="(item, index) in line" class="item test_center ellipsis_1" >{{item }}</div> | |||||
</div> | |||||
</scroll> | |||||
</div> | |||||
</div> | |||||
</div> |
@@ -0,0 +1,69 @@ | |||||
import scroll from 'vue-seamless-scroll' | |||||
export default { | |||||
components: { | |||||
scroll | |||||
}, | |||||
data () { | |||||
return { | |||||
}; | |||||
}, | |||||
props: { | |||||
width: { | |||||
type: [String, Number], | |||||
default: '100%' | |||||
}, | |||||
height: { | |||||
type: [String, Number], | |||||
default: '100' | |||||
}, | |||||
headers: { | |||||
type: Array, | |||||
default: function () { | |||||
return ['表头1', '表头2', '表头3'] | |||||
} | |||||
}, | |||||
data: { | |||||
type: Array, | |||||
default: function () { | |||||
return [ | |||||
['表头1', '表头2', '表头3'], | |||||
['表头1', '表头2', '表头3'], | |||||
['表头1', '表头2', '表头3'], | |||||
['表头1', '表头2', '表头3'], | |||||
['表头1', '表头2', '表头3'], | |||||
['表头1', '表头2', '表头3'], | |||||
['表头1', '表头2', '表头3'], | |||||
['表头11', '表头22', '表头33'] | |||||
] | |||||
} | |||||
} | |||||
}, | |||||
computed: { | |||||
dataLength: function () { | |||||
return this.dataList.length; | |||||
}, | |||||
style: function () { | |||||
return { | |||||
height: this.height, | |||||
width: this.width | |||||
}; | |||||
}, | |||||
// 如果数据不足5条则不滚动 | |||||
swiperOption: function () { | |||||
return { | |||||
step: 0.4, | |||||
limitMoveNum: 1, | |||||
hoverStop: true, | |||||
direction: 1, | |||||
openWatch: true, | |||||
singleHeight: 0, | |||||
singleHeight: 0, | |||||
waitTime: 1000 | |||||
} | |||||
} | |||||
}, | |||||
created () { | |||||
}, | |||||
methods: { | |||||
} | |||||
}; |
@@ -0,0 +1,132 @@ | |||||
.table_show { | |||||
box-sizing: border-box; | |||||
padding: 0 10px; | |||||
margin-top: 10px; | |||||
.table_header { | |||||
width: 100%; | |||||
background: rgba(44, 117, 223, 0.5); | |||||
border-radius: 4px; | |||||
height: 40px; | |||||
font-size: 12px; | |||||
font-family: MicrosoftYaHeiUI, MicrosoftYaHeiUI-Bold; | |||||
font-weight: 700; | |||||
text-align: center; | |||||
color: rgba(185, 211, 235, 1); | |||||
} | |||||
.table_bodyer { | |||||
margin-top: 20px; | |||||
overflow: hidden; | |||||
height: 200px; | |||||
line-height: 40px; | |||||
.table_one { | |||||
height: 40px; | |||||
display: flex; | |||||
justify-content: space-around; | |||||
} | |||||
} | |||||
.table_one { | |||||
width: 100%; | |||||
height: 40px; | |||||
display: flex; | |||||
justify-content: space-around; | |||||
align-items: center; | |||||
} | |||||
} | |||||
.swiper-container { | |||||
height: 100%; | |||||
} | |||||
.table_bodyer { | |||||
height: 100%; | |||||
} | |||||
.margin { | |||||
margin-right: 5px; | |||||
} | |||||
.item_height { | |||||
color: rgba(214, 234, 252, 1); | |||||
font-size: 10px; | |||||
line-height: 40px; | |||||
height: 40px; | |||||
display: flex; | |||||
justify-content: space-around; | |||||
align-items: center; | |||||
border-bottom: 1px solid #183053; | |||||
&:nth-child(odd) { | |||||
background-color: rgba(49, 129, 246, 0.1); | |||||
} | |||||
&:hover { | |||||
color: rgba(49, 129, 246, 1); | |||||
} | |||||
} | |||||
.item { | |||||
font-size: 14px; | |||||
text-align: center; | |||||
overflow: hidden; | |||||
white-space: nowrap; | |||||
} | |||||
.item1 { | |||||
flex: 1.8; | |||||
} | |||||
.item:nth-child(1) { | |||||
text-align: left; | |||||
flex: 1.8; | |||||
padding-left: 5px; | |||||
} | |||||
.item:nth-child(2) { | |||||
flex: 1.3; | |||||
} | |||||
.item:nth-child(3) { | |||||
flex: 1.8; | |||||
} | |||||
.item:nth-child(4) { | |||||
flex: 1.4; | |||||
} | |||||
.item:nth-child(5) { | |||||
flex: 1.3; | |||||
} | |||||
.item:nth-child(6) { | |||||
flex: 1.3; | |||||
} | |||||
.item:nth-child(7) { | |||||
flex: 2; | |||||
} | |||||
.text_overflow { | |||||
text-overflow: ellipsis; | |||||
} | |||||
.test_center { | |||||
text-align: center; | |||||
} | |||||
.pop { | |||||
padding: 4px; | |||||
position: fixed; | |||||
z-index: 20; | |||||
color: white; | |||||
background: rgba($color: #000000, $alpha: 0.3); | |||||
border-radius: 6px; | |||||
} | |||||
.margin_top { | |||||
margin-top: 5px; | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1,3 @@ | |||||
<div class="tabs row"> | |||||
<div v-for="(item) in data" class="tab hover_pointer" :class="[item.id === currentClick ? 'active' : '']" @click="tabClick(item)">{{item.name}}</div> | |||||
</div> |
@@ -0,0 +1,34 @@ | |||||
export default { | |||||
props: { | |||||
data: { | |||||
type: Array, | |||||
default: function () { | |||||
return [ | |||||
{ | |||||
id: '1', | |||||
name: '选项一' | |||||
}, | |||||
{ | |||||
id: '2', | |||||
name: '选项二' | |||||
} | |||||
] | |||||
} | |||||
}, | |||||
}, | |||||
data () { | |||||
return { | |||||
currentClick: '1' | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
methods: { | |||||
tabClick (info) { | |||||
this.currentClick = info.id | |||||
this.$emit('change', info) | |||||
} | |||||
} | |||||
}; |
@@ -0,0 +1,16 @@ | |||||
.tab { | |||||
width: 111px; | |||||
height: 43px; | |||||
line-height: 43px; | |||||
text-align: center; | |||||
background: url('./normal.png'); | |||||
background-size: 100% 100%; | |||||
} | |||||
.active { | |||||
width: 111px; | |||||
height: 43px; | |||||
text-align: center; | |||||
background: url('./actice.png') !important; | |||||
background-size: 100% 100% !important; | |||||
} |
@@ -0,0 +1,3 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped></style> |
@@ -0,0 +1,75 @@ | |||||
// 自定义指令 | |||||
export default { | |||||
increase: { // 自增 | |||||
inserted: function (el) { | |||||
console.log('【inserted】 inserted'); | |||||
const endText = el.innerText; | |||||
// const endText = el.dataset.value; | |||||
const end = el.innerText * 1; | |||||
const step = el.dataset.step; | |||||
el.innerText = 0; | |||||
const timer = setInterval(function () { | |||||
el.innerText = el.innerText * 1 + step * 1; | |||||
if (el.innerText >= end) { | |||||
clearInterval(timer); | |||||
el.innerText = endText; | |||||
} | |||||
}, 200); | |||||
} | |||||
}, | |||||
input: { | |||||
bind (el, bidding, vnode) { | |||||
const input = el.tagName === 'INPUT' ? el : el.querySelector('input'); | |||||
input.addEventListener('compositionstart', () => { | |||||
vnode.locking = true; // 解决中文输入双向绑定失效 | |||||
}); | |||||
input.addEventListener('compositionend', () => { | |||||
vnode.locking = false; // 解决中文输入双向绑定失效 | |||||
input.dispatchEvent(new Event('input')); | |||||
}); | |||||
// 输入监听处理 | |||||
input.onkeyup = () => { | |||||
if (vnode.locking) return; | |||||
let regObj = { | |||||
num: /\D/g, // 只能输入数字可以0开头 | |||||
int: /\D/g, // 只能输入整数 | |||||
float: /[^\.\d]/g, // 只能输入数字、浮点数 | |||||
numEn: /[^a-zA-Z0-9]/g, // 只能输入数字、字母 | |||||
en: /[^a-zA-Z]/g, // 只能输入字母 | |||||
numEnCn: /[^A-Za-z0-9-\u4e00-\u9fa5]/g // 只能输入汉字、数字、字母^A-Za-z0-9\u4e00-\u9fa5 | |||||
}; | |||||
for (let key in bidding.modifiers) { | |||||
let reg = regObj[key]; | |||||
if (key === 'float') { | |||||
// v-input.flot="4" // 小数点位数 | |||||
onlyFloat(input, bidding.value || 2); | |||||
} else { | |||||
input.value = input.value.replace(reg, ''); | |||||
} | |||||
// 使用Number函数最多16位,超过16位会转换为0 | |||||
if (key === 'int') { | |||||
input.value = input.value && Number(input.value); | |||||
} | |||||
} | |||||
input.dispatchEvent(new Event('input')); | |||||
}; | |||||
} | |||||
} | |||||
}; | |||||
function onlyFloat (input, n) { | |||||
let value = input.value; | |||||
value = value.replace(/[^\d.]/g, ''); | |||||
value = value.replace(/^\./g, ''); | |||||
value = value.replace('.', '$#$').replace(/\./g, '').replace('$#$', '.'); | |||||
if (n && Number(n) > 0) { // 限制n位 | |||||
var d = new Array(Number(n)).fill('\\d').join(''); | |||||
var reg = new RegExp(`^(\\-)*(\\d+)\\.(${d}).*$`, 'ig'); | |||||
value = value.replace(reg, '$1$2.$3'); | |||||
} | |||||
if (value && !value.includes('.')) { | |||||
value = Number(value).toString(); // 去掉开头多个0 | |||||
} | |||||
input.value = value; | |||||
}; |
@@ -0,0 +1,91 @@ | |||||
export function formatDate(date, fmt) { | |||||
let o = { | |||||
'M+': date.getMonth() + 1, // 月份 | |||||
'd+': date.getDate(), // 日 | |||||
'h+': date.getHours(), // 小时 | |||||
'm+': date.getMinutes(), // 分 | |||||
's+': date.getSeconds(), // 秒 | |||||
'q+': Math.floor((date.getMonth() + 3) / 3), // 季度 | |||||
'S': date.getMilliseconds() // 毫秒 | |||||
}; | |||||
if (/(y+)/.test(fmt)) | |||||
fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length)); | |||||
for (let k in o) | |||||
if (new RegExp('(' + k + ')').test(fmt)) | |||||
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length))); | |||||
return fmt; | |||||
}; | |||||
// 保留小数点一位 | |||||
export function toFixedd(test) { | |||||
var str = parseFloat(test); | |||||
return str.toFixed(2); | |||||
} | |||||
// 如果为空 | |||||
export function ifNullNum(val) { | |||||
if (val === 0 || val === '' || val === null || val === '0') { | |||||
return 0; | |||||
} else { | |||||
return val; | |||||
} | |||||
} | |||||
// 保留整数 | |||||
export function toInteger(test) { | |||||
return parseInt(test); | |||||
} | |||||
export function fullDate(dateText) { | |||||
let reg = /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$/; | |||||
if (reg.test(dateText)) { | |||||
return formatDate(new Date(dateText), 'yyyy-MM-dd hh:mm:ss'); | |||||
} else { | |||||
return dateText; | |||||
} | |||||
} | |||||
// 空判断 | |||||
export function ifNull2(value) { | |||||
if (value === '' || !value) { | |||||
return '-'; | |||||
}else { | |||||
return value; | |||||
} | |||||
} | |||||
export function baseDate(dateText) { | |||||
return formatDate(new Date(dateText), 'yyyy-MM-dd'); | |||||
} | |||||
// 数字转化为百分比 | |||||
export function numberStrToFixed(str, length = 2) { | |||||
return (str * 1).toFixed(length); | |||||
} | |||||
// 身份证加密 | |||||
export function idCardChange(str) { | |||||
if (str) { | |||||
return str.replace(/(\w{6})\w*(\w{4})/, '$1********$2'); | |||||
} | |||||
return ''; | |||||
} | |||||
// 空判断 | |||||
export function isNull(value) { | |||||
if (!value) { | |||||
return '暂无'; | |||||
} else { | |||||
return value; | |||||
} | |||||
} | |||||
// 空判断 | |||||
export function unit(value) { | |||||
if (value) { | |||||
return value+ '元'; | |||||
} else { | |||||
return 0+ '元'; | |||||
} | |||||
} | |||||
export function toFixed(value) { | |||||
return parseFloat(value).toFixed(0); | |||||
} |
@@ -0,0 +1,42 @@ | |||||
import Vue from 'vue'; | |||||
import ElementUI from 'element-ui'; | |||||
import 'element-ui/lib/theme-chalk/index.css'; | |||||
import App from './App.vue'; | |||||
import router from './router'; | |||||
import store from './store/index'; | |||||
import "swiper/dist/css/swiper.css"; | |||||
import './style/_base.scss'; | |||||
import * as filters from '@/filter/index.js'; | |||||
import directives from '@/directive/index.js'; | |||||
import message from '@/utils/message.js'; | |||||
// import interceptor from '@/interceptor/index.js'; | |||||
// import '@/permission'; // permission control | |||||
import VScaleScreen from 'v-scale-screen'; | |||||
// 过滤器 | |||||
Object.keys(filters).forEach(key => { | |||||
Vue.filter(key, filters[key]); | |||||
}); | |||||
// 自定义指令 | |||||
Object.keys(directives).forEach(key => { | |||||
Vue.directive(key, directives[key]); | |||||
}); | |||||
// 消息提醒 | |||||
Object.keys(message).forEach(key => { | |||||
Vue.prototype['$' + key] = message[key]; | |||||
}); | |||||
// interceptor.init(); | |||||
Vue.use(ElementUI); | |||||
// Vue.use(Select); | |||||
// Vue.use(Option); | |||||
// Vue.use(Input); | |||||
// Vue.use(Pagination); | |||||
// Vue.use(Button); | |||||
// Vue.use(Dropdown); | |||||
Vue.use(VScaleScreen); | |||||
new Vue({ | |||||
router, | |||||
store, | |||||
render: h => h(App) | |||||
}).$mount('#app'); |
@@ -0,0 +1,18 @@ | |||||
import router from './router'; | |||||
import store from './store'; | |||||
const whiteList = ['/login']; // 不重定向白名单 | |||||
router.beforeEach((to, from, next) => { | |||||
if (store.getters.loginInfo) { | |||||
if (to.path === '/login') { | |||||
next({ path: '/login' }); | |||||
} else { | |||||
next(); | |||||
} | |||||
} else { | |||||
if (whiteList.indexOf(to.path) !== -1) { | |||||
next(); | |||||
} else { | |||||
next(`/login?redirect=${to.path}`); // 否则全部重定向到登录页 | |||||
} | |||||
} | |||||
}); |
@@ -0,0 +1,24 @@ | |||||
import Vue from 'vue'; | |||||
import VueRouter from 'vue-router'; | |||||
Vue.use(VueRouter); | |||||
const routes = [ | |||||
{ | |||||
path: '/', | |||||
name: 'root', | |||||
redirect: '/capital' | |||||
}, | |||||
// 首页 | |||||
{ | |||||
path: '/capital', | |||||
name: 'capital', | |||||
component: () => import('@/views/capital/index.vue') | |||||
} | |||||
]; | |||||
const router = new VueRouter({ | |||||
routes | |||||
// mode: 'history' | |||||
}); | |||||
export default router; |
@@ -0,0 +1,27 @@ | |||||
import { login } from '@/api/login.js'; | |||||
import { setToken } from '@/utils/auth'; | |||||
import { Message } from 'element-ui'; | |||||
export const actions = { | |||||
// 登录 | |||||
Login ({ commit }, params) { | |||||
return new Promise((resolve, reject) => { | |||||
login(params).then(response => { | |||||
if (response.code !== '0') { | |||||
Message({ | |||||
message: response.reason, | |||||
type: 'error', | |||||
duration: 2000 | |||||
}); | |||||
resolve(); | |||||
}; | |||||
const data = response.data; | |||||
commit('SET_LOGIN_INFO', data); | |||||
setToken(data.token); | |||||
resolve(); | |||||
}).catch(error => { | |||||
reject(error); | |||||
}); | |||||
}); | |||||
} | |||||
}; |
@@ -0,0 +1,6 @@ | |||||
export const getters = { | |||||
areaCode: state => state.areaCode, | |||||
loginInfo: state => state.loginInfo, | |||||
industrialSubjectOccupancy: state => state.industrialSubjectOccupancy, | |||||
currentLayerName: state => state.currentLayerName | |||||
}; |
@@ -0,0 +1,11 @@ | |||||
import { state } from './state'; | |||||
import { mutations } from './mutations'; | |||||
import { actions } from './actions'; | |||||
import { getters } from './getters'; | |||||
export default { | |||||
state, | |||||
mutations, | |||||
actions, | |||||
getters | |||||
}; |
@@ -0,0 +1,14 @@ | |||||
export const mutations = { | |||||
SET_CURRENT_AREACODE: (state, areaCode) => { // 当前地图层级信息 | |||||
state.areaCode = areaCode; | |||||
}, | |||||
SET_LOGIN_INFO: (state, item) => { | |||||
state.loginInfo = item; | |||||
}, | |||||
RESET_LOGIN_INFO: (state) => { | |||||
state.loginInfo = null; | |||||
}, | |||||
SET_CURRENT_LAYERNAME: (state, currentLayerName) => { | |||||
state.currentLayerName = currentLayerName; | |||||
}, | |||||
}; |
@@ -0,0 +1,5 @@ | |||||
export const state = { | |||||
areaCode: '', | |||||
loginInfo: null, | |||||
currentLayerName: '' // 当前操作的图层名 | |||||
}; |
@@ -0,0 +1,19 @@ | |||||
import Vue from 'vue'; | |||||
import Vuex from 'vuex'; | |||||
import VuexPersistence from 'vuex-persist'; | |||||
import app from '@/store/app/index.js'; | |||||
Vue.use(Vuex); | |||||
const vuexLocal = new VuexPersistence({ | |||||
key: 'rongxin.nongjing.expo', | |||||
modules: ['app'] | |||||
}); | |||||
export default new Vuex.Store({ | |||||
modules: { | |||||
app | |||||
}, | |||||
plugins: [vuexLocal.plugin] | |||||
}); |
@@ -0,0 +1,106 @@ | |||||
@import "./element-reset"; | |||||
@import "./animation"; | |||||
@import "./font"; | |||||
@import "./layout"; | |||||
* { | |||||
margin: 0; | |||||
padding: 0; | |||||
font-family: '微软雅黑'; | |||||
box-sizing: border-box; | |||||
} | |||||
html, | |||||
body { | |||||
position: relative; | |||||
height: 100%; | |||||
color: #FFFFFF; | |||||
overflow-y: auto; | |||||
} | |||||
.page { | |||||
position: relative; | |||||
width: 1920px; | |||||
height: 1080px; | |||||
border: 1px solid red; | |||||
.left_side { | |||||
position: absolute; | |||||
left: 20px; | |||||
top: 100px; | |||||
bottom: 20px; | |||||
} | |||||
.right_side { | |||||
position: absolute; | |||||
right: 20px; | |||||
top: 100px; | |||||
bottom: 20px; | |||||
} | |||||
} | |||||
.scrollbar::-webkit-scrollbar { | |||||
width: 0; | |||||
height: 0; | |||||
} | |||||
.scrollbar::-webkit-scrollbar-thumb { | |||||
border-radius: 5px; | |||||
background-color: #124394; | |||||
} | |||||
.scrollbar::-webkit-scrollbar-track { | |||||
border-radius: 5px; | |||||
background-color: #00286b; | |||||
} | |||||
.scrollbar2::-webkit-scrollbar { | |||||
width: 5px; | |||||
} | |||||
.scrollbar2::-webkit-scrollbar-thumb { | |||||
border-radius: 5px; | |||||
background-color: #124394; | |||||
} | |||||
.scrollbar2::-webkit-scrollbar-track { | |||||
border-radius: 5px; | |||||
background-color: #00286b; | |||||
} | |||||
// 省略号 | |||||
.ellipsis_1 { | |||||
overflow: hidden; | |||||
text-overflow: ellipsis; | |||||
white-space: nowrap; | |||||
} | |||||
.full { | |||||
width: 100%; | |||||
height: 100%; | |||||
} | |||||
.hover_pointer { | |||||
cursor: pointer; | |||||
} | |||||
.border { | |||||
border: 1px solid red; | |||||
} | |||||
.screen { | |||||
width: 1920px; | |||||
height: 1080px; | |||||
} | |||||
.relative { | |||||
position: relative; | |||||
} | |||||
.menu_style { | |||||
border: 1px solid #48B7FF; | |||||
box-sizing: border-box; | |||||
background-color: rgba(6, 24, 24, 0.585); | |||||
border-radius: 4px; | |||||
box-shadow: 0px 0px 13px 0px #48B7FF inset; | |||||
} |
@@ -0,0 +1,67 @@ | |||||
@keyframes selfRotate { | |||||
from{ | |||||
transform: translate(-50%, -50%) rotate(0deg); | |||||
} | |||||
to{ | |||||
transform: translate(-50%, -50%) rotate(360deg); | |||||
} | |||||
} | |||||
@keyframes selfRotate2 { | |||||
from{ | |||||
// transform: ; | |||||
transform: rotate(0deg); | |||||
} | |||||
to{ | |||||
// transform: ; | |||||
transform: rotate(360deg); | |||||
} | |||||
} | |||||
@keyframes selfRotateReverse { | |||||
from{ | |||||
transform: rotate(0deg); | |||||
} | |||||
to{ | |||||
transform: rotate(-360deg); | |||||
} | |||||
} | |||||
@keyframes showFromSmall { | |||||
from{ | |||||
transform: translate(-50%, -50%) scale(0.1); | |||||
} | |||||
to{ | |||||
transform: translate(-50%, -50%) scale(1); | |||||
} | |||||
} | |||||
@keyframes showfromSide { | |||||
from{ | |||||
opacity: 0 !important; | |||||
transform: translateX(-100px); | |||||
} | |||||
to{ | |||||
opacity: 1 !important; | |||||
transform: translate(0px); | |||||
} | |||||
} | |||||
@keyframes showfromSide2 { | |||||
from{ | |||||
opacity: 0.1; | |||||
transform: translateX(100px); | |||||
} | |||||
to{ | |||||
opacity: 1; | |||||
transform: translate(0px); | |||||
} | |||||
} | |||||
@keyframes selfRotateButtom { | |||||
from{ | |||||
transform: rotate(0deg); | |||||
} | |||||
to{ | |||||
transform: rotate(-360deg); | |||||
} | |||||
} | |||||
@@ -0,0 +1,112 @@ | |||||
// 镇地图 | |||||
$bg_color: rgba(0, 23, 59, 0.5); | |||||
$border_color: rgba(30, 56, 92, 1); | |||||
.map_select.el-select, | |||||
.map_input { | |||||
width: 100%; | |||||
border: 1px solid red; | |||||
display: block; | |||||
.el-input__inner { | |||||
height: 60px; | |||||
line-height: 60px; | |||||
background: $bg_color; | |||||
border: 1px solid $border_color; | |||||
color: #FFFFFF; | |||||
} | |||||
.el-input__inner::-webkit-input-placeholder { | |||||
font-size: 14px; | |||||
font-weight: 400; | |||||
color: #6789AC; | |||||
} | |||||
} | |||||
.el-input-number { | |||||
width: 100%; | |||||
} | |||||
.el-textarea { | |||||
width: 100% !important; | |||||
.el-textarea__inner { | |||||
border: 0; | |||||
background: $bg_color; | |||||
} | |||||
} | |||||
.map_select_popper.el-select-dropdown { | |||||
background: $bg_color; | |||||
border: 1px solid $border_color; | |||||
width: 20px; | |||||
.el-select-dropdown__item { | |||||
height: 50px; | |||||
line-height: 50px; | |||||
color: #FFFFFF; | |||||
&.hover { | |||||
background: rgba(0, 31, 73, 1); | |||||
} | |||||
} | |||||
.popper__arrow { | |||||
border-bottom-color: $bg_color; | |||||
&::after { | |||||
border-bottom-color: $bg_color; | |||||
} | |||||
} | |||||
} | |||||
.pagination { | |||||
* { | |||||
background: transparent !important; | |||||
color: #FFFFFF !important; | |||||
} | |||||
*:hover, | |||||
.active { | |||||
color: #409EFF !important; | |||||
} | |||||
} | |||||
.el-popover { | |||||
border: 0; | |||||
border-radius: 0; | |||||
background-color: transparent !important; | |||||
z-index: 0; | |||||
} | |||||
.el-popper { | |||||
z-index: 0; | |||||
} | |||||
.el-input__inner { | |||||
width: 100% !important; | |||||
color: #DFF2FF; | |||||
border: 0; | |||||
background: $bg_color; | |||||
} | |||||
.el-range-input { | |||||
background-color: transparent !important; | |||||
} | |||||
.el-date-editor .el-range-separator { | |||||
color: #C0C4CC !important; | |||||
} | |||||
.el-select { | |||||
width: 100% !important; | |||||
} | |||||
.el-textarea__inner { | |||||
color: #FFFFFF; | |||||
} | |||||
.el-date-editor { | |||||
width: 100% !important; | |||||
} |
@@ -0,0 +1,55 @@ | |||||
// @font-face { | |||||
// font-family: "special"; | |||||
// src: url("~@/assets/fonts/DIN Alternate Bold.ttf"); | |||||
// font-weight: normal; | |||||
// font-style: normal; | |||||
// } | |||||
// @font-face { | |||||
// font-family: "incline"; | |||||
// src: url("~@/assets/fonts/优设标题黑.ttf"); | |||||
// font-weight: normal; | |||||
// font-style: normal; | |||||
// } | |||||
// @font-face { | |||||
// font-family: "title"; | |||||
// src: url("~@/assets/fonts/锐字真言体.ttf"); | |||||
// font-weight: normal; | |||||
// font-style: normal; | |||||
// } | |||||
// @font-face { | |||||
// /* 重命名字体名 */ | |||||
// font-family: 'title2'; | |||||
// /* 引入字体 */ | |||||
// src: url('~@/assets/fonts/庞门正道标题体.ttf'); | |||||
// font-weight: normal; | |||||
// font-style: normal; | |||||
// } | |||||
// .title2 { | |||||
// font-family: title2 !important; | |||||
// } | |||||
// .special_font { | |||||
// font-family: special !important; | |||||
// } | |||||
// .title_font { | |||||
// font-family: title !important; | |||||
// } | |||||
// .incline_font { | |||||
// font-family: incline !important; | |||||
// } | |||||
// .font_size_14 { | |||||
// font-size: 14px; | |||||
// } | |||||
// .font_size_18 { | |||||
// font-size: 18px; | |||||
// } |
@@ -0,0 +1,61 @@ | |||||
@function fact($number) { | |||||
$value: 1; | |||||
@if $number > 0 { | |||||
@for $i from 1 through $number { | |||||
$value: $value * $i; | |||||
} | |||||
} | |||||
@return $value; | |||||
} | |||||
@function pow($number, $exp) { | |||||
$value: 1; | |||||
@if $exp > 0 { | |||||
@for $i from 1 through $exp { | |||||
$value: $value * $number; | |||||
} | |||||
} | |||||
@else if $exp < 0 { | |||||
@for $i from 1 through -$exp { | |||||
$value: $value / $number; | |||||
} | |||||
} | |||||
@return $value; | |||||
} | |||||
@function rad($angle) { | |||||
$unit: unit($angle); | |||||
$unitless: $angle / ($angle * 0 + 1); | |||||
@if $unit == deg { | |||||
$unitless: $unitless / 180 * pi(); | |||||
} | |||||
@return $unitless; | |||||
} | |||||
@function pi() { | |||||
@return 3.14159265359; | |||||
} | |||||
@function sin($angle) { | |||||
$sin: 0; | |||||
$angle: rad($angle); | |||||
// Iterate a bunch of times. | |||||
@for $i from 0 through 10 { | |||||
$sin: $sin + pow(-1, $i) * pow($angle, (2 * $i + 1)) / fact(2 * $i + 1); | |||||
} | |||||
@return $sin; | |||||
} | |||||
@function cos($angle) { | |||||
$cos: 0; | |||||
$angle: rad($angle); | |||||
// Iterate a bunch of times. | |||||
@for $i from 0 through 10 { | |||||
$cos: $cos + pow(-1, $i) * pow($angle, 2 * $i) / fact(2 * $i); | |||||
} | |||||
@return $cos; | |||||
} | |||||
@function tan($angle) { | |||||
@return sin($angle) / cos($angle); | |||||
} |
@@ -0,0 +1,21 @@ | |||||
.row { | |||||
display: flex; | |||||
} | |||||
.col { | |||||
display: flex; | |||||
flex-direction: column; | |||||
} | |||||
.space_between { | |||||
justify-content: space-between; | |||||
} | |||||
.flex_1 { | |||||
flex: 1; | |||||
} | |||||
.align_item_center { | |||||
align-items: center; | |||||
} |
@@ -0,0 +1,15 @@ | |||||
const TokenKey = 'Admin-Token'; | |||||
// 获取token | |||||
export function getToken() { | |||||
return localStorage.getItem(TokenKey); // 将token保存在本地 | |||||
} | |||||
// 保存token | |||||
export function setToken(token) { | |||||
return localStorage.setItem(TokenKey, token); // 将token保存在本地 | |||||
} | |||||
// 删除token | |||||
export function removeToken() { | |||||
return localStorage.removeItem(TokenKey); | |||||
} |
@@ -0,0 +1,142 @@ | |||||
/** | |||||
* 文字链接 | |||||
*/ | |||||
export function cancleAnim (ev) { | |||||
ev.target.style.color = '#57acfb'; | |||||
ev.target.style.cursor = 'pointer'; | |||||
}; | |||||
export function startAnim (ev) { | |||||
ev.target.style.color = '#6789AC'; | |||||
}; | |||||
/** | |||||
* 生成uuid | |||||
* @returns | |||||
*/ | |||||
export function generateUUID () { | |||||
var d = new Date().getTime(); //Timestamp | |||||
var d2 = (performance && performance.now && (performance.now() * 1000)) || 0; //Time in microseconds since page-load or 0 if unsupported | |||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { | |||||
var r = Math.random() * 16; //random number between 0 and 16 | |||||
if (d > 0) { //Use timestamp until depleted | |||||
r = (d + r) % 16 | 0; | |||||
d = Math.floor(d / 16); | |||||
} else { //Use microseconds since page-load if supported | |||||
r = (d2 + r) % 16 | 0; | |||||
d2 = Math.floor(d2 / 16); | |||||
} | |||||
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16); | |||||
}); | |||||
} | |||||
/** | |||||
* 判断是几维数组 | |||||
* @param {*} arr | |||||
* @returns | |||||
*/ | |||||
export function getArrayDimensions (arr) { | |||||
if (Array.isArray(arr)) { | |||||
let maxDimension = 0; | |||||
for (let i = 0; i < arr.length; i++) { | |||||
const dimensions = getArrayDimensions(arr[i]); | |||||
maxDimension = Math.max(maxDimension, dimensions); | |||||
} | |||||
return maxDimension + 1; | |||||
} | |||||
return 1; | |||||
} | |||||
/** | |||||
* 数组转化为对象 | |||||
*/ | |||||
export function arrayToMap (list, key) { | |||||
const obj = {}; | |||||
list.forEach(item => obj[item[key]] = item); | |||||
return obj; | |||||
}; | |||||
/** | |||||
* 计算百分比 | |||||
*/ | |||||
export function getPercent (mun, max) { | |||||
var newNum = (mun / max) * 100; | |||||
return newNum.toFixed(2); | |||||
}; | |||||
/** | |||||
* 求和 | |||||
*/ | |||||
export function getMax (list, key) { | |||||
var max = 0; | |||||
if (key) { | |||||
list.map(item => { | |||||
max += item[key]; | |||||
}); | |||||
} else { | |||||
list.map(item => { | |||||
max += item; | |||||
}); | |||||
} | |||||
return max; | |||||
}; | |||||
/** | |||||
* 最大值 | |||||
*/ | |||||
export function getTotal (list, key) { | |||||
let valueList = list; | |||||
if (key) { | |||||
valueList = list.map(item => item[key]); | |||||
} | |||||
return valueList.reduce((prev, now) => { | |||||
return prev + now; | |||||
}); | |||||
}; | |||||
/** | |||||
* 获取客户端标识 | |||||
*/ | |||||
export function getClientId () { | |||||
return '5cf4828d94e9a37422d323a3'; | |||||
}; | |||||
/** | |||||
* 根据范围获取中心点 | |||||
*/ | |||||
export function getCenterByExtent (extent) { | |||||
const x = (extent[0] + extent[2]) / 2; | |||||
const y = (extent[1] + extent[3]) / 2; | |||||
return [x, y]; | |||||
}; | |||||
// 随机获取一个范围整数 | |||||
export function getRandom (m, n) { | |||||
return Math.floor(Math.random() * (m - n + 1) + n); | |||||
}; | |||||
export function random (min, max) { | |||||
return Math.floor(Math.random() * (max - min + 1)) + min; | |||||
} | |||||
/** | |||||
* 获取时间 | |||||
*/ | |||||
export function getDay (_date, fmt) { | |||||
const weekList = ['日', '一', '二', '三', '四', '五', '六']; | |||||
const date = _date || new Date(); | |||||
const opt = { | |||||
'y+': date.getFullYear().toString(), // 年 | |||||
'M+': (date.getMonth() + 1).toString(), // 月 | |||||
'd+': date.getDate().toString(), // 日 | |||||
'w+': weekList[date.getDay()], // 周 | |||||
'h+': date.getHours().toString(), // 时 | |||||
'm+': date.getMinutes().toString(), // 分 | |||||
's+': date.getSeconds().toString() // 秒 | |||||
}; | |||||
for (const k in opt) { | |||||
const ret = new RegExp('(' + k + ')').exec(fmt); | |||||
if (ret) { | |||||
if (/(y+)/.test(k)) { | |||||
fmt = fmt.replace(ret[1], opt[k].substring(4 - ret[1].length)); | |||||
} else { | |||||
fmt = fmt.replace(ret[1], (ret[1].length === 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, '0'))); | |||||
} | |||||
} | |||||
} | |||||
return fmt; | |||||
} |
@@ -0,0 +1,775 @@ | |||||
import { getCenterByExtent } from '@/utils/common.js'; | |||||
import { | |||||
Map, | |||||
View, | |||||
Collection, | |||||
Feature | |||||
} from 'ol'; | |||||
import WFS from 'ol/format/WFS.js'; | |||||
import { | |||||
transform, | |||||
fromLonLat | |||||
} from 'ol/proj'; | |||||
import { Point } from 'ol/geom'; | |||||
import TileLayer from 'ol/layer/Tile'; | |||||
import XYZ from 'ol/source/XYZ'; | |||||
import { | |||||
Style, | |||||
Stroke, | |||||
Fill, | |||||
Text, | |||||
Circle, | |||||
Icon | |||||
} from 'ol/style'; | |||||
import { extend, createEmpty } from 'ol/extent'; | |||||
import VectorLayer from 'ol/layer/Vector'; | |||||
import VectorSource from 'ol/source/Vector'; | |||||
import TileWMS from 'ol/source/TileWMS'; | |||||
import GeoJSON from 'ol/format/GeoJSON'; | |||||
import { get as getProjection } from 'ol/proj'; | |||||
import { getWidth, getTopLeft } from 'ol/extent'; | |||||
import WMTSTileGrid from 'ol/tilegrid/WMTS'; | |||||
import WKT from 'ol/format/WKT'; | |||||
import WMTS from 'ol/source/WMTS'; | |||||
import { Overlay } from 'ol'; | |||||
const pointVectorSource = new VectorSource(); | |||||
import PluggableMap from 'ol/PluggableMap'; | |||||
import { MousePosition, defaults } from 'ol/control'; | |||||
import { createStringXY } from 'ol/coordinate'; | |||||
import { Draw, Modify } from 'ol/interaction'; | |||||
import { get, post } from '@/api/index.js'; | |||||
import { MultiPolygon } from 'ol/geom'; | |||||
class GisUtils { | |||||
map = null; | |||||
overLayer = null; | |||||
instance = null; | |||||
textName = { | |||||
}; | |||||
// 构造一个广为人知的接口,供用户对该类进行实例化 | |||||
static getInstance () { | |||||
if (!this.instance) { | |||||
this.instance = new GisUtils(name); | |||||
} | |||||
return this.instance; | |||||
} | |||||
/** | |||||
* 获取一个地图容器 | |||||
* @param {string} domId dom节点id | |||||
*/ | |||||
getMap (domId) { | |||||
let view = new View({ | |||||
projection: 'EPSG:4326' | |||||
}); | |||||
PluggableMap.prototype.getEventPixel = function (event) { | |||||
// eslint-disable-next-line no-underscore-dangle | |||||
const viewportPosition = this.viewport_.getBoundingClientRect(); | |||||
let size = [viewportPosition.width, viewportPosition.height]; | |||||
const view = this.getView(); | |||||
if (view) { | |||||
size = view.getSizeFromViewport_(); | |||||
} | |||||
const eventPosition = | |||||
'changedTouches' in event /** @type {TouchEvent} */ ? | |||||
event.changedTouches[0] /** @type {MouseEvent} */ : | |||||
event; | |||||
return [ | |||||
(eventPosition.clientX - viewportPosition.left) * size[0] / | |||||
viewportPosition.width, | |||||
(eventPosition.clientY - viewportPosition.top) * size[1] / | |||||
viewportPosition.height | |||||
]; | |||||
}; | |||||
let mousePositionControl = new MousePosition({ | |||||
coordinateFormat: createStringXY(4), | |||||
projection: 'EPSG:3857', | |||||
className: 'custom-mouse-position', | |||||
target: document.getElementById('mouse-position'), | |||||
undefinedHTML: ' ' | |||||
}); | |||||
let map = new Map({ | |||||
target: domId, | |||||
view: view, | |||||
controls: defaults({ | |||||
zoom: false, | |||||
rotate: false, | |||||
attribution: false, | |||||
attributionOptions: { | |||||
collapsible: false | |||||
} | |||||
}).extend([mousePositionControl]), | |||||
layers: [ | |||||
] | |||||
}); | |||||
this.map = map; | |||||
return this.map; | |||||
} | |||||
/** | |||||
* 获取适量图层 | |||||
* @param {*} color | |||||
* @returns | |||||
*/ | |||||
getVectorLayerByColor (color) { | |||||
let layer = new VectorLayer({ | |||||
renderMode: 'webgl', // 使用WebGL渲染器 | |||||
source: new VectorSource(), | |||||
zIndex: 101, | |||||
style: new Style({ | |||||
fill: new Fill({ | |||||
color: color | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: color, | |||||
width: 2 | |||||
}) | |||||
}) | |||||
}); | |||||
this.map.addLayer(layer); | |||||
return layer; | |||||
} | |||||
addLayer (layer) { | |||||
this.map.addLayer(layer); | |||||
} | |||||
getPolygon (coordinates) { | |||||
const polygon = new MultiPolygon([coordinates]); | |||||
return polygon; | |||||
} | |||||
getFeature (polygon) { | |||||
return new Feature(polygon); | |||||
} | |||||
writeFeature (fs) { | |||||
return new GeoJSON().writeFeature(fs); | |||||
} | |||||
addModify (layer) { | |||||
const modify = new Modify({ | |||||
features: new Collection(layer.getSource().getFeatures()), | |||||
pixelTolerance: 4 | |||||
}); | |||||
return modify; | |||||
} | |||||
drawLineSplit (source) { | |||||
let draw = new Draw({ | |||||
source: source, | |||||
type: "LineString", | |||||
style: new Style({ | |||||
image: new Circle({ | |||||
radius: 5, | |||||
fill: new Fill({ | |||||
color: "#03a9f4" | |||||
}) | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: "#03a9f4", | |||||
width: 2 | |||||
}), | |||||
fill: new Fill({ | |||||
color: "rgba(255, 255, 255, 0.7)" | |||||
}) | |||||
}) | |||||
}); | |||||
return draw; | |||||
} | |||||
getMapContainer () { | |||||
return this.map; | |||||
} | |||||
/** | |||||
* 键入弹窗 | |||||
* @param {*} el dom | |||||
* @param {*} coord 位置 | |||||
*/ | |||||
addOverlay (el, coord) { | |||||
let overLayer = new Overlay({ | |||||
element: el, // 挂载元素 | |||||
position: coord, | |||||
className: 'overLay', | |||||
positioning: 'top-center', | |||||
autoPanAnimation: { | |||||
duration: 250 | |||||
}, | |||||
stopEvent: true | |||||
}); | |||||
this.map.addOverlay(overLayer); | |||||
this.overLayer = overLayer; | |||||
} | |||||
/** | |||||
* 移除弹窗 | |||||
*/ | |||||
removeOverlay () { | |||||
if (this.overLayer) { | |||||
this.map.addOverlay(this.overLayer); | |||||
} | |||||
} | |||||
/** | |||||
* 飞入动画 | |||||
*/ | |||||
flyTo (duration = 2000, position = [0, 0]) { | |||||
this.map.getView().animate({ | |||||
center: position, | |||||
duration: duration | |||||
}); | |||||
} | |||||
/** | |||||
* | |||||
* @param {*} evt 事件 | |||||
* @param {*} layerName 图层名称 | |||||
* @param {*} owsUrl 请求路径 | |||||
*/ | |||||
async getFeatureByEvt (evt, layerName, owsUrl) { | |||||
let point = new Point([evt.coordinate[0], evt.coordinate[1]]); | |||||
let cql_filter = `INTERSECTS (the_geom,${new WKT().writeGeometry(point)})`; | |||||
const params = this.getWFSparams(layerName, cql_filter); | |||||
const feature = await this.getFeaturesByWFS(owsUrl, params); | |||||
return feature; | |||||
} | |||||
/** | |||||
* 获取一个视图 | |||||
* @param {array} extent 四至 | |||||
* @param {int} zoom 缩放级别 | |||||
* @param {int} minZoom 最小缩放级别 | |||||
* @param {int} maxZoom 最大缩放级别 | |||||
*/ | |||||
getView (extent = [100, 100, 100, 100], zoom = 4, minZoom = 3, maxZoom = 18.4) { | |||||
let view = new View({ | |||||
center: getCenterByExtent(extent), | |||||
zoom, | |||||
minZoom, | |||||
maxZoom, | |||||
projection: 'EPSG:4326' | |||||
}); | |||||
this.map.setView(view); | |||||
return view; | |||||
} | |||||
/** | |||||
* 获取WMS图层 | |||||
* @param {*} wmsurl wms路径 | |||||
* @param {*} layerName 图层名 | |||||
* @param {*} isShow 是否隐藏 | |||||
*/ | |||||
getWMSLayer (wmsurl, layerName, isShow = false, zIndex = 50) { | |||||
let layer = new TileLayer({ | |||||
visible: isShow, | |||||
zIndex, | |||||
source: new TileWMS({ | |||||
url: wmsurl, | |||||
params: { 'LAYERS': layerName, 'TILED': true, SRID: 4326 }, | |||||
transition: 0 | |||||
}) | |||||
}); | |||||
this.map.addLayer(layer); | |||||
return layer; | |||||
} | |||||
/** | |||||
* 获取天地图图层 | |||||
* @param {string} url 最小缩放级别 | |||||
*/ | |||||
tianDiTuLayer (url, visible = true) { | |||||
let tianDitTu = new TileLayer({ | |||||
visible, | |||||
source: new XYZ({ | |||||
url | |||||
}) | |||||
}); | |||||
this.map.addLayer(tianDitTu); | |||||
return tianDitTu; | |||||
} | |||||
/** | |||||
* 获取wfs服务请求参数 | |||||
* @param {string} typename 请求的图层名 | |||||
* @param {string} cql cql语句 | |||||
* @return {obj} params wfs 的请求参数 | |||||
*/ | |||||
getWFSparams (typename, cql = null) { | |||||
var params = { | |||||
srsName: 'EPSG:4326', | |||||
service: 'WFS', | |||||
version: '1.0.0', | |||||
request: 'GetFeature', | |||||
typename, | |||||
outputFormat: 'application/json' | |||||
}; | |||||
if (cql) { | |||||
params.CQL_FILTER = cql; | |||||
} | |||||
return params; | |||||
} | |||||
getVectorSource () { | |||||
let source = new VectorSource(); | |||||
return source; | |||||
} | |||||
getVectorLayer () { | |||||
let layer = new VectorLayer({ | |||||
editable: true, // 确保图层是可编辑的 | |||||
source: new VectorSource(), | |||||
zIndex: 101, | |||||
style: new Style({ | |||||
fill: new Fill({ | |||||
color: [255, 80, 80, 0.5] | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: [255, 80, 80, 1], | |||||
width: 2 | |||||
}) | |||||
}) | |||||
}); | |||||
this.map.addLayer(layer); | |||||
return layer; | |||||
} | |||||
/** | |||||
* 根据描边颜色获取新的要素集合 | |||||
* @param {string} strokeColor 描边颜色 | |||||
* @param {array} fsList 要素数组 | |||||
*/ | |||||
getStrokeStyle (fsList, strokeColor = '#00FEFA', textName = 'NAME') { | |||||
const arr = fsList.map(item => { | |||||
item.setStyle( | |||||
new Style({ | |||||
stroke: new Stroke({ | |||||
color: strokeColor, | |||||
width: 1 | |||||
}), | |||||
text: new Text({ | |||||
text: item.values_[textName], | |||||
overflow: true, | |||||
font: 'bold 11px serif', | |||||
fill: new Fill({ | |||||
color: strokeColor | |||||
}) | |||||
}) | |||||
}) | |||||
); | |||||
return item; | |||||
}); | |||||
return arr; | |||||
} | |||||
/** | |||||
* 根据要素集合设置填充样式 | |||||
* @param {array} fsList 要素集合 | |||||
* @param {*} fillColor 填充色 | |||||
* @returns 返回矢量图层 | |||||
*/ | |||||
getFillStyle (fsList, fillColor = '#00FEFA', testName = 'XZQHMC') { | |||||
fsList.forEach(item => { | |||||
item.setStyle( | |||||
new Style({ | |||||
stroke: new Stroke({ | |||||
color: fillColor, | |||||
width: 2 | |||||
}), | |||||
text: new Text({ | |||||
text: item.values_[testName], | |||||
overflow: true, | |||||
font: 'bold 11px serif', | |||||
fill: new Fill({ | |||||
color: '#00FEFA' | |||||
}) | |||||
}) | |||||
}) | |||||
); | |||||
}); | |||||
return fsList; | |||||
} | |||||
/** | |||||
* 通过wfs服务拿到要素 | |||||
* @param {string} url 请求的路径 | |||||
* @param {obj} params 参数 | |||||
* @returns | |||||
*/ | |||||
async getFeaturesByWFS (url, params = {}) { | |||||
const res = await get(url, params); | |||||
const fs = new GeoJSON().readFeatures(res); | |||||
return fs; | |||||
} | |||||
getStyle (strokeColor = [255, 0, 0, 1], fillColor = [255, 0, 0, 0.1]) { | |||||
let style = new Style({ | |||||
stroke: new Stroke({ | |||||
color: strokeColor, | |||||
width: 2 | |||||
}), | |||||
fill: new Stroke({ | |||||
color: fillColor | |||||
}) | |||||
}); | |||||
return style; | |||||
} | |||||
/** | |||||
*根据要素集合获得矢量图层 | |||||
* @param {array} fs 要素集合 | |||||
*/ | |||||
getVectorLayerByFs (fs, zIndex = 200, opacity = 1, strokeColor = [0, 180, 241, 1], fillColor = [0, 180, 241, 0.1]) { | |||||
let style = this.getStyle(strokeColor, fillColor); | |||||
let textName = ['mj', 'uuid']; | |||||
const source = new VectorSource({ | |||||
}); | |||||
if (fs.length) { | |||||
source.addFeatures(fs); | |||||
} | |||||
const layer = new VectorLayer({ | |||||
renderMode: 'webgl', | |||||
style: style, | |||||
opacity, | |||||
style: (feature) => { | |||||
let arr = ''; | |||||
textName.forEach(item => { | |||||
arr += feature.getProperties()[item] + '\n'; | |||||
}); | |||||
return new Style({ | |||||
fill: new Fill({ | |||||
color: fillColor | |||||
}), | |||||
text: new Text({ | |||||
overflow: true, | |||||
text: arr, | |||||
font: 'bold 12px serif', | |||||
fill: new Fill({ | |||||
color: '#ffffff' | |||||
}) | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: strokeColor, | |||||
width: 1 | |||||
}) | |||||
}); | |||||
}, | |||||
source: source, | |||||
zIndex: zIndex | |||||
}); | |||||
this.map.addLayer(layer); | |||||
return layer; | |||||
} | |||||
changeTextName (arr, layerName) { | |||||
this.textName[layerName] = arr; | |||||
} | |||||
getStyleWithText (strokeColor = [180, 180, 0, 1], fillColor = [180, 180, 0, 0.1]) { | |||||
let style = new Style({ | |||||
stroke: new Stroke({ | |||||
color: strokeColor, | |||||
width: 2 | |||||
}), | |||||
fill: new Stroke({ | |||||
color: fillColor | |||||
}), | |||||
text: new Text({ | |||||
text: '333', | |||||
overflow: true, | |||||
font: 'bold 11px serif', | |||||
fill: new Fill({ | |||||
color: '#00FEFA' | |||||
}) | |||||
}) | |||||
}); | |||||
return style; | |||||
} | |||||
/** | |||||
*根据要素集合获得矢量图层 | |||||
* @param {array} fs 要素集合 | |||||
*/ | |||||
getVectorLayerByFsWidthText (fs, zIndex = 200, opacity = 1, strokeColor = [0, 180, 241, 1], fillColor = [0, 180, 241, 0.1], layerName) { | |||||
const source = new VectorSource({ | |||||
}); | |||||
if (fs.length) { | |||||
source.addFeatures(fs); | |||||
} | |||||
const layer = new VectorLayer({ | |||||
renderMode: 'webgl', | |||||
style: (feature) => { | |||||
let arr = ''; | |||||
this.textName[layerName].forEach(item => { | |||||
arr += feature.getProperties()[item] + '\n'; | |||||
}); | |||||
return new Style({ | |||||
fill: new Fill({ | |||||
color: fillColor | |||||
}), | |||||
text: new Text({ | |||||
overflow: false, | |||||
text: arr, | |||||
font: 'bold 12px serif', | |||||
fill: new Fill({ | |||||
color: '#ffffff' | |||||
}) | |||||
}), | |||||
stroke: new Stroke({ | |||||
color: strokeColor, | |||||
width: 1 | |||||
}) | |||||
}); | |||||
}, | |||||
opacity, | |||||
source: source, | |||||
zIndex: zIndex | |||||
}); | |||||
this.map.addLayer(layer); | |||||
return layer; | |||||
} | |||||
/** | |||||
* 根据图层名获取瓦片图层 | |||||
*/ | |||||
getTileLayerByLayerName (url, layerName, visible = true, zIndex = 50) { | |||||
const layer = new TileLayer({ | |||||
visible, | |||||
zIndex: zIndex, | |||||
source: new TileWMS({ | |||||
url, | |||||
params: { 'LAYERS': layerName, 'TILED': true, SRID: 3857 }, | |||||
transition: 0 | |||||
}) | |||||
}); | |||||
return layer; | |||||
} | |||||
/** | |||||
* 键入弹窗 | |||||
* @param {*} el dom | |||||
* @param {*} coord 位置 | |||||
*/ | |||||
addOverlay (el, coord) { | |||||
let overLayer = new Overlay({ | |||||
element: el, // 挂载元素 | |||||
position: coord, | |||||
autoPanAnimation: { | |||||
duration: 250 | |||||
}, | |||||
stopEvent: true | |||||
}); | |||||
this.map.addOverlay(overLayer); | |||||
this.overLayer = overLayer; | |||||
} | |||||
/** | |||||
* 根据要素集合适配视图 | |||||
* @param {map} 地图容器 | |||||
* @param {*} featureList 要素集合 | |||||
*/ | |||||
mapSetFit (featureList, padding = [100, 20, 20, 20], duration = 2000) { | |||||
let options = { | |||||
padding, | |||||
duration | |||||
}; | |||||
let extent = createEmpty(); | |||||
featureList.forEach(item => { | |||||
const itemExtent = item.getGeometry().getExtent(); | |||||
extent = extend(extent, itemExtent); | |||||
}); | |||||
if (featureList.length) { | |||||
this.map.getView().fit(extent, options); | |||||
} | |||||
} | |||||
/** | |||||
* 坐标转换 | |||||
* @param {coordinate } openlayer 输出坐标值 | |||||
* Amap public index.html 导入 | |||||
*/ | |||||
transform (coordinate) { | |||||
return transform(coordinate, 'EPSG:3857', 'EPSG:4326'); | |||||
} | |||||
// 在地图上添加点, 并添加点的样式 | |||||
setPoint (map, pointList) { | |||||
pointVectorSource.clear(); | |||||
if (pointList.length === 0) return; | |||||
const pointStyle = new Style({ | |||||
image: new Icon({ | |||||
src: locationIcon, | |||||
scale: 1, | |||||
anchor: [0.5, 0.5], | |||||
rotateWithView: false, | |||||
rotation: 45 | |||||
}) | |||||
}); | |||||
let pointFeature; | |||||
pointList.forEach(item => { | |||||
pointFeature = new Feature({ | |||||
geometry: new Point(new fromLonLat([item.longitude, item.latitude])), | |||||
url: item.url, | |||||
showText: true, | |||||
showPicture: item.url ? true : false | |||||
}); | |||||
pointFeature.setStyle(pointStyle); | |||||
pointVectorSource.addFeature(pointFeature); | |||||
}); | |||||
const vectorLayer = new VectorLayer({ | |||||
// zIndex: 999, | |||||
source: pointVectorSource | |||||
}); | |||||
map.addLayer(vectorLayer); | |||||
// 每隔1秒旋转10度 | |||||
let rotation = 0; | |||||
setInterval(() => { | |||||
rotation += 5 * Math.PI / 180; | |||||
pointStyle.getImage().setRotation(rotation); | |||||
pointFeature.setStyle(pointStyle); | |||||
}, 100); | |||||
} | |||||
// 初始化地块图层 | |||||
initDKlayer (layerName, extent) { | |||||
// 地块图层 | |||||
let projection = getProjection('EPSG:3857'); | |||||
let projectionExtent = projection.getExtent(); | |||||
var size = getWidth(projectionExtent) / 256; | |||||
var resolutions = []; | |||||
for (var z = 0; z < 20; ++z) { | |||||
resolutions[z] = size / Math.pow(2, z); | |||||
} | |||||
const layer = new TileLayer({ | |||||
zIndex: 51, | |||||
visible: true, | |||||
source: new WMTS({ | |||||
url: '/geoserver/gwc/service/wmts', | |||||
layer: layerName, | |||||
matrixSet: 'EPSG:3857', | |||||
format: 'image/png', | |||||
projection: projection, | |||||
tileGrid: new WMTSTileGrid({ | |||||
tileSize: [256, 256], | |||||
resolutions: resolutions, | |||||
origin: getTopLeft(projectionExtent), | |||||
matrixIds: ['EPSG:3857:0', 'EPSG:3857:1', 'EPSG:3857:2', 'EPSG:3857:3', 'EPSG:3857:4', 'EPSG:3857:5', | |||||
'EPSG:3857:6', 'EPSG:3857:7', 'EPSG:3857:8', 'EPSG:3857:9', 'EPSG:3857:10', 'EPSG:3857:11', 'EPSG:3857:12', | |||||
'EPSG:3857:13', 'EPSG:3857:14', 'EPSG:3857:15', 'EPSG:3857:16', 'EPSG:3857:17', 'EPSG:3857:18', 'EPSG:3857:19', | |||||
'EPSG:3857:20', 'EPSG:3857:21', 'EPSG:3857:22', 'EPSG:3857:23', 'EPSG:3857:24', 'EPSG:3857:25', 'EPSG:3857:26', | |||||
'EPSG:3857:27', 'EPSG:3857:28', 'EPSG:3857:29', 'EPSG:3857:30'], | |||||
extent: extent | |||||
}), | |||||
style: '', | |||||
wrapX: false | |||||
}) | |||||
}); | |||||
this.map.addLayer(layer); | |||||
return layer; | |||||
} | |||||
/** | |||||
* 根据一个带有经纬度,返回一个矢量图层 | |||||
* @param {*} dataList 带有经纬度的数组 | |||||
* { type: type, | |||||
geometry: [经度, 维度] | |||||
} | |||||
* @param {*} icon 图标 | |||||
*/ | |||||
getVectorLayerByGeometrylist (dataList, icon, zIndex = 100) { | |||||
let featureList = []; | |||||
const style = new Style({ | |||||
image: new Icon({ | |||||
anchor: [0.5, 28], | |||||
anchorXUnits: 'fraction', | |||||
anchorYUnits: 'pixels', | |||||
src: icon | |||||
}) | |||||
}); | |||||
dataList.forEach(item => { | |||||
const iconFeature = new Feature({ | |||||
_geometry: item.geometry, | |||||
geometry: new Point(fromLonLat(item.geometry)) | |||||
// geometry: new Point(item.geometry) | |||||
}); | |||||
iconFeature.setProperties(item.data); | |||||
iconFeature.setStyle(style); | |||||
featureList.push(iconFeature); | |||||
}); | |||||
const source = new VectorSource({ | |||||
features: featureList | |||||
}); | |||||
const iconLayer = new VectorLayer({ | |||||
zIndex, | |||||
source: source | |||||
}); | |||||
this.map.addLayer(iconLayer); | |||||
return iconLayer; | |||||
} | |||||
/** | |||||
* 加载geojson数据 | |||||
*/ | |||||
loadGeojsonData (geoData) { | |||||
const fs = new GeoJSON().readFeatures(geoData); | |||||
this.mapSetFit(fs); | |||||
let layer = this.getVectorLayerByFs(fs); | |||||
return layer; | |||||
} | |||||
removeLayer (layer) { | |||||
this.map.removeLayer(layer); | |||||
} | |||||
/** | |||||
* 增删改查要素 | |||||
* @param {*} inserts 要插入的要素集合 | |||||
* @param {*} updates 要更新的要素集合 | |||||
* @param {*} deletes 要删除的要素集合 | |||||
* @param {*} layer 要操作的图层 | |||||
* @param {*} fs | |||||
*/ | |||||
async crudFs (inserts = null, updates = null, deletes = null, layer = 'cwd2') { | |||||
const geoserverData = { | |||||
workSpaceName: 'qianguo', | |||||
uri: 'http://124.235.241.109:8080/geoserver/qianguo', | |||||
wfsURL: 'http://124.235.241.109:8080/geoserver/qianguo/ows?', | |||||
layer: layer | |||||
}; | |||||
let wfs = new WFS(); | |||||
let transact_xml = wfs.writeTransaction( | |||||
inserts, updates, deletes, | |||||
{ | |||||
version: '1.1.0', | |||||
srsName: 'EPSG:3857', | |||||
featureNS: geoserverData.uri, | |||||
featurePrefix: geoserverData.workSpaceName, | |||||
featureType: [geoserverData.layer], | |||||
} | |||||
); | |||||
let transact_str = (new XMLSerializer()).serializeToString(transact_xml); | |||||
let updStr = transact_str.replace(/geometry/g, 'the_geom'); | |||||
let res = await post('/geoserver/wfs', updStr); | |||||
let transactRes = wfs.readTransactionResponse(res); | |||||
let str = transactRes.transactionSummary.totalInserted + | |||||
" totalInserted!, insertIds: " + transactRes.insertIds + "\n"; | |||||
str += transactRes.transactionSummary.totalUpdated + " totalUpdated!\n"; | |||||
str += transactRes.transactionSummary.totalDeleted + " totalDeleted!"; | |||||
} | |||||
} | |||||
export default GisUtils; |
@@ -0,0 +1,56 @@ | |||||
import { Message } from 'element-ui'; | |||||
/** | |||||
* 【成功】提示框 | |||||
*/ | |||||
export function successMessage(message = '成功!') { | |||||
Message({ | |||||
message: message, | |||||
type: 'success', | |||||
duration: 2000, | |||||
offset: 327 | |||||
}); | |||||
} | |||||
/** | |||||
* 【异常】提示框 | |||||
*/ | |||||
export function errorMessage(message = '异常!') { | |||||
Message({ | |||||
message: message, | |||||
type: 'error', | |||||
duration: 2000, | |||||
offset: 327 | |||||
}); | |||||
} | |||||
/** | |||||
* 【警告】提示框 | |||||
*/ | |||||
export function warningMessage(message = '警告!') { | |||||
Message({ | |||||
message: message, | |||||
type: 'warning', | |||||
duration: 2000, | |||||
offset: 327 | |||||
}); | |||||
} | |||||
/** | |||||
* 【消息】提示框 | |||||
*/ | |||||
export function infoMessage(message = '提示!') { | |||||
Message({ | |||||
message: message, | |||||
type: 'info', | |||||
duration: 2000, | |||||
offset: 327 | |||||
}); | |||||
} | |||||
export default { | |||||
successMessage, | |||||
errorMessage, | |||||
warningMessage, | |||||
infoMessage | |||||
}; |
@@ -0,0 +1,74 @@ | |||||
import axios from 'axios'; | |||||
import { Message } from 'element-ui'; | |||||
import store from '../store'; | |||||
import { getToken } from '@/utils/auth'; | |||||
import router from '@/router/index'; | |||||
// 创建axios实例 | |||||
const service = axios.create({ | |||||
baseURL: process.env.BASE_API, // api 的 base_url | |||||
timeout: 1000 * 5 * 60 // 请求超时时间 | |||||
}); | |||||
// request拦截器 | |||||
service.interceptors.request.use( | |||||
config => { | |||||
if (getToken()) { | |||||
config.headers['authorization'] = getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改 | |||||
} | |||||
// config.headers['Authorization'] = 'Basic ' + btoa('admin:/UhQ28VFomqWr3qL9') // 使用你的用户名和密码进行Base64编码 | |||||
return config; | |||||
}, | |||||
error => { | |||||
// Do something with request error | |||||
console.log(error); // for debug | |||||
Promise.reject(error); | |||||
} | |||||
); | |||||
// response 拦截器 | |||||
service.interceptors.response.use( | |||||
response => { | |||||
/** | |||||
* code为非20000是抛错 可结合自己业务进行修改 | |||||
*/ | |||||
const res = response.data; | |||||
if (response.status === 200) { | |||||
let data = response.data; | |||||
if (data.hasOwnProperty('code') && data.code === 401) { | |||||
Message({ | |||||
message: '请重新登录', | |||||
type: 'error', | |||||
duration: 5 * 1000 | |||||
}); | |||||
store.commit('RESET_LOGIN_INFO'); | |||||
router.replace('/login'); | |||||
} else { | |||||
return response.data; | |||||
} | |||||
} else { | |||||
if (response.data.code === 401) { | |||||
Message({ | |||||
message: '请重新登录', | |||||
type: 'error', | |||||
duration: 5 * 1000 | |||||
}); | |||||
store.commit('RESET_LOGIN_INFO'); | |||||
router.replace('/login'); | |||||
} | |||||
} | |||||
}, | |||||
error => { | |||||
console.log('err' + error); // for debug | |||||
Message({ | |||||
message: error.message, | |||||
type: 'error', | |||||
duration: 5 * 1000 | |||||
}); | |||||
return Promise.reject(error); | |||||
} | |||||
); | |||||
export default service; |
@@ -0,0 +1,11 @@ | |||||
<Pannel title="资金支出分析" height="340"> | |||||
<div class="full"> | |||||
<div class="top"> | |||||
<PannelTabs @change="tabChange" ></PannelTabs> | |||||
</div> | |||||
<div class="buttom"> | |||||
<LineCharts v-if="tabIndex === '1'" id="otherline"></LineCharts> | |||||
<PieCharts v-if="tabIndex === '2'" id="otherpie"></PieCharts> | |||||
</div> | |||||
</div> | |||||
</Pannel> |
@@ -0,0 +1,28 @@ | |||||
import Pannel from '@/components/pannel/index.vue'; | |||||
import PannelTabs from '@/components/pannel-tabs/index.vue'; | |||||
import LineCharts from '@/components/charts/line/index.vue'; | |||||
import PieCharts from '@/components/charts/pie/index.vue'; | |||||
export default { | |||||
components: { | |||||
LineCharts, | |||||
PieCharts, | |||||
PannelTabs, | |||||
Pannel | |||||
}, | |||||
data () { | |||||
return { | |||||
tabIndex: '1' | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
mounted () { | |||||
}, | |||||
methods: { | |||||
tabChange (info) { | |||||
console.log(info); | |||||
this.tabIndex = info.id | |||||
} | |||||
} | |||||
}; |
@@ -0,0 +1,17 @@ | |||||
.full { | |||||
display: flex; | |||||
flex-direction: column; | |||||
.top { | |||||
height: 50px !important; | |||||
width: 100%; | |||||
display: flex !important; | |||||
align-items: center !important; | |||||
justify-content: flex-end; | |||||
} | |||||
.buttom { | |||||
flex: 1; | |||||
width: 100%; | |||||
} | |||||
} |
@@ -0,0 +1,4 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped> | |||||
</style> |
@@ -0,0 +1,4 @@ | |||||
<Pannel> | |||||
</Pannel> |
@@ -0,0 +1,17 @@ | |||||
import Pannel from '@/components/pannel/index.vue'; | |||||
export default { | |||||
components: { | |||||
Pannel | |||||
}, | |||||
data () { | |||||
return { | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
mounted () { | |||||
}, | |||||
methods: { | |||||
} | |||||
}; |
@@ -0,0 +1,4 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped> | |||||
</style> |
@@ -0,0 +1,11 @@ | |||||
<Pannel title="资金收入分析" height="340"> | |||||
<div class="full"> | |||||
<div class="top"> | |||||
<PannelTabs @change="tabChange"></PannelTabs> | |||||
</div> | |||||
<div class="buttom"> | |||||
<LineCharts v-if="tabIndex === '1'"></LineCharts> | |||||
<PieCharts v-if="tabIndex === '2'"></PieCharts> | |||||
</div> | |||||
</div> | |||||
</Pannel> |
@@ -0,0 +1,28 @@ | |||||
import Pannel from '@/components/pannel/index.vue'; | |||||
import PannelTabs from '@/components/pannel-tabs/index.vue'; | |||||
import LineCharts from '@/components/charts/line/index.vue'; | |||||
import PieCharts from '@/components/charts/pie/index.vue'; | |||||
export default { | |||||
components: { | |||||
LineCharts, | |||||
PieCharts, | |||||
PannelTabs, | |||||
Pannel | |||||
}, | |||||
data () { | |||||
return { | |||||
tabIndex: '1' | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
mounted () { | |||||
}, | |||||
methods: { | |||||
tabChange (info) { | |||||
console.log(info); | |||||
this.tabIndex = info.id | |||||
} | |||||
} | |||||
}; |
@@ -0,0 +1,17 @@ | |||||
.full { | |||||
display: flex; | |||||
flex-direction: column; | |||||
.top { | |||||
height: 50px !important; | |||||
width: 100%; | |||||
display: flex !important; | |||||
align-items: center !important; | |||||
justify-content: flex-end; | |||||
} | |||||
.buttom { | |||||
flex: 1; | |||||
width: 100%; | |||||
} | |||||
} |
@@ -0,0 +1,4 @@ | |||||
<template src='./index.html'/> | |||||
<script lang='js' src='./index.js'></script> | |||||
<style lang='scss' src='./index.scss' scoped> | |||||
</style> |
@@ -0,0 +1,4 @@ | |||||
<Pannel> | |||||
</Pannel> |
@@ -0,0 +1,17 @@ | |||||
import Pannel from '@/components/pannel/index.vue'; | |||||
export default { | |||||
components: { | |||||
Pannel | |||||
}, | |||||
data () { | |||||
return { | |||||
}; | |||||
}, | |||||
created () { | |||||
}, | |||||
mounted () { | |||||
}, | |||||
methods: { | |||||
} | |||||
}; |