Auteur | SHA1 | Bericht | Datum |
---|---|---|---|
|
dac4df1580 | 资金支出分析 | 2 dagen geleden |
|
c9493b9b97 | 饼图和线图 | 2 dagen geleden |
|
84eb6adbd5 | 滚动图标封装 | 2 dagen geleden |
|
f2a4491d45 | 货币资金分析 | 3 dagen geleden |
|
f607bfa181 | 组件布局 | 3 dagen geleden |
|
f91cb02b7f | 项目初始化 | 3 dagen geleden |
@@ -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: { | |||
} | |||
}; |